diff --git a/src/server/Server.js b/src/server/Server.js index acff59d..3149e1f 100644 --- a/src/server/Server.js +++ b/src/server/Server.js @@ -6,6 +6,7 @@ const http = require('node:http'); // External const { LoggerClient } = require('@navy.gif/logger'); +const Strategy = require('@navy.gif/passport-discord'); // const { Collection } = require('@discordjs/collection'); const express = require('express'); const { default: helmet } = require('helmet'); @@ -55,16 +56,20 @@ class Server extends EventEmitter { this.authenticator = new Authenticator(this, this.userDatabase, { mongo: this.mongodb, secret: SECRET, - discordID: DISCORD_ID, - discordScope: discord.scope, - discordSecret: DISCORD_SECRET, - discordVersion: discord.version, - callbackURL: `${this.baseURL}${callbackURL}`, cookie: { secure: true } }); + // Probably move this out of the constructor later + this.authenticator.addStrategy('discord', new Strategy({ + clientID: DISCORD_ID, clientSecret: DISCORD_SECRET, callbackURL: this.baseURL + callbackURL + '/discord', scope: discord.scope, version: discord.version + }, async (accessToken, refreshToken, profile, callback) => { + this.logger.info(`${profile.username} (${profile.id}) is logging in.`); + const user = await this.userdb.userFromDiscord(profile); + callback(null, user); + })); + // Expecting every other env to be behind a proxy if (NODE_ENV !== 'development') this.app.set('trust proxy', 1); diff --git a/src/server/middleware/Authenticator.js b/src/server/middleware/Authenticator.js index 275efc9..5744e8d 100644 --- a/src/server/middleware/Authenticator.js +++ b/src/server/middleware/Authenticator.js @@ -3,7 +3,6 @@ const { Util } = require('../../util'); const session = require('express-session'); const MongoStore = require('connect-mongo'); -const Strategy = require('@navy.gif/passport-discord'); const Passport = require('passport'); /** @@ -27,10 +26,7 @@ class Authenticator { * } * @memberof Authenticator */ - constructor (server, users, { - mongo, secret, discordID, discordSecret, callbackURL, discordScope, discordVersion, - cookie = { } - }) { + constructor (server, users, { mongo, secret, cookie = { } }) { if (!(users instanceof AbstractUserDatabase)) Util.fatal(new Error(`Expecting user database to be an instance inheriting AbstractUserDatabase`)); this.userdb = users; @@ -62,15 +58,17 @@ class Authenticator { callback(null, user); }); - // TODO: Should probably allow injection of strategies instead of hardcoding this this through a function - this.passport.use('discord', new Strategy({ - clientID: discordID, clientSecret: discordSecret, callbackURL: callbackURL + '/discord', scope: discordScope, version: discordVersion - }, async (accessToken, refreshToken, profile, callback) => { - this.logger.info(`${profile.username} (${profile.id}) is logging in.`); - const user = await this.userdb.userFromDiscord(profile); - callback(null, user); - })); + } + addStrategy (name, strategy) { + this.logger.info(`Adding ${name} authentication strategy`); + this.passport.use(name, strategy); + // Quick access getter to get the middleware for authenticating + Object.defineProperty(this, name, { + get: () => { + return this.passport.authenticate(name, { failureRedirect: '/login/fail' }); + } + }); } // Getters for bound functions to avoid having to bind them elsewhere