Move the constants (mostly) into common package
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@mifi/auth-common",
|
"name": "@mifi/auth-common",
|
||||||
"version": "1.0.0",
|
"version": "1.0.5",
|
||||||
"author": "mifi (Mike Fitzpatrick)",
|
"author": "mifi (Mike Fitzpatrick)",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -17,8 +17,10 @@
|
|||||||
"@babel/core": "^7.21.8",
|
"@babel/core": "^7.21.8",
|
||||||
"@babel/preset-env": "^7.21.5",
|
"@babel/preset-env": "^7.21.5",
|
||||||
"@babel/preset-typescript": "^7.21.5",
|
"@babel/preset-typescript": "^7.21.5",
|
||||||
|
"@mifi/auth-db": "^1.0.10",
|
||||||
"@tsconfig/node16": "^1.0.4",
|
"@tsconfig/node16": "^1.0.4",
|
||||||
"@types/jest": "^29.5.1",
|
"@types/jest": "^29.5.1",
|
||||||
|
"@types/jsonwebtoken": "^9.0.2",
|
||||||
"@types/koa": "^2.13.6",
|
"@types/koa": "^2.13.6",
|
||||||
"@types/node": "^20.2.5",
|
"@types/node": "^20.2.5",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||||
@@ -47,6 +49,7 @@
|
|||||||
"packageManager": "yarn@3.5.1",
|
"packageManager": "yarn@3.5.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mifi/breakerbox-db": "^1.0.3",
|
"@mifi/breakerbox-db": "^1.0.3",
|
||||||
"@mifi/services-common": "^1.0.9"
|
"@mifi/services-common": "^1.0.11",
|
||||||
|
"jsonwebtoken": "^9.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
src/db/index.ts
Normal file
3
src/db/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { Breakerbox } from '@mifi/breakerbox-db/lib/index';
|
||||||
|
|
||||||
|
export const breakerbox = Breakerbox.getInstance({ path: 'auth-service-settings.yml', storageType: 'yaml' });
|
||||||
9
src/enums/action.ts
Normal file
9
src/enums/action.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export enum Action {
|
||||||
|
AUTHENTICATE = 'AUTHENTICATE',
|
||||||
|
AUTHENTICATE_FAILURE = 'AUTHENTICATE_FAILURE',
|
||||||
|
CREATE = 'CREATE',
|
||||||
|
DELETE = 'DELETE',
|
||||||
|
RESET = 'RESET',
|
||||||
|
RESET_REQUEST = 'RESET_REQUEST',
|
||||||
|
UPDATE = 'UPDATE',
|
||||||
|
}
|
||||||
8
src/enums/status.ts
Normal file
8
src/enums/status.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export enum Status {
|
||||||
|
ACTIVE,
|
||||||
|
BLOCK_HARD,
|
||||||
|
BLOCK_SOFT,
|
||||||
|
DELETED,
|
||||||
|
INACTIVE,
|
||||||
|
UNVERIFIED,
|
||||||
|
}
|
||||||
7
src/enums/strategies.ts
Normal file
7
src/enums/strategies.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export enum STRATEGIES {
|
||||||
|
LOCAL,
|
||||||
|
APPLE,
|
||||||
|
FACEBOOK,
|
||||||
|
FIDO2,
|
||||||
|
GOOGLE,
|
||||||
|
}
|
||||||
4
src/enums/tokens.ts
Normal file
4
src/enums/tokens.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export enum TokenType {
|
||||||
|
RESET = 'RESET',
|
||||||
|
VERIFICATION = 'VERIFICATION',
|
||||||
|
}
|
||||||
5
src/env/jwt.ts
vendored
Normal file
5
src/env/jwt.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { getEnvVar } from '@mifi/services-common/lib/utils/getEnvVar';
|
||||||
|
|
||||||
|
export const JWT_AUDIENCE = getEnvVar<string>('JWT_AUDIENCE', 'mifi.dev');
|
||||||
|
export const JWT_ISSUER = getEnvVar<string>('JWT_ISSUER', 'mifi.dev Auth Service');
|
||||||
|
export const JWT_SECRET = getEnvVar<string>('JWT_SECRET', 'secret');
|
||||||
6
src/env/routes.ts
vendored
Normal file
6
src/env/routes.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { getEnvVar } from '@mifi/services-common/lib/utils/getEnvVar';
|
||||||
|
|
||||||
|
export const ROUTE_PREFIX = getEnvVar<string>('ROUTE_PREFIX', '/auth');
|
||||||
|
export const LOGIN_ROUTE = getEnvVar<string>('LOGIN_ROUTE', '/login');
|
||||||
|
export const RESET_ROUTE = getEnvVar<string>('RESET_ROUTE', '/reset');
|
||||||
|
export const VERIFICATION_ROUTE = getEnvVar<string>('VERIFICATION_ROUTE', '/verification');
|
||||||
6
src/env/timeouts.ts
vendored
Normal file
6
src/env/timeouts.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { getEnvVar } from '@mifi/services-common/lib/utils/getEnvVar';
|
||||||
|
|
||||||
|
export const LOGIN_VALID_TIMEOUT = getEnvVar<string>('LOGIN_VALID_TIMEOUT', '12h'); // ###d|h|m
|
||||||
|
export const RESET_VALID_TIMEOUT = getEnvVar<string>('RESET_VALID_TIMEOUT', '15m'); // ###d|h|m
|
||||||
|
export const VERIFY_VALID_TIMEOUT = getEnvVar<string>('VERIFY_VALID_TIMEOUT', '60d'); // ###d|h|m
|
||||||
|
export const DEFAULT_TOKEN_DAYS = getEnvVar<number>('DEFAULT_TOKEN_DAYS', 365);
|
||||||
15
src/helpers/getDefaultExpiresFor.ts
Normal file
15
src/helpers/getDefaultExpiresFor.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { LOGIN_VALID_TIMEOUT, RESET_VALID_TIMEOUT, VERIFY_VALID_TIMEOUT } from '../env/timeouts';
|
||||||
|
import { TokenType } from '../enums/tokens';
|
||||||
|
import { parseTimeoutToMs } from './parseTimeoutToMs';
|
||||||
|
|
||||||
|
export const getDefaultExpiresFor = (type: TokenType | void) => {
|
||||||
|
if (type === TokenType.RESET) {
|
||||||
|
return Date.now() + parseTimeoutToMs(RESET_VALID_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === TokenType.VERIFICATION) {
|
||||||
|
return Date.now() + parseTimeoutToMs(VERIFY_VALID_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Date.now() + parseTimeoutToMs(LOGIN_VALID_TIMEOUT);
|
||||||
|
};
|
||||||
13
src/helpers/parseTimeoutToMs.ts
Normal file
13
src/helpers/parseTimeoutToMs.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
export const parseTimeoutToMs = (timeout: string) => {
|
||||||
|
const match = timeout.match(/(?<number>\d+)(?<unit>d|h|m)/gi)?.groups || {};
|
||||||
|
const { number, unit } = match;
|
||||||
|
switch (unit) {
|
||||||
|
case 'd':
|
||||||
|
return 1000 * 60 * 60 * 24 * parseInt(number);
|
||||||
|
case 'h':
|
||||||
|
return 1000 * 60 * 60 * parseInt(number);
|
||||||
|
case 'm':
|
||||||
|
default:
|
||||||
|
return 1000 * 60 * parseInt(number) || 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export const ROUTE_PREFIX = process.env.ROUTE_PREFIX || '/auth';
|
|
||||||
export const LOGIN_ROUTE = process.env.LOGIN_ROUTE || '/login';
|
|
||||||
export const RESET_ROUTE = process.env.RESET_ROUTE || '/reset';
|
|
||||||
export const VERIFICATION_ROUTE = process.env.VERIFICATION_ROUTE || '/verification';
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { breakerbox } from '@mifi/breakerbox-db/lib/index';
|
|
||||||
import { getEnvVar } from '@mifi/services-common/lib/utils/getEnvVar';
|
|
||||||
|
|
||||||
const breakers = breakerbox({ path: 'auth-service-settings.yml', storageType: 'yaml' });
|
|
||||||
|
|
||||||
const envValue = getEnvVar('REQUIRE_VERIFICATION');
|
|
||||||
export const REQUIRE_VERIFICATION = breakers.getValue<boolean>(
|
|
||||||
'REQUIRE_VERIFICATION',
|
|
||||||
envValue !== undefined ? envValue : true,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
9
src/settings/index.ts
Normal file
9
src/settings/index.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { getEnvVar } from '@mifi/services-common/lib/utils/getEnvVar';
|
||||||
|
|
||||||
|
import { breakerbox } from '../db';
|
||||||
|
|
||||||
|
export const REQUIRE_VERIFICATION = breakerbox.getValue<boolean>(
|
||||||
|
'REQUIRE_VERIFICATION',
|
||||||
|
getEnvVar('REQUIRE_VERIFICATION', true),
|
||||||
|
true,
|
||||||
|
);
|
||||||
12
src/utils/generateLoginToken.ts
Normal file
12
src/utils/generateLoginToken.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { AuthDocument } from '@mifi/auth-db/lib/schema/auth';
|
||||||
|
|
||||||
|
import { LOGIN_VALID_TIMEOUT } from '../env/timeouts';
|
||||||
|
import { parseTimeoutToMs } from '../helpers/parseTimeoutToMs';
|
||||||
|
import { sign } from '../utils/jwt/sign';
|
||||||
|
|
||||||
|
export const generateLoginToken = ({ record: sub, status }: Pick<AuthDocument, 'record' | 'status'>) =>
|
||||||
|
sign({
|
||||||
|
sub: <string>sub,
|
||||||
|
status,
|
||||||
|
exp: Date.now() + parseTimeoutToMs(LOGIN_VALID_TIMEOUT),
|
||||||
|
});
|
||||||
4
src/utils/jwt/index.ts
Normal file
4
src/utils/jwt/index.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { sign } from './sign';
|
||||||
|
import { verify } from './verify';
|
||||||
|
|
||||||
|
export { sign, verify };
|
||||||
37
src/utils/jwt/sign.ts
Normal file
37
src/utils/jwt/sign.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { sign as jwtSign } from 'jsonwebtoken';
|
||||||
|
|
||||||
|
import { Payload } from '@mifi/services-common/lib/types/Payload';
|
||||||
|
|
||||||
|
import { JWT_AUDIENCE, JWT_ISSUER, JWT_SECRET } from '../../env/jwt';
|
||||||
|
import { DEFAULT_TOKEN_DAYS } from '../../env/timeouts';
|
||||||
|
|
||||||
|
export type TokenProps = Payload & {
|
||||||
|
aud?: string;
|
||||||
|
exp?: number;
|
||||||
|
iss?: string;
|
||||||
|
sub: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SignProps = string | TokenProps | void;
|
||||||
|
|
||||||
|
export const sign = (props: SignProps) => {
|
||||||
|
const today = new Date();
|
||||||
|
const { sub = null, ...rest }: TokenProps =
|
||||||
|
typeof props === 'string' || typeof props === 'undefined' ? { sub: props || null } : props;
|
||||||
|
let { exp } = rest;
|
||||||
|
if (!exp) {
|
||||||
|
const defaultExp = new Date(today);
|
||||||
|
defaultExp.setDate(today.getDate() + DEFAULT_TOKEN_DAYS);
|
||||||
|
exp = defaultExp.getTime() / 1000;
|
||||||
|
}
|
||||||
|
return jwtSign(
|
||||||
|
{
|
||||||
|
exp,
|
||||||
|
sub,
|
||||||
|
aud: rest.aud || JWT_AUDIENCE,
|
||||||
|
iat: today.getTime(),
|
||||||
|
iss: rest.iss || JWT_ISSUER,
|
||||||
|
},
|
||||||
|
JWT_SECRET,
|
||||||
|
);
|
||||||
|
};
|
||||||
5
src/utils/jwt/verify.ts
Normal file
5
src/utils/jwt/verify.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { verify as jwtVerify } from 'jsonwebtoken';
|
||||||
|
|
||||||
|
import { JWT_SECRET } from '../../env/jwt';
|
||||||
|
|
||||||
|
export const verify = (token: string) => jwtVerify(token, JWT_SECRET);
|
||||||
Reference in New Issue
Block a user