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 { removeCookies } from '../utils/getSetAccessToken';
|
||||||
import { ifUserRedirectTo, ifNoUserRedirectHome } from '../utils/middleware';
|
import { ifUserRedirectTo, ifNoUserRedirectHome } from '../utils/middleware';
|
||||||
import { getRedirectParams } from '../utils/redirection';
|
import { getRedirectParams } from '../utils/redirection';
|
||||||
import { createDeleteUserToken } from '../middlewares/delete-user-token';
|
import { createDeleteUserToken } from '../middlewares/user-token';
|
||||||
|
|
||||||
const passwordlessGetValidators = [
|
const passwordlessGetValidators = [
|
||||||
check('email')
|
check('email')
|
||||||
|
@ -12,6 +12,9 @@ import { Observable } from 'rx';
|
|||||||
import isNumeric from 'validator/lib/isNumeric';
|
import isNumeric from 'validator/lib/isNumeric';
|
||||||
import isURL from 'validator/lib/isURL';
|
import isURL from 'validator/lib/isURL';
|
||||||
|
|
||||||
|
import jwt from 'jsonwebtoken';
|
||||||
|
import { jwtSecret } from '../../../../config/secrets';
|
||||||
|
|
||||||
import { environment, deploymentEnv } from '../../../../config/env.json';
|
import { environment, deploymentEnv } from '../../../../config/env.json';
|
||||||
import {
|
import {
|
||||||
fixCompletedChallengeItem,
|
fixCompletedChallengeItem,
|
||||||
@ -399,14 +402,22 @@ function createCoderoadChallengeCompleted(app) {
|
|||||||
const { UserToken, User } = app.models;
|
const { UserToken, User } = app.models;
|
||||||
|
|
||||||
return async function coderoadChallengeCompleted(req, res) {
|
return async function coderoadChallengeCompleted(req, res) {
|
||||||
const { 'coderoad-user-token': userToken } = req.headers;
|
const { 'coderoad-user-token': encodedUserToken } = req.headers;
|
||||||
const { tutorialId } = req.body;
|
const { tutorialId } = req.body;
|
||||||
|
|
||||||
if (!tutorialId) return res.send(`'tutorialId' not found in request 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`);
|
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 tutorialRepo = tutorialId?.split(':')[0];
|
||||||
const tutorialOrg = tutorialRepo?.split('/')?.[0];
|
const tutorialOrg = tutorialRepo?.split('/')?.[0];
|
||||||
|
|
||||||
|
@ -17,7 +17,10 @@ import {
|
|||||||
} from '../utils/publicUserProps';
|
} from '../utils/publicUserProps';
|
||||||
import { getRedirectParams } from '../utils/redirection';
|
import { getRedirectParams } from '../utils/redirection';
|
||||||
import { trimTags } from '../utils/validators';
|
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 log = debugFactory('fcc:boot:user');
|
||||||
const sendNonUserToHome = ifNoUserRedirectHome();
|
const sendNonUserToHome = ifNoUserRedirectHome();
|
||||||
@ -64,16 +67,19 @@ function createPostUserToken(app) {
|
|||||||
|
|
||||||
return async function postUserToken(req, res) {
|
return async function postUserToken(req, res) {
|
||||||
const ttl = 900 * 24 * 60 * 60 * 1000;
|
const ttl = 900 * 24 * 60 * 60 * 1000;
|
||||||
let newToken;
|
let encodedUserToken;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await UserToken.destroyAll({ userId: req.user.id });
|
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) {
|
} catch (e) {
|
||||||
return res.status(500).send('Error starting project');
|
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.status(500).send('Error deleting user token');
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.send({ token: null });
|
return res.send({ userToken: null });
|
||||||
}
|
}
|
||||||
|
|
||||||
function createReadSessionUser(app) {
|
function createReadSessionUser(app) {
|
||||||
@ -94,7 +100,14 @@ function createReadSessionUser(app) {
|
|||||||
const userTokenArr = await queryUser.userTokens({
|
const userTokenArr = await queryUser.userTokens({
|
||||||
userId: queryUser.id
|
userId: queryUser.id
|
||||||
});
|
});
|
||||||
|
|
||||||
const userToken = userTokenArr[0]?.id;
|
const userToken = userTokenArr[0]?.id;
|
||||||
|
let encodedUserToken;
|
||||||
|
|
||||||
|
// only encode if a userToken was found
|
||||||
|
if (userToken) {
|
||||||
|
encodedUserToken = encodeUserToken(userToken);
|
||||||
|
}
|
||||||
|
|
||||||
const source =
|
const source =
|
||||||
queryUser &&
|
queryUser &&
|
||||||
@ -151,7 +164,7 @@ function createReadSessionUser(app) {
|
|||||||
isWebsite: !!user.website,
|
isWebsite: !!user.website,
|
||||||
...normaliseUserFields(user),
|
...normaliseUserFields(user),
|
||||||
joinDate: user.id.getTimestamp(),
|
joinDate: user.id.getTimestamp(),
|
||||||
userToken
|
userToken: encodedUserToken
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sessionMeta,
|
sessionMeta,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import debugFactory from 'debug';
|
import debugFactory from 'debug';
|
||||||
const log = debugFactory('fcc:boot:user');
|
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
|
* User tokens for submitting external curriculum are deleted when they sign
|
||||||
@ -23,3 +25,7 @@ export function createDeleteUserToken(app) {
|
|||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function encodeUserToken(userToken) {
|
||||||
|
return jwt.sign({ userToken }, jwtSecret);
|
||||||
|
}
|
@ -24,8 +24,8 @@ function* tryToShowCodeAllySaga() {
|
|||||||
try {
|
try {
|
||||||
const response = yield call(postUserToken);
|
const response = yield call(postUserToken);
|
||||||
|
|
||||||
if (response?.token) {
|
if (response?.userToken) {
|
||||||
yield put(updateUserToken(response.token));
|
yield put(updateUserToken(response.userToken));
|
||||||
yield put(showCodeAlly());
|
yield put(showCodeAlly());
|
||||||
} else {
|
} else {
|
||||||
yield put(createFlashMessage(startProjectErrMessage));
|
yield put(createFlashMessage(startProjectErrMessage));
|
||||||
|
@ -19,7 +19,10 @@ function* deleteUserTokenSaga() {
|
|||||||
try {
|
try {
|
||||||
const response = yield call(deleteUserToken);
|
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(deleteUserTokenComplete());
|
||||||
yield put(createFlashMessage(message.deleted));
|
yield put(createFlashMessage(message.deleted));
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user