From 1f9c02928a8580ec8870fa567506d7a66c13f109 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Fri, 8 Jan 2021 19:25:57 -0600 Subject: [PATCH 01/25] Enable connection to Mongo --- api/src/app.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/api/src/app.js b/api/src/app.js index 5490234..2e8f25a 100644 --- a/api/src/app.js +++ b/api/src/app.js @@ -20,17 +20,16 @@ if (process.env.NODE_ENV != 'production') { } // CONNECTION TO MONGO +mongoose.connect(process.env.MONGO_URL, { + useNewUrlParser: true, + useUnifiedTopology: true, +}); -// mongoose.connect(process.env.MONGO_URL, { -// useNewUrlParser: true, -// useUnifiedTopology: true, -// }); - -// mongoose.Promise = global.Promise; +mongoose.Promise = global.Promise; -// mongoose.connection -// .once('open', () => console.log('Connected to MongoLab instance.')) -// .on('error', error => console.log('Error connecting to MongoLab:', error)); +mongoose.connection + .once('open', () => console.log('Connected to MongoLab instance.')) + .on('error', error => console.log('Error connecting to MongoLab:', error)); app.use(helmet()); app.use(cors()); From e72171e6f573ffd6ee41ad99c33bec1fc76d327a Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Fri, 8 Jan 2021 21:24:43 -0600 Subject: [PATCH 02/25] Install passport and express-session --- api/package.json | 5 ++- api/yarn.lock | 95 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 95 insertions(+), 5 deletions(-) diff --git a/api/package.json b/api/package.json index d029684..dd982f9 100644 --- a/api/package.json +++ b/api/package.json @@ -16,13 +16,16 @@ "debug": "~2.6.9", "dotenv": "^8.2.0", "express": "~4.16.1", + "express-session": "^1.17.1", "helmet": "^3.21.1", "http-errors": "~1.6.3", "if-env": "^1.0.4", "isomorphic-unfetch": "^3.0.0", "mongodb": "^3.3.2", "mongoose": "^5.7.5", - "morgan": "~1.9.1" + "morgan": "~1.9.1", + "passport": "^0.4.1", + "passport-google-oauth20": "^2.0.0" }, "devDependencies": { "babel-eslint": "^10.0.3", diff --git a/api/yarn.lock b/api/yarn.lock index 3776827..958098c 100644 --- a/api/yarn.lock +++ b/api/yarn.lock @@ -863,6 +863,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +base64url@3.x.x: + version "3.0.1" + resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" + integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== + base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" @@ -1259,6 +1264,11 @@ cookie@0.3.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + cookiejar@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" @@ -1455,7 +1465,7 @@ denque@^1.4.1: resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf" integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ== -depd@2.0.0: +depd@2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -1817,6 +1827,20 @@ expect@^25.5.0: jest-message-util "^25.5.0" jest-regex-util "^25.2.6" +express-session@^1.17.1: + version "1.17.1" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.1.tgz#36ecbc7034566d38c8509885c044d461c11bf357" + integrity sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q== + dependencies: + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~2.0.0" + on-headers "~1.0.2" + parseurl "~1.3.3" + safe-buffer "5.2.0" + uid-safe "~2.1.5" + express@~4.16.1: version "4.16.4" resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" @@ -3688,6 +3712,11 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== +oauth@0.9.x: + version "0.9.15" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" + integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE= + object-assign@^4: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -3723,7 +3752,7 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -on-headers@~1.0.1: +on-headers@~1.0.1, on-headers@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== @@ -3830,7 +3859,7 @@ parse5@5.1.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== -parseurl@~1.3.2: +parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== @@ -3840,6 +3869,37 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= +passport-google-oauth20@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz#0d241b2d21ebd3dc7f2b60669ec4d587e3a674ef" + integrity sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ== + dependencies: + passport-oauth2 "1.x.x" + +passport-oauth2@1.x.x: + version "1.5.0" + resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.5.0.tgz#64babbb54ac46a4dcab35e7f266ed5294e3c4108" + integrity sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ== + dependencies: + base64url "3.x.x" + oauth "0.9.x" + passport-strategy "1.x.x" + uid2 "0.0.x" + utils-merge "1.x.x" + +passport-strategy@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= + +passport@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" + integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg== + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -3877,6 +3937,11 @@ pause-stream@0.0.11: dependencies: through "~2.3" +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -4021,6 +4086,11 @@ qs@^6.5.1: resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ== +random-bytes@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" + integrity sha1-T2ih3Arli9P7lYSMMDJNt11kNgs= + range-parser@~1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" @@ -4313,6 +4383,11 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -4980,6 +5055,18 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +uid-safe@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" + integrity sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA== + dependencies: + random-bytes "~1.0.0" + +uid2@0.0.x: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + integrity sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I= + undefsafe@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" @@ -5070,7 +5157,7 @@ util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -utils-merge@1.0.1: +utils-merge@1.0.1, utils-merge@1.x.x: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= From 165d5c2825ce3d42079dd52cd00f3636a2066f7a Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Fri, 8 Jan 2021 21:27:02 -0600 Subject: [PATCH 03/25] Change most member attributes to not required --- api/src/models/member.js | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/api/src/models/member.js b/api/src/models/member.js index 1824b18..80c154e 100644 --- a/api/src/models/member.js +++ b/api/src/models/member.js @@ -53,50 +53,50 @@ const classStandingEnum = { }; const Member = new mongoose.Schema({ - firstName: { type: String, required: true }, - lastName: { type: String, required: true }, + firstName: { type: String, required: false }, + lastName: { type: String, required: false }, oauthID: { type: String, required: true, unique: true }, - email: { type: String, required: true, unique: true }, - phone: { type: String, required: true }, - netID: { type: String, required: true }, - UIN: { type: String, required: true }, - major: { type: String, required: true }, - birthdate: { type: Date, required: true }, + email: { type: String, required: false, unique: true }, + phone: { type: String, required: false }, + netID: { type: String, required: false }, + UIN: { type: String, required: false }, + major: { type: String, required: false }, + birthdate: { type: Date, required: false }, github: { type: String, required: false }, snapchat: { type: String, required: false }, instagram: { type: String, required: false }, - areDuesPaid: { type: Boolean, required: true }, + areDuesPaid: { type: Boolean, required: false }, - gradYear: { type: Number, required: true }, + gradYear: { type: Number, required: false }, gradSemester: { type: String, enum: Object.values(semesterEnum), - required: true, + required: false, }, classStanding: { type: String, enum: Object.values(classStandingEnum), - required: true, + required: false, }, - generationYear: { type: Number, required: true }, + generationYear: { type: Number, required: false }, generationSemester: { type: String, enum: Object.values(semesterEnum), - required: true, + required: false, }, location: { type: String, enum: Object.values(locationEnum), - required: true, + required: false, }, role: { type: String, enum: Object.values(roleEnum), - required: true, + required: false, }, level: { @@ -108,7 +108,7 @@ const Member = new mongoose.Schema({ status: { type: String, enum: Object.values(statusEnum), - required: true, + required: false, }, }); From c2058872073596c8e74fb40eb2bac4f17f79b148 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Fri, 8 Jan 2021 21:27:30 -0600 Subject: [PATCH 04/25] Add auth routes --- api/src/api/auth.js | 38 ++++++++++++++++++++++++++++++++++++++ api/src/api/index.js | 2 ++ api/src/routes/index.js | 3 ++- 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 api/src/api/auth.js diff --git a/api/src/api/auth.js b/api/src/api/auth.js new file mode 100644 index 0000000..992b557 --- /dev/null +++ b/api/src/api/auth.js @@ -0,0 +1,38 @@ +const express = require('express'); +const router = express.Router(); +const passport = require('passport'); + +router.get('/user', (req, res) => { + const user = req.user || null; + + res.json({ + code: 200, + data: user, + success: true, + }); +}); + +router.get( + '/login', + passport.authenticate('google', { scope: ['profile', 'email'] }), +); + +router.get( + '/callback', + passport.authenticate('google', { failureRedirect: '/login' }), + (req, res) => { + // Successful authentication, redirect home. + res.redirect('/'); + }, +); + +router.post('/logout', (req, res) => { + req.logout(); + res.json({ + code: 200, + message: 'Logged out.', + success: true, + }); +}); + +module.exports = router; diff --git a/api/src/api/index.js b/api/src/api/index.js index 7f5a1ec..f15c24d 100644 --- a/api/src/api/index.js +++ b/api/src/api/index.js @@ -1,5 +1,7 @@ const home = require('./home'); +const auth = require('./auth'); module.exports = { home, + auth, }; diff --git a/api/src/routes/index.js b/api/src/routes/index.js index f50d2a5..c9f7766 100644 --- a/api/src/routes/index.js +++ b/api/src/routes/index.js @@ -1,8 +1,9 @@ const express = require('express'); const router = express.Router(); -const { home } = require('../api'); +const { home, auth } = require('../api'); router.use('/api/home', home); +router.use('/api/auth', auth); module.exports = router; From a6b98fee6e3e9ccbcffb180721c22951b48c2ed4 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Fri, 8 Jan 2021 21:27:52 -0600 Subject: [PATCH 05/25] Add passport setup with cookie sessions --- api/src/app.js | 19 +++++++++++-- api/src/middleware/passport.js | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 api/src/middleware/passport.js diff --git a/api/src/app.js b/api/src/app.js index 9d3bded..5546e09 100644 --- a/api/src/app.js +++ b/api/src/app.js @@ -7,8 +7,10 @@ const helmet = require('helmet'); const logger = require('morgan'); const mongoose = require('mongoose'); const path = require('path'); -const routes = require('./routes'); +const session = require('express-session'); const bodyParser = require('body-parser'); +const passport = require('passport'); +const routes = require('./routes'); const app = express(); const { errorHandler } = require('./middleware'); @@ -29,7 +31,7 @@ mongoose.Promise = global.Promise; mongoose.connection .once('open', () => console.log('Connected to MongoLab instance.')) - .on('error', error => console.log('Error connecting to MongoLab:', error)); + .on('error', (error) => console.log('Error connecting to MongoLab:', error)); app.use(helmet()); app.use(cors()); @@ -39,6 +41,19 @@ app.use(logger('dev')); app.use(bodyParser.json({ limit: '2.1mb' })); app.use(bodyParser.urlencoded({ limit: '2.1mb', extended: false })); +// Session support, needed for authentication +app.use( + session({ + secret: process.env.SESSION_SECRET, + cookie: {}, + }), +); + +// Passport setup +require('./middleware/passport'); +app.use(passport.initialize()); +app.use(passport.session()); + app.use('/', routes); app.get('/', (req, res) => res.json('API working!')); diff --git a/api/src/middleware/passport.js b/api/src/middleware/passport.js new file mode 100644 index 0000000..9d99e32 --- /dev/null +++ b/api/src/middleware/passport.js @@ -0,0 +1,52 @@ +const GoogleStrategy = require('passport-google-oauth20').Strategy; +const passport = require('passport'); +const Member = require('../models/member'); + +// Defines the default level a user gets assigned with upon first sign-in +const DEFAULT_LEVEL = process.env.DEFAULT_LEVEL || Member.levelEnum.TBD; + +passport.serializeUser((user, done) => { + done(null, user._id); +}); + +passport.deserializeUser((id, done) => { + // Find in DB and return user + Member.findById(id, (err, user) => { + if (err) { + console.error('err'); + done(err); + } + done(null, user); + }); +}); + +passport.use( + new GoogleStrategy( + { + clientID: process.env.GOOGLE_CLIENT_ID, + clientSecret: process.env.GOOGLE_CLIENT_SECRET, + callbackURL: process.env.OAUTH_CALLBACK_URI, + }, + async (accessToken, refreshToken, profile, cb) => { + // find the user in the database based on their oauth id + const user = await Member.findOne({ oauthID: profile.id }); + + console.log(profile); + + if (user) { + // user exists + return cb(null, user); + } else { + const newUser = await new Member({ + firstName: profile.name.givenName, + lastName: profile.name.familyName, + oauthID: profile.id, + email: profile.emails[0].value, + level: DEFAULT_LEVEL, + }).save(); + + cb(null, newUser); + } + }, + ), +); From ccfcf7bde42ae082aa63ee76436cd17adcf56170 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Tue, 12 Jan 2021 12:33:03 -0600 Subject: [PATCH 06/25] Add options for express-session --- api/src/app.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/src/app.js b/api/src/app.js index 06a12f3..fd16826 100644 --- a/api/src/app.js +++ b/api/src/app.js @@ -46,7 +46,10 @@ app.use(bodyParser.urlencoded({ limit: '2.1mb', extended: false })); app.use( session({ secret: process.env.SESSION_SECRET, - cookie: {}, + cookie: { + }, + resave: false, + saveUninitialized: false, }), ); From e823022aaf20aad28a661e4e0059cba2037a531d Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Tue, 12 Jan 2021 12:33:15 -0600 Subject: [PATCH 07/25] Add options for express-session --- api/src/app.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/src/app.js b/api/src/app.js index fd16826..ecfc61e 100644 --- a/api/src/app.js +++ b/api/src/app.js @@ -46,8 +46,7 @@ app.use(bodyParser.urlencoded({ limit: '2.1mb', extended: false })); app.use( session({ secret: process.env.SESSION_SECRET, - cookie: { - }, + cookie: {}, resave: false, saveUninitialized: false, }), From 0d5b7e492f81564404ab5b0fe4ad3908201e2e66 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Tue, 12 Jan 2021 12:59:07 -0600 Subject: [PATCH 08/25] Move passport-setup to root --- api/src/app.js | 2 +- api/src/passport-setup.js | 52 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 api/src/passport-setup.js diff --git a/api/src/app.js b/api/src/app.js index ecfc61e..0e496ad 100644 --- a/api/src/app.js +++ b/api/src/app.js @@ -53,7 +53,7 @@ app.use( ); // Passport setup -require('./middleware/passport'); +require('./passport-setup'); app.use(passport.initialize()); app.use(passport.session()); diff --git a/api/src/passport-setup.js b/api/src/passport-setup.js new file mode 100644 index 0000000..64b180b --- /dev/null +++ b/api/src/passport-setup.js @@ -0,0 +1,52 @@ +const GoogleStrategy = require('passport-google-oauth20').Strategy; +const passport = require('passport'); +const Member = require('./models/member'); + +// Defines the default level a user gets assigned with upon first sign-in +const DEFAULT_LEVEL = process.env.DEFAULT_LEVEL || Member.levelEnum.TBD; + +passport.serializeUser((user, done) => { + done(null, user._id); +}); + +passport.deserializeUser((id, done) => { + // Find in DB and return user + Member.findById(id, (err, user) => { + if (err) { + console.error('err'); + done(err); + } + done(null, user); + }); +}); + +passport.use( + new GoogleStrategy( + { + clientID: process.env.GOOGLE_CLIENT_ID, + clientSecret: process.env.GOOGLE_CLIENT_SECRET, + callbackURL: process.env.OAUTH_CALLBACK_URI, + }, + async (accessToken, refreshToken, profile, cb) => { + // find the user in the database based on their oauth id + const user = await Member.findOne({ oauthID: profile.id }); + + console.log(profile); + + if (user) { + // user exists + return cb(null, user); + } else { + const newUser = await new Member({ + firstName: profile.name.givenName, + lastName: profile.name.familyName, + oauthID: profile.id, + email: profile.emails[0].value, + level: DEFAULT_LEVEL, + }).save(); + + cb(null, newUser); + } + }, + ), +); From 7799472a4cfdd1b58364425bcb433a70fb71ef84 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Tue, 12 Jan 2021 12:59:27 -0600 Subject: [PATCH 09/25] Add middleware for auth --- api/src/middleware/auth.js | 41 +++++++++++++++++++++++++++ api/src/middleware/index.js | 2 ++ api/src/middleware/passport.js | 52 ---------------------------------- 3 files changed, 43 insertions(+), 52 deletions(-) create mode 100644 api/src/middleware/auth.js delete mode 100644 api/src/middleware/passport.js diff --git a/api/src/middleware/auth.js b/api/src/middleware/auth.js new file mode 100644 index 0000000..b4bfd3d --- /dev/null +++ b/api/src/middleware/auth.js @@ -0,0 +1,41 @@ +const { levelEnum } = require('../models/member'); + +const requireLevel = (levels) => (req, res, next) => { + console.log(req.user); + if (!req.user || !levels.includes(req.user.level)) { + return res.status(401).json({ + success: false, + message: 'Unauthorized', + }); + } else { + next(); + } +}; + +const requireRegistered = requireLevel(Object.values(levelEnum)); + +const requireMember = requireLevel([ + levelEnum.ADMIN, + levelEnum.DIRECTOR, + levelEnum.LEAD, + levelEnum.MEMBER, +]); + +const requireLead = requireLevel([ + levelEnum.ADMIN, + levelEnum.DIRECTOR, + levelEnum.LEAD, +]); + +const requireDirector = requireLevel([levelEnum.ADMIN, levelEnum.DIRECTOR]); + +const requireAdmin = requireLevel([levelEnum.ADMIN]); + +module.exports = { + requireLevel, + requireRegistered, + requireMember, + requireLead, + requireDirector, + requireAdmin, +}; diff --git a/api/src/middleware/index.js b/api/src/middleware/index.js index 5027954..977feb3 100644 --- a/api/src/middleware/index.js +++ b/api/src/middleware/index.js @@ -1,7 +1,9 @@ const errorHandler = require('./errorHandler'); const errorWrap = require('./errorWrap'); +const auth = require('./auth'); module.exports = { errorHandler, errorWrap, + auth, }; diff --git a/api/src/middleware/passport.js b/api/src/middleware/passport.js deleted file mode 100644 index 9d99e32..0000000 --- a/api/src/middleware/passport.js +++ /dev/null @@ -1,52 +0,0 @@ -const GoogleStrategy = require('passport-google-oauth20').Strategy; -const passport = require('passport'); -const Member = require('../models/member'); - -// Defines the default level a user gets assigned with upon first sign-in -const DEFAULT_LEVEL = process.env.DEFAULT_LEVEL || Member.levelEnum.TBD; - -passport.serializeUser((user, done) => { - done(null, user._id); -}); - -passport.deserializeUser((id, done) => { - // Find in DB and return user - Member.findById(id, (err, user) => { - if (err) { - console.error('err'); - done(err); - } - done(null, user); - }); -}); - -passport.use( - new GoogleStrategy( - { - clientID: process.env.GOOGLE_CLIENT_ID, - clientSecret: process.env.GOOGLE_CLIENT_SECRET, - callbackURL: process.env.OAUTH_CALLBACK_URI, - }, - async (accessToken, refreshToken, profile, cb) => { - // find the user in the database based on their oauth id - const user = await Member.findOne({ oauthID: profile.id }); - - console.log(profile); - - if (user) { - // user exists - return cb(null, user); - } else { - const newUser = await new Member({ - firstName: profile.name.givenName, - lastName: profile.name.familyName, - oauthID: profile.id, - email: profile.emails[0].value, - level: DEFAULT_LEVEL, - }).save(); - - cb(null, newUser); - } - }, - ), -); From c903f280aa36937b5a8f56d6a2694eace2dc1e55 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Tue, 12 Jan 2021 12:59:38 -0600 Subject: [PATCH 10/25] Change auth routes to use result instead of data --- api/src/api/auth.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/api/src/api/auth.js b/api/src/api/auth.js index 992b557..47b51ab 100644 --- a/api/src/api/auth.js +++ b/api/src/api/auth.js @@ -6,8 +6,7 @@ router.get('/user', (req, res) => { const user = req.user || null; res.json({ - code: 200, - data: user, + result: user, success: true, }); }); @@ -29,8 +28,7 @@ router.get( router.post('/logout', (req, res) => { req.logout(); res.json({ - code: 200, - message: 'Logged out.', + message: 'Logged out', success: true, }); }); From ea19c9ff02ed92c9ac38bdf1088529ae100691d8 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Tue, 12 Jan 2021 12:59:49 -0600 Subject: [PATCH 11/25] Add protected route as an example --- api/src/api/home.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/api/src/api/home.js b/api/src/api/home.js index b641d3a..3fabc1f 100644 --- a/api/src/api/home.js +++ b/api/src/api/home.js @@ -1,6 +1,7 @@ const express = require('express'); const router = express.Router(); const { errorWrap } = require('../middleware'); +const { requireRegistered } = require('../middleware/auth'); const Home = require('../models/home'); @@ -16,4 +17,17 @@ router.get( }), ); +router.get( + '/registeredOnly', + [requireRegistered], + errorWrap(async (req, res) => { + const home = await Home.findOne(); + res.status(200).json({ + message: `Successfully returned home text`, + success: true, + result: home.text, + }); + }), +); + module.exports = router; From ab65429c2385411f60418aa3328d19dda732d085 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Tue, 12 Jan 2021 13:05:17 -0600 Subject: [PATCH 12/25] Remove home test and replace with dummy test --- api/test/dummy.test.js | 3 +++ api/test/home.test.js | 26 -------------------------- 2 files changed, 3 insertions(+), 26 deletions(-) create mode 100644 api/test/dummy.test.js delete mode 100644 api/test/home.test.js diff --git a/api/test/dummy.test.js b/api/test/dummy.test.js new file mode 100644 index 0000000..344b6f2 --- /dev/null +++ b/api/test/dummy.test.js @@ -0,0 +1,3 @@ +describe('Dummy test', () => { + test('Dummy test', () => {}); +}); diff --git a/api/test/home.test.js b/api/test/home.test.js deleted file mode 100644 index a3f1807..0000000 --- a/api/test/home.test.js +++ /dev/null @@ -1,26 +0,0 @@ -const app = require('../src/app'); -const mongoose = require('mongoose'); -const request = require('supertest'); - -afterAll(async () => { - await mongoose.connection.close(); -}); - -describe('GET / ', () => { - test('API should return working message', async () => { - const response = await request(app).get('/'); - expect(response.body).toEqual('API working!'); - expect(response.statusCode).toBe(200); - }); -}); - -describe('GET /api/home/ ', () => { - test('API should return home text', async () => { - const response = await request(app).get('/api/home/'); - expect(response.body.message).toEqual('Successfully returned home text'); - expect(response.body.result).toEqual( - "You've connected the database! Isn't it so beautiful???", - ); - expect(response.statusCode).toBe(200); - }); -}); From 08b8433eeae53041b8666c4227c499a1da099a83 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Tue, 12 Jan 2021 22:58:28 -0600 Subject: [PATCH 13/25] Remove dummy test --- api/test/dummy.test.js | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 api/test/dummy.test.js diff --git a/api/test/dummy.test.js b/api/test/dummy.test.js deleted file mode 100644 index 344b6f2..0000000 --- a/api/test/dummy.test.js +++ /dev/null @@ -1,3 +0,0 @@ -describe('Dummy test', () => { - test('Dummy test', () => {}); -}); From f9040195819a9b72edaa86863569115bc92cc9e8 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Tue, 12 Jan 2021 22:58:37 -0600 Subject: [PATCH 14/25] Remove console.log --- api/src/passport-setup.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/src/passport-setup.js b/api/src/passport-setup.js index 64b180b..d788101 100644 --- a/api/src/passport-setup.js +++ b/api/src/passport-setup.js @@ -31,8 +31,6 @@ passport.use( // find the user in the database based on their oauth id const user = await Member.findOne({ oauthID: profile.id }); - console.log(profile); - if (user) { // user exists return cb(null, user); From fc9e9d6949309323197db0aabb86a877a74b676a Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Tue, 12 Jan 2021 22:58:47 -0600 Subject: [PATCH 15/25] Remove extra || null --- api/src/api/auth.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/api/src/api/auth.js b/api/src/api/auth.js index 47b51ab..99ae002 100644 --- a/api/src/api/auth.js +++ b/api/src/api/auth.js @@ -3,10 +3,8 @@ const router = express.Router(); const passport = require('passport'); router.get('/user', (req, res) => { - const user = req.user || null; - res.json({ - result: user, + result: req.user || null, success: true, }); }); From 288fb436441d6a55883ab5e6985b297cbf5718f7 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Tue, 12 Jan 2021 23:35:52 -0600 Subject: [PATCH 16/25] Add back home.test.js and new env vars to api.yaml --- .github/workflows/api.yaml | 4 ++++ api/test/home.test.js | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 api/test/home.test.js diff --git a/.github/workflows/api.yaml b/.github/workflows/api.yaml index d2858be..685a452 100644 --- a/.github/workflows/api.yaml +++ b/.github/workflows/api.yaml @@ -79,3 +79,7 @@ jobs: run: yarn test env: MONGO_URL: ${{ secrets.MONGO_URL }} + GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} + GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }} + OAUTH_CALLBACK_URI: ${{ secrets.OAUTH_CALLBACK_URI }} + SESSION_SECRET: ${{ secrets.SESSION_SECRET }} diff --git a/api/test/home.test.js b/api/test/home.test.js new file mode 100644 index 0000000..a3f1807 --- /dev/null +++ b/api/test/home.test.js @@ -0,0 +1,26 @@ +const app = require('../src/app'); +const mongoose = require('mongoose'); +const request = require('supertest'); + +afterAll(async () => { + await mongoose.connection.close(); +}); + +describe('GET / ', () => { + test('API should return working message', async () => { + const response = await request(app).get('/'); + expect(response.body).toEqual('API working!'); + expect(response.statusCode).toBe(200); + }); +}); + +describe('GET /api/home/ ', () => { + test('API should return home text', async () => { + const response = await request(app).get('/api/home/'); + expect(response.body.message).toEqual('Successfully returned home text'); + expect(response.body.result).toEqual( + "You've connected the database! Isn't it so beautiful???", + ); + expect(response.statusCode).toBe(200); + }); +}); From e7138b225a3771560cad3106b347dc519096edcf Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Wed, 13 Jan 2021 01:20:56 -0600 Subject: [PATCH 17/25] Add example dev.env --- api/config/dev.env.example | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 api/config/dev.env.example diff --git a/api/config/dev.env.example b/api/config/dev.env.example new file mode 100644 index 0000000..30696d4 --- /dev/null +++ b/api/config/dev.env.example @@ -0,0 +1,6 @@ +MONGO_URL=mongodb://localhost +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= +SESSION_SECRET= +OAUTH_CALLBACK_URI=http://localhost:9000/api/auth/redirectURI +FRONTEND_URI=http://localhost:3000 \ No newline at end of file From af713651244dd3c4daa1e422cda9cfac677285ab Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Wed, 13 Jan 2021 01:21:19 -0600 Subject: [PATCH 18/25] Add redirectURI endpoint to allow for changing Vercel subdomains --- api/src/api/auth.js | 50 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/api/src/api/auth.js b/api/src/api/auth.js index 99ae002..aec061e 100644 --- a/api/src/api/auth.js +++ b/api/src/api/auth.js @@ -2,6 +2,12 @@ const express = require('express'); const router = express.Router(); const passport = require('passport'); +// Where to go after successful authentication +const LOGIN_SUCCESS_REDIRECT = process.env.FRONTEND_URI || '/'; +// Defines the callback endpoint which will be passed to LAH's redirect URI +// via Google OAuth's state parameter +const CALLBACK_ENDPOINT = '/api/auth/callback'; + router.get('/user', (req, res) => { res.json({ result: req.user || null, @@ -9,17 +15,51 @@ router.get('/user', (req, res) => { }); }); -router.get( - '/login', - passport.authenticate('google', { scope: ['profile', 'email'] }), -); +router.get('/login', (req, res, next) => { + // Construct the "callback" url by concatenating the current base URL (host) with the callback URL + // We do all this to use one single callback URL so it works with Vercel deploying on multiple + // domains. See LAH's api/auth/login.js for more details on how this works + const callbackUrl = `${req.protocol}://${req.get( + 'host', + )}${CALLBACK_ENDPOINT}`; + const state = callbackUrl + ? Buffer.from(JSON.stringify({ callbackUrl })).toString('base64') + : undefined; + + const auth = passport.authenticate('google', { + scope: ['profile', 'email'], + state, + }); + auth(req, res, next); +}); + +router.get('/redirectURI', (req, res) => { + try { + // If we are here, this endpoint is likely being run on the MAIN deployment + const { state } = req.query; + // Grab the branch deployment (lah-branch-deploy.hack4impact.now.sh) for example + const { callbackUrl } = JSON.parse(Buffer.from(state, 'base64').toString()); + if (typeof callbackUrl === 'string') { + // Reconstruct the URL and redirect + const callbackURL = `${callbackUrl}?${req._parsedUrl.query}`; + return res.redirect(callbackURL); + } + // There was no base + return res.redirect(CALLBACK_ENDPOINT); + } catch (e) { + return res.status(400).json({ + message: 'Something went wrong with the URL redirection', + success: false, + }); + } +}); router.get( '/callback', passport.authenticate('google', { failureRedirect: '/login' }), (req, res) => { // Successful authentication, redirect home. - res.redirect('/'); + res.redirect(LOGIN_SUCCESS_REDIRECT); }, ); From e70b9ec23c073521f50525a29b19b626858570cb Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Wed, 13 Jan 2021 01:36:07 -0600 Subject: [PATCH 19/25] Add redirect URLs as parameters for /login --- api/src/api/auth.js | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/api/src/api/auth.js b/api/src/api/auth.js index aec061e..b3b1f94 100644 --- a/api/src/api/auth.js +++ b/api/src/api/auth.js @@ -2,8 +2,6 @@ const express = require('express'); const router = express.Router(); const passport = require('passport'); -// Where to go after successful authentication -const LOGIN_SUCCESS_REDIRECT = process.env.FRONTEND_URI || '/'; // Defines the callback endpoint which will be passed to LAH's redirect URI // via Google OAuth's state parameter const CALLBACK_ENDPOINT = '/api/auth/callback'; @@ -16,19 +14,24 @@ router.get('/user', (req, res) => { }); router.get('/login', (req, res, next) => { + // Get URLs to redirect to on success and failure + const { successRedirect = '/', failureRedirect = '/login' } = req.query; // Construct the "callback" url by concatenating the current base URL (host) with the callback URL // We do all this to use one single callback URL so it works with Vercel deploying on multiple // domains. See LAH's api/auth/login.js for more details on how this works const callbackUrl = `${req.protocol}://${req.get( 'host', )}${CALLBACK_ENDPOINT}`; - const state = callbackUrl - ? Buffer.from(JSON.stringify({ callbackUrl })).toString('base64') - : undefined; + // State object that will be passed to OAuth and back to our callback + const state = { + callbackUrl, + successRedirect, + failureRedirect, + }; const auth = passport.authenticate('google', { scope: ['profile', 'email'], - state, + state: Buffer.from(JSON.stringify(state)).toString('base64'), }); auth(req, res, next); }); @@ -56,7 +59,16 @@ router.get('/redirectURI', (req, res) => { router.get( '/callback', - passport.authenticate('google', { failureRedirect: '/login' }), + (req, res, next) => { + const { state } = req.query; + const { successRedirect, failureRedirect } = JSON.parse(Buffer.from(state, 'base64').toString()); + + const auth = passport.authenticate('google', { + successRedirect, + failureRedirect, + }); + auth(req, res, next); + }, (req, res) => { // Successful authentication, redirect home. res.redirect(LOGIN_SUCCESS_REDIRECT); From ebd34ed1b3c6b5f0b841e85e38a349f4f86bf341 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Wed, 13 Jan 2021 01:41:32 -0600 Subject: [PATCH 20/25] Format auth.js --- api/src/api/auth.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/src/api/auth.js b/api/src/api/auth.js index b3b1f94..10bff2c 100644 --- a/api/src/api/auth.js +++ b/api/src/api/auth.js @@ -61,7 +61,9 @@ router.get( '/callback', (req, res, next) => { const { state } = req.query; - const { successRedirect, failureRedirect } = JSON.parse(Buffer.from(state, 'base64').toString()); + const { successRedirect, failureRedirect } = JSON.parse( + Buffer.from(state, 'base64').toString(), + ); const auth = passport.authenticate('google', { successRedirect, From 8dc2b4d0be3b43abb3476d88ffa95a4628d50b70 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Wed, 13 Jan 2021 01:43:06 -0600 Subject: [PATCH 21/25] Remove FRONTEND_URI from example env file --- api/config/dev.env.example | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/config/dev.env.example b/api/config/dev.env.example index 30696d4..fd9cb77 100644 --- a/api/config/dev.env.example +++ b/api/config/dev.env.example @@ -2,5 +2,4 @@ MONGO_URL=mongodb://localhost GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= SESSION_SECRET= -OAUTH_CALLBACK_URI=http://localhost:9000/api/auth/redirectURI -FRONTEND_URI=http://localhost:3000 \ No newline at end of file +OAUTH_CALLBACK_URI=http://localhost:9000/api/auth/redirectURI \ No newline at end of file From d4f710f9e368a08418a657213b1869dcc875344c Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Wed, 13 Jan 2021 01:58:50 -0600 Subject: [PATCH 22/25] Enable failure flash --- api/src/api/auth.js | 1 + 1 file changed, 1 insertion(+) diff --git a/api/src/api/auth.js b/api/src/api/auth.js index 10bff2c..94966d7 100644 --- a/api/src/api/auth.js +++ b/api/src/api/auth.js @@ -68,6 +68,7 @@ router.get( const auth = passport.authenticate('google', { successRedirect, failureRedirect, + failureFlash: true, }); auth(req, res, next); }, From 4b5a8a12a25afee92012d2bd8daab01fb8448d94 Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Wed, 13 Jan 2021 15:28:11 -0600 Subject: [PATCH 23/25] Add back .env files --- api/config/dev.env | 5 +++++ api/config/production.env | 2 +- api/config/test.env | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 api/config/dev.env diff --git a/api/config/dev.env b/api/config/dev.env new file mode 100644 index 0000000..c74a452 --- /dev/null +++ b/api/config/dev.env @@ -0,0 +1,5 @@ +MONGO_URL= +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= +SESSION_SECRET=keyboard cat +OAUTH_CALLBACK_URI=http://localhost:9000/api/auth/redirectURI \ No newline at end of file diff --git a/api/config/production.env b/api/config/production.env index a7552d1..553b941 100644 --- a/api/config/production.env +++ b/api/config/production.env @@ -1 +1 @@ -MONGO_URL=production-mongo +OAUTH_CALLBACK_URI=${VERCEL_URL}/api/auth/redirectURI diff --git a/api/config/test.env b/api/config/test.env index 4ddcce8..4ebe874 100644 --- a/api/config/test.env +++ b/api/config/test.env @@ -1 +1,5 @@ -MONGO_URL=test-mongo +MONGO_URL= +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= +SESSION_SECRET= +OAUTH_CALLBACK_URI=http://localhost:9000/api/auth/redirectURI \ No newline at end of file From 3814432458c9a6a59d1ab013eab069bf3d57d14f Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Wed, 13 Jan 2021 15:36:18 -0600 Subject: [PATCH 24/25] Add vercel env vars --- api/config/production.env | 2 +- vercel.json | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/api/config/production.env b/api/config/production.env index 553b941..693cf22 100644 --- a/api/config/production.env +++ b/api/config/production.env @@ -1 +1 @@ -OAUTH_CALLBACK_URI=${VERCEL_URL}/api/auth/redirectURI +OAUTH_CALLBACK_URI=${VERCEL_URL}/api/auth/redirectURI \ No newline at end of file diff --git a/vercel.json b/vercel.json index f857491..a83ef84 100644 --- a/vercel.json +++ b/vercel.json @@ -1,7 +1,11 @@ { "regions": ["iad1"], "env": { - "MONGO_URL": "@memberdb_tool_db_url" + "MONGO_URL": "@memberdb_tool_db_url", + "GOOGLE_CLIENT_ID": "@memberdb_tool_google_client_id", + "GOOGLE_CLIENT_SECRET": "@memberdb_tool_google_client_secret", + "SESSION_SECRET": "@memberdb_tool_session_secret", + "OAUTH_CALLBACK_URI": "https://memberdb-tool.vercel.app/api/auth/redirectURI" }, "builds": [ { "src": "api/src/app.js", "use": "@now/node" }, @@ -40,6 +44,3 @@ { "src": "/(.*)", "dest": "client/index.html" } ] } - - - From aa2969bf286c886b8916817f93bf1b837c7122db Mon Sep 17 00:00:00 2001 From: Jeffrey Tang Date: Wed, 13 Jan 2021 15:41:24 -0600 Subject: [PATCH 25/25] Remove OAUTH_CALLBACK_URI from production env --- api/config/production.env | 1 - 1 file changed, 1 deletion(-) diff --git a/api/config/production.env b/api/config/production.env index 693cf22..e69de29 100644 --- a/api/config/production.env +++ b/api/config/production.env @@ -1 +0,0 @@ -OAUTH_CALLBACK_URI=${VERCEL_URL}/api/auth/redirectURI \ No newline at end of file