Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
cc3e97d2e1
|
|||
|
e9681fbc9a
|
|||
|
4ce4b62fe5
|
|||
|
64e1f53f4e
|
@@ -6,6 +6,5 @@
|
|||||||
.yarnrc.yml
|
.yarnrc.yml
|
||||||
babel.config.*
|
babel.config.*
|
||||||
jest.config.*
|
jest.config.*
|
||||||
src
|
|
||||||
tsconfig*.json
|
tsconfig*.json
|
||||||
tslint.json
|
tslint.json
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@mifi/auth-db",
|
"name": "@mifi/auth-db",
|
||||||
"version": "1.0.6",
|
"version": "1.0.20",
|
||||||
"author": "mifi (Mike Fitzpatrick)",
|
"author": "mifi (Mike Fitzpatrick)",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -39,7 +39,8 @@
|
|||||||
"typescript": "^4.9.5"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mifi/services-common": "1.x.x",
|
"@mifi/auth-common": "^1.0.15",
|
||||||
|
"@mifi/services-common": "^1.0.16",
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"jsonwebtoken": "^9.0.0",
|
"jsonwebtoken": "^9.0.0",
|
||||||
"mongoose": "^6.9.2"
|
"mongoose": "^6.9.2"
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
import { Auth, Log } from '..';
|
import { Action } from '@mifi/auth-common/lib/enums/action';
|
||||||
import { Action } from '../constants/action';
|
import { generateLoginToken } from '@mifi/auth-common/lib/utils/generateLoginToken';
|
||||||
import { getLoginToken } from '../utils/getLoginToken';
|
|
||||||
|
|
||||||
export const authenticate = async (username: string, password: string) => {
|
import { Auth, Log } from '..';
|
||||||
|
|
||||||
|
export const authenticate = async (username: string, password: string, includeToken = false) => {
|
||||||
const doc = await Auth.findByUsername(username).catch();
|
const doc = await Auth.findByUsername(username).catch();
|
||||||
if (!!doc && (await doc.authenticate(password))) {
|
if (!!doc && (await doc.authenticate(password))) {
|
||||||
Log.add(doc.id, Action.AUTHENTICATE);
|
Log.add(doc.id, Action.AUTHENTICATE);
|
||||||
return { ...doc, token: getLoginToken(doc) };
|
return { sub: doc._id, record: doc.record, token: includeToken ? generateLoginToken(doc) : undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc) {
|
if (doc) {
|
||||||
Log.add(doc.id, Action.AUTHENTICATE_FAILURE);
|
Log.add(doc.id, Action.AUTHENTICATE_FAILURE, { ...doc });
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { StringSchemaDefinition } from 'mongoose';
|
import { StringSchemaDefinition } from 'mongoose';
|
||||||
|
|
||||||
import { Auth, Strategy } from '..';
|
import { Auth, Strategy } from '..';
|
||||||
|
|
||||||
export const deleteStrategy = async (id: StringSchemaDefinition) => {
|
export const deleteStrategy = async (id: StringSchemaDefinition) => {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import { Action } from '@mifi/auth-common/lib/enums/action';
|
||||||
|
import { TokenType } from '@mifi/auth-common/lib/enums/tokens';
|
||||||
|
|
||||||
import { readOneByUsername } from '../dao/readOneByUsername';
|
import { readOneByUsername } from '../dao/readOneByUsername';
|
||||||
import { Log, Token } from '..';
|
import { Log, Token } from '..';
|
||||||
import { TokenType } from '../constants/tokens';
|
|
||||||
import { Action } from '../constants/action';
|
|
||||||
|
|
||||||
export const resetPasswordGet = async (username: string) => {
|
export const resetPasswordGet = async (username: string) => {
|
||||||
const doc = await readOneByUsername(username);
|
const doc = await readOneByUsername(username);
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { Types } from 'mongoose';
|
import { Types } from 'mongoose';
|
||||||
|
|
||||||
import { Log, Strategy, Token } from '..';
|
import { Action } from '@mifi/auth-common/lib/enums/action';
|
||||||
import { STRATEGIES } from '../constants/strategies';
|
import { STRATEGIES } from '@mifi/auth-common/lib/enums/strategies';
|
||||||
|
import { generateLoginToken } from '@mifi/auth-common/lib/utils/generateLoginToken';
|
||||||
|
|
||||||
import { AuthDocument } from '../schema/auth';
|
import { AuthDocument } from '../schema/auth';
|
||||||
import { getLoginToken } from '../utils/getLoginToken';
|
|
||||||
import { StrategyDocument } from '../schema/strategy';
|
import { StrategyDocument } from '../schema/strategy';
|
||||||
import { Action } from '../constants/action';
|
import { Log, Strategy, Token } from '..';
|
||||||
|
|
||||||
export const resetPasswordPost = async (token: string, password: string) => {
|
export const resetPasswordPost = async (token: string, password: string) => {
|
||||||
const parentId = await Token.validateResetToken(token);
|
const parentId = await Token.validateResetToken(token);
|
||||||
@@ -34,7 +35,7 @@ export const resetPasswordPost = async (token: string, password: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log.add(parent._id, Action.RESET);
|
Log.add(parent._id, Action.RESET);
|
||||||
return { record: parent.record, token: getLoginToken(parent) };
|
return { record: parent.record, token: generateLoginToken(parent) };
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
export enum Action {
|
|
||||||
AUTHENTICATE = 'AUTHENTICATE',
|
|
||||||
AUTHENTICATE_FAILURE = 'AUTHENTICATE_FAILURE',
|
|
||||||
CREATE = 'CREATE',
|
|
||||||
DELETE = 'DELETE',
|
|
||||||
RESET = 'RESET',
|
|
||||||
RESET_REQUEST = 'RESET_REQUEST',
|
|
||||||
UPDATE = 'UPDATE',
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
export enum Status {
|
|
||||||
ACTIVE,
|
|
||||||
BLOCK_HARD,
|
|
||||||
BLOCK_SOFT,
|
|
||||||
DELETED,
|
|
||||||
INACTIVE,
|
|
||||||
UNVERIFIED,
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
export const PACKAGE_NAME = '@mifi/auth';
|
|
||||||
export const PORT = process.env.PORT || 9000;
|
|
||||||
|
|
||||||
export const SESSION_KEY = process.env.SESSION_KEY || 'secret-key';
|
|
||||||
|
|
||||||
export const JWT_AUDIENCE = process.env.JWT_AUDIENCE || 'mifi.dev';
|
|
||||||
export const JWT_ISSUER = process.env.JWT_ISSUER || PACKAGE_NAME;
|
|
||||||
export const JWT_SECRET = process.env.JWT_SECRET || 'secret';
|
|
||||||
|
|
||||||
export const LOGIN_VALID_TIMEOUT = process.env.LOGIN_VALID_TIMEOUT || '12h'; // ###d|h|m
|
|
||||||
export const RESET_VALID_TIMEOUT = process.env.RESET_VALID_TIMEOUT || '15m'; // ###d|h|m
|
|
||||||
export const VERIFY_VALID_TIMEOUT = process.env.VERIFY_VALID_TIMEOUT || '60d'; // ###d|h|m
|
|
||||||
export const DEFAULT_TOKEN_DAYS = process.env.DEFAULT_TOKEN_DAYS || 365;
|
|
||||||
|
|
||||||
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';
|
|
||||||
|
|
||||||
export const REQUIRE_VERIFICATION = process.env.REQUIRE_VERIFICATION || true;
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
export enum ErrorCodes {
|
|
||||||
RESET_REQUEST_DATA = 'RESET_REQUEST_DATA',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ErrorMessages = {
|
|
||||||
[ErrorCodes.RESET_REQUEST_DATA]: 'A valid username and password must be provided',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getErrorBody = (code: ErrorCodes) => ({
|
|
||||||
code,
|
|
||||||
message: ErrorMessages[code],
|
|
||||||
});
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
export enum STRATEGIES {
|
|
||||||
LOCAL,
|
|
||||||
APPLE,
|
|
||||||
FACEBOOK,
|
|
||||||
FIDO2,
|
|
||||||
GOOGLE,
|
|
||||||
}
|
|
||||||
4
src/constants/timeouts.ts
Normal file
4
src/constants/timeouts.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export const LOGIN_VALID_TIMEOUT = process.env.LOGIN_VALID_TIMEOUT || '12h'; // ###d|h|m
|
||||||
|
export const RESET_VALID_TIMEOUT = process.env.RESET_VALID_TIMEOUT || '15m'; // ###d|h|m
|
||||||
|
export const VERIFY_VALID_TIMEOUT = process.env.VERIFY_VALID_TIMEOUT || '60d'; // ###d|h|m
|
||||||
|
export const DEFAULT_TOKEN_DAYS = process.env.DEFAULT_TOKEN_DAYS || 365;
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export enum TokenType {
|
|
||||||
RESET = 'RESET',
|
|
||||||
VERIFICATION = 'VERIFICATION',
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,25 @@
|
|||||||
|
import { Action } from '@mifi/auth-common/lib/enums/action';
|
||||||
|
import { Status } from '@mifi/auth-common/lib/enums/status';
|
||||||
|
import { STRATEGIES } from '@mifi/auth-common/lib/enums/strategies';
|
||||||
|
import { TokenType } from '@mifi/auth-common/lib/enums/tokens';
|
||||||
|
import { REQUIRE_VERIFICATION } from '@mifi/auth-common/lib/settings';
|
||||||
import { DatabaseError } from '@mifi/services-common/lib/domain/errors/DatabaseError';
|
import { DatabaseError } from '@mifi/services-common/lib/domain/errors/DatabaseError';
|
||||||
|
|
||||||
import { Auth, Log, Strategy, Token } from '../..';
|
|
||||||
import { Auth as AuthProps } from '../../schema/auth';
|
import { Auth as AuthProps } from '../../schema/auth';
|
||||||
import { STRATEGIES } from '../../constants/strategies';
|
import { Auth, Log, Strategy, Token } from '../..';
|
||||||
import { REQUIRE_VERIFICATION } from '../../constants/env';
|
|
||||||
import { TokenType } from '../../constants/tokens';
|
|
||||||
import { Status } from '../../constants/auth';
|
|
||||||
import { Action } from '../../constants/action';
|
|
||||||
|
|
||||||
type CreateProps = Pick<AuthProps, 'record' | 'username'> & {
|
type CreateProps = Pick<AuthProps, 'username'> & {
|
||||||
externalId?: string;
|
externalId?: string;
|
||||||
|
handle?: AuthProps['handle'];
|
||||||
password?: string;
|
password?: string;
|
||||||
publicKey?: string;
|
publicKey?: string;
|
||||||
|
record?: AuthProps['record'];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const create = async ({ record, username, externalId, password, publicKey }: CreateProps) => {
|
export const create = async ({ record, username, externalId, handle, password, publicKey }: CreateProps) => {
|
||||||
const status = REQUIRE_VERIFICATION ? Status.UNVERIFIED : Status.ACTIVE;
|
const status = REQUIRE_VERIFICATION ? Status.UNVERIFIED : Status.ACTIVE;
|
||||||
const doc = await Auth.create({
|
const doc = await Auth.create({
|
||||||
|
handle,
|
||||||
record,
|
record,
|
||||||
status,
|
status,
|
||||||
username,
|
username,
|
||||||
@@ -55,7 +58,7 @@ export const create = async ({ record, username, externalId, password, publicKey
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Fido2UserProps = Pick<AuthProps, 'record' | 'username'> & { externalId: string; publicKey: string };
|
export type Fido2UserProps = Pick<AuthProps, 'handle' | 'username'> & { externalId: string; publicKey: string };
|
||||||
export const createFido2User = (props: Fido2UserProps) => create(props);
|
export const createFido2User = (props: Fido2UserProps) => create(props);
|
||||||
|
|
||||||
export type LocalUserProps = Pick<AuthProps, 'record' | 'username'> & { password: string };
|
export type LocalUserProps = Pick<AuthProps, 'record' | 'username'> & { password: string };
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { StringSchemaDefinition } from 'mongoose';
|
import { StringSchemaDefinition } from 'mongoose';
|
||||||
|
|
||||||
|
import { Action } from '@mifi/auth-common/lib/enums/action';
|
||||||
|
import { Status } from '@mifi/auth-common/lib/enums/status';
|
||||||
|
|
||||||
import { Auth, Log, Strategy, Token } from '../..';
|
import { Auth, Log, Strategy, Token } from '../..';
|
||||||
import { Status } from '../../constants/auth';
|
|
||||||
import { Action } from '../../constants/action';
|
|
||||||
|
|
||||||
export const deleteById = async (id: StringSchemaDefinition) => {
|
export const deleteById = async (id: StringSchemaDefinition) => {
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { FilterQuery } from 'mongoose';
|
import { FilterQuery } from 'mongoose';
|
||||||
|
|
||||||
|
import { Status } from '@mifi/auth-common/lib/enums/status';
|
||||||
|
|
||||||
import { Auth } from '../../model/auth';
|
import { Auth } from '../../model/auth';
|
||||||
import { Status } from '../../constants/auth';
|
|
||||||
import { AuthDocument } from '../../schema/auth';
|
import { AuthDocument } from '../../schema/auth';
|
||||||
|
|
||||||
export const readAll = async (query: FilterQuery<AuthDocument> = {}) => Auth.find(query);
|
export const readAll = async (query: FilterQuery<AuthDocument> = {}) => Auth.find(query);
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
import { Strategy } from '../../model/strategy';
|
import { Strategy } from '../../model/strategy';
|
||||||
|
import { AuthDocument } from '../../schema/auth';
|
||||||
|
|
||||||
export const readOneByExternalId = async (externalId: string) => Strategy.findOne({ externalId });
|
export const readOneByExternalId = async (externalId: string, populate = false) =>
|
||||||
|
populate
|
||||||
|
? Strategy.findOne({ externalId }).populate<{ parent: AuthDocument }>('parent')
|
||||||
|
: Strategy.findOne({ externalId });
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Types } from 'mongoose';
|
import { Types } from 'mongoose';
|
||||||
|
|
||||||
import { STRATEGIES } from '../../constants/strategies';
|
import { STRATEGIES } from '@mifi/auth-common/lib/enums/strategies';
|
||||||
|
|
||||||
import { Strategy } from '../../model/strategy';
|
import { Strategy } from '../../model/strategy';
|
||||||
|
|
||||||
export const readOneByParentAndMethod = async (parent: Types.ObjectId, method: STRATEGIES) =>
|
export const readOneByParentAndMethod = async (parent: Types.ObjectId, method: STRATEGIES) =>
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import { Document, InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose';
|
import { Document, InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose';
|
||||||
|
|
||||||
import { Status } from '../constants/auth';
|
import { Status } from '@mifi/auth-common/lib/enums/status';
|
||||||
|
import { STRATEGIES } from '@mifi/auth-common/lib/enums/strategies';
|
||||||
|
|
||||||
import { COLL_STRATEGY } from '../constants/db';
|
import { COLL_STRATEGY } from '../constants/db';
|
||||||
import { STRATEGIES } from '../constants/strategies';
|
|
||||||
import { StrategyDocument } from './strategy';
|
|
||||||
import { verify } from '../utils/password';
|
import { verify } from '../utils/password';
|
||||||
|
import { StrategyDocument } from './strategy';
|
||||||
|
|
||||||
export interface Auth {
|
export interface Auth {
|
||||||
|
handle?: string;
|
||||||
is2FA?: boolean;
|
is2FA?: boolean;
|
||||||
record: StringSchemaDefinition;
|
record: StringSchemaDefinition;
|
||||||
username: string;
|
username: string;
|
||||||
@@ -35,6 +37,7 @@ export interface AuthModel extends Model<AuthDocument> {
|
|||||||
|
|
||||||
export const AuthSchema = new Schema<AuthDocument, AuthModel>(
|
export const AuthSchema = new Schema<AuthDocument, AuthModel>(
|
||||||
{
|
{
|
||||||
|
handle: { type: String },
|
||||||
is2FA: { type: Boolean, default: false },
|
is2FA: { type: Boolean, default: false },
|
||||||
record: { type: Types.ObjectId, unique: true },
|
record: { type: Types.ObjectId, unique: true },
|
||||||
status: {
|
status: {
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose';
|
import { InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose';
|
||||||
|
|
||||||
|
import { Action } from '@mifi/auth-common/lib/enums/action';
|
||||||
import { Payload } from '@mifi/services-common/lib/types/Payload';
|
import { Payload } from '@mifi/services-common/lib/types/Payload';
|
||||||
|
|
||||||
import { Action } from '../constants/action';
|
|
||||||
|
|
||||||
export interface Log {
|
export interface Log {
|
||||||
action: Action;
|
action: Action;
|
||||||
auth: StringSchemaDefinition;
|
auth: StringSchemaDefinition;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Document, InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose';
|
import { Document, InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose';
|
||||||
|
|
||||||
import { STRATEGIES } from '../constants/strategies';
|
import { STRATEGIES } from '@mifi/auth-common/lib/enums/strategies';
|
||||||
|
|
||||||
import { encrypt } from '../utils/password';
|
import { encrypt } from '../utils/password';
|
||||||
import { COLL_AUTH } from '../constants/db';
|
import { COLL_AUTH } from '../constants/db';
|
||||||
import { AuthDocument } from './auth';
|
import { AuthDocument } from './auth';
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose';
|
import { InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose';
|
||||||
|
|
||||||
import { TokenType } from '../constants/tokens';
|
import { TokenType } from '@mifi/auth-common/lib/enums/tokens';
|
||||||
import { getDefaultExpiresFor } from '../utils/getDefaultExpiresFor';
|
import { getDefaultExpiresFor } from '@mifi/auth-common/lib/helpers/getDefaultExpiresFor';
|
||||||
import { sign, verify } from '../utils/jwt';
|
import { sign, verify } from '@mifi/auth-common/lib/utils/jwt';
|
||||||
|
import { SignProps } from '@mifi/auth-common/lib/utils/jwt/sign';
|
||||||
|
|
||||||
export interface Token {
|
export interface Token {
|
||||||
auth: StringSchemaDefinition;
|
auth: StringSchemaDefinition;
|
||||||
@@ -50,7 +51,7 @@ TokenSchema.statics = {
|
|||||||
return sign({
|
return sign({
|
||||||
sub: `${doc._id}`,
|
sub: `${doc._id}`,
|
||||||
exp: doc.expires,
|
exp: doc.expires,
|
||||||
});
|
} as SignProps);
|
||||||
},
|
},
|
||||||
|
|
||||||
async validateResetToken(token: string) {
|
async validateResetToken(token: string) {
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
import { LOGIN_VALID_TIMEOUT, RESET_VALID_TIMEOUT, VERIFY_VALID_TIMEOUT } from '../constants/env';
|
|
||||||
import { TokenType } from '../constants/tokens';
|
|
||||||
import { parseTimeoutToMs } from '../utils/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);
|
|
||||||
};
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { sign } from '../utils/jwt';
|
|
||||||
import { LOGIN_VALID_TIMEOUT } from '../constants/env';
|
|
||||||
import { parseTimeoutToMs } from '../utils/parseTimeoutToMs';
|
|
||||||
import { AuthDocument } from '../schema/auth';
|
|
||||||
|
|
||||||
export const getLoginToken = ({ record: sub, status }: AuthDocument) =>
|
|
||||||
sign({
|
|
||||||
sub: <string>sub,
|
|
||||||
status,
|
|
||||||
exp: Date.now() + parseTimeoutToMs(LOGIN_VALID_TIMEOUT),
|
|
||||||
});
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import jwt from 'jsonwebtoken';
|
|
||||||
import { JWT_AUDIENCE, JWT_ISSUER, JWT_SECRET } from '../constants/env';
|
|
||||||
export interface TokenProps {
|
|
||||||
aud?: string;
|
|
||||||
exp?: number | Date;
|
|
||||||
iss?: string;
|
|
||||||
sub: string | null;
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
exp = new Date(today);
|
|
||||||
exp.setDate(today.getDate() + parseInt(process.env.JWT_DAYS_VALID as string));
|
|
||||||
exp = exp.getTime() / 1000;
|
|
||||||
}
|
|
||||||
return jwt.sign(
|
|
||||||
{
|
|
||||||
exp,
|
|
||||||
sub,
|
|
||||||
aud: rest.aud || JWT_AUDIENCE,
|
|
||||||
iat: today.getTime(),
|
|
||||||
iss: rest.iss || JWT_ISSUER,
|
|
||||||
},
|
|
||||||
JWT_SECRET,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const verify = (token: string) => jwt.verify(token, JWT_SECRET);
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import { RESET_ROUTE, ROUTE_PREFIX, VERIFICATION_ROUTE } from '../constants/env';
|
|
||||||
|
|
||||||
export const getPasswordResetPath = (token: string) => `${ROUTE_PREFIX}${RESET_ROUTE}?t=${token}`;
|
|
||||||
|
|
||||||
export const getVerificationPath = (token: string) => `${ROUTE_PREFIX}${VERIFICATION_ROUTE}?t=${token}`;
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -5,8 +5,3 @@ export const encrypt = (password: string) => {
|
|||||||
const hash = pbkdf2Sync(password, salt, 10000, 512, 'sha512').toString('hex');
|
const hash = pbkdf2Sync(password, salt, 10000, 512, 'sha512').toString('hex');
|
||||||
return `${salt}:${hash}`;
|
return `${salt}:${hash}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const verify = (test: string, secret: string) => {
|
|
||||||
const [salt, hash] = secret.split(':');
|
|
||||||
return pbkdf2Sync(test, salt, 10000, 512, 'sha512').toString('hex') === hash;
|
|
||||||
};
|
|
||||||
4
src/utils/password/index.ts
Normal file
4
src/utils/password/index.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { encrypt } from './encrypt';
|
||||||
|
import { verify } from './verify';
|
||||||
|
|
||||||
|
export { encrypt, verify };
|
||||||
6
src/utils/password/verify.ts
Normal file
6
src/utils/password/verify.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { pbkdf2Sync } from 'crypto';
|
||||||
|
|
||||||
|
export const verify = (test: string, secret: string) => {
|
||||||
|
const [salt, hash] = secret.split(':');
|
||||||
|
return pbkdf2Sync(test, salt, 10000, 512, 'sha512').toString('hex') === hash;
|
||||||
|
};
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { sign } from './jwt';
|
|
||||||
import { LOGIN_VALID_TIMEOUT } from '../constants/env';
|
|
||||||
import { Status } from '../constants/auth';
|
|
||||||
import { parseTimeoutToMs } from './parseTimeoutToMs';
|
|
||||||
|
|
||||||
export const generateLoginToken = (sub: string, status: Status) =>
|
|
||||||
sign({
|
|
||||||
sub,
|
|
||||||
status,
|
|
||||||
exp: Date.now() + parseTimeoutToMs(LOGIN_VALID_TIMEOUT),
|
|
||||||
});
|
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
"rootDirs": ["./", "src/"],
|
"rootDirs": ["./", "src/"],
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"sourceMap": false,
|
"sourceMap": true,
|
||||||
"removeComments": true
|
"removeComments": false
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|||||||
169
yarn.lock
169
yarn.lock
@@ -2648,6 +2648,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@mifi/auth-common@npm:^1.0.15":
|
||||||
|
version: 1.0.15
|
||||||
|
resolution: "@mifi/auth-common@npm:1.0.15::__archiveUrl=https%3A%2F%2Fgit.mifi.dev%2Fapi%2Fpackages%2Fmifi%2Fnpm%2F%2540mifi%252Fauth-common%2F-%2F1.0.15%2Fauth-common-1.0.15.tgz"
|
||||||
|
dependencies:
|
||||||
|
"@mifi/breakerbox-db": ^1.0.13
|
||||||
|
"@mifi/services-common": ^1.0.16
|
||||||
|
jsonwebtoken: ^9.0.0
|
||||||
|
checksum: 63931f45a18871362e16e0affc95d16ece4f0a4e6cf05d99146063115fc51d62cf75f262cfad661d76ec4a47f6e5ee32742fe840fb466cb4905829f67999d974
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@mifi/auth-db@workspace:.":
|
"@mifi/auth-db@workspace:.":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@mifi/auth-db@workspace:."
|
resolution: "@mifi/auth-db@workspace:."
|
||||||
@@ -2655,7 +2666,8 @@ __metadata:
|
|||||||
"@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/services-common": 1.x.x
|
"@mifi/auth-common": ^1.0.15
|
||||||
|
"@mifi/services-common": ^1.0.16
|
||||||
"@tsconfig/node16": ^1.0.4
|
"@tsconfig/node16": ^1.0.4
|
||||||
"@types/jsonwebtoken": ^9.0.2
|
"@types/jsonwebtoken": ^9.0.2
|
||||||
"@types/node": ^18.14.0
|
"@types/node": ^18.14.0
|
||||||
@@ -2682,10 +2694,20 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@mifi/services-common@npm:1.x.x":
|
"@mifi/breakerbox-db@npm:^1.0.13":
|
||||||
version: 1.0.6
|
version: 1.0.13
|
||||||
resolution: "@mifi/services-common@npm:1.0.6::__archiveUrl=https%3A%2F%2Fgit.mifi.dev%2Fapi%2Fpackages%2Fmifi%2Fnpm%2F%2540mifi%252Fservices-common%2F-%2F1.0.6%2Fservices-common-1.0.6.tgz"
|
resolution: "@mifi/breakerbox-db@npm:1.0.13::__archiveUrl=https%3A%2F%2Fgit.mifi.dev%2Fapi%2Fpackages%2Fmifi%2Fnpm%2F%2540mifi%252Fbreakerbox-db%2F-%2F1.0.13%2Fbreakerbox-db-1.0.13.tgz"
|
||||||
checksum: 22e9aa2714d088a286fc76ddf88c89698764f966ea5f3a208da45df893ec8a0c4e43848f4ba59746cd96b16880dbfa9f3a88610e43aa3825cbdb78afc11f59dc
|
dependencies:
|
||||||
|
level: ^8.0.0
|
||||||
|
yaml: ^2.3.1
|
||||||
|
checksum: 57d431249b2b20387faea8e99546ff67b60b543636d1bf80479e9443f1bda71364cb890ef1d2c8d6cf28623c2b208e68c44076a03c4080417c0b072188362b9c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@mifi/services-common@npm:^1.0.16":
|
||||||
|
version: 1.0.16
|
||||||
|
resolution: "@mifi/services-common@npm:1.0.16::__archiveUrl=https%3A%2F%2Fgit.mifi.dev%2Fapi%2Fpackages%2Fmifi%2Fnpm%2F%2540mifi%252Fservices-common%2F-%2F1.0.16%2Fservices-common-1.0.16.tgz"
|
||||||
|
checksum: 9ef5aae54cfdc21b2f1ee78366767890d0fbda0d2459783ffba0af239a7a7a27e52dc2cb2dc82318763a5ecc8ec1bac0570a79f0973b620bd8a5c911a65768bc
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -3162,6 +3184,21 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"abstract-level@npm:^1.0.2":
|
||||||
|
version: 1.0.3
|
||||||
|
resolution: "abstract-level@npm:1.0.3"
|
||||||
|
dependencies:
|
||||||
|
buffer: ^6.0.3
|
||||||
|
catering: ^2.1.0
|
||||||
|
is-buffer: ^2.0.5
|
||||||
|
level-supports: ^4.0.0
|
||||||
|
level-transcoder: ^1.0.1
|
||||||
|
module-error: ^1.0.1
|
||||||
|
queue-microtask: ^1.2.3
|
||||||
|
checksum: 70d61a3924526ebc257b138992052f9ff571a6cee5a7660836e37a1cc7081273c3acf465dd2f5e1897b38dc743a6fd9dba14a5d8a2a9d39e5787cd3da99f301d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"acorn-jsx@npm:^5.3.2":
|
"acorn-jsx@npm:^5.3.2":
|
||||||
version: 5.3.2
|
version: 5.3.2
|
||||||
resolution: "acorn-jsx@npm:5.3.2"
|
resolution: "acorn-jsx@npm:5.3.2"
|
||||||
@@ -3600,6 +3637,18 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"browser-level@npm:^1.0.1":
|
||||||
|
version: 1.0.1
|
||||||
|
resolution: "browser-level@npm:1.0.1"
|
||||||
|
dependencies:
|
||||||
|
abstract-level: ^1.0.2
|
||||||
|
catering: ^2.1.1
|
||||||
|
module-error: ^1.0.2
|
||||||
|
run-parallel-limit: ^1.1.0
|
||||||
|
checksum: 67fbc77ce832940bfa25073eccff279f512ad56f545deb996a5b23b02316f5e76f4a79d381acc27eda983f5c9a2566aaf9c97e4fdd0748288c4407307537a29b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"browserslist@npm:^4.21.3, browserslist@npm:^4.21.5":
|
"browserslist@npm:^4.21.3, browserslist@npm:^4.21.5":
|
||||||
version: 4.21.5
|
version: 4.21.5
|
||||||
resolution: "browserslist@npm:4.21.5"
|
resolution: "browserslist@npm:4.21.5"
|
||||||
@@ -3656,6 +3705,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"buffer@npm:^6.0.3":
|
||||||
|
version: 6.0.3
|
||||||
|
resolution: "buffer@npm:6.0.3"
|
||||||
|
dependencies:
|
||||||
|
base64-js: ^1.3.1
|
||||||
|
ieee754: ^1.2.1
|
||||||
|
checksum: 5ad23293d9a731e4318e420025800b42bf0d264004c0286c8cc010af7a270c7a0f6522e84f54b9ad65cbd6db20b8badbfd8d2ebf4f80fa03dab093b89e68c3f9
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"builtins@npm:^5.0.1":
|
"builtins@npm:^5.0.1":
|
||||||
version: 5.0.1
|
version: 5.0.1
|
||||||
resolution: "builtins@npm:5.0.1"
|
resolution: "builtins@npm:5.0.1"
|
||||||
@@ -3750,6 +3809,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"catering@npm:^2.1.0, catering@npm:^2.1.1":
|
||||||
|
version: 2.1.1
|
||||||
|
resolution: "catering@npm:2.1.1"
|
||||||
|
checksum: 205daefa69c935b0c19f3d8f2e0a520dd69aebe9bda55902958003f7c9cff8f967dfb90071b421bd6eb618576f657a89d2bc0986872c9bc04bbd66655e9d4bd6
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"chalk@npm:^1.1.3":
|
"chalk@npm:^1.1.3":
|
||||||
version: 1.1.3
|
version: 1.1.3
|
||||||
resolution: "chalk@npm:1.1.3"
|
resolution: "chalk@npm:1.1.3"
|
||||||
@@ -3812,6 +3878,20 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"classic-level@npm:^1.2.0":
|
||||||
|
version: 1.3.0
|
||||||
|
resolution: "classic-level@npm:1.3.0"
|
||||||
|
dependencies:
|
||||||
|
abstract-level: ^1.0.2
|
||||||
|
catering: ^2.1.0
|
||||||
|
module-error: ^1.0.1
|
||||||
|
napi-macros: ^2.2.2
|
||||||
|
node-gyp: latest
|
||||||
|
node-gyp-build: ^4.3.0
|
||||||
|
checksum: 773da48aef52a041115d413fee8340b357a4da2eb505764f327183b155edd7cc9d24819eb4f707c83dbdae8588024f5dddeb322125567c59d5d1f6f16334cdb9
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"clean-stack@npm:^2.0.0":
|
"clean-stack@npm:^2.0.0":
|
||||||
version: 2.2.0
|
version: 2.2.0
|
||||||
resolution: "clean-stack@npm:2.2.0"
|
resolution: "clean-stack@npm:2.2.0"
|
||||||
@@ -5221,7 +5301,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"ieee754@npm:^1.1.13":
|
"ieee754@npm:^1.1.13, ieee754@npm:^1.2.1":
|
||||||
version: 1.2.1
|
version: 1.2.1
|
||||||
resolution: "ieee754@npm:1.2.1"
|
resolution: "ieee754@npm:1.2.1"
|
||||||
checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e
|
checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e
|
||||||
@@ -5350,6 +5430,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"is-buffer@npm:^2.0.5":
|
||||||
|
version: 2.0.5
|
||||||
|
resolution: "is-buffer@npm:2.0.5"
|
||||||
|
checksum: 764c9ad8b523a9f5a32af29bdf772b08eb48c04d2ad0a7240916ac2688c983bf5f8504bf25b35e66240edeb9d9085461f9b5dae1f3d2861c6b06a65fe983de42
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7":
|
"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7":
|
||||||
version: 1.2.7
|
version: 1.2.7
|
||||||
resolution: "is-callable@npm:1.2.7"
|
resolution: "is-callable@npm:1.2.7"
|
||||||
@@ -6197,6 +6284,33 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"level-supports@npm:^4.0.0":
|
||||||
|
version: 4.0.1
|
||||||
|
resolution: "level-supports@npm:4.0.1"
|
||||||
|
checksum: d4552b42bb8cdeada07b0f6356c7a90fefe76279147331f291aceae26e3e56d5f927b09ce921647c0230bfe03ddfbdcef332be921e5c2194421ae2bfa3cf6368
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"level-transcoder@npm:^1.0.1":
|
||||||
|
version: 1.0.1
|
||||||
|
resolution: "level-transcoder@npm:1.0.1"
|
||||||
|
dependencies:
|
||||||
|
buffer: ^6.0.3
|
||||||
|
module-error: ^1.0.1
|
||||||
|
checksum: 304f08d802faf3491a533b6d87ad8be3cabfd27f2713bbe9d4c633bf50fcb9460eab5a6776bf015e101ead7ba1c1853e05e7f341112f17a9d0cb37ee5a421a25
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"level@npm:^8.0.0":
|
||||||
|
version: 8.0.0
|
||||||
|
resolution: "level@npm:8.0.0"
|
||||||
|
dependencies:
|
||||||
|
browser-level: ^1.0.1
|
||||||
|
classic-level: ^1.2.0
|
||||||
|
checksum: 13eb25bd71bfdca6cd714d1233adf9da97de9a8a4bf9f28d62a390b5c96d0250abaf983eb90eb8c4e89c7a985bb330750683d106f12670e5ea8fba1d7e608a1f
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"leven@npm:^3.1.0":
|
"leven@npm:^3.1.0":
|
||||||
version: 3.1.0
|
version: 3.1.0
|
||||||
resolution: "leven@npm:3.1.0"
|
resolution: "leven@npm:3.1.0"
|
||||||
@@ -6538,6 +6652,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"module-error@npm:^1.0.1, module-error@npm:^1.0.2":
|
||||||
|
version: 1.0.2
|
||||||
|
resolution: "module-error@npm:1.0.2"
|
||||||
|
checksum: 5d653e35bd55b3e95f8aee2cdac108082ea892e71b8f651be92cde43e4ee86abee4fa8bd7fc3fe5e68b63926d42f63c54cd17b87a560c31f18739295575a3962
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"mongodb-connection-string-url@npm:^2.5.4":
|
"mongodb-connection-string-url@npm:^2.5.4":
|
||||||
version: 2.6.0
|
version: 2.6.0
|
||||||
resolution: "mongodb-connection-string-url@npm:2.6.0"
|
resolution: "mongodb-connection-string-url@npm:2.6.0"
|
||||||
@@ -6618,6 +6739,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"napi-macros@npm:^2.2.2":
|
||||||
|
version: 2.2.2
|
||||||
|
resolution: "napi-macros@npm:2.2.2"
|
||||||
|
checksum: c6f9bd71cdbbc37ddc3535aa5be481238641d89585b8a3f4d301cb89abf459e2d294810432bb7d12056d1f9350b1a0899a5afcf460237a3da6c398cf0fec7629
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"natural-compare-lite@npm:^1.4.0":
|
"natural-compare-lite@npm:^1.4.0":
|
||||||
version: 1.4.0
|
version: 1.4.0
|
||||||
resolution: "natural-compare-lite@npm:1.4.0"
|
resolution: "natural-compare-lite@npm:1.4.0"
|
||||||
@@ -6639,6 +6767,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"node-gyp-build@npm:^4.3.0":
|
||||||
|
version: 4.6.0
|
||||||
|
resolution: "node-gyp-build@npm:4.6.0"
|
||||||
|
bin:
|
||||||
|
node-gyp-build: bin.js
|
||||||
|
node-gyp-build-optional: optional.js
|
||||||
|
node-gyp-build-test: build-test.js
|
||||||
|
checksum: 25d78c5ef1f8c24291f4a370c47ba52fcea14f39272041a90a7894cd50d766f7c8cb8fb06c0f42bf6f69b204b49d9be3c8fc344aac09714d5bdb95965499eb15
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"node-gyp@npm:latest":
|
"node-gyp@npm:latest":
|
||||||
version: 9.3.1
|
version: 9.3.1
|
||||||
resolution: "node-gyp@npm:9.3.1"
|
resolution: "node-gyp@npm:9.3.1"
|
||||||
@@ -7092,7 +7231,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"queue-microtask@npm:^1.2.2":
|
"queue-microtask@npm:^1.2.2, queue-microtask@npm:^1.2.3":
|
||||||
version: 1.2.3
|
version: 1.2.3
|
||||||
resolution: "queue-microtask@npm:1.2.3"
|
resolution: "queue-microtask@npm:1.2.3"
|
||||||
checksum: b676f8c040cdc5b12723ad2f91414d267605b26419d5c821ff03befa817ddd10e238d22b25d604920340fd73efd8ba795465a0377c4adf45a4a41e4234e42dc4
|
checksum: b676f8c040cdc5b12723ad2f91414d267605b26419d5c821ff03befa817ddd10e238d22b25d604920340fd73efd8ba795465a0377c4adf45a4a41e4234e42dc4
|
||||||
@@ -7317,6 +7456,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"run-parallel-limit@npm:^1.1.0":
|
||||||
|
version: 1.1.0
|
||||||
|
resolution: "run-parallel-limit@npm:1.1.0"
|
||||||
|
dependencies:
|
||||||
|
queue-microtask: ^1.2.2
|
||||||
|
checksum: 672c3b87e7f939c684b9965222b361421db0930223ed1e43ebf0e7e48ccc1a022ea4de080bef4d5468434e2577c33b7681e3f03b7593fdc49ad250a55381123c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"run-parallel@npm:^1.1.9":
|
"run-parallel@npm:^1.1.9":
|
||||||
version: 1.2.0
|
version: 1.2.0
|
||||||
resolution: "run-parallel@npm:1.2.0"
|
resolution: "run-parallel@npm:1.2.0"
|
||||||
@@ -8255,6 +8403,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"yaml@npm:^2.3.1":
|
||||||
|
version: 2.3.1
|
||||||
|
resolution: "yaml@npm:2.3.1"
|
||||||
|
checksum: 2c7bc9a7cd4c9f40d3b0b0a98e370781b68b8b7c4515720869aced2b00d92f5da1762b4ffa947f9e795d6cd6b19f410bd4d15fdd38aca7bd96df59bd9486fb54
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"yargs-parser@npm:^13.1.2":
|
"yargs-parser@npm:^13.1.2":
|
||||||
version: 13.1.2
|
version: 13.1.2
|
||||||
resolution: "yargs-parser@npm:13.1.2"
|
resolution: "yargs-parser@npm:13.1.2"
|
||||||
|
|||||||
Reference in New Issue
Block a user