chore: offload retrieval of environment variables from jwt.ts to env.ts
This commit is contained in:
@@ -5,7 +5,7 @@ import * as ms from '../schemas/miscSchema';
|
|||||||
import * as ls from '../schemas/linkSchema';
|
import * as ls from '../schemas/linkSchema';
|
||||||
import { LinkService } from '../services/linkService';
|
import { LinkService } from '../services/linkService';
|
||||||
import { UserService } from '../services/userService';
|
import { UserService } from '../services/userService';
|
||||||
import * as jwt from '../tools/jwt';
|
import * as env from '../tools/env';
|
||||||
import { generateSentenceString, generateShortString } from '../tools/wordlist';
|
import { generateSentenceString, generateShortString } from '../tools/wordlist';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,7 +32,7 @@ export async function generateShortLinkHandler(
|
|||||||
);
|
);
|
||||||
let generatedSubdomain: string | null = null;
|
let generatedSubdomain: string | null = null;
|
||||||
|
|
||||||
if (val.query['withSubdomain'] === true && jwt.getEnvString('useSubdomains', true) === 'true')
|
if (val.query['withSubdomain'] === true && env.getString('useSubdomains', true) === 'true')
|
||||||
generatedSubdomain = generateSentenceString('[subdomain]');
|
generatedSubdomain = generateSentenceString('[subdomain]');
|
||||||
|
|
||||||
const userResponse: ls.LinkResponseDTO = {
|
const userResponse: ls.LinkResponseDTO = {
|
||||||
@@ -65,7 +65,7 @@ export async function generateSentenceLinkHandler(
|
|||||||
let generatedSentenceString: string = generateSentenceString();
|
let generatedSentenceString: string = generateSentenceString();
|
||||||
let generatedSubdomain: string | null = null;
|
let generatedSubdomain: string | null = null;
|
||||||
|
|
||||||
if (val.query['withSubdomain'] === true && jwt.getEnvString('useSubdomains', true) === 'true')
|
if (val.query['withSubdomain'] === true && env.getString('useSubdomains', true) === 'true')
|
||||||
generatedSubdomain = generateSentenceString('[subdomain]');
|
generatedSubdomain = generateSentenceString('[subdomain]');
|
||||||
|
|
||||||
const userResponse: ls.LinkResponseDTO = {
|
const userResponse: ls.LinkResponseDTO = {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import z from 'zod';
|
import z from 'zod';
|
||||||
|
|
||||||
|
// GET /api/v1/link/short
|
||||||
const shortLinkRequestSchemaQuery = z.object({
|
const shortLinkRequestSchemaQuery = z.object({
|
||||||
// https://zod.dev/v4?id=stringbool
|
// https://zod.dev/v4?id=stringbool
|
||||||
length: z.coerce
|
length: z.coerce
|
||||||
@@ -20,6 +21,7 @@ export const shortLinkRequestSchema = z.object({
|
|||||||
});
|
});
|
||||||
export type ShortLinkRequestDTO = z.TypeOf<typeof shortLinkRequestSchema>;
|
export type ShortLinkRequestDTO = z.TypeOf<typeof shortLinkRequestSchema>;
|
||||||
|
|
||||||
|
// GET /api/v1/link/fromWordlist
|
||||||
const sentenceLinkRequestSchemaQuery = z.object({
|
const sentenceLinkRequestSchemaQuery = z.object({
|
||||||
// https://zod.dev/v4?id=stringbool
|
// https://zod.dev/v4?id=stringbool
|
||||||
withSubdomain: z.stringbool('WithSubdomain must be a boolean')
|
withSubdomain: z.stringbool('WithSubdomain must be a boolean')
|
||||||
@@ -31,6 +33,7 @@ export const sentenceLinkRequestSchema = z.object({
|
|||||||
});
|
});
|
||||||
export type SentenceLinkRequestDTO = z.TypeOf<typeof sentenceLinkRequestSchema>;
|
export type SentenceLinkRequestDTO = z.TypeOf<typeof sentenceLinkRequestSchema>;
|
||||||
|
|
||||||
|
// response for both /api/v1/link/short and /api/v1/link/fromWordlist
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import * as dotenv from 'dotenv';
|
import * as env from './env';
|
||||||
dotenv.config({ quiet: true });
|
|
||||||
|
|
||||||
let cors = require('cors');
|
let cors = require('cors');
|
||||||
import { getEnvString } from './jwt';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns user-trusted origins from the .env file.
|
* Returns user-trusted origins from the .env file.
|
||||||
@@ -12,7 +9,7 @@ import { getEnvString } from './jwt';
|
|||||||
*/
|
*/
|
||||||
export function getTrustedOrigins(): string[] {
|
export function getTrustedOrigins(): string[] {
|
||||||
let trustedOrigins: string[] = ['http://localhost:6568'];
|
let trustedOrigins: string[] = ['http://localhost:6568'];
|
||||||
const configOriginsString: string | undefined = getEnvString('trustedOrigins', true);
|
const configOriginsString: string | undefined = env.getString('trustedOrigins', true);
|
||||||
|
|
||||||
// No config available.
|
// No config available.
|
||||||
if (configOriginsString === undefined) {
|
if (configOriginsString === undefined) {
|
||||||
|
|||||||
37
src/tools/env.ts
Normal file
37
src/tools/env.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import * as dotenv from 'dotenv';
|
||||||
|
dotenv.config({ quiet: true });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the environmental string from .env.
|
||||||
|
* Supports rewriting names to UPPER_SNAKE_CASE if isGlobal is set.
|
||||||
|
*
|
||||||
|
* @param {string} key The key
|
||||||
|
* @param {boolean} [isGlobal=true] Indicates if global
|
||||||
|
* @return {(string|undefined)} The environment string.
|
||||||
|
*/
|
||||||
|
export function getString(
|
||||||
|
key: string,
|
||||||
|
isGlobal: boolean = true
|
||||||
|
): string | undefined {
|
||||||
|
let keyName: string = '';
|
||||||
|
|
||||||
|
if (isGlobal) {
|
||||||
|
// Global values are DECLARED_LIKE_THIS=...
|
||||||
|
for (let i: number = 0; i < key.length; i++) {
|
||||||
|
if (key[i].toLowerCase() === key[i]) {
|
||||||
|
// If is lowercase, skip.
|
||||||
|
keyName += key[i];
|
||||||
|
} else {
|
||||||
|
// If is uppercase, convert to snake case.
|
||||||
|
keyName += `_${key[i].toLowerCase()}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keyName = keyName.toUpperCase();
|
||||||
|
} else {
|
||||||
|
// Non-global keys are parsed as passed
|
||||||
|
keyName = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return process.env[keyName];
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
// Heavily based on:
|
// Heavily based on:
|
||||||
// https://github.com/TomDoesTech/REST-API-Tutorial-Updated/blob/7b5f040e1acd94d267df585516b33ee7e3b75f70/src/utils/jwt.utils.ts
|
// https://github.com/TomDoesTech/REST-API-Tutorial-Updated/blob/7b5f040e1acd94d267df585516b33ee7e3b75f70/src/utils/jwt.utils.ts
|
||||||
import * as dotenv from 'dotenv';
|
|
||||||
dotenv.config({ quiet: true });
|
|
||||||
|
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
import { DEFAULT_TOKEN_LIFETIME } from '../schemas/authSchema';
|
import { DEFAULT_TOKEN_LIFETIME } from '../schemas/authSchema';
|
||||||
|
import * as env from './env';
|
||||||
|
|
||||||
type JwtStatus = {
|
type JwtStatus = {
|
||||||
valid: boolean;
|
valid: boolean;
|
||||||
@@ -12,40 +10,6 @@ type JwtStatus = {
|
|||||||
decoded: string | jwt.JwtPayload | null;
|
decoded: string | jwt.JwtPayload | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the environmental string from .env.
|
|
||||||
* Supports rewriting names to UPPER_SNAKE_CASE if isGlobal is set.
|
|
||||||
*
|
|
||||||
* @param {string} key The key
|
|
||||||
* @param {boolean} [isGlobal=true] Indicates if global
|
|
||||||
* @return {(string|undefined)} The environment string.
|
|
||||||
*/
|
|
||||||
export function getEnvString(
|
|
||||||
key: string,
|
|
||||||
isGlobal: boolean = true
|
|
||||||
): string | undefined {
|
|
||||||
let keyName: string = '';
|
|
||||||
|
|
||||||
if (isGlobal) {
|
|
||||||
// Global values are DECLARED_LIKE_THIS=...
|
|
||||||
for (let i: number = 0; i < key.length; i++) {
|
|
||||||
if (key[i].toLowerCase() === key[i]) {
|
|
||||||
// If is lowercase, skip.
|
|
||||||
keyName += key[i];
|
|
||||||
} else {
|
|
||||||
// If is uppercase, convert to snake case.
|
|
||||||
keyName += `_${key[i].toLowerCase()}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keyName = keyName.toUpperCase();
|
|
||||||
} else {
|
|
||||||
// Non-global keys are parsed as passed
|
|
||||||
keyName = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
return process.env[keyName];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign a JWT containing sub (number), role (number, 0/1), iat/exp (unix timestamp) claims.
|
* Sign a JWT containing sub (number), role (number, 0/1), iat/exp (unix timestamp) claims.
|
||||||
*
|
*
|
||||||
@@ -66,7 +30,7 @@ export function signJwt(
|
|||||||
// 'base64'
|
// 'base64'
|
||||||
// ).toString('utf8');
|
// ).toString('utf8');
|
||||||
|
|
||||||
const secret: string = getEnvString(keyName, true)!;
|
const secret: string = env.getString(keyName, true)!;
|
||||||
|
|
||||||
// Use the default expiration time of 24 hours.
|
// Use the default expiration time of 24 hours.
|
||||||
if (options === undefined)
|
if (options === undefined)
|
||||||
@@ -97,7 +61,7 @@ export function verifyJwt(
|
|||||||
// 'base64'
|
// 'base64'
|
||||||
// ).toString('utf8');
|
// ).toString('utf8');
|
||||||
|
|
||||||
const secret: string = getEnvString(keyName, true)!;
|
const secret: string = env.getString(keyName, true)!;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const decoded: string | jwt.JwtPayload = jwt.verify(token, secret);
|
const decoded: string | jwt.JwtPayload = jwt.verify(token, secret);
|
||||||
|
|||||||
Reference in New Issue
Block a user