mirror of
https://github.com/wassname/talk.git
synced 2026-07-23 13:10:20 +08:00
Added support for auth based plugins
This commit is contained in:
+52
@@ -233,6 +233,58 @@ module.exports = {
|
||||
}
|
||||
```
|
||||
|
||||
#### Field: `auth`
|
||||
|
||||
```js
|
||||
const FacebookStrategy = require('passport-facebook').Strategy;
|
||||
const UsersService = require('services/users');
|
||||
const {ValidateUserLogin, HandleAuthPopupCallback} = require('services/passport');
|
||||
|
||||
module.exports = {
|
||||
auth(passport) {
|
||||
passport.use(new FacebookStrategy({
|
||||
clientID: process.env.TALK_FACEBOOK_APP_ID,
|
||||
clientSecret: process.env.TALK_FACEBOOK_APP_SECRET,
|
||||
callbackURL: `${process.env.TALK_ROOT_URL}/api/v1/auth/facebook/callback`,
|
||||
passReqToCallback: true,
|
||||
profileFields: ['id', 'displayName', 'picture.type(large)']
|
||||
}, async (req, accessToken, refreshToken, profile, done) => {
|
||||
|
||||
let user;
|
||||
try {
|
||||
user = await UsersService.findOrCreateExternalUser(profile);
|
||||
} catch (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
return ValidateUserLogin(profile, user, done);
|
||||
}));
|
||||
},
|
||||
routes(router) {
|
||||
const {passport} = require('services/passport');
|
||||
|
||||
/**
|
||||
* Facebook auth endpoint, this will redirect the user immediatly to facebook
|
||||
* for authorization.
|
||||
*/
|
||||
router.get('/facebook', passport.authenticate('facebook', {display: 'popup', authType: 'rerequest', scope: ['public_profile']}));
|
||||
|
||||
/**
|
||||
* Facebook callback endpoint, this will send the user a html page designed to
|
||||
* send back the user credentials upon sucesfull login.
|
||||
*/
|
||||
router.get('/facebook/callback', (req, res, next) => {
|
||||
|
||||
// Perform the facebook login flow and pass the data back through the opener.
|
||||
passport.authenticate('facebook', HandleAuthPopupCallback(req, res, next))(req, res, next);
|
||||
});
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
This is a full example including the routes hook to add the required components
|
||||
to the application router to support a different auth strategy.
|
||||
|
||||
### Full Example
|
||||
|
||||
Contents of `plugins.json`:
|
||||
|
||||
@@ -3,7 +3,7 @@ const bodyParser = require('body-parser');
|
||||
const morgan = require('morgan');
|
||||
const path = require('path');
|
||||
const helmet = require('helmet');
|
||||
const passport = require('./services/passport');
|
||||
const {passport} = require('./services/passport');
|
||||
const session = require('express-session');
|
||||
const enabled = require('debug').enabled;
|
||||
const RedisStore = require('connect-redis')(session);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
const express = require('express');
|
||||
const passport = require('../../../services/passport');
|
||||
const {passport, HandleAuthCallback, HandleAuthPopupCallback} = require('../../../services/passport');
|
||||
const authorization = require('../../../middleware/authorization');
|
||||
const errors = require('../../../errors');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
@@ -34,53 +33,6 @@ router.delete('/', authorization.needed(), (req, res) => {
|
||||
// PASSPORT ROUTES
|
||||
//==============================================================================
|
||||
|
||||
/**
|
||||
* This sends back the user data as JSON.
|
||||
*/
|
||||
const HandleAuthCallback = (req, res, next) => (err, user) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return next(errors.ErrNotAuthorized);
|
||||
}
|
||||
|
||||
// Perform the login of the user!
|
||||
req.logIn(user, (err) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
// We logged in the user! Let's send back the user data and the CSRF token.
|
||||
res.json({user});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the response to the login attempt via a popup callback with some JS.
|
||||
*/
|
||||
|
||||
const HandleAuthPopupCallback = (req, res, next) => (err, user) => {
|
||||
if (err) {
|
||||
return res.render('auth-callback', {err: JSON.stringify(err), data: null});
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return res.render('auth-callback', {err: JSON.stringify(errors.ErrNotAuthorized), data: null});
|
||||
}
|
||||
|
||||
// Perform the login of the user!
|
||||
req.logIn(user, (err) => {
|
||||
if (err) {
|
||||
return res.render('auth-callback', {err: JSON.stringify(err), data: null});
|
||||
}
|
||||
|
||||
// We logged in the user! Let's send back the user data.
|
||||
res.render('auth-callback', {err: null, data: JSON.stringify(user)});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Local auth endpoint, will recieve a email and password
|
||||
*/
|
||||
|
||||
+63
-1
@@ -7,6 +7,7 @@ const LocalStrategy = require('passport-local').Strategy;
|
||||
const FacebookStrategy = require('passport-facebook').Strategy;
|
||||
const errors = require('../errors');
|
||||
const debug = require('debug')('talk:passport');
|
||||
const plugins = require('./plugins');
|
||||
|
||||
//==============================================================================
|
||||
// SESSION SERIALIZATION
|
||||
@@ -27,6 +28,52 @@ passport.deserializeUser((id, done) => {
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* This sends back the user data as JSON.
|
||||
*/
|
||||
const HandleAuthCallback = (req, res, next) => (err, user) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return next(errors.ErrNotAuthorized);
|
||||
}
|
||||
|
||||
// Perform the login of the user!
|
||||
req.logIn(user, (err) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
// We logged in the user! Let's send back the user data and the CSRF token.
|
||||
res.json({user});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the response to the login attempt via a popup callback with some JS.
|
||||
*/
|
||||
const HandleAuthPopupCallback = (req, res, next) => (err, user) => {
|
||||
if (err) {
|
||||
return res.render('auth-callback', {err: JSON.stringify(err), data: null});
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return res.render('auth-callback', {err: JSON.stringify(errors.ErrNotAuthorized), data: null});
|
||||
}
|
||||
|
||||
// Perform the login of the user!
|
||||
req.logIn(user, (err) => {
|
||||
if (err) {
|
||||
return res.render('auth-callback', {err: JSON.stringify(err), data: null});
|
||||
}
|
||||
|
||||
// We logged in the user! Let's send back the user data.
|
||||
res.render('auth-callback', {err: null, data: JSON.stringify(user)});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates that a user is allowed to login.
|
||||
* @param {User} user the user to be validated
|
||||
@@ -329,4 +376,19 @@ if (process.env.TALK_FACEBOOK_APP_ID && process.env.TALK_FACEBOOK_APP_SECRET &&
|
||||
console.error('Facebook cannot be enabled, missing one of TALK_FACEBOOK_APP_ID, TALK_FACEBOOK_APP_SECRET, TALK_ROOT_URL');
|
||||
}
|
||||
|
||||
module.exports = passport;
|
||||
// Inject server route plugins.
|
||||
plugins.get('server', 'auth').forEach(({plugin, auth}) => {
|
||||
debug(`added plugin '${plugin.name}'`);
|
||||
|
||||
// Pass the passport.js instance to the plugin to allow it to inject it's
|
||||
// functionality.
|
||||
auth(passport);
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
passport,
|
||||
ValidateUserLogin,
|
||||
HandleFailedAttempt,
|
||||
HandleAuthCallback,
|
||||
HandleAuthPopupCallback
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user