feat: mobile login enpoint (#51829)

Co-authored-by: Mrugesh Mohapatra <noreply@mrugesh.dev>
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Niraj Nandish
2023-11-08 23:07:57 +04:00
committed by GitHub
parent 10d5cbeb88
commit be00d5f3bb
5 changed files with 75 additions and 52 deletions
+3 -1
View File
@@ -7,7 +7,7 @@
"@aws-sdk/client-ses": "3.441.0",
"@fastify/cookie": "9.1.0",
"@fastify/csrf-protection": "6.4.1",
"@fastify/middie": "8.3",
"@fastify/express": "^2.3.0",
"@fastify/session": "10.5.0",
"@fastify/swagger": "8.12.0",
"@fastify/swagger-ui": "1.10.1",
@@ -19,6 +19,7 @@
"connect-mongo": "4.6.0",
"date-fns": "2.30.0",
"dotenv": "16.3.1",
"express-rate-limit": "^6.7.0",
"fast-uri": "2.3.0",
"fastify": "4.24.3",
"fastify-auth0-verify": "1.2.1",
@@ -33,6 +34,7 @@
"nodemon": "2.0.22",
"pino-pretty": "10.2.3",
"query-string": "7.1.3",
"rate-limit-mongo": "^2.3.2",
"stripe": "8.222.0"
},
"description": "The freeCodeCamp.org open-source codebase and curriculum",
+5 -6
View File
@@ -1,6 +1,6 @@
import fastifyCookie from '@fastify/cookie';
import fastifyCsrfProtection from '@fastify/csrf-protection';
import middie from '@fastify/middie';
import express from '@fastify/express';
import fastifySession from '@fastify/session';
import fastifySwagger from '@fastify/swagger';
import fastifySwaggerUI from '@fastify/swagger-ui';
@@ -21,7 +21,6 @@ import Fastify, {
import fastifyAuth0 from 'fastify-auth0-verify';
import prismaPlugin from './db/prisma';
import { testMiddleware } from './middleware';
import cors from './plugins/cors';
import jwtAuthz from './plugins/fastify-jwt-authz';
import { NodemailerProvider } from './plugins/mail-providers/nodemailer';
@@ -33,7 +32,8 @@ import sessionAuth from './plugins/session-auth';
import {
auth0Routes,
devLoginCallback,
devLegacyAuthRoutes
devLegacyAuthRoutes,
mobileAuth0Routes
} from './routes/auth';
import { challengeRoutes } from './routes/challenge';
import { deprecatedEndpoints } from './routes/deprecated-endpoints';
@@ -106,7 +106,7 @@ export const build = async (
return { hello: 'world' };
});
// NOTE: Awaited to ensure `.use` is registered on `fastify`
await fastify.register(middie);
await fastify.register(express);
if (SENTRY_DSN) {
await fastify.register(fastifySentry, { dsn: SENTRY_DSN });
}
@@ -202,11 +202,10 @@ export const build = async (
void fastify.register(jwtAuthz);
void fastify.register(sessionAuth);
void fastify.use('/test', testMiddleware);
void fastify.register(prismaPlugin);
void fastify.register(auth0Routes, { prefix: '/auth' });
void fastify.register(mobileAuth0Routes);
if (FCC_ENABLE_DEV_LOGIN_MODE) {
void fastify.register(devLoginCallback, { prefix: '/auth' });
void fastify.register(devLegacyAuthRoutes);
-23
View File
@@ -1,23 +0,0 @@
import type { NextFunction, NextHandleFunction } from '@fastify/middie';
type MiddieRequest = Parameters<NextHandleFunction>[0];
type MiddieResponse = Parameters<NextHandleFunction>[1];
/**
* Test middleware used to log request and response data?
*
* @param req The request payload.
* @param res The response to be sent back to the request.
* @param next Callback function to indicate that the middleware logic is complete.
*/
export function testMiddleware(
req: MiddieRequest,
res: MiddieResponse,
next: NextFunction
): void {
console.log('Test middleware running');
console.log(req.headers);
console.log(req.query);
res.setHeader('X-Test-Header', 'test');
next();
}
+49 -2
View File
@@ -4,8 +4,12 @@ import {
FastifyRequest
} from 'fastify';
import rateLimit from 'express-rate-limit';
// @ts-expect-error - no types
import MongoStoreRL from 'rate-limit-mongo';
import { createUserInput } from '../utils/create-user';
import { AUTH0_DOMAIN, HOME_LOCATION } from '../utils/env';
import { AUTH0_DOMAIN, HOME_LOCATION, MONGOHQ_URL } from '../utils/env';
declare module 'fastify' {
interface Session {
@@ -85,7 +89,50 @@ export const devLoginCallback: FastifyPluginCallback = (
export const auth0Routes: FastifyPluginCallback = (fastify, _options, done) => {
fastify.addHook('onRequest', fastify.authenticate);
fastify.get('/callback', async req => {
fastify.get('/auth0/callback', async req => {
const email = await getEmailFromAuth0(req);
const { id } = await findOrCreateUser(fastify, email);
req.session.user = { id };
await req.session.save();
});
done();
};
/**
* Route handler for Mobile authentication.
*
* @param fastify The Fastify instance.
* @param _options Options passed to the plugin via `fastify.register(plugin, options)`.
* @param done Callback to signal that the logic has completed.
*/
export const mobileAuth0Routes: FastifyPluginCallback = (
fastify,
_options,
done
) => {
// Rate limit for mobile login
// 10 requests per 15 minute windows
void fastify.use(
rateLimit({
windowMs: 15 * 60 * 1000,
max: 10,
standardHeaders: true,
legacyHeaders: false,
keyGenerator: req => {
return (req.headers['x-forwarded-for'] as string) || 'localhost';
},
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
store: new MongoStoreRL({
collectionName: 'UserRateLimit',
uri: MONGOHQ_URL,
expireTimeMs: 15 * 60 * 1000
})
})
);
fastify.get('/mobile-login', async req => {
const email = await getEmailFromAuth0(req);
const { id } = await findOrCreateUser(fastify, email);