Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
router.get('/callback', async function (ctx) {
const client = getClient();
if (!client) {
throw new ServiceUnavailable();
}
const oauth = ctx.cookies.get('oauth' + sessionSuffix);
if (!oauth) {
throw new BadRequest('Missing OAuth session');
}
ctx.cookies.set('oauth' + sessionSuffix, null);
const oauthSession = lru.get(oauth);
if (!oauthSession) {
throw new BadRequest('Invalid OAuth session');
}
const { state, nonce } = oauthSession;
let tokenSet;
try {
tokenSet = await client.authorizationCallback(
getClientRedirectURL() /* TODO: check arg */,
ctx.query,
async function resetPassword(ctx, next) {
const { email, username } = ctx.request.body
if (!username || !email) {
throw new httpErrors.BadRequest('invalid parameters')
}
const trimmedEmail = email.trim()
if (!isValidUsername(username) || !isValidEmail(trimmedEmail)) {
throw new httpErrors.BadRequest('invalid parameters')
}
const user = await findUser(username)
ctx.status = 204
if (!user || user.email !== trimmedEmail) {
return
}
const isLimited = await forgotPasswordSuccessThrottle.rateLimit(username.toLowerCase())
if (isLimited) {
exports.getRegexQuery = ($regex) => {
if (!$regex) return {};
const EVIL_REGEX = /[[(+*{}?]/;
/** @type {Array} */
const value = tryParse($regex, 'Invalid $regex');
if (!isArray(value)) throw new HttpError.BadRequest('$regex should be an array');
if (value.length < 2) throw new HttpError.BadRequest('$regex minimal length is 2');
if (value.some(i => !isString(i))) throw new HttpError.BadRequest('$regex format is Array');
const [field, regex, flags] = value;
if (!isSafeRegex(regex)) throw new HttpError.BadRequest('unsafe $regex');
if (EVIL_REGEX.test(regex)) throw new HttpError.BadRequest('unsafe $regex');
return {
[field]: {
$regex: regex,
$options: flags || 'i',
},
};
};
exports.getRangeQuery = () => ({});
);
} catch (err) {
log.warn(err);
throw new BadRequest(err.message);
}
let info;
try {
info = await client.userinfo(tokenSet);
} catch (err) {
log.warn(err);
throw new BadRequest(err.message);
}
if (!info.email) {
throw new BadRequest('Missing "email" response field');
}
if (!info.email_verified) {
throw new BadRequest(info.email_verified === false ? 'Email must be verified' : 'Missing "email_verified" response field');
}
if (!info.name) {
throw new BadRequest('Missing "name" response field');
}
let session = await createOAuthSession(info.email);
if (session) {
ctx.cookies.set('session' + sessionSuffix, session.token, cookies.options);
if (session.user.x500CommonName !== info.name) {
async function uploadPatch(ctx, next) {
const { hash, filename, description } = ctx.request.body
const { path } = ctx.request.files.diff
if (!hash) {
throw new httpErrors.BadRequest('hash must be specified')
} else if (!filename) {
throw new httpErrors.BadRequest('filename must be specified')
} else if (!description) {
throw new httpErrors.BadRequest('description must be specified')
} else if (!path) {
throw new httpErrors.BadRequest('diff file must be specified')
}
const exists = await patchExists(hash, filename)
if (exists) {
ctx.status = 204
return
}
await addPatch(hash, filename, description, () =>
writeFile(patchPath(hash, filename), fs.createReadStream(path)),
)
ctx.status = 204
}
async function getSignature(ctx: Context) {
const query = ctx.query;
const token = ctx.token;
if (!query.hashToSign) {
throw new BadRequest('Missing mandatory "hashToSign" query parameter');
}
if (!(await vhash(query.hashToSign))) {
throw new BadRequest('Query parameter "hashToSign" must be a SHA256 hash (in lowercase)');
}
if (query.userId && !(await vuuid(query.userId))) {
throw new BadRequest('Invalid query parameter "userId"');
}
if (query.userId && token.userId && (token.userId !== query.userId)) {
throw new Unauthorized('Cannot sign for another user.');
}
if (query.pubKey && !(await vaddr(query.pubKey))) {
throw new BadRequest('Invalid query parameter "pubKey"');
async function upsertPreferences(ctx, next) {
const { name, gameType, gameSubType, recentMaps, selectedMap } = ctx.request.body
if (name && !isValidLobbyName(name)) {
throw new httpErrors.BadRequest('invalid lobby name')
} else if (gameType && !isValidGameType(gameType)) {
throw new httpErrors.BadRequest('invalid game type')
} else if (gameSubType && !isValidGameSubType(gameSubType)) {
throw new httpErrors.BadRequest('invalid game sub type')
} else if (recentMaps && !Array.isArray(recentMaps)) {
throw new httpErrors.BadRequest('recentMaps must be an array')
} else if (selectedMap && !recentMaps.includes(selectedMap)) {
throw new httpErrors.BadRequest('invalid selected map')
}
const preferences = await upsertLobbyPreferences(
ctx.session.userId,
name,
gameType,
gameSubType,
recentMaps.slice(0, 5),
selectedMap,
)
ctx.body = {
...preferences,
recentMaps: await getMapInfo(preferences.recentMaps, ctx.session.userId),
}
async function removeMapPool(ctx, next) {
const { mapPoolId } = ctx.params
const mapPool = await getMapPoolById(mapPoolId)
if (!mapPool) {
throw new httpErrors.NotFound("map pool doesn't exist")
} else if (mapPool.startDate < Date.now()) {
throw new httpErrors.BadRequest("can't delete map pools in past")
}
await removeMapPoolDb(mapPoolId)
ctx.status = 204
}