chore: Remove old auth cruft
This commit is contained in:
committed by
mrugesh mohapatra
parent
081284c2d3
commit
0c23844793
@ -1,9 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
import { Observable } from 'rx';
|
||||
import dedent from 'dedent';
|
||||
import passport from 'passport';
|
||||
import { isEmail } from 'validator';
|
||||
import { check } from 'express-validator/check';
|
||||
|
||||
import { homeLocation } from '../../../config/env';
|
||||
import {
|
||||
@ -11,11 +6,7 @@ import {
|
||||
saveResponseAuthCookies,
|
||||
loginRedirect
|
||||
} from '../component-passport';
|
||||
import {
|
||||
ifUserRedirectTo,
|
||||
ifNoUserRedirectTo,
|
||||
createValidatorErrorHandler
|
||||
} from '../utils/middleware';
|
||||
import { ifUserRedirectTo } from '../utils/middleware';
|
||||
import { wrapHandledError } from '../utils/create-handled-error.js';
|
||||
import { removeCookies } from '../utils/getSetAccessToken';
|
||||
|
||||
@ -31,9 +22,7 @@ module.exports = function enableAuthentication(app) {
|
||||
const ifUserRedirect = ifUserRedirectTo();
|
||||
const saveAuthCookies = saveResponseAuthCookies();
|
||||
const loginSuccessRedirect = loginRedirect();
|
||||
const ifNoUserRedirectHome = ifNoUserRedirectTo(homeLocation);
|
||||
const api = app.loopback.Router();
|
||||
const { AuthToken, User } = app.models;
|
||||
|
||||
// Use a local mock strategy for signing in if we are in dev mode.
|
||||
// Otherwise we use auth0 login. We use a string for 'true' because values
|
||||
@ -73,167 +62,5 @@ module.exports = function enableAuthentication(app) {
|
||||
});
|
||||
});
|
||||
|
||||
const defaultErrorMsg = dedent`
|
||||
Oops, something is not right,
|
||||
please request a fresh link to sign in / sign up.
|
||||
`;
|
||||
|
||||
const passwordlessGetValidators = [
|
||||
check('email')
|
||||
.isBase64()
|
||||
.withMessage('Email should be a base64 encoded string.'),
|
||||
check('token')
|
||||
.exists()
|
||||
.withMessage('Token should exist.')
|
||||
// based on strongloop/loopback/common/models/access-token.js#L15
|
||||
.isLength({ min: 64, max: 64 })
|
||||
.withMessage('Token is not the right length.')
|
||||
];
|
||||
|
||||
function getPasswordlessAuth(req, res, next) {
|
||||
const {
|
||||
query: { email: encodedEmail, token: authTokenId, emailChange } = {}
|
||||
} = req;
|
||||
|
||||
const email = User.decodeEmail(encodedEmail);
|
||||
if (!isEmail(email)) {
|
||||
return next(
|
||||
wrapHandledError(new TypeError('decoded email is invalid'), {
|
||||
type: 'info',
|
||||
message: 'The email encoded in the link is incorrectly formatted',
|
||||
redirectTo: `${homeLocation}/signin`
|
||||
})
|
||||
);
|
||||
}
|
||||
// first find
|
||||
return (
|
||||
AuthToken.findOne$({ where: { id: authTokenId } })
|
||||
.flatMap(authToken => {
|
||||
if (!authToken) {
|
||||
throw wrapHandledError(
|
||||
new Error(`no token found for id: ${authTokenId}`),
|
||||
{
|
||||
type: 'info',
|
||||
message: defaultErrorMsg,
|
||||
redirectTo: `${homeLocation}/signin`
|
||||
}
|
||||
);
|
||||
}
|
||||
// find user then validate and destroy email validation token
|
||||
// finally retun user instance
|
||||
return User.findOne$({ where: { id: authToken.userId } }).flatMap(
|
||||
user => {
|
||||
if (!user) {
|
||||
throw wrapHandledError(
|
||||
new Error(`no user found for token: ${authTokenId}`),
|
||||
{
|
||||
type: 'info',
|
||||
message: defaultErrorMsg,
|
||||
redirectTo: `${homeLocation}/signin`
|
||||
}
|
||||
);
|
||||
}
|
||||
if (user.email !== email) {
|
||||
if (!emailChange || (emailChange && user.newEmail !== email)) {
|
||||
throw wrapHandledError(
|
||||
new Error('user email does not match'),
|
||||
{
|
||||
type: 'info',
|
||||
message: defaultErrorMsg,
|
||||
redirectTo: `${homeLocation}/signin`
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
return authToken
|
||||
.validate$()
|
||||
.map(isValid => {
|
||||
if (!isValid) {
|
||||
throw wrapHandledError(new Error('token is invalid'), {
|
||||
type: 'info',
|
||||
message: `
|
||||
Looks like the link you clicked has expired,
|
||||
please request a fresh link, to sign in.
|
||||
`,
|
||||
redirectTo: `${homeLocation}/signin`
|
||||
});
|
||||
}
|
||||
return authToken.destroy$();
|
||||
})
|
||||
.map(() => user);
|
||||
}
|
||||
);
|
||||
})
|
||||
// at this point token has been validated and destroyed
|
||||
// update user and log them in
|
||||
.map(user => user.loginByRequest(req, res))
|
||||
.do(() => {
|
||||
req.flash(
|
||||
'success',
|
||||
'Success! You have signed in to your account. Happy Coding!'
|
||||
);
|
||||
return res.redirectWithFlash(`${homeLocation}/welcome`);
|
||||
})
|
||||
.subscribe(() => {}, next)
|
||||
);
|
||||
}
|
||||
|
||||
api.get(
|
||||
'/passwordless-auth',
|
||||
ifUserRedirect,
|
||||
passwordlessGetValidators,
|
||||
createValidatorErrorHandler('errors', `${homeLocation}/signin`),
|
||||
getPasswordlessAuth
|
||||
);
|
||||
|
||||
api.get('/passwordless-change', (req, res) =>
|
||||
res.redirect(301, '/confirm-email')
|
||||
);
|
||||
|
||||
api.get(
|
||||
'/confirm-email',
|
||||
ifNoUserRedirectHome,
|
||||
passwordlessGetValidators,
|
||||
getPasswordlessAuth
|
||||
);
|
||||
|
||||
const passwordlessPostValidators = [
|
||||
check('email')
|
||||
.isEmail()
|
||||
.withMessage('Email is not a valid email address.')
|
||||
];
|
||||
function postPasswordlessAuth(req, res, next) {
|
||||
const { body: { email } = {} } = req;
|
||||
|
||||
return User.findOne$({ where: { email } })
|
||||
.flatMap(_user =>
|
||||
Observable.if(
|
||||
// if no user found create new user and save to db
|
||||
_.constant(_user),
|
||||
Observable.of(_user),
|
||||
User.create$({ email })
|
||||
).flatMap(user => user.requestAuthEmail(!_user))
|
||||
)
|
||||
.do(msg => {
|
||||
let redirectTo = homeLocation;
|
||||
|
||||
if (req.session && req.session.returnTo) {
|
||||
redirectTo = req.session.returnTo;
|
||||
}
|
||||
|
||||
req.flash('info', msg);
|
||||
return res.redirect(redirectTo);
|
||||
})
|
||||
.subscribe(_.noop, next);
|
||||
}
|
||||
|
||||
api.post(
|
||||
'/passwordless-auth',
|
||||
ifUserRedirect,
|
||||
passwordlessPostValidators,
|
||||
createValidatorErrorHandler('errors', `${homeLocation}/signin`),
|
||||
postPasswordlessAuth
|
||||
);
|
||||
|
||||
app.use(api);
|
||||
};
|
||||
|
@ -25,8 +25,6 @@ export function setAccessTokenToResponse(
|
||||
};
|
||||
const jwtAccess = jwt.sign({ accessToken }, jwtSecret);
|
||||
res.cookie(jwtCookieNS, jwtAccess, cookieConfig);
|
||||
res.cookie('access_token', accessToken.id, cookieConfig);
|
||||
res.cookie('userId', accessToken.userId, cookieConfig);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -121,8 +121,7 @@ describe('getSetAccessToken', () => {
|
||||
});
|
||||
|
||||
describe('setAccessTokenToResponse', () => {
|
||||
it('sets three cookies in the response', () => {
|
||||
expect.assertions(3);
|
||||
it('sets a jwt access token cookie in the response', () => {
|
||||
const req = mockReq();
|
||||
const res = mockRes();
|
||||
|
||||
@ -139,24 +138,6 @@ describe('getSetAccessToken', () => {
|
||||
maxAge: accessToken.ttl
|
||||
}
|
||||
]);
|
||||
expect(res.cookie.getCall(1).args).toEqual([
|
||||
'access_token',
|
||||
accessToken.id,
|
||||
{
|
||||
signed: false,
|
||||
domain: 'localhost',
|
||||
maxAge: accessToken.ttl
|
||||
}
|
||||
]);
|
||||
expect(res.cookie.getCall(2).args).toEqual([
|
||||
'userId',
|
||||
accessToken.userId,
|
||||
{
|
||||
signed: false,
|
||||
domain: 'localhost',
|
||||
maxAge: accessToken.ttl
|
||||
}
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
Here's your sign in link. It will instantly sign you into freeCodeCamp.org - no password necessary:
|
||||
|
||||
<%= host %>/internal/passwordless-auth/?email=<%= loginEmail %>&token=<%= loginToken %>
|
||||
|
||||
Note: this sign in link will expire after 15 minutes. If you need a new sign in link, go to https://www.freecodecamp.org/signin
|
||||
|
||||
See you soon!
|
||||
|
||||
- The freeCodeCamp.org Team
|
@ -1,13 +0,0 @@
|
||||
Welcome to the freeCodeCamp community!
|
||||
|
||||
We have created a new account for you.
|
||||
|
||||
Here's your sign in link. It will instantly sign you into freeCodeCamp.org - no password necessary:
|
||||
|
||||
<%= host %>/internal/passwordless-auth/?email=<%= loginEmail %>&token=<%= loginToken %>
|
||||
|
||||
Note: this sign in link will expire after 15 minutes. If you need a new sign in link, go to https://www.freecodecamp.org/signin
|
||||
|
||||
See you soon!
|
||||
|
||||
- The freeCodeCamp.org Team
|
@ -1,7 +0,0 @@
|
||||
Please confirm this address for freeCodeCamp:
|
||||
|
||||
<%= host %>/internal/confirm-email?email=<%= loginEmail %>&token=<%= loginToken %>&emailChange=<%= emailChange %>
|
||||
|
||||
Happy coding!
|
||||
|
||||
- The freeCodeCamp.org Team
|
Reference in New Issue
Block a user