move provider factories from router to src/providers
This commit is contained in:
@@ -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,
|
||||
// },
|
||||
// },
|
||||
];
|
||||
|
||||
@@ -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(`
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
(window.opener || window.parent).postMessage(JSON.parse(atob('${base64Data}')), location.origin)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
};
|
||||
@@ -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');
|
||||
},
|
||||
);
|
||||
@@ -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 };
|
||||
};
|
||||
@@ -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<any>;
|
||||
handle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction,
|
||||
): express.Response<any>;
|
||||
refresh?(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction,
|
||||
): Promise<any>;
|
||||
logout(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction,
|
||||
): express.Response<any>;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
@@ -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<any>;
|
||||
handle(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction,
|
||||
): express.Response<any>;
|
||||
refresh?(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction,
|
||||
): Promise<any>;
|
||||
logout(
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
next: express.NextFunction,
|
||||
): express.Response<any>;
|
||||
};
|
||||
|
||||
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(`
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
(window.opener || window.parent).postMessage(JSON.parse(atob('${base64Data}')), location.origin)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
};
|
||||
|
||||
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<express.Router> {
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user