feat: encode user tokens (#45429)

This commit is contained in:
Tom
2022-03-15 03:41:43 -05:00
committed by GitHub
parent d94177d85c
commit daaa2b38cf
6 changed files with 45 additions and 12 deletions

View File

@ -16,7 +16,7 @@ import { wrapHandledError } from '../utils/create-handled-error.js';
import { removeCookies } from '../utils/getSetAccessToken';
import { ifUserRedirectTo, ifNoUserRedirectHome } from '../utils/middleware';
import { getRedirectParams } from '../utils/redirection';
import { createDeleteUserToken } from '../middlewares/delete-user-token';
import { createDeleteUserToken } from '../middlewares/user-token';
const passwordlessGetValidators = [
check('email')

View File

@ -12,6 +12,9 @@ import { Observable } from 'rx';
import isNumeric from 'validator/lib/isNumeric';
import isURL from 'validator/lib/isURL';
import jwt from 'jsonwebtoken';
import { jwtSecret } from '../../../../config/secrets';
import { environment, deploymentEnv } from '../../../../config/env.json';
import {
fixCompletedChallengeItem,
@ -399,14 +402,22 @@ function createCoderoadChallengeCompleted(app) {
const { UserToken, User } = app.models;
return async function coderoadChallengeCompleted(req, res) {
const { 'coderoad-user-token': userToken } = req.headers;
const { 'coderoad-user-token': encodedUserToken } = req.headers;
const { tutorialId } = req.body;
if (!tutorialId) return res.send(`'tutorialId' not found in request body`);
if (!userToken)
if (!encodedUserToken)
return res.send(`'coderoad-user-token' not found in request headers`);
let userToken;
try {
userToken = jwt.verify(encodedUserToken, jwtSecret)?.userToken;
} catch {
return res.send(`invalid user token`);
}
const tutorialRepo = tutorialId?.split(':')[0];
const tutorialOrg = tutorialRepo?.split('/')?.[0];

View File

@ -17,7 +17,10 @@ import {
} from '../utils/publicUserProps';
import { getRedirectParams } from '../utils/redirection';
import { trimTags } from '../utils/validators';
import { createDeleteUserToken } from '../middlewares/delete-user-token';
import {
createDeleteUserToken,
encodeUserToken
} from '../middlewares/user-token';
const log = debugFactory('fcc:boot:user');
const sendNonUserToHome = ifNoUserRedirectHome();
@ -64,16 +67,19 @@ function createPostUserToken(app) {
return async function postUserToken(req, res) {
const ttl = 900 * 24 * 60 * 60 * 1000;
let newToken;
let encodedUserToken;
try {
await UserToken.destroyAll({ userId: req.user.id });
newToken = await UserToken.create({ ttl, userId: req.user.id });
const newUserToken = await UserToken.create({ ttl, userId: req.user.id });
if (!newUserToken?.id) throw new Error();
encodedUserToken = encodeUserToken(newUserToken.id);
} catch (e) {
return res.status(500).send('Error starting project');
}
return res.json({ token: newToken?.id });
return res.json({ userToken: encodedUserToken });
};
}
@ -82,7 +88,7 @@ function deleteUserTokenResponse(req, res) {
return res.status(500).send('Error deleting user token');
}
return res.send({ token: null });
return res.send({ userToken: null });
}
function createReadSessionUser(app) {
@ -94,7 +100,14 @@ function createReadSessionUser(app) {
const userTokenArr = await queryUser.userTokens({
userId: queryUser.id
});
const userToken = userTokenArr[0]?.id;
let encodedUserToken;
// only encode if a userToken was found
if (userToken) {
encodedUserToken = encodeUserToken(userToken);
}
const source =
queryUser &&
@ -151,7 +164,7 @@ function createReadSessionUser(app) {
isWebsite: !!user.website,
...normaliseUserFields(user),
joinDate: user.id.getTimestamp(),
userToken
userToken: encodedUserToken
}
},
sessionMeta,

View File

@ -1,5 +1,7 @@
import debugFactory from 'debug';
const log = debugFactory('fcc:boot:user');
import jwt from 'jsonwebtoken';
import { jwtSecret } from '../../../../config/secrets';
/*
* User tokens for submitting external curriculum are deleted when they sign
@ -23,3 +25,7 @@ export function createDeleteUserToken(app) {
next();
};
}
export function encodeUserToken(userToken) {
return jwt.sign({ userToken }, jwtSecret);
}

View File

@ -24,8 +24,8 @@ function* tryToShowCodeAllySaga() {
try {
const response = yield call(postUserToken);
if (response?.token) {
yield put(updateUserToken(response.token));
if (response?.userToken) {
yield put(updateUserToken(response.userToken));
yield put(showCodeAlly());
} else {
yield put(createFlashMessage(startProjectErrMessage));

View File

@ -19,7 +19,10 @@ function* deleteUserTokenSaga() {
try {
const response = yield call(deleteUserToken);
if (response && Object.prototype.hasOwnProperty.call(response, 'token')) {
if (
response &&
Object.prototype.hasOwnProperty.call(response, 'userToken')
) {
yield put(deleteUserTokenComplete());
yield put(createFlashMessage(message.deleted));
} else {