diff --git a/plugins/auth-backend/src/providers/github/router.ts b/plugins/auth-backend/src/providers/github/router.ts deleted file mode 100644 index a1c6efa64f..0000000000 --- a/plugins/auth-backend/src/providers/github/router.ts +++ /dev/null @@ -1,22 +0,0 @@ -import express from 'express'; -import Router from 'express-promise-router'; - -export const router = Router(); -router.get('/', async (_req: express.Request, res: express.Response) => { - res.send('initiate auth'); -}); - -router.get('/login', async (_req: express.Request, res: express.Response) => { - res.send('github provider login'); -}); - -router.get('/logout', async (_req: express.Request, res: express.Response) => { - res.send('github provider logout'); -}); - -router.get( - '/handler/frame', - async (req: express.Request, res: express.Response) => { - res.send('github provider frame response handler'); - }, -); diff --git a/plugins/auth-backend/src/providers/google/provider.ts b/plugins/auth-backend/src/providers/google/provider.ts index 0754e0abc0..94f6ca7fcc 100644 --- a/plugins/auth-backend/src/providers/google/provider.ts +++ b/plugins/auth-backend/src/providers/google/provider.ts @@ -1,13 +1,55 @@ import passport from 'passport'; import express from 'express'; -import Router from 'express-promise-router'; import { Strategy as GoogleStrategy } from 'passport-google-oauth20'; -import { AuthProviderHandlers, AuthResponse } from './../types'; +import { + AuthProvider, + AuthProviderRouteHandlers, + AuthResponse, +} from './../types'; -export const provider = { - makeStrategy(options: any): passport.Strategy { +export class GoogleAuthProvider + implements AuthProvider, AuthProviderRouteHandlers { + providerConfig: any; + constructor(providerConfig: any) { + this.providerConfig = providerConfig; + } + + start( + req: express.Request, + res: express.Response, + next: express.NextFunction, + ) { + const scopes = req.query.scopes?.toString().split(','); + return passport.authenticate('google', { + scope: scopes, + accessType: 'offline', + prompt: 'consent', + })(req, res, next); + } + frameHandler( + req: express.Request, + res: express.Response, + next: express.NextFunction, + ) { + return passport.authenticate('google', function (_, user) { + postMessageResponse(res, { + type: 'auth-result', + payload: user, + }); + })(req, res, next); + } + + logout( + req: express.Request, + res: express.Response, + next: express.NextFunction, + ) { + return res.send('logout!'); + } + + strategy(): passport.Strategy { return new GoogleStrategy( - { ...options, passReqToCallback: true }, + { ...this.providerConfig.options, passReqToCallback: true }, function ( _req: any, accessToken: any, @@ -18,56 +60,8 @@ export const provider = { cb(undefined, { profile, accessToken, refreshToken }); }, ); - }, - makeRouter(): express.Router { - return defaultRouter(GoogleAuthProviderHandler); - }, -}; - -const defaultRouter = (handlers: AuthProviderHandlers) => { - const router = Router(); - router.get('/start', handlers.start); - router.get('/handler/frame', handlers.handle); - router.get('/logout', handlers.logout); - if (handlers.refresh) { - router.get('/refreshToken', handlers.refresh); } - return router; -}; - -// Make this a class -// add a getStrategy method -// pass the config as a new constructor - -// class GoogleAuthProvider implements AuthProviderHandlers { -// config: any; -// constructor(config: any) { -// this.config = config; -// } - -// } - -export const GoogleAuthProviderHandler: AuthProviderHandlers = { - start(req, res, next) { - const scopes = req.query.scopes?.toString().split(','); - return passport.authenticate('google', { - scope: scopes, - accessType: 'offline', - prompt: 'consent', - })(req, res, next); - }, - handle(req, res, next) { - return passport.authenticate('google', function (_, user) { - postMessageResponse(res, { - type: 'oauth-result', - payload: user, - }); - })(req, res, next); - }, - logout(_req, res, _next) { - return res.send('logout!'); - }, -}; +} const postMessageResponse = (res: express.Response, data: AuthResponse) => { const jsonData = JSON.stringify(data); diff --git a/plugins/auth-backend/src/providers/index.ts b/plugins/auth-backend/src/providers/index.ts index 7bfd10224e..ea58df2fad 100644 --- a/plugins/auth-backend/src/providers/index.ts +++ b/plugins/auth-backend/src/providers/index.ts @@ -1,14 +1,31 @@ -import { AuthProvider } from './types'; -import { provider as GoogleAuthProvider } from './google/provider'; +import Router from 'express-promise-router'; +import { AuthProviderRouteHandlers, AuthProviderFactories } from './types'; -const providerFactories: AuthProvider = { +import { GoogleAuthProvider } from './google/provider'; + +const providerFactories: AuthProviderFactories = { google: GoogleAuthProvider, }; export const makeProvider = (config: any) => { const provider = config.provider; - const providerFactory = providerFactories[provider]; - const strategy = providerFactory.makeStrategy(config.options); - const providerRouter = providerFactory.makeRouter(); + const providerImpl = providerFactories[provider]; + if (!providerImpl) { + throw Error(`Provider Implementation missing for provider: ${provider}`); + } + const providerInstance = new providerImpl(config); + const strategy = providerInstance.strategy(); + const providerRouter = defaultRouter(providerInstance); return { provider, strategy, providerRouter }; }; + +export const defaultRouter = (provider: AuthProviderRouteHandlers) => { + const router = Router(); + router.get('/start', provider.start); + router.get('/handler/frame', provider.frameHandler); + router.get('/logout', provider.logout); + if (provider.refresh) { + router.get('/refreshToken', provider.refresh); + } + return router; +}; diff --git a/plugins/auth-backend/src/providers/types.ts b/plugins/auth-backend/src/providers/types.ts index d76b1c74fe..1a9c609724 100644 --- a/plugins/auth-backend/src/providers/types.ts +++ b/plugins/auth-backend/src/providers/types.ts @@ -1,13 +1,13 @@ import express from 'express'; import passport from 'passport'; -export type AuthProviderHandlers = { +export interface AuthProviderRouteHandlers { start( req: express.Request, res: express.Response, next: express.NextFunction, ): Promise; - handle( + frameHandler( req: express.Request, res: express.Response, next: express.NextFunction, @@ -22,12 +22,15 @@ export type AuthProviderHandlers = { res: express.Response, next: express.NextFunction, ): express.Response; -}; +} +export interface AuthProvider { + strategy(): passport.Strategy; + router?(): express.Router; +} -export type AuthProvider = { +export type AuthProviderFactories = { [key: string]: { - makeStrategy(options: any): passport.Strategy; - makeRouter(): express.Router; + new (providerConfig: any): AuthProvider & AuthProviderRouteHandlers; }; }; @@ -38,7 +41,12 @@ export type AuthInfo = { expiresAt?: number; }; -export type AuthResponse = { - type: string; - payload: AuthInfo; -}; +export type AuthResponse = + | { + type: 'auth-result'; + payload: AuthInfo; + } + | { + type: 'auth-result'; + error: Error | undefined; + };