mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-04-30 16:01:14 -04:00
feat(api): use jwt_access_token (in development) (#53997)
Co-authored-by: Tom <20648924+moT01@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
bb2efe7618
commit
aacfb281fb
@@ -55,6 +55,7 @@ assert.ok(process.env.JWT_SECRET);
|
||||
assert.ok(process.env.STRIPE_SECRET_KEY);
|
||||
assert.ok(process.env.SHOW_UPCOMING_CHANGES);
|
||||
assert.ok(process.env.MONGOHQ_URL);
|
||||
assert.ok(process.env.COOKIE_SECRET);
|
||||
|
||||
if (process.env.FREECODECAMP_NODE_ENV !== 'development') {
|
||||
assert.ok(process.env.SES_ID);
|
||||
@@ -66,6 +67,7 @@ if (process.env.FREECODECAMP_NODE_ENV !== 'development') {
|
||||
);
|
||||
assert.ok(process.env.SES_REGION);
|
||||
assert.ok(process.env.COOKIE_DOMAIN);
|
||||
assert.notEqual(process.env.COOKIE_SECRET, 'a_cookie_secret');
|
||||
assert.ok(process.env.PORT);
|
||||
assert.ok(process.env.SENTRY_DSN);
|
||||
// The following values can exist in development, but production-like
|
||||
@@ -125,6 +127,7 @@ export const SENTRY_DSN =
|
||||
? ''
|
||||
: process.env.SENTRY_DSN;
|
||||
export const COOKIE_DOMAIN = process.env.COOKIE_DOMAIN || 'localhost';
|
||||
export const COOKIE_SECRET = process.env.COOKIE_SECRET;
|
||||
export const JWT_SECRET = process.env.JWT_SECRET;
|
||||
export const SES_ID = process.env.SES_ID;
|
||||
export const SES_SECRET = process.env.SES_SECRET;
|
||||
|
||||
7
api/src/utils/ids.ts
Normal file
7
api/src/utils/ids.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { customAlphabet } from 'nanoid';
|
||||
|
||||
// uppercase, lowercase letters and numbers
|
||||
export const customNanoid = customAlphabet(
|
||||
'1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
64
|
||||
);
|
||||
@@ -1,7 +1,6 @@
|
||||
import { FastifyRequest } from 'fastify';
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
// import { allowedOrigins } from '../../config/allowed-origins';
|
||||
import { availableLangs } from '../../../shared/config/i18n';
|
||||
import { allowedOrigins } from './allowed-origins';
|
||||
|
||||
|
||||
28
api/src/utils/tokens.test.ts
Normal file
28
api/src/utils/tokens.test.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
import { createAccessToken } from './tokens';
|
||||
|
||||
describe('createAccessToken', () => {
|
||||
it('creates an object with id, ttl, created and userId', () => {
|
||||
const userId = 'abc';
|
||||
|
||||
const actual = createAccessToken(userId);
|
||||
|
||||
expect(actual).toStrictEqual({
|
||||
id: expect.stringMatching(/[a-zA-Z0-9]{64}/),
|
||||
ttl: 77760000000,
|
||||
created: expect.stringMatching(
|
||||
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/
|
||||
),
|
||||
userId
|
||||
});
|
||||
});
|
||||
|
||||
it('sets the ttl, defaulting to 77760000000 ms', () => {
|
||||
const userId = 'abc';
|
||||
const ttl = 123;
|
||||
const actual = createAccessToken(userId, ttl);
|
||||
|
||||
expect(actual.ttl).toBe(ttl);
|
||||
expect(createAccessToken(userId).ttl).toBe(77760000000);
|
||||
});
|
||||
});
|
||||
39
api/src/utils/tokens.ts
Normal file
39
api/src/utils/tokens.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { customNanoid } from './ids';
|
||||
|
||||
import { JWT_SECRET } from './env';
|
||||
|
||||
/**
|
||||
* Encode an id into a JWT (the naming suggests it's a user token, but it's the
|
||||
* id of the UserToken document).
|
||||
* @param userToken A token id to encode.
|
||||
* @returns An encoded object with the userToken property.
|
||||
*/
|
||||
export function encodeUserToken(userToken: string): string {
|
||||
return jwt.sign({ userToken }, JWT_SECRET);
|
||||
}
|
||||
|
||||
export type AccessToken = {
|
||||
userId: string;
|
||||
id: string;
|
||||
ttl: number;
|
||||
created: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an access token.
|
||||
* @param userId The user ID as a string (yes, it's an ObjectID, but it will be serialized to a string anyway).
|
||||
* @param ttl The time to live for the token in milliseconds (default: 77760000000).
|
||||
* @returns The access token.
|
||||
*/
|
||||
export const createAccessToken = (
|
||||
userId: string,
|
||||
ttl?: number
|
||||
): AccessToken => {
|
||||
return {
|
||||
userId,
|
||||
id: customNanoid(),
|
||||
ttl: ttl ?? 77760000000,
|
||||
created: new Date().toISOString()
|
||||
};
|
||||
};
|
||||
@@ -1,13 +0,0 @@
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
import { JWT_SECRET } from './env';
|
||||
|
||||
/**
|
||||
* Encode an id into a JWT (the naming suggests it's a user token, but it's the
|
||||
* id of the UserToken document).
|
||||
* @param userToken A token id to encode.
|
||||
* @returns An encoded object with the userToken property.
|
||||
*/
|
||||
export function encodeUserToken(userToken: string): string {
|
||||
return jwt.sign({ userToken }, JWT_SECRET);
|
||||
}
|
||||
Reference in New Issue
Block a user