Refactor authentication to use argon2 and update package dependencies
- Replaced bcrypt with argon2 for password hashing and verification in the authentication workflow, enhancing security. - Updated JWT signing implementation to use the jose library for improved token management. - Removed outdated bcrypt dependencies from package.json and pnpm-lock.yaml, and added argon2 and jose. - Adjusted pnpm-workspace.yaml to reflect changes in onlyBuiltDependencies, ensuring better package management.
This commit is contained in:
parent
1323600978
commit
eb31fae344
@ -42,13 +42,13 @@
|
|||||||
"@prisma/adapter-pg": "^7.1.0",
|
"@prisma/adapter-pg": "^7.1.0",
|
||||||
"@prisma/client": "^7.1.0",
|
"@prisma/client": "^7.1.0",
|
||||||
"@sendgrid/mail": "^8.1.6",
|
"@sendgrid/mail": "^8.1.6",
|
||||||
"bcrypt": "^6.0.0",
|
"argon2": "^0.43.0",
|
||||||
"bullmq": "^5.65.1",
|
"bullmq": "^5.65.1",
|
||||||
"cookie-parser": "^1.4.7",
|
"cookie-parser": "^1.4.7",
|
||||||
"helmet": "^8.1.0",
|
"helmet": "^8.1.0",
|
||||||
"ioredis": "^5.8.2",
|
"ioredis": "^5.8.2",
|
||||||
|
"jose": "^6.0.11",
|
||||||
"jsforce": "^3.10.10",
|
"jsforce": "^3.10.10",
|
||||||
"jsonwebtoken": "^9.0.3",
|
|
||||||
"nestjs-pino": "^4.5.0",
|
"nestjs-pino": "^4.5.0",
|
||||||
"nestjs-zod": "^5.0.1",
|
"nestjs-zod": "^5.0.1",
|
||||||
"p-queue": "^9.0.1",
|
"p-queue": "^9.0.1",
|
||||||
@ -68,11 +68,9 @@
|
|||||||
"@nestjs/cli": "^11.0.14",
|
"@nestjs/cli": "^11.0.14",
|
||||||
"@nestjs/schematics": "^11.0.9",
|
"@nestjs/schematics": "^11.0.9",
|
||||||
"@nestjs/testing": "^11.1.9",
|
"@nestjs/testing": "^11.1.9",
|
||||||
"@types/bcrypt": "^6.0.0",
|
|
||||||
"@types/cookie-parser": "^1.4.10",
|
"@types/cookie-parser": "^1.4.10",
|
||||||
"@types/express": "^5.0.6",
|
"@types/express": "^5.0.6",
|
||||||
"@types/jest": "^30.0.0",
|
"@types/jest": "^30.0.0",
|
||||||
"@types/jsonwebtoken": "^9.0.10",
|
|
||||||
"@types/node": "^24.10.2",
|
"@types/node": "^24.10.2",
|
||||||
"@types/passport-jwt": "^4.0.1",
|
"@types/passport-jwt": "^4.0.1",
|
||||||
"@types/passport-local": "^1.0.38",
|
"@types/passport-local": "^1.0.38",
|
||||||
@ -85,7 +83,6 @@
|
|||||||
"supertest": "^7.1.4",
|
"supertest": "^7.1.4",
|
||||||
"ts-jest": "^29.4.6",
|
"ts-jest": "^29.4.6",
|
||||||
"tsc-alias": "^1.8.16",
|
"tsc-alias": "^1.8.16",
|
||||||
"tsx": "^4.21.0",
|
|
||||||
"typescript": "^5.9.3"
|
"typescript": "^5.9.3"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
-- Force password reset for all users due to migration from bcrypt to argon2
|
||||||
|
-- bcrypt hashes are incompatible with argon2, so all users must reset their passwords
|
||||||
|
|
||||||
|
-- Set all password hashes to NULL, which will require users to go through password reset flow
|
||||||
|
UPDATE "User" SET password_hash = NULL WHERE password_hash IS NOT NULL;
|
||||||
|
|
||||||
|
-- Log the migration for audit purposes (optional - create entry in audit_log if table exists)
|
||||||
|
-- This is a data migration, not a schema change
|
||||||
|
|
||||||
@ -4,7 +4,7 @@ import { ConfigService } from "@nestjs/config";
|
|||||||
import { getErrorMessage } from "@bff/core/utils/error.util.js";
|
import { getErrorMessage } from "@bff/core/utils/error.util.js";
|
||||||
import { SalesforceRequestQueueService } from "@bff/core/queue/services/salesforce-request-queue.service.js";
|
import { SalesforceRequestQueueService } from "@bff/core/queue/services/salesforce-request-queue.service.js";
|
||||||
import jsforce from "jsforce";
|
import jsforce from "jsforce";
|
||||||
import jwt from "jsonwebtoken";
|
import { SignJWT, importPKCS8 } from "jose";
|
||||||
import fs from "node:fs/promises";
|
import fs from "node:fs/promises";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
@ -138,15 +138,14 @@ export class SalesforceConnection {
|
|||||||
throw new Error(isProd ? "Invalid Salesforce private key" : devMsg);
|
throw new Error(isProd ? "Invalid Salesforce private key" : devMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create JWT assertion
|
// Create JWT assertion using jose
|
||||||
const payload = {
|
const key = await importPKCS8(privateKey, "RS256");
|
||||||
iss: clientId,
|
const assertion = await new SignJWT({ sub: username })
|
||||||
sub: username,
|
.setProtectedHeader({ alg: "RS256" })
|
||||||
aud: audience,
|
.setIssuer(clientId)
|
||||||
exp: Math.floor(Date.now() / 1000) + 300, // 5 minutes
|
.setAudience(audience)
|
||||||
};
|
.setExpirationTime("5m")
|
||||||
|
.sign(key);
|
||||||
const assertion = jwt.sign(payload, privateKey, { algorithm: "RS256" });
|
|
||||||
|
|
||||||
// Get access token with timeout
|
// Get access token with timeout
|
||||||
const tokenUrl = `${audience}/services/oauth2/token`;
|
const tokenUrl = `${audience}/services/oauth2/token`;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { Injectable, UnauthorizedException, BadRequestException, Inject } from "@nestjs/common";
|
import { Injectable, UnauthorizedException, BadRequestException, Inject } from "@nestjs/common";
|
||||||
import { JwtService } from "@nestjs/jwt";
|
import { JwtService } from "@nestjs/jwt";
|
||||||
import { ConfigService } from "@nestjs/config";
|
import { ConfigService } from "@nestjs/config";
|
||||||
import * as bcrypt from "bcrypt";
|
import * as argon2 from "argon2";
|
||||||
import { UsersFacade } from "@bff/modules/users/application/users.facade.js";
|
import { UsersFacade } from "@bff/modules/users/application/users.facade.js";
|
||||||
import { MappingsService } from "@bff/modules/id-mappings/mappings.service.js";
|
import { MappingsService } from "@bff/modules/id-mappings/mappings.service.js";
|
||||||
import { WhmcsService } from "@bff/integrations/whmcs/whmcs.service.js";
|
import { WhmcsService } from "@bff/integrations/whmcs/whmcs.service.js";
|
||||||
@ -222,7 +222,7 @@ export class AuthFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isPasswordValid = await bcrypt.compare(password, user.passwordHash);
|
const isPasswordValid = await argon2.verify(user.passwordHash, password);
|
||||||
|
|
||||||
if (isPasswordValid) {
|
if (isPasswordValid) {
|
||||||
// Return sanitized user object matching the return type
|
// Return sanitized user object matching the return type
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import {
|
|||||||
import { ConfigService } from "@nestjs/config";
|
import { ConfigService } from "@nestjs/config";
|
||||||
import { JwtService } from "@nestjs/jwt";
|
import { JwtService } from "@nestjs/jwt";
|
||||||
import { Logger } from "nestjs-pino";
|
import { Logger } from "nestjs-pino";
|
||||||
import * as bcrypt from "bcrypt";
|
import * as argon2 from "argon2";
|
||||||
import type { Request } from "express";
|
import type { Request } from "express";
|
||||||
import { UsersFacade } from "@bff/modules/users/application/users.facade.js";
|
import { UsersFacade } from "@bff/modules/users/application/users.facade.js";
|
||||||
import { AuditService, AuditAction } from "@bff/infra/audit/audit.service.js";
|
import { AuditService, AuditAction } from "@bff/infra/audit/audit.service.js";
|
||||||
@ -59,10 +59,7 @@ export class PasswordWorkflowService {
|
|||||||
throw new BadRequestException("User already has a password set");
|
throw new BadRequestException("User already has a password set");
|
||||||
}
|
}
|
||||||
|
|
||||||
const saltRoundsConfig = this.configService.get<string | number>("BCRYPT_ROUNDS", 12);
|
const passwordHash = await argon2.hash(password);
|
||||||
const saltRounds =
|
|
||||||
typeof saltRoundsConfig === "string" ? Number(saltRoundsConfig) : saltRoundsConfig;
|
|
||||||
const passwordHash = await bcrypt.hash(password, saltRounds);
|
|
||||||
try {
|
try {
|
||||||
await this.usersFacade.update(user.id, { passwordHash });
|
await this.usersFacade.update(user.id, { passwordHash });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -141,10 +138,7 @@ export class PasswordWorkflowService {
|
|||||||
const prismaUser = await this.usersFacade.findByIdInternal(payload.sub);
|
const prismaUser = await this.usersFacade.findByIdInternal(payload.sub);
|
||||||
if (!prismaUser) throw new BadRequestException("Invalid token");
|
if (!prismaUser) throw new BadRequestException("Invalid token");
|
||||||
|
|
||||||
const saltRoundsConfig = this.configService.get<string | number>("BCRYPT_ROUNDS", 12);
|
const passwordHash = await argon2.hash(newPassword);
|
||||||
const saltRounds =
|
|
||||||
typeof saltRoundsConfig === "string" ? Number(saltRoundsConfig) : saltRoundsConfig;
|
|
||||||
const passwordHash = await bcrypt.hash(newPassword, saltRounds);
|
|
||||||
|
|
||||||
await this.usersFacade.update(prismaUser.id, { passwordHash });
|
await this.usersFacade.update(prismaUser.id, { passwordHash });
|
||||||
const freshUser = await this.usersFacade.findByIdInternal(prismaUser.id);
|
const freshUser = await this.usersFacade.findByIdInternal(prismaUser.id);
|
||||||
@ -186,7 +180,7 @@ export class PasswordWorkflowService {
|
|||||||
const parsed = changePasswordRequestSchema.parse(data);
|
const parsed = changePasswordRequestSchema.parse(data);
|
||||||
const { currentPassword, newPassword } = parsed;
|
const { currentPassword, newPassword } = parsed;
|
||||||
|
|
||||||
const isCurrentValid = await bcrypt.compare(currentPassword, user.passwordHash);
|
const isCurrentValid = await argon2.verify(user.passwordHash, currentPassword);
|
||||||
if (!isCurrentValid) {
|
if (!isCurrentValid) {
|
||||||
await this.auditService.logAuthEvent(
|
await this.auditService.logAuthEvent(
|
||||||
AuditAction.PASSWORD_CHANGE,
|
AuditAction.PASSWORD_CHANGE,
|
||||||
@ -202,10 +196,7 @@ export class PasswordWorkflowService {
|
|||||||
// Password validation is handled by changePasswordRequestSchema (uses passwordSchema from domain)
|
// Password validation is handled by changePasswordRequestSchema (uses passwordSchema from domain)
|
||||||
// No need for duplicate validation here
|
// No need for duplicate validation here
|
||||||
|
|
||||||
const saltRoundsConfig = this.configService.get<string | number>("BCRYPT_ROUNDS", 14);
|
const passwordHash = await argon2.hash(newPassword);
|
||||||
const saltRounds =
|
|
||||||
typeof saltRoundsConfig === "string" ? Number(saltRoundsConfig) : saltRoundsConfig;
|
|
||||||
const passwordHash = await bcrypt.hash(newPassword, saltRounds);
|
|
||||||
|
|
||||||
await this.usersFacade.update(user.id, { passwordHash });
|
await this.usersFacade.update(user.id, { passwordHash });
|
||||||
const prismaUser = await this.usersFacade.findByIdInternal(user.id);
|
const prismaUser = await this.usersFacade.findByIdInternal(user.id);
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
} from "@nestjs/common";
|
} from "@nestjs/common";
|
||||||
import { ConfigService } from "@nestjs/config";
|
import { ConfigService } from "@nestjs/config";
|
||||||
import { Logger } from "nestjs-pino";
|
import { Logger } from "nestjs-pino";
|
||||||
import * as bcrypt from "bcrypt";
|
import * as argon2 from "argon2";
|
||||||
import type { Request } from "express";
|
import type { Request } from "express";
|
||||||
import { AuditService, AuditAction } from "@bff/infra/audit/audit.service.js";
|
import { AuditService, AuditAction } from "@bff/infra/audit/audit.service.js";
|
||||||
import { UsersFacade } from "@bff/modules/users/application/users.facade.js";
|
import { UsersFacade } from "@bff/modules/users/application/users.facade.js";
|
||||||
@ -185,10 +185,7 @@ export class SignupWorkflowService {
|
|||||||
throw new ConflictException(message);
|
throw new ConflictException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
const saltRoundsConfig = this.configService.get<string | number>("BCRYPT_ROUNDS", 14);
|
const passwordHash = await argon2.hash(password);
|
||||||
const saltRounds =
|
|
||||||
typeof saltRoundsConfig === "string" ? Number(saltRoundsConfig) : saltRoundsConfig;
|
|
||||||
const passwordHash = await bcrypt.hash(password, saltRounds);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const accountSnapshot = await this.getAccountSnapshot(sfNumber);
|
const accountSnapshot = await this.getAccountSnapshot(sfNumber);
|
||||||
|
|||||||
@ -66,6 +66,9 @@
|
|||||||
"overrides": {
|
"overrides": {
|
||||||
"js-yaml": ">=4.1.1",
|
"js-yaml": ">=4.1.1",
|
||||||
"glob": "^8.1.0"
|
"glob": "^8.1.0"
|
||||||
}
|
},
|
||||||
|
"onlyBuiltDependencies": [
|
||||||
|
"argon2"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
58
pnpm-lock.yaml
generated
58
pnpm-lock.yaml
generated
@ -85,9 +85,9 @@ importers:
|
|||||||
'@sendgrid/mail':
|
'@sendgrid/mail':
|
||||||
specifier: ^8.1.6
|
specifier: ^8.1.6
|
||||||
version: 8.1.6
|
version: 8.1.6
|
||||||
bcrypt:
|
argon2:
|
||||||
specifier: ^6.0.0
|
specifier: ^0.43.0
|
||||||
version: 6.0.0
|
version: 0.43.1
|
||||||
bullmq:
|
bullmq:
|
||||||
specifier: ^5.65.1
|
specifier: ^5.65.1
|
||||||
version: 5.65.1
|
version: 5.65.1
|
||||||
@ -100,12 +100,12 @@ importers:
|
|||||||
ioredis:
|
ioredis:
|
||||||
specifier: ^5.8.2
|
specifier: ^5.8.2
|
||||||
version: 5.8.2
|
version: 5.8.2
|
||||||
|
jose:
|
||||||
|
specifier: ^6.0.11
|
||||||
|
version: 6.1.3
|
||||||
jsforce:
|
jsforce:
|
||||||
specifier: ^3.10.10
|
specifier: ^3.10.10
|
||||||
version: 3.10.10(@types/node@24.10.2)
|
version: 3.10.10(@types/node@24.10.2)
|
||||||
jsonwebtoken:
|
|
||||||
specifier: ^9.0.3
|
|
||||||
version: 9.0.3
|
|
||||||
nestjs-pino:
|
nestjs-pino:
|
||||||
specifier: ^4.5.0
|
specifier: ^4.5.0
|
||||||
version: 4.5.0(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.1.0)(rxjs@7.8.2)
|
version: 4.5.0(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.1.0)(rxjs@7.8.2)
|
||||||
@ -158,9 +158,6 @@ importers:
|
|||||||
'@nestjs/testing':
|
'@nestjs/testing':
|
||||||
specifier: ^11.1.9
|
specifier: ^11.1.9
|
||||||
version: 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@nestjs/platform-express@11.1.9)
|
version: 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@nestjs/platform-express@11.1.9)
|
||||||
'@types/bcrypt':
|
|
||||||
specifier: ^6.0.0
|
|
||||||
version: 6.0.0
|
|
||||||
'@types/cookie-parser':
|
'@types/cookie-parser':
|
||||||
specifier: ^1.4.10
|
specifier: ^1.4.10
|
||||||
version: 1.4.10(@types/express@5.0.6)
|
version: 1.4.10(@types/express@5.0.6)
|
||||||
@ -170,9 +167,6 @@ importers:
|
|||||||
'@types/jest':
|
'@types/jest':
|
||||||
specifier: ^30.0.0
|
specifier: ^30.0.0
|
||||||
version: 30.0.0
|
version: 30.0.0
|
||||||
'@types/jsonwebtoken':
|
|
||||||
specifier: ^9.0.10
|
|
||||||
version: 9.0.10
|
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^24.10.2
|
specifier: ^24.10.2
|
||||||
version: 24.10.2
|
version: 24.10.2
|
||||||
@ -209,9 +203,6 @@ importers:
|
|||||||
tsc-alias:
|
tsc-alias:
|
||||||
specifier: ^1.8.16
|
specifier: ^1.8.16
|
||||||
version: 1.8.16
|
version: 1.8.16
|
||||||
tsx:
|
|
||||||
specifier: ^4.21.0
|
|
||||||
version: 4.21.0
|
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.9.3
|
specifier: ^5.9.3
|
||||||
version: 5.9.3
|
version: 5.9.3
|
||||||
@ -1550,6 +1541,10 @@ packages:
|
|||||||
'@paralleldrive/cuid2@2.3.1':
|
'@paralleldrive/cuid2@2.3.1':
|
||||||
resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==}
|
resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==}
|
||||||
|
|
||||||
|
'@phc/format@1.0.0':
|
||||||
|
resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
'@pinojs/redact@0.4.0':
|
'@pinojs/redact@0.4.0':
|
||||||
resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==}
|
resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==}
|
||||||
|
|
||||||
@ -1922,9 +1917,6 @@ packages:
|
|||||||
'@types/babel__traverse@7.28.0':
|
'@types/babel__traverse@7.28.0':
|
||||||
resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
|
resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
|
||||||
|
|
||||||
'@types/bcrypt@6.0.0':
|
|
||||||
resolution: {integrity: sha512-/oJGukuH3D2+D+3H4JWLaAsJ/ji86dhRidzZ/Od7H/i8g+aCmvkeCc6Ni/f9uxGLSQVCRZkX2/lqEFG2BvWtlQ==}
|
|
||||||
|
|
||||||
'@types/body-parser@1.19.6':
|
'@types/body-parser@1.19.6':
|
||||||
resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==}
|
resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==}
|
||||||
|
|
||||||
@ -2400,6 +2392,10 @@ packages:
|
|||||||
arg@4.1.3:
|
arg@4.1.3:
|
||||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
||||||
|
|
||||||
|
argon2@0.43.1:
|
||||||
|
resolution: {integrity: sha512-TfOzvDWUaQPurCT1hOwIeFNkgrAJDpbBGBGWDgzDsm11nNhImc13WhdGdCU6K7brkp8VpeY07oGtSex0Wmhg8w==}
|
||||||
|
engines: {node: '>=16.17.0'}
|
||||||
|
|
||||||
argparse@2.0.1:
|
argparse@2.0.1:
|
||||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||||
|
|
||||||
@ -2546,10 +2542,6 @@ packages:
|
|||||||
bcrypt-pbkdf@1.0.2:
|
bcrypt-pbkdf@1.0.2:
|
||||||
resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
|
resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
|
||||||
|
|
||||||
bcrypt@6.0.0:
|
|
||||||
resolution: {integrity: sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==}
|
|
||||||
engines: {node: '>= 18'}
|
|
||||||
|
|
||||||
bin-version-check@5.1.0:
|
bin-version-check@5.1.0:
|
||||||
resolution: {integrity: sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==}
|
resolution: {integrity: sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@ -4055,6 +4047,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
jose@6.1.3:
|
||||||
|
resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==}
|
||||||
|
|
||||||
joycon@3.1.1:
|
joycon@3.1.1:
|
||||||
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
|
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -7123,6 +7118,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@noble/hashes': 1.8.0
|
'@noble/hashes': 1.8.0
|
||||||
|
|
||||||
|
'@phc/format@1.0.0': {}
|
||||||
|
|
||||||
'@pinojs/redact@0.4.0': {}
|
'@pinojs/redact@0.4.0': {}
|
||||||
|
|
||||||
'@pkgr/core@0.2.9': {}
|
'@pkgr/core@0.2.9': {}
|
||||||
@ -7504,10 +7501,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@babel/types': 7.28.5
|
'@babel/types': 7.28.5
|
||||||
|
|
||||||
'@types/bcrypt@6.0.0':
|
|
||||||
dependencies:
|
|
||||||
'@types/node': 24.10.2
|
|
||||||
|
|
||||||
'@types/body-parser@1.19.6':
|
'@types/body-parser@1.19.6':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/connect': 3.4.38
|
'@types/connect': 3.4.38
|
||||||
@ -8093,6 +8086,12 @@ snapshots:
|
|||||||
arg@4.1.3:
|
arg@4.1.3:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
argon2@0.43.1:
|
||||||
|
dependencies:
|
||||||
|
'@phc/format': 1.0.0
|
||||||
|
node-addon-api: 8.5.0
|
||||||
|
node-gyp-build: 4.8.4
|
||||||
|
|
||||||
argparse@2.0.1: {}
|
argparse@2.0.1: {}
|
||||||
|
|
||||||
aria-query@5.3.2: {}
|
aria-query@5.3.2: {}
|
||||||
@ -8274,11 +8273,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tweetnacl: 0.14.5
|
tweetnacl: 0.14.5
|
||||||
|
|
||||||
bcrypt@6.0.0:
|
|
||||||
dependencies:
|
|
||||||
node-addon-api: 8.5.0
|
|
||||||
node-gyp-build: 4.8.4
|
|
||||||
|
|
||||||
bin-version-check@5.1.0:
|
bin-version-check@5.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
bin-version: 6.0.0
|
bin-version: 6.0.0
|
||||||
@ -10218,6 +10212,8 @@ snapshots:
|
|||||||
|
|
||||||
jiti@2.6.1: {}
|
jiti@2.6.1: {}
|
||||||
|
|
||||||
|
jose@6.1.3: {}
|
||||||
|
|
||||||
joycon@3.1.1: {}
|
joycon@3.1.1: {}
|
||||||
|
|
||||||
js-tokens@4.0.0: {}
|
js-tokens@4.0.0: {}
|
||||||
|
|||||||
@ -2,13 +2,4 @@ packages:
|
|||||||
- apps/*
|
- apps/*
|
||||||
- packages/*
|
- packages/*
|
||||||
|
|
||||||
onlyBuiltDependencies:
|
onlyBuiltDependencies: '[]'
|
||||||
- "@swc/core"
|
|
||||||
- "esbuild"
|
|
||||||
- "bcrypt"
|
|
||||||
- "ssh2"
|
|
||||||
- "cpu-features"
|
|
||||||
- "prisma"
|
|
||||||
- "@prisma/engines"
|
|
||||||
- "@prisma/client"
|
|
||||||
- "unrs-resolver"
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user