feat: encode user tokens (#45429)
This commit is contained in:
@ -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')
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
@ -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));
|
||||
|
@ -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 {
|
||||
|
Reference in New Issue
Block a user