feat: update user identity login
This commit is contained in:
@ -4,8 +4,7 @@ import dedent from 'dedent';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
getSocialProvider,
|
getSocialProvider,
|
||||||
getUsernameFromProvider,
|
getUsernameFromProvider
|
||||||
createUserUpdatesFromProfile
|
|
||||||
} from '../../server/utils/auth';
|
} from '../../server/utils/auth';
|
||||||
import { observeMethod, observeQuery } from '../../server/utils/rx';
|
import { observeMethod, observeQuery } from '../../server/utils/rx';
|
||||||
import { wrapHandledError } from '../../server/utils/create-handled-error.js';
|
import { wrapHandledError } from '../../server/utils/create-handled-error.js';
|
||||||
@ -15,6 +14,7 @@ import { wrapHandledError } from '../../server/utils/create-handled-error.js';
|
|||||||
export default function(UserIdent) {
|
export default function(UserIdent) {
|
||||||
UserIdent.on('dataSourceAttached', () => {
|
UserIdent.on('dataSourceAttached', () => {
|
||||||
UserIdent.findOne$ = observeMethod(UserIdent, 'findOne');
|
UserIdent.findOne$ = observeMethod(UserIdent, 'findOne');
|
||||||
|
UserIdent.create$ = observeMethod(UserIdent, 'create');
|
||||||
});
|
});
|
||||||
// original source
|
// original source
|
||||||
// github.com/strongloop/loopback-component-passport
|
// github.com/strongloop/loopback-component-passport
|
||||||
@ -48,6 +48,23 @@ export default function(UserIdent) {
|
|||||||
},
|
},
|
||||||
include: 'user'
|
include: 'user'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (provider === 'auth0') {
|
||||||
|
|
||||||
|
const email = profile.emails[0].value;
|
||||||
|
return User.findOne$({ where: { email } })
|
||||||
|
.flatMap(user => {
|
||||||
|
if (!user) {
|
||||||
|
return User.create$({ email });
|
||||||
|
}
|
||||||
|
return Observable.of(user);
|
||||||
|
})
|
||||||
|
.subscribe(
|
||||||
|
( user ) => cb(null, user, null, null),
|
||||||
|
cb
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
return UserIdent.findOne$(query)
|
return UserIdent.findOne$(query)
|
||||||
.flatMap(identity => {
|
.flatMap(identity => {
|
||||||
if (!identity) {
|
if (!identity) {
|
||||||
@ -59,7 +76,7 @@ export default function(UserIdent) {
|
|||||||
Please create an account below
|
Please create an account below
|
||||||
`,
|
`,
|
||||||
type: 'info',
|
type: 'info',
|
||||||
redirectTo: '/signup'
|
redirectTo: '/deprecated-signup'
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -79,7 +96,7 @@ export default function(UserIdent) {
|
|||||||
new Error('user identity is not associated with a user'),
|
new Error('user identity is not associated with a user'),
|
||||||
{
|
{
|
||||||
type: 'info',
|
type: 'info',
|
||||||
redirectTo: '/signup',
|
redirectTo: '/deprecated-signup',
|
||||||
message: dedent`
|
message: dedent`
|
||||||
The user account associated with the ${provider} user ${username || 'Anon'}
|
The user account associated with the ${provider} user ${username || 'Anon'}
|
||||||
no longer exists.
|
no longer exists.
|
||||||
@ -88,10 +105,7 @@ export default function(UserIdent) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const updateUser = User.update$(
|
|
||||||
{ id: user.id },
|
|
||||||
createUserUpdatesFromProfile(provider, profile)
|
|
||||||
).map(() => user);
|
|
||||||
// identity already exists
|
// identity already exists
|
||||||
// find user and log them in
|
// find user and log them in
|
||||||
identity.credentials = credentials;
|
identity.credentials = credentials;
|
||||||
@ -117,7 +131,6 @@ export default function(UserIdent) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
return Observable.combineLatest(
|
return Observable.combineLatest(
|
||||||
updateUser,
|
|
||||||
updateIdentity,
|
updateIdentity,
|
||||||
createToken,
|
createToken,
|
||||||
(user, identity, token) => ({ user, identity, token })
|
(user, identity, token) => ({ user, identity, token })
|
||||||
@ -127,5 +140,6 @@ export default function(UserIdent) {
|
|||||||
({ user, identity, token }) => cb(null, user, identity, token),
|
({ user, identity, token }) => cb(null, user, identity, token),
|
||||||
cb
|
cb
|
||||||
);
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,8 @@ module.exports = function enableAuthentication(app) {
|
|||||||
const { AuthToken, User } = app.models;
|
const { AuthToken, User } = app.models;
|
||||||
|
|
||||||
router.get('/email-signin', (req, res) => res.redirect(301, '/login'));
|
router.get('/email-signin', (req, res) => res.redirect(301, '/login'));
|
||||||
router.get('/signin', (req, res) => res.redirect(301, '/login'));
|
router.get('/signin', (req, res) => res.redirect(301, '/signup'));
|
||||||
router.get('/signout', (req, res) => res.redirect(301, '/logout'));
|
router.get('/signout', (req, res) => res.redirect(301, '/logout'));
|
||||||
router.get('/signup', (req, res) => res.redirect(301, '/deprecated-signup'));
|
|
||||||
|
|
||||||
function getLegacySignUp(req, res) {
|
function getLegacySignUp(req, res) {
|
||||||
if (isSignUpDisabled) {
|
if (isSignUpDisabled) {
|
||||||
@ -44,7 +43,7 @@ module.exports = function enableAuthentication(app) {
|
|||||||
title: 'Sign in to freeCodeCamp using your Email Address'
|
title: 'Sign in to freeCodeCamp using your Email Address'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
router.get('/deprecated-signup', ifUserRedirect, getLegacySignUp);
|
router.get('/signup', ifUserRedirect, getLegacySignUp);
|
||||||
router.get('/login',
|
router.get('/login',
|
||||||
ifUserRedirect,
|
ifUserRedirect,
|
||||||
(req, res) => res.redirect(301, '/auth/auth0'));
|
(req, res) => res.redirect(301, '/auth/auth0'));
|
||||||
|
@ -2,6 +2,7 @@ import passport from 'passport';
|
|||||||
import { PassportConfigurator } from
|
import { PassportConfigurator } from
|
||||||
'@freecodecamp/loopback-component-passport';
|
'@freecodecamp/loopback-component-passport';
|
||||||
import passportProviders from './passport-providers';
|
import passportProviders from './passport-providers';
|
||||||
|
import url from 'url';
|
||||||
|
|
||||||
const passportOptions = {
|
const passportOptions = {
|
||||||
emailOptional: true,
|
emailOptional: true,
|
||||||
@ -90,26 +91,27 @@ export default function setupPassport(app) {
|
|||||||
configurator.init();
|
configurator.init();
|
||||||
|
|
||||||
Object.keys(passportProviders).map(function(strategy) {
|
Object.keys(passportProviders).map(function(strategy) {
|
||||||
var config = passportProviders[strategy];
|
let config = passportProviders[strategy];
|
||||||
config.session = config.session !== false;
|
config.session = config.session !== false;
|
||||||
|
|
||||||
// https://stackoverflow.com/q/37430452
|
// https://stackoverflow.com/q/37430452
|
||||||
let successRedirect = (req) => {
|
let successRedirect = (req) => {
|
||||||
if (!!req && req.session && req.session.returnTo) {
|
if (!!req && req.session && req.session.returnTo) {
|
||||||
var returnTo = req.session.returnTo;
|
let returnTo = req.session.returnTo;
|
||||||
delete req.session.returnTo;
|
delete req.session.returnTo;
|
||||||
return returnTo;
|
return returnTo;
|
||||||
}
|
}
|
||||||
return config.successRedirect || '';
|
return config.successRedirect || '';
|
||||||
};
|
};
|
||||||
|
|
||||||
config.customCallback = !config.redirectWithToken
|
config.customCallback = !config.redirectWithToken
|
||||||
? null
|
? null
|
||||||
: function(req, res, next) {
|
: (req, res, next) => {
|
||||||
var url = require('url');
|
|
||||||
passport.authenticate(
|
passport.authenticate(
|
||||||
strategy,
|
strategy,
|
||||||
{session: false},
|
{ session: false },
|
||||||
function(err, user, info) {
|
(err, user) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
@ -117,16 +119,24 @@ export default function setupPassport(app) {
|
|||||||
if (!user) {
|
if (!user) {
|
||||||
return res.redirect(config.failureRedirect);
|
return res.redirect(config.failureRedirect);
|
||||||
}
|
}
|
||||||
var redirect = url.parse(successRedirect(req), true);
|
let redirect = url.parse(successRedirect(req), true);
|
||||||
|
|
||||||
delete redirect.search;
|
delete redirect.search;
|
||||||
|
|
||||||
redirect.query = {
|
req.flash(
|
||||||
/* eslint-disable camelcase */
|
'success',
|
||||||
access_token: info.accessToken.id,
|
'Success! You have signed in to your account. Happy Coding!'
|
||||||
/* eslint-enable camelcase */
|
);
|
||||||
userId: user.id.toString()
|
|
||||||
};
|
// redirect.query = {
|
||||||
|
// /* eslint-disable camelcase */
|
||||||
|
// access_token: info.accessToken.id,
|
||||||
|
// /* eslint-enable camelcase */
|
||||||
|
// userId: user.id.toString()
|
||||||
|
// };
|
||||||
|
|
||||||
|
user.loginByRequest(req, res);
|
||||||
|
|
||||||
redirect = url.format(redirect);
|
redirect = url.format(redirect);
|
||||||
return res.redirect(redirect);
|
return res.redirect(redirect);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const successRedirect = '/settings';
|
const successRedirect = '/';
|
||||||
const failureRedirect = '/';
|
const failureRedirect = '/';
|
||||||
const linkSuccessRedirect = '/settings';
|
const linkSuccessRedirect = '/settings';
|
||||||
const linkFailureRedirect = '/settings';
|
const linkFailureRedirect = '/settings';
|
||||||
@ -176,7 +176,7 @@ export default {
|
|||||||
callbackURL: '/auth/auth0/callback',
|
callbackURL: '/auth/auth0/callback',
|
||||||
authPath: '/auth/auth0',
|
authPath: '/auth/auth0',
|
||||||
callbackPath: '/auth/auth0/callback',
|
callbackPath: '/auth/auth0/callback',
|
||||||
redirectWithToken: false,
|
redirectWithToken: true,
|
||||||
successRedirect: successRedirect,
|
successRedirect: successRedirect,
|
||||||
failureRedirect: failureRedirect,
|
failureRedirect: failureRedirect,
|
||||||
scope: ['openid email'],
|
scope: ['openid email'],
|
||||||
|
@ -6,10 +6,15 @@ block content
|
|||||||
.text-center
|
.text-center
|
||||||
h2 Sign up (or sign in with your existing account)
|
h2 Sign up (or sign in with your existing account)
|
||||||
br
|
br
|
||||||
|
br
|
||||||
|
br
|
||||||
a.btn.btn-lg.btn-primary(href='/auth/auth0')
|
a.btn.btn-lg.btn-primary(href='/auth/auth0')
|
||||||
| Get a link on your email
|
| Continue with your email
|
||||||
.row
|
.row
|
||||||
.text-center
|
.text-center
|
||||||
|
br
|
||||||
|
br
|
||||||
|
br
|
||||||
br
|
br
|
||||||
a(href="/deprecated-signin")
|
a(href="/deprecated-signin")
|
||||||
| Continute with old sign in methods
|
| Continute with an old sign in method, that you used previously.
|
||||||
|
Reference in New Issue
Block a user