From 422d85b67da28eb844faa78c8fae1257463112de Mon Sep 17 00:00:00 2001 From: Raghunandan Date: Mon, 18 May 2020 22:24:39 +0200 Subject: [PATCH] move provider factories from router to src/providers --- plugins/auth-backend/src/providers/config.ts | 9 -- .../src/providers/google/provider.ts | 67 ++++++++++ .../src/providers/google/router.ts | 34 ----- plugins/auth-backend/src/providers/index.ts | 17 +++ plugins/auth-backend/src/providers/types.ts | 44 +++++++ plugins/auth-backend/src/service/router.ts | 124 +----------------- 6 files changed, 130 insertions(+), 165 deletions(-) create mode 100644 plugins/auth-backend/src/providers/google/provider.ts delete mode 100644 plugins/auth-backend/src/providers/google/router.ts create mode 100644 plugins/auth-backend/src/providers/index.ts create mode 100644 plugins/auth-backend/src/providers/types.ts diff --git a/plugins/auth-backend/src/providers/config.ts b/plugins/auth-backend/src/providers/config.ts index b899347938..92d50ee208 100644 --- a/plugins/auth-backend/src/providers/config.ts +++ b/plugins/auth-backend/src/providers/config.ts @@ -8,13 +8,4 @@ export const providers = [ passReqToCallback: true, }, }, - // { - // provider: 'github', - // options: { - // clientID: process.env.GITHUB_CLIENT_ID!, - // clientSecret: process.env.GITHUB_CLIENT_SECRET!, - // callbackURL: 'http://localhost:7000/auth/github/handler/frame', - // passReqToCallback: true, - // }, - // }, ]; diff --git a/plugins/auth-backend/src/providers/google/provider.ts b/plugins/auth-backend/src/providers/google/provider.ts new file mode 100644 index 0000000000..ddbb42c98b --- /dev/null +++ b/plugins/auth-backend/src/providers/google/provider.ts @@ -0,0 +1,67 @@ +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'; + +export const provider = { + makeStrategy(options: any): passport.Strategy { + return new GoogleStrategy(options, function ( + _req: any, + accessToken: any, + refreshToken: any, + profile: any, + cb: any, + ) { + cb(undefined, { profile, accessToken, refreshToken }); + }); + }, + makeRouter(handlers: AuthProviderHandlers): express.Router { + 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; + }, +}; + +export const GoogleAuthProviderHandler: AuthProviderHandlers = { + start(req, res, next) { + return passport.authenticate('google', { + scope: ['profile', 'email'], + accessType: 'offline', + prompt: 'consent', + state: '8745634875963', + })(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); + const base64Data = Buffer.from(jsonData, 'utf8').toString('base64'); + + res.setHeader('X-Frame-Options', 'sameorigin'); + res.end(` + + + + + + `); +}; diff --git a/plugins/auth-backend/src/providers/google/router.ts b/plugins/auth-backend/src/providers/google/router.ts deleted file mode 100644 index 73f5ee6f9d..0000000000 --- a/plugins/auth-backend/src/providers/google/router.ts +++ /dev/null @@ -1,34 +0,0 @@ -import express from 'express'; -import Router from 'express-promise-router'; -import passport from 'passport'; - -export const router = Router(); -router.get('/start', (req, res, next) => { - passport.authenticate('google', { - scope: ['profile', 'email'], - accessType: 'offline', - prompt: 'consent', - state: '8745634875963', - })(req, res, next); -}); - -router.get('/handler/frame', passport.authenticate('google'), function ( - req, - res, -) { - console.log('DEBUG: req.session.passport.user', req.session?.passport.user); - console.log('DEBUG: req.params =', req.params); - console.log('DEBUG: req.url =', req.url); - res.send('yay!'); -}); - -router.get('/logout', async (_req: express.Request, res: express.Response) => { - res.send('google provider logout'); -}); - -router.get( - '/refreshToken', - async (_req: express.Request, res: express.Response) => { - res.send('google provider refreshToken'); - }, -); diff --git a/plugins/auth-backend/src/providers/index.ts b/plugins/auth-backend/src/providers/index.ts new file mode 100644 index 0000000000..3cb2b6a018 --- /dev/null +++ b/plugins/auth-backend/src/providers/index.ts @@ -0,0 +1,17 @@ +import { AuthProvider } from './types'; +import { + provider as GoogleAuthProvider, + GoogleAuthProviderHandler, +} from './google/provider'; + +const providerFactories: AuthProvider = { + 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(GoogleAuthProviderHandler); + return { provider, strategy, providerRouter }; +}; diff --git a/plugins/auth-backend/src/providers/types.ts b/plugins/auth-backend/src/providers/types.ts new file mode 100644 index 0000000000..442ab405e2 --- /dev/null +++ b/plugins/auth-backend/src/providers/types.ts @@ -0,0 +1,44 @@ +import express from 'express'; +import passport from 'passport'; + +export type AuthProviderHandlers = { + start( + req: express.Request, + res: express.Response, + next: express.NextFunction, + ): Promise; + handle( + req: express.Request, + res: express.Response, + next: express.NextFunction, + ): express.Response; + refresh?( + req: express.Request, + res: express.Response, + next: express.NextFunction, + ): Promise; + logout( + req: express.Request, + res: express.Response, + next: express.NextFunction, + ): express.Response; +}; + +export type AuthProvider = { + [key: string]: { + makeStrategy(options: any): passport.Strategy; + makeRouter(handlers: AuthProviderHandlers): express.Router; + }; +}; + +export type AuthInfo = { + profile: passport.Profile; + accessToken: string; + refreshToken?: string; + expiresAt?: number; +}; + +export type AuthResponse = { + type: string; + payload: AuthInfo; +}; diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index ae0f3d822b..b22dbe310c 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -17,139 +17,23 @@ import express from 'express'; import Router from 'express-promise-router'; import passport from 'passport'; -import { Strategy as GoogleStrategy } from 'passport-google-oauth20'; import { Logger } from 'winston'; import { providers } from './../providers/config'; +import { makeProvider } from '../providers'; export interface RouterOptions { logger: Logger; } -type AuthProviderHandlers = { - start( - req: express.Request, - res: express.Response, - next: express.NextFunction, - ): Promise; - handle( - req: express.Request, - res: express.Response, - next: express.NextFunction, - ): express.Response; - refresh?( - req: express.Request, - res: express.Response, - next: express.NextFunction, - ): Promise; - logout( - req: express.Request, - res: express.Response, - next: express.NextFunction, - ): express.Response; -}; - -type AuthProvider = { - [key: string]: { - makeStrategy(options: any): passport.Strategy; - makeRouter(handlers: AuthProviderHandlers): express.Router; - }; -}; - -type AuthInfo = { - profile: passport.Profile; - accessToken: string; - refreshToken?: string; - expiresAt?: number; -}; - -type AuthResponse = { - type: string; - payload: AuthInfo; -}; - -const postMessageResponse = (res: express.Response, data: AuthResponse) => { - const jsonData = JSON.stringify(data); - const base64Data = Buffer.from(jsonData, 'utf8').toString('base64'); - - res.setHeader('X-Frame-Options', 'sameorigin'); - res.end(` - - - - - - `); -}; - -const GoogleAuthProviderHandler: AuthProviderHandlers = { - start(req, res, next) { - return passport.authenticate('google', { - scope: ['profile', 'email'], - accessType: 'offline', - prompt: 'consent', - state: '8745634875963', - })(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 providerFactories: AuthProvider = { - google: { - makeStrategy(options: any): passport.Strategy { - return new GoogleStrategy(options, function ( - _req: any, - accessToken: any, - refreshToken: any, - profile: any, - cb: any, - ) { - cb(undefined, { profile, accessToken, refreshToken }); - }); - }, - makeRouter(handlers: AuthProviderHandlers): express.Router { - 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; - }, - }, -}; - -function makeProvider(config: any) { - const provider = config.provider; - const providerFactory = providerFactories[provider]; - const strategy: passport.Strategy = providerFactory.makeStrategy( - config.options, - ); - const providerRouter = providerFactory.makeRouter(GoogleAuthProviderHandler); - return { provider, strategy, providerRouter }; -} - export async function createRouter( options: RouterOptions, ): Promise { const router = Router(); + // configure all the providers for (const providerConfig of providers) { const { provider, strategy, providerRouter } = makeProvider(providerConfig); passport.use(strategy); - router.use(`/${provider}`, providerRouter); } @@ -164,9 +48,5 @@ export async function createRouter( router.use(passport.initialize()); router.use(passport.session()); - router.get('/ping', async (_req, res) => { - res.status(200).send('pong'); - }); - return router; }