Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,31 @@ node_modules/

# Settings
.idea/
=======
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

api/config/config.env
database
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Follow the instructions with [local](README.md#local-environment) or [container]

## Languages and style guide

The project currently uses static files to render the content, and run client-side JavaScript. HTML, JavaScript and CSS knowledge is recommended for code contributions.
The project currently uses static files to render the content, and run database-side JavaScript. HTML, JavaScript and CSS knowledge is recommended for code contributions.

Please follow the existing code style, and avoid changes in Pull Requests, for example indent changes.

Expand Down
39 changes: 39 additions & 0 deletions api/auth/strategy/GoogleStrategy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const User = require("../../models/User");
const defaultHelpers = require("../../serverHelpers/defaultsHelpers");

const googleStrategy = new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "/api/auth/google/callback",
}, authCallback);

// We identify users at login using emails, which allows users to sign in with
// multiple kinds of accounts sharing the same email.
async function authCallback(accessToken, refreshToken, profile, done) {
try {
const currentEmail = profile["emails"][0]["value"];
const existingUser = await User.findOne({email: currentEmail});
if (existingUser) {
done(null, existingUser);
} else {
const newUser = new User({
googleId: profile["id"],
email: currentEmail,
profilePicture: profile["photos"][0]["value"],
displayName: profile["displayName"],
name: {
givenName: profile["name"]["givenName"],
familyName: profile["name"]["familyName"],
}
});
await newUser.save();
await defaultHelpers.loadButtonDefaultsForNewUser(newUser._id.toString());
done(null, newUser);
}
} catch (e) {
console.error(e);
}
}

module.exports = googleStrategy;
9 changes: 9 additions & 0 deletions api/config/cloudinary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const cloudinary = require("cloudinary").v2;

cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
});

module.exports = cloudinary;
22 changes: 22 additions & 0 deletions api/config/database.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const mongoose = require("mongoose");

let database = new mongoose.Mongoose();
let dbname = "userdata";
let parameters = "?retryWrites=true&w=majority";
let dbConnectionString;

if (process.env.MODE === "production") {
dbConnectionString = process.env.MONGODB_URI_PRODUCTION + dbname + parameters;
} else {
dbConnectionString = process.env.MONGODB_URI_DEVELOPMENT + dbname + parameters;
}

database.connect(dbConnectionString).catch(e => {
console.log(e.message);
process.exit();
});

module.exports = {
database,
dbConnectionString
};
19 changes: 19 additions & 0 deletions api/config/multer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
let multer = require("multer");
let path = require("path");

const VALID_EXT_NAMES = [".png", ".jpeg", ".jpg", ".svg"];
const MAX_MEGABYTES_ALLOWED = 5;

module.exports = multer({
dest: path.join(__dirname, "..", "tmp", "uploads"),
fileFilter(req, file, callback) {
let ext = path.extname(file.originalname);
if (!VALID_EXT_NAMES.includes(ext)) {
callback(new Error(`File must be one of these types: ${VALID_EXT_NAMES.join(", ")}`), false);
} else if (file.size >= MAX_MEGABYTES_ALLOWED * 1024 ** 2) {
callback(new Error(`File must be smaller than ${MAX_MEGABYTES_ALLOWED} megabytes.`), false);
} else {
callback(null, true);
}
},
});
46 changes: 46 additions & 0 deletions api/config/passport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const passport = require("passport");
const session = require("express-session");
const googleStrategy = require("../auth/strategy/GoogleStrategy");
const Users = require("../models/User");
const MongoStore = require("connect-mongo");
const {dbConnectionString} = require("./database");

/**
* Adds Google authorization and other OAuth middlewares in the future.
*
* @param expressApp {Express} The ExpressJS application to add patches to.
*/
function addAuthorization(expressApp) {
const newSession = session({
secret: "TalkToMe",
resave: false,
saveUninitialized: false,
store: new MongoStore({
mongoUrl: dbConnectionString
}),
});

expressApp.use(newSession);
expressApp.use(passport.initialize({}));
expressApp.use(passport.session({}));
passport.use(googleStrategy);

passport.serializeUser((user, done) => {
console.log(user._id);
done(null, user._id);
});
passport.deserializeUser((id, done) => {
void async function() {
let user, error = null;
try {
user = await Users.findById(id);
} catch (e) {
error = e;
}
done(error, user);
}();
});
}


module.exports = addAuthorization;
32 changes: 32 additions & 0 deletions api/config/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Environment setup.
const dotenv = require("dotenv");
const path = require("path");
dotenv.config({path: path.join(__dirname, "config.env")});

// Database setup.
require("./database");
console.log("Connecting to MongoDB server.");

// Servers and middlewares.
const express = require("express");
const cors = require("cors");
const app = express();

app.use(express.urlencoded({extended: true}));
app.use(express.json());
app.use(cors());

// Authorization middleware and session login.
const addAuthorization = require("./passport");
addAuthorization(app);

let PORT = process.env.PORT || process.env.PORT_DEVELOPMENT;
if (process.env.MODE !== "production") {
PORT = process.env.PORT_DEVELOPMENT;
}

app.listen(PORT, () => {
console.log("Listening at port " + PORT);
});

module.exports = {app};
Loading