mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 13:20:31 +00:00
refactor: auth module to nestjs
This commit is contained in:
@@ -24,7 +24,6 @@
|
||||
"@aws-sdk/s3-request-presigner": "^3.583.0",
|
||||
"@bigcapital/email-components": "*",
|
||||
"@bigcapital/pdf-templates": "*",
|
||||
"@bigcapital/server": "*",
|
||||
"@bigcapital/utils": "*",
|
||||
"@casl/ability": "^5.4.3",
|
||||
"@lemonsqueezy/lemonsqueezy.js": "^2.2.0",
|
||||
@@ -49,6 +48,7 @@
|
||||
"async": "^3.2.0",
|
||||
"async-mutex": "^0.5.0",
|
||||
"axios": "^1.6.0",
|
||||
"bcrypt": "^5.1.1",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"bluebird": "^3.7.2",
|
||||
"bull": "^4.16.3",
|
||||
|
||||
@@ -1,25 +1,74 @@
|
||||
import { Body, Controller, Post, Request } from '@nestjs/common';
|
||||
import { Body, Controller, Param, Post, Request } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiBody, ApiParam } from '@nestjs/swagger';
|
||||
import { PublicRoute } from './Jwt.guard';
|
||||
import { AuthenticationApplication } from './AuthApplication.sevice';
|
||||
import { AuthSignupDto } from './dtos/AuthSignup.dto';
|
||||
import { AuthSigninDto } from './dtos/AuthSignin.dto';
|
||||
|
||||
@ApiTags('Auth')
|
||||
@Controller('/auth')
|
||||
@PublicRoute()
|
||||
export class AuthController {
|
||||
constructor(private readonly authApp: AuthenticationApplication) {}
|
||||
|
||||
@Post('/signin')
|
||||
@ApiOperation({ summary: 'Sign in a user' })
|
||||
@ApiBody({ type: AuthSigninDto })
|
||||
signin(@Request() req: Request, @Body() signinDto: AuthSigninDto) {
|
||||
return this.authApp.signIn(signinDto);
|
||||
}
|
||||
|
||||
@Post('/signup')
|
||||
@ApiOperation({ summary: 'Sign up a new user' })
|
||||
@ApiBody({ type: AuthSignupDto })
|
||||
signup(@Request() req: Request, @Body() signupDto: AuthSignupDto) {
|
||||
this.authApp.signUp(signupDto);
|
||||
return this.authApp.signUp(signupDto);
|
||||
}
|
||||
|
||||
@Post('/signup/confirm')
|
||||
@ApiOperation({ summary: 'Confirm user signup' })
|
||||
@ApiBody({
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
email: { type: 'string', example: 'user@example.com' },
|
||||
token: { type: 'string', example: 'confirmation-token' },
|
||||
},
|
||||
},
|
||||
})
|
||||
signupConfirm(@Body('email') email: string, @Body('token') token: string) {
|
||||
return this.authApp.signUpConfirm(email, token);
|
||||
}
|
||||
|
||||
@Post('/send_reset_password')
|
||||
@ApiOperation({ summary: 'Send reset password email' })
|
||||
@ApiBody({
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
email: { type: 'string', example: 'user@example.com' },
|
||||
},
|
||||
},
|
||||
})
|
||||
sendResetPassword(@Body('email') email: string) {
|
||||
return this.authApp.sendResetPassword(email);
|
||||
}
|
||||
|
||||
@Post('/reset_password/:token')
|
||||
@ApiOperation({ summary: 'Reset password using token' })
|
||||
@ApiParam({ name: 'token', description: 'Reset password token' })
|
||||
@ApiBody({
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
password: { type: 'string', example: 'new-password' },
|
||||
},
|
||||
},
|
||||
})
|
||||
resetPassword(
|
||||
@Param('token') token: string,
|
||||
@Body('password') password: string,
|
||||
) {
|
||||
return this.authApp.resetPassword(token, password);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,12 @@ import { AuthSignupConfirmResendService } from './commands/AuthSignupConfirmRese
|
||||
import { AuthSignupConfirmService } from './commands/AuthSignupConfirm.service';
|
||||
import { AuthSignupService } from './commands/AuthSignup.service';
|
||||
import { AuthSigninService } from './commands/AuthSignin.service';
|
||||
import { RegisterTenancyModel } from '../Tenancy/TenancyModels/Tenancy.module';
|
||||
import { PasswordReset } from './models/PasswordReset';
|
||||
import { TenantDBManagerModule } from '../TenantDBManager/TenantDBManager.module';
|
||||
import { AuthenticationMailMesssages } from './AuthMailMessages.esrvice';
|
||||
|
||||
const models = [RegisterTenancyModel(PasswordReset)];
|
||||
|
||||
@Module({
|
||||
controllers: [AuthController],
|
||||
@@ -18,7 +24,10 @@ import { AuthSigninService } from './commands/AuthSignin.service';
|
||||
secret: 'asdfasdfasdf',
|
||||
signOptions: { expiresIn: '60s' },
|
||||
}),
|
||||
TenantDBManagerModule,
|
||||
...models,
|
||||
],
|
||||
exports: [...models],
|
||||
providers: [
|
||||
AuthService,
|
||||
JwtStrategy,
|
||||
@@ -29,6 +38,7 @@ import { AuthSigninService } from './commands/AuthSignin.service';
|
||||
AuthSignupConfirmService,
|
||||
AuthSignupService,
|
||||
AuthSigninService,
|
||||
AuthenticationMailMesssages,
|
||||
],
|
||||
})
|
||||
export class AuthModule {}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { SystemUser } from '../System/models/SystemUser';
|
||||
import { ModelObject } from 'objection';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { Mail } from '../Mail/Mail';
|
||||
|
||||
@Injectable()
|
||||
export class AuthenticationMailMesssages {
|
||||
constructor(private readonly configService: ConfigService) {}
|
||||
/**
|
||||
* Sends reset password message.
|
||||
* @param {ISystemUser} user - The system user.
|
||||
* @param {string} token - Reset password token.
|
||||
* @returns {Mail}
|
||||
*/
|
||||
sendResetPasswordMessage(user: ModelObject<SystemUser>, token: string) {
|
||||
const baseURL = this.configService.get('baseURL');
|
||||
|
||||
return new Mail()
|
||||
.setSubject('Bigcapital - Password Reset')
|
||||
.setView('mail/ResetPassword.html')
|
||||
.setTo(user.email)
|
||||
.setAttachments([
|
||||
{
|
||||
filename: 'bigcapital.png',
|
||||
path: `${global.__views_dir}/images/bigcapital.png`,
|
||||
cid: 'bigcapital_logo',
|
||||
},
|
||||
])
|
||||
.setData({
|
||||
resetPasswordUrl: `${baseURL}/auth/reset_password/${token}`,
|
||||
first_name: user.firstName,
|
||||
last_name: user.lastName,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends signup verification mail.
|
||||
* @param {string} email - Email address
|
||||
* @param {string} fullName - User name.
|
||||
* @param {string} token - Verification token.
|
||||
* @returns {Mail}
|
||||
*/
|
||||
sendSignupVerificationMail(email: string, fullName: string, token: string) {
|
||||
const baseURL = this.configService.get('baseURL');
|
||||
const verifyUrl = `${baseURL}/auth/email_confirmation?token=${token}&email=${email}`;
|
||||
|
||||
return new Mail()
|
||||
.setSubject('Bigcapital - Verify your email')
|
||||
.setView('mail/SignupVerifyEmail.html')
|
||||
.setTo(email)
|
||||
.setAttachments([
|
||||
{
|
||||
filename: 'bigcapital.png',
|
||||
path: `${global.__views_dir}/images/bigcapital.png`,
|
||||
cid: 'bigcapital_logo',
|
||||
},
|
||||
])
|
||||
.setData({ verifyUrl, fullName });
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,88 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { SystemUser } from '@/modules/System/models/SystemUser';
|
||||
import { PasswordReset } from '../models/PasswordReset';
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
import { ERRORS } from '../Auth.constants';
|
||||
import { hashPassword } from '../Auth.utils';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { events } from '@/common/events/events';
|
||||
import { IAuthResetedPasswordEventPayload } from '../Auth.interfaces';
|
||||
|
||||
@Injectable()
|
||||
export class AuthResetPasswordService {
|
||||
resetPassword(token: string, password: string): Promise<{ message: string }> {
|
||||
return new Promise((resolve) => {
|
||||
resolve({ message: 'Reset password link sent to your email' });
|
||||
});
|
||||
/**
|
||||
* @param {ConfigService} configService - Config service.
|
||||
* @param {EventEmitter2} eventEmitter - Event emitter.
|
||||
* @param {typeof SystemUser} systemUserModel
|
||||
* @param {typeof PasswordReset} passwordResetModel - Reset password model.
|
||||
*/
|
||||
constructor(
|
||||
private readonly configService: ConfigService,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
|
||||
@Inject(SystemUser.name)
|
||||
private readonly systemUserModel: typeof SystemUser,
|
||||
|
||||
@Inject(PasswordReset.name)
|
||||
private readonly passwordResetModel: typeof PasswordReset,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Resets a user password from given token.
|
||||
* @param {string} token - Password reset token.
|
||||
* @param {string} password - New Password.
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
public async resetPassword(token: string, password: string): Promise<void> {
|
||||
// Finds the password reset token.
|
||||
const tokenModel = await this.passwordResetModel
|
||||
.query()
|
||||
.findOne('token', token);
|
||||
|
||||
// In case the password reset token not found throw token invalid error..
|
||||
if (!tokenModel) {
|
||||
throw new ServiceError(ERRORS.TOKEN_INVALID);
|
||||
}
|
||||
const resetPasswordSeconds = this.configService.get('resetPasswordSeconds');
|
||||
|
||||
// Different between tokne creation datetime and current time.
|
||||
if (moment().diff(tokenModel.createdAt, 'seconds') > resetPasswordSeconds) {
|
||||
// Deletes the expired token by expired token email.
|
||||
await this.deletePasswordResetToken(tokenModel.email);
|
||||
throw new ServiceError(ERRORS.TOKEN_EXPIRED);
|
||||
}
|
||||
const user = await this.systemUserModel
|
||||
.query()
|
||||
.findOne({ email: tokenModel.email });
|
||||
|
||||
if (!user) {
|
||||
throw new ServiceError(ERRORS.USER_NOT_FOUND);
|
||||
}
|
||||
const hashedPassword = await hashPassword(password);
|
||||
|
||||
await this.systemUserModel
|
||||
.query()
|
||||
.findById(user.id)
|
||||
.update({ password: hashedPassword });
|
||||
|
||||
// Deletes the used token.
|
||||
await this.deletePasswordResetToken(tokenModel.email);
|
||||
|
||||
// Triggers `onResetPassword` event.
|
||||
await this.eventEmitter.emitAsync(events.auth.resetPassword, {
|
||||
user,
|
||||
token,
|
||||
password,
|
||||
} as IAuthResetedPasswordEventPayload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the password reset token by the given email.
|
||||
* @param {string} email
|
||||
* @returns {Promise}
|
||||
*/
|
||||
private async deletePasswordResetToken(email: string) {
|
||||
return PasswordReset.query().where('email', email).delete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,70 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import * as uniqid from 'uniqid';
|
||||
import {
|
||||
IAuthSendedResetPassword,
|
||||
IAuthSendingResetPassword,
|
||||
} from '../Auth.interfaces';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { PasswordReset } from '../models/PasswordReset';
|
||||
import { SystemUser } from '@/modules/System/models/SystemUser';
|
||||
import { events } from '@/common/events/events';
|
||||
|
||||
@Injectable()
|
||||
export class AuthSendResetPasswordService {
|
||||
sendResetPassword(email: string): Promise<{ message: string }> {
|
||||
return new Promise((resolve) => {
|
||||
resolve({ message: 'Reset password link sent to your email' });
|
||||
/**
|
||||
* @param {EventEmitter2} eventPublisher - Event emitter.
|
||||
* @param {typeof PasswordReset} resetPasswordModel - Password reset model.
|
||||
* @param {typeof SystemUser} systemUserModel - System user model.
|
||||
*/
|
||||
constructor(
|
||||
private readonly eventPublisher: EventEmitter2,
|
||||
|
||||
@Inject(PasswordReset.name)
|
||||
private readonly resetPasswordModel: typeof PasswordReset,
|
||||
|
||||
@Inject(SystemUser.name)
|
||||
private readonly systemUserModel: typeof SystemUser,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Sends the given email reset password email.
|
||||
* @param {string} email - Email address.
|
||||
*/
|
||||
async sendResetPassword(email: string): Promise<void> {
|
||||
const user = await this.systemUserModel
|
||||
.query()
|
||||
.findOne({ email })
|
||||
.throwIfNotFound();
|
||||
|
||||
const token: string = uniqid();
|
||||
|
||||
// Triggers sending reset password event.
|
||||
await this.eventPublisher.emitAsync(events.auth.sendingResetPassword, {
|
||||
user,
|
||||
token,
|
||||
} as IAuthSendingResetPassword);
|
||||
|
||||
// Delete all stored tokens of reset password that associate to the give email.
|
||||
this.deletePasswordResetToken(email);
|
||||
|
||||
// Creates a new password reset row with unique token.
|
||||
const passwordReset = await this.resetPasswordModel.query().insert({
|
||||
email,
|
||||
token,
|
||||
});
|
||||
// Triggers sent reset password event.
|
||||
await this.eventPublisher.emitAsync(events.auth.sendResetPassword, {
|
||||
user,
|
||||
token,
|
||||
} as IAuthSendedResetPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the password reset token by the given email.
|
||||
* @param {string} email
|
||||
* @returns {Promise}
|
||||
*/
|
||||
private async deletePasswordResetToken(email: string) {
|
||||
return this.resetPasswordModel.query().where('email', email).delete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import crypto from 'crypto';
|
||||
import * as crypto from 'crypto';
|
||||
import * as moment from 'moment';
|
||||
import { events } from '@/common/events/events';
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
import { SystemUser } from '@/modules/System/models/SystemUser';
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { SystemModel } from '@/modules/System/models/SystemModel';
|
||||
|
||||
export class PasswordReset extends SystemModel {
|
||||
readonly email: string;
|
||||
readonly token: string;
|
||||
|
||||
readonly createdAt: Date;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'password_resets';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['createdAt'];
|
||||
}
|
||||
}
|
||||
@@ -103,8 +103,8 @@ export class PlanSubscription extends mixin(SystemModel) {
|
||||
* Relations mappings.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const Tenant = require('system/models/Tenant');
|
||||
const Plan = require('system/models/Subscriptions/Plan');
|
||||
const { TenantModel } = require('../../System/models/TenantModel');
|
||||
const { Plan } = require('./Plan');
|
||||
|
||||
return {
|
||||
/**
|
||||
@@ -112,7 +112,7 @@ export class PlanSubscription extends mixin(SystemModel) {
|
||||
*/
|
||||
tenant: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Tenant.default,
|
||||
modelClass: TenantModel,
|
||||
join: {
|
||||
from: 'subscription_plan_subscriptions.tenantId',
|
||||
to: 'tenants.id',
|
||||
@@ -124,7 +124,7 @@ export class PlanSubscription extends mixin(SystemModel) {
|
||||
*/
|
||||
plan: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Plan.default,
|
||||
modelClass: Plan,
|
||||
join: {
|
||||
from: 'subscription_plan_subscriptions.planId',
|
||||
to: 'subscription_plans.id',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Knex } from 'knex';
|
||||
import { Global, Inject, Injectable } from '@nestjs/common';
|
||||
import uniqid from 'uniqid';
|
||||
import * as uniqid from 'uniqid';
|
||||
import { TenantRepository as TenantBaseRepository } from '@/common/repository/TenantRepository';
|
||||
import { SystemKnexConnection } from '../SystemDB/SystemDB.constants';
|
||||
import { TenantModel } from '../models/TenantModel';
|
||||
|
||||
164
pnpm-lock.yaml
generated
164
pnpm-lock.yaml
generated
@@ -496,9 +496,6 @@ importers:
|
||||
'@bigcapital/pdf-templates':
|
||||
specifier: '*'
|
||||
version: link:../../shared/pdf-templates
|
||||
'@bigcapital/server':
|
||||
specifier: '*'
|
||||
version: link:../server
|
||||
'@bigcapital/utils':
|
||||
specifier: '*'
|
||||
version: link:../../shared/bigcapital-utils
|
||||
@@ -571,6 +568,9 @@ importers:
|
||||
axios:
|
||||
specifier: ^1.6.0
|
||||
version: 1.7.7
|
||||
bcrypt:
|
||||
specifier: ^5.1.1
|
||||
version: 5.1.1
|
||||
bcryptjs:
|
||||
specifier: ^2.4.3
|
||||
version: 2.4.3
|
||||
@@ -7229,6 +7229,24 @@ packages:
|
||||
resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
/@mapbox/node-pre-gyp@1.0.11:
|
||||
resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
detect-libc: 2.0.3
|
||||
https-proxy-agent: 5.0.1
|
||||
make-dir: 3.1.0
|
||||
node-fetch: 2.6.7
|
||||
nopt: 5.0.0
|
||||
npmlog: 5.0.1
|
||||
rimraf: 3.0.2
|
||||
semver: 7.6.3
|
||||
tar: 6.2.1
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@mdx-js/react@2.3.0(react@18.3.1):
|
||||
resolution: {integrity: sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g==}
|
||||
peerDependencies:
|
||||
@@ -7751,7 +7769,7 @@ packages:
|
||||
node-gyp: 10.1.0
|
||||
node-gyp-build: 4.8.1
|
||||
prebuildify: 6.0.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
@@ -7786,7 +7804,7 @@ packages:
|
||||
pretty-bytes: 5.6.0
|
||||
request-ip: 3.3.0
|
||||
ringbufferjs: 2.0.0
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
sync-request: 6.1.0
|
||||
unescape: 1.0.1
|
||||
unescape-js: 1.1.4
|
||||
@@ -7844,7 +7862,7 @@ packages:
|
||||
resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==}
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||
dependencies:
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
|
||||
/@npmcli/git@5.0.7:
|
||||
resolution: {integrity: sha512-WaOVvto604d5IpdCRV2KjQu8PzkfE96d50CQGKgywXh2GxXmDeUO5EWcBC4V57uFyrNqx83+MewuJh3WTR3xPA==}
|
||||
@@ -7856,7 +7874,7 @@ packages:
|
||||
proc-log: 4.2.0
|
||||
promise-inflight: 1.0.1
|
||||
promise-retry: 2.0.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
which: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
- bluebird
|
||||
@@ -10744,7 +10762,7 @@ packages:
|
||||
prompts: 2.4.2
|
||||
puppeteer-core: 2.1.1
|
||||
read-pkg-up: 7.0.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
simple-update-notifier: 2.0.0
|
||||
strip-json-comments: 3.1.1
|
||||
tempy: 1.0.1
|
||||
@@ -10962,7 +10980,7 @@ packages:
|
||||
pretty-hrtime: 1.0.3
|
||||
prompts: 2.4.2
|
||||
read-pkg-up: 7.0.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
serve-favicon: 2.5.0
|
||||
telejson: 7.2.0
|
||||
tiny-invariant: 1.3.3
|
||||
@@ -11078,7 +11096,7 @@ packages:
|
||||
memoizerific: 1.11.3
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
store2: 2.14.3
|
||||
telejson: 7.2.0
|
||||
ts-dedent: 2.2.0
|
||||
@@ -12876,7 +12894,7 @@ packages:
|
||||
graphemer: 1.4.0
|
||||
ignore: 5.3.1
|
||||
natural-compare-lite: 1.4.0
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
tsutils: 3.21.0(typescript@4.9.5)
|
||||
typescript: 4.9.5
|
||||
transitivePeerDependencies:
|
||||
@@ -13117,7 +13135,7 @@ packages:
|
||||
glob: 7.2.3
|
||||
is-glob: 4.0.3
|
||||
lodash: 4.17.21
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
tsutils: 3.21.0(typescript@4.9.5)
|
||||
typescript: 4.9.5
|
||||
transitivePeerDependencies:
|
||||
@@ -13223,7 +13241,7 @@ packages:
|
||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@3.9.10)
|
||||
eslint: 8.57.0
|
||||
eslint-scope: 5.1.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
@@ -13243,7 +13261,7 @@ packages:
|
||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5)
|
||||
eslint: 8.57.0
|
||||
eslint-scope: 5.1.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
@@ -13263,7 +13281,7 @@ packages:
|
||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.6.3)
|
||||
eslint: 9.13.0
|
||||
eslint-scope: 5.1.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
@@ -13751,6 +13769,10 @@ packages:
|
||||
deprecated: Use your platform's native atob() and btoa() methods instead
|
||||
dev: false
|
||||
|
||||
/abbrev@1.1.1:
|
||||
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
||||
dev: false
|
||||
|
||||
/abbrev@2.0.0:
|
||||
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||
@@ -14190,11 +14212,19 @@ packages:
|
||||
|
||||
/aproba@2.0.0:
|
||||
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
|
||||
dev: true
|
||||
|
||||
/archy@1.0.0:
|
||||
resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==}
|
||||
|
||||
/are-we-there-yet@2.0.0:
|
||||
resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
|
||||
engines: {node: '>=10'}
|
||||
deprecated: This package is no longer supported.
|
||||
dependencies:
|
||||
delegates: 1.0.0
|
||||
readable-stream: 3.6.2
|
||||
dev: false
|
||||
|
||||
/are-we-there-yet@3.0.1:
|
||||
resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
@@ -15146,6 +15176,18 @@ packages:
|
||||
resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==}
|
||||
dev: false
|
||||
|
||||
/bcrypt@5.1.1:
|
||||
resolution: {integrity: sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@mapbox/node-pre-gyp': 1.0.11
|
||||
node-addon-api: 5.1.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/bcryptjs@2.4.3:
|
||||
resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==}
|
||||
dev: false
|
||||
@@ -15580,7 +15622,7 @@ packages:
|
||||
/builtins@5.1.0:
|
||||
resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==}
|
||||
dependencies:
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
dev: true
|
||||
|
||||
/bull@4.16.4:
|
||||
@@ -16526,7 +16568,6 @@ packages:
|
||||
|
||||
/console-control-strings@1.1.0:
|
||||
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
|
||||
dev: true
|
||||
|
||||
/constant-case@3.0.4:
|
||||
resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==}
|
||||
@@ -16615,7 +16656,7 @@ packages:
|
||||
handlebars: 4.7.8
|
||||
json-stringify-safe: 5.0.1
|
||||
meow: 8.1.2
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
split: 1.0.1
|
||||
dev: true
|
||||
|
||||
@@ -17092,7 +17133,7 @@ packages:
|
||||
postcss-modules-scope: 3.2.0(postcss@8.4.47)
|
||||
postcss-modules-values: 4.0.0(postcss@8.4.47)
|
||||
postcss-value-parser: 4.2.0
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0)
|
||||
|
||||
/css-loader@6.11.0(webpack@5.96.1):
|
||||
@@ -17114,7 +17155,7 @@ packages:
|
||||
postcss-modules-scope: 3.2.0(postcss@8.4.47)
|
||||
postcss-modules-values: 4.0.0(postcss@8.4.47)
|
||||
postcss-value-parser: 4.2.0
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
webpack: 5.96.1(esbuild@0.18.20)
|
||||
dev: true
|
||||
|
||||
@@ -17702,7 +17743,6 @@ packages:
|
||||
|
||||
/delegates@1.0.0:
|
||||
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
|
||||
dev: true
|
||||
|
||||
/denque@1.5.1:
|
||||
resolution: {integrity: sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==}
|
||||
@@ -17767,7 +17807,6 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/detect-newline@3.1.0:
|
||||
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
|
||||
@@ -18123,7 +18162,7 @@ packages:
|
||||
'@one-ini/wasm': 0.1.1
|
||||
commander: 10.0.1
|
||||
minimatch: 9.0.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
dev: false
|
||||
|
||||
/ee-first@1.1.1:
|
||||
@@ -20232,7 +20271,7 @@ packages:
|
||||
memfs: 3.5.3
|
||||
minimatch: 3.1.2
|
||||
schema-utils: 2.7.0
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
tapable: 1.1.3
|
||||
typescript: 4.9.5
|
||||
webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0)
|
||||
@@ -20504,6 +20543,22 @@ packages:
|
||||
/functions-have-names@1.2.3:
|
||||
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
|
||||
|
||||
/gauge@3.0.2:
|
||||
resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==}
|
||||
engines: {node: '>=10'}
|
||||
deprecated: This package is no longer supported.
|
||||
dependencies:
|
||||
aproba: 2.0.0
|
||||
color-support: 1.1.3
|
||||
console-control-strings: 1.1.0
|
||||
has-unicode: 2.0.1
|
||||
object-assign: 4.1.1
|
||||
signal-exit: 3.0.7
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wide-align: 1.1.5
|
||||
dev: false
|
||||
|
||||
/gauge@4.0.4:
|
||||
resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
@@ -20702,7 +20757,7 @@ packages:
|
||||
hasBin: true
|
||||
dependencies:
|
||||
meow: 8.1.2
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
dev: true
|
||||
|
||||
/git-up@7.0.0:
|
||||
@@ -21192,7 +21247,6 @@ packages:
|
||||
|
||||
/has-unicode@2.0.1:
|
||||
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
|
||||
dev: true
|
||||
|
||||
/has-value@0.3.1:
|
||||
resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==}
|
||||
@@ -22664,7 +22718,7 @@ packages:
|
||||
'@babel/parser': 7.26.1
|
||||
'@istanbuljs/schema': 0.1.3
|
||||
istanbul-lib-coverage: 3.2.2
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -23487,7 +23541,7 @@ packages:
|
||||
jest-util: 27.5.1
|
||||
natural-compare: 1.4.0
|
||||
pretty-format: 27.5.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
@@ -23515,7 +23569,7 @@ packages:
|
||||
jest-util: 29.7.0
|
||||
natural-compare: 1.4.0
|
||||
pretty-format: 29.7.0
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -26117,13 +26171,17 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/node-abort-controller@3.1.1:
|
||||
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
|
||||
|
||||
/node-addon-api@5.1.0:
|
||||
resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==}
|
||||
dev: false
|
||||
|
||||
/node-cache@4.2.1:
|
||||
resolution: {integrity: sha512-BOb67bWg2dTyax5kdef5WfU3X8xu4wPg+zHzkvls0Q/QpYycIFRLEEIdAx9Wma43DxG6Qzn4illdZoYseKWa4A==}
|
||||
engines: {node: '>= 0.4.6'}
|
||||
@@ -26198,7 +26256,7 @@ packages:
|
||||
make-fetch-happen: 13.0.1
|
||||
nopt: 7.2.1
|
||||
proc-log: 3.0.0
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
tar: 6.2.1
|
||||
which: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
@@ -26272,6 +26330,14 @@ packages:
|
||||
update-notifier: 2.5.0
|
||||
dev: false
|
||||
|
||||
/nopt@5.0.0:
|
||||
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
abbrev: 1.1.1
|
||||
dev: false
|
||||
|
||||
/nopt@7.2.1:
|
||||
resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==}
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||
@@ -26293,7 +26359,7 @@ packages:
|
||||
dependencies:
|
||||
hosted-git-info: 4.1.0
|
||||
is-core-module: 2.13.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
validate-npm-package-license: 3.0.4
|
||||
dev: true
|
||||
|
||||
@@ -26303,7 +26369,7 @@ packages:
|
||||
dependencies:
|
||||
hosted-git-info: 6.1.1
|
||||
is-core-module: 2.13.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
validate-npm-package-license: 3.0.4
|
||||
dev: true
|
||||
|
||||
@@ -26313,7 +26379,7 @@ packages:
|
||||
dependencies:
|
||||
hosted-git-info: 7.0.2
|
||||
is-core-module: 2.13.1
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
validate-npm-package-license: 3.0.4
|
||||
dev: true
|
||||
|
||||
@@ -26366,7 +26432,7 @@ packages:
|
||||
resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==}
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||
dependencies:
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
dev: true
|
||||
|
||||
/npm-normalize-package-bin@1.0.1:
|
||||
@@ -26384,7 +26450,7 @@ packages:
|
||||
dependencies:
|
||||
hosted-git-info: 6.1.1
|
||||
proc-log: 3.0.0
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
validate-npm-package-name: 5.0.0
|
||||
dev: true
|
||||
|
||||
@@ -26394,7 +26460,7 @@ packages:
|
||||
dependencies:
|
||||
hosted-git-info: 7.0.2
|
||||
proc-log: 4.2.0
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
validate-npm-package-name: 5.0.0
|
||||
dev: true
|
||||
|
||||
@@ -26432,7 +26498,7 @@ packages:
|
||||
npm-install-checks: 6.3.0
|
||||
npm-normalize-package-bin: 3.0.1
|
||||
npm-package-arg: 11.0.2
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
dev: true
|
||||
|
||||
/npm-registry-fetch@14.0.5:
|
||||
@@ -26511,6 +26577,16 @@ packages:
|
||||
path-key: 4.0.0
|
||||
dev: true
|
||||
|
||||
/npmlog@5.0.1:
|
||||
resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
|
||||
deprecated: This package is no longer supported.
|
||||
dependencies:
|
||||
are-we-there-yet: 2.0.0
|
||||
console-control-strings: 1.1.0
|
||||
gauge: 3.0.2
|
||||
set-blocking: 2.0.0
|
||||
dev: false
|
||||
|
||||
/npmlog@6.0.2:
|
||||
resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
@@ -28130,7 +28206,7 @@ packages:
|
||||
cosmiconfig: 7.1.0
|
||||
klona: 2.0.6
|
||||
postcss: 8.4.38
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0)
|
||||
dev: false
|
||||
|
||||
@@ -28144,7 +28220,7 @@ packages:
|
||||
cosmiconfig: 8.3.6(typescript@5.6.3)
|
||||
jiti: 1.21.0
|
||||
postcss: 8.4.47
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
webpack: 5.91.0(esbuild@0.18.20)(webpack-cli@5.1.4)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
@@ -28160,7 +28236,7 @@ packages:
|
||||
cosmiconfig: 8.3.6(typescript@5.6.3)
|
||||
jiti: 1.21.0
|
||||
postcss: 8.4.47
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
webpack: 5.96.1(esbuild@0.18.20)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
@@ -31417,7 +31493,6 @@ packages:
|
||||
resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/send@0.18.0:
|
||||
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
|
||||
@@ -31703,7 +31778,7 @@ packages:
|
||||
resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
semver: 7.6.2
|
||||
semver: 7.6.3
|
||||
dev: true
|
||||
|
||||
/sinon@7.5.0:
|
||||
@@ -35235,7 +35310,6 @@ packages:
|
||||
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
dev: true
|
||||
|
||||
/widest-line@2.0.1:
|
||||
resolution: {integrity: sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==}
|
||||
|
||||
Reference in New Issue
Block a user