From 85f293706d4a517d1feba532154d11af138109a9 Mon Sep 17 00:00:00 2001 From: chertik77 Date: Fri, 1 Aug 2025 12:45:31 +0100 Subject: [PATCH 1/6] refactor: add server auth --- .env.example | 6 ++ app/app.ts | 14 ++-- app/config/env.config.ts | 10 ++- app/controllers/auth.controller.ts | 84 ++++++++++++++++------- app/middlewares/authenticate.ts | 10 +-- app/routes/api/auth.ts | 19 ++---- app/schemas/auth.schema.ts | 4 -- app/schemas/index.ts | 7 +- package.json | 2 + swagger.json | 105 +++++++++++++++-------------- yarn.lock | 20 +++++- 11 files changed, 166 insertions(+), 115 deletions(-) diff --git a/.env.example b/.env.example index 8b0ed98..8aae689 100644 --- a/.env.example +++ b/.env.example @@ -2,6 +2,7 @@ CLOUDINARY_API_KEY= CLOUDINARY_API_SECRET= CLOUDINARY_CLOUD_NAME= DATABASE_URL= +FRONTEND_URL= REDIS_USERNAME= REDIS_PASSWORD= REDIS_HOST= @@ -11,7 +12,12 @@ GOOGLE_CLIENT_SECRET= GOOGLE_REDIRECT_URI= PORT= API_PREFIX= +NODE_ENV= ALLOWED_ORIGINS= +COOKIE_HTTP_ONLY= +COOKIE_SECURE= +COOKIE_SAME_SITE= +COOKIE_DOMAIN= ACCESS_JWT_SECRET= REFRESH_JWT_SECRET= ACCESS_JWT_EXPIRES_IN= diff --git a/app/app.ts b/app/app.ts index f6baaf2..d41bca0 100644 --- a/app/app.ts +++ b/app/app.ts @@ -1,22 +1,20 @@ import express from 'express' +import cookieParser from 'cookie-parser' import cors from 'cors' import helmet from 'helmet' import logger from 'morgan' import { env } from './config' -import { - globalErrorHandler, - globalLimiter, - notFoundHandler -} from './middlewares' +import { globalErrorHandler, notFoundHandler } from './middlewares' import { apiRouter } from './routes' export const app = express() app.use(helmet()) -app.use(cors({ origin: env.ALLOWED_ORIGINS })) -app.use(globalLimiter) -app.use(logger(app.get('env') === 'development' ? 'dev' : 'combined')) +app.use(cors({ origin: env.ALLOWED_ORIGINS, credentials: true })) +// app.use(globalLimiter) +app.use(logger(env.NODE_ENV === 'development' ? 'dev' : 'combined')) +app.use(cookieParser()) app.use(express.json()) app.use(env.API_PREFIX, apiRouter) diff --git a/app/config/env.config.ts b/app/config/env.config.ts index a0eee8e..d64b55d 100644 --- a/app/config/env.config.ts +++ b/app/config/env.config.ts @@ -8,7 +8,8 @@ const envSchema = z.object({ CLOUDINARY_API_KEY: z.string(), CLOUDINARY_API_SECRET: z.string(), CLOUDINARY_CLOUD_NAME: z.string(), - DATABASE_URL: z.string(), + DATABASE_URL: z.string().url(), + FRONTEND_URL: z.string().url(), GOOGLE_CLIENT_ID: z.string(), GOOGLE_CLIENT_SECRET: z.string(), GOOGLE_REDIRECT_URI: z.string().url(), @@ -19,6 +20,13 @@ const envSchema = z.object({ v => (v ? v : undefined), z.coerce.number().int().positive() ), + NODE_ENV: z.enum(['development', 'production']), + COOKIE_HTTP_ONLY: z + .enum(['true', 'false']) + .transform(value => value === 'true'), + COOKIE_SECURE: z.enum(['true', 'false']).transform(value => value === 'true'), + COOKIE_SAME_SITE: z.enum(['lax', 'strict', 'none']), + COOKIE_DOMAIN: z.string(), ACCESS_JWT_SECRET: z.string().transform(v => new TextEncoder().encode(v)), REFRESH_JWT_SECRET: z.string().transform(v => new TextEncoder().encode(v)), PORT: z.preprocess( diff --git a/app/controllers/auth.controller.ts b/app/controllers/auth.controller.ts index 0a17c1d..d9d08f0 100644 --- a/app/controllers/auth.controller.ts +++ b/app/controllers/auth.controller.ts @@ -1,13 +1,11 @@ import crypto from 'crypto' -import type { - GoogleCodeSchema, - RefreshTokenSchema, - SigninSchema, - SignupSchema -} from '@/schemas' +import type { GoogleCodeSchema, SigninSchema, SignupSchema } from '@/schemas' import type { JwtPayload } from '@/types' import type { NextFunction, Request, Response } from 'express' -import type { TypedRequestBody } from 'zod-express-middleware' +import type { + TypedRequestBody, + TypedRequestQuery +} from 'zod-express-middleware' import { prisma } from '@/prisma' import { hash, verify } from 'argon2' @@ -27,16 +25,24 @@ const { REFRESH_JWT_ALGORITHM, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, - GOOGLE_REDIRECT_URI + GOOGLE_REDIRECT_URI, + FRONTEND_URL, + COOKIE_HTTP_ONLY, + COOKIE_DOMAIN, + COOKIE_SECURE, + COOKIE_SAME_SITE } = env class AuthController { - googleClient = new OAuth2Client( + private googleClient = new OAuth2Client( GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REDIRECT_URI ) + private readonly ACCESS_TOKEN_NAME = 'accessToken' + private readonly REFRESH_TOKEN_NAME = 'refreshToken' + signup = async ( { body }: TypedRequestBody, res: Response, @@ -61,7 +67,9 @@ class AuthController { const tokens = await this.getNewTokens({ id: user.id, sid: newSession.id }) - res.json({ user, ...tokens }) + this.setTokensCookie(res, tokens) + + res.json({ user }) } signin = async ( @@ -90,10 +98,12 @@ class AuthController { const tokens = await this.getNewTokens({ id: user.id, sid: newSession.id }) - res.json({ user: userWithoutPassword, ...tokens }) + this.setTokensCookie(res, tokens) + + res.json({ user: userWithoutPassword }) } - getGoogleRedirectUrl = async (_: Request, res: Response) => { + googleRedirect = async (_: Request, res: Response) => { const state = crypto.randomBytes(32).toString('hex') await redisClient.set(`oauth_state:${state}`, 'true', 'EX', 5 * 60) @@ -104,15 +114,15 @@ class AuthController { scope: ['profile', 'email'] }) - res.json({ redirectUrl: url }) + res.redirect(url) } googleCallback = async ( - req: TypedRequestBody, + req: TypedRequestQuery, res: Response, next: NextFunction ) => { - const { code, state: receivedState } = req.body + const { code, state: receivedState } = req.query const redisStateKey = `oauth_state:${receivedState}` @@ -157,7 +167,9 @@ class AuthController { sid: newSession.id }) - res.json({ user, ...tokens }) + this.setTokensCookie(res, tokens) + + res.redirect(FRONTEND_URL) } else { const newSession = await prisma.session.create({ data: { userId: user.id } @@ -168,19 +180,21 @@ class AuthController { sid: newSession.id }) - res.json({ user, ...tokens }) + this.setTokensCookie(res, tokens) + + res.redirect(FRONTEND_URL) } } - refresh = async ( - { body }: TypedRequestBody, - res: Response, - next: NextFunction - ) => { + refresh = async (req: Request, res: Response, next: NextFunction) => { + const refreshToken = req.cookies.refreshToken + + if (!refreshToken) return next(Forbidden()) + try { const { payload: { id, sid } - } = await jwtVerify(body.refreshToken, REFRESH_JWT_SECRET) + } = await jwtVerify(refreshToken, REFRESH_JWT_SECRET) const user = await prisma.user.findFirst({ where: { id } }) @@ -208,8 +222,9 @@ class AuthController { } } - logout = async ({ session }: Request, res: Response) => { - await prisma.session.delete({ where: { id: session } }) + logout = async (_: Request, res: Response) => { + res.clearCookie(this.ACCESS_TOKEN_NAME) + res.clearCookie(this.REFRESH_TOKEN_NAME) res.sendStatus(204) } @@ -227,6 +242,25 @@ class AuthController { return { accessToken, refreshToken } } + + private setTokensCookie = ( + res: Response, + tokens: { accessToken: string; refreshToken: string } + ) => { + res.cookie(this.ACCESS_TOKEN_NAME, tokens.accessToken, { + httpOnly: COOKIE_HTTP_ONLY, + secure: COOKIE_SECURE, + sameSite: COOKIE_SAME_SITE, + domain: COOKIE_DOMAIN + }) + + res.cookie(this.REFRESH_TOKEN_NAME, tokens.refreshToken, { + httpOnly: COOKIE_HTTP_ONLY, + secure: COOKIE_SECURE, + sameSite: COOKIE_SAME_SITE, + domain: COOKIE_DOMAIN + }) + } } export const authController = new AuthController() diff --git a/app/middlewares/authenticate.ts b/app/middlewares/authenticate.ts index 642a2cf..4e6eb54 100644 --- a/app/middlewares/authenticate.ts +++ b/app/middlewares/authenticate.ts @@ -4,6 +4,7 @@ import type { NextFunction, Request, Response } from 'express' import { prisma } from '@/prisma' import { Unauthorized } from 'http-errors' import { jwtVerify } from 'jose' +import { JWTExpired } from 'jose/errors' import { env } from '@/config' @@ -12,10 +13,9 @@ export const authenticate = async ( _: Response, next: NextFunction ) => { - const { authorization = '' } = req.headers - const [bearer, token] = authorization.split(' ') + const token: string = req.cookies.accessToken - if (bearer !== 'Bearer') return next(Unauthorized()) + if (!token) return next(Unauthorized()) try { const { @@ -35,7 +35,9 @@ export const authenticate = async ( req.session = session.id next() - } catch { + } catch (e) { + if (e instanceof JWTExpired) return next(Unauthorized(e.code)) + return next(Unauthorized()) } } diff --git a/app/routes/api/auth.ts b/app/routes/api/auth.ts index b908965..f58752b 100644 --- a/app/routes/api/auth.ts +++ b/app/routes/api/auth.ts @@ -5,12 +5,7 @@ import { authController } from '@/controllers' import { authenticate } from '@/middlewares' -import { - GoogleCodeSchema, - RefreshTokenSchema, - SigninSchema, - SignupSchema -} from '@/schemas' +import { GoogleCodeSchema, SigninSchema, SignupSchema } from '@/schemas' export const authRouter = Router() @@ -26,18 +21,14 @@ authRouter.post( authController.signin ) -authRouter.get('/google/initiate', authController.getGoogleRedirectUrl) +authRouter.post('/google/redirect', authController.googleRedirect) -authRouter.post( +authRouter.get( '/google/callback', - validateRequest({ body: GoogleCodeSchema }), + validateRequest({ query: GoogleCodeSchema }), authController.googleCallback ) -authRouter.post( - '/refresh', - validateRequest({ body: RefreshTokenSchema }), - authController.refresh -) +authRouter.post('/refresh', authController.refresh) authRouter.post('/logout', authenticate, authController.logout) diff --git a/app/schemas/auth.schema.ts b/app/schemas/auth.schema.ts index 329540d..08012e6 100644 --- a/app/schemas/auth.schema.ts +++ b/app/schemas/auth.schema.ts @@ -12,10 +12,6 @@ export const SignupSchema = SigninSchema.extend({ name: z.string().min(2, 'Name must be at least 2 characters') }) -export const RefreshTokenSchema = z.object({ - refreshToken: z.string().min(1, 'Refresh token is required') -}) - export const GoogleCodeSchema = z.object({ code: z.string().min(1, 'Code is required'), state: z.string().min(1, 'State is required') diff --git a/app/schemas/index.ts b/app/schemas/index.ts index 1670178..394fc23 100644 --- a/app/schemas/index.ts +++ b/app/schemas/index.ts @@ -15,10 +15,5 @@ export { ColumnParamsSchema, UpdateColumnOrderSchema } from './column.schema' -export { - SigninSchema, - SignupSchema, - RefreshTokenSchema, - GoogleCodeSchema -} from './auth.schema' +export { SigninSchema, SignupSchema, GoogleCodeSchema } from './auth.schema' export { EditUserSchema, NeedHelpSchema } from './user.schema' diff --git a/package.json b/package.json index 96f6819..b7a6600 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@prisma/client": "^6.11.1", "argon2": "^0.43.0", "cloudinary": "^2.7.0", + "cookie-parser": "^1.4.7", "cors": "2.8.5", "dotenv": "^17.0.1", "express": "^5.1.0", @@ -41,6 +42,7 @@ "@commitlint/cli": "^19.8.1", "@commitlint/config-conventional": "^19.8.1", "@ianvs/prettier-plugin-sort-imports": "^4.4.2", + "@types/cookie-parser": "^1.4.9", "@types/cors": "^2.8.19", "@types/express": "5.0.3", "@types/morgan": "^1.9.10", diff --git a/swagger.json b/swagger.json index 87253d0..0bb340f 100644 --- a/swagger.json +++ b/swagger.json @@ -132,24 +132,7 @@ "post": { "tags": ["Auth"], "summary": "Get new access and refresh tokens", - "security": [{ "Bearer": [] }], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": ["refreshToken"], - "properties": { - "refreshToken": { - "type": "string", - "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NzE3NDNkYjg1Yzk2NDUzZTA0YTY4NCIsInNpZCI6IjY2NzE3OWE0YTgxZmI1MjIzOTg0NmY2MSIsImlhdCI6MTcxODcxMjc0MCwiZXhwIjoxNzE5MzE3NTQwfQ.B8htZY5kU0kvX2UYsEN0u7ZUPVxTKfCs5ASAocTc-P4" - } - } - } - } - } - }, + "security": [{ "CookieAuth": [] }], "responses": { "200": { "$ref": "#/components/responses/RefreshResponse" }, "400": { "$ref": "#/components/responses/BadRequestError" }, @@ -162,7 +145,7 @@ "post": { "tags": ["Auth"], "summary": "Logout a user", - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "responses": { "204": { "description": "The user was logged out successfully." }, "401": { "$ref": "#/components/responses/Unauthorized" } @@ -173,7 +156,7 @@ "get": { "tags": ["User"], "summary": "Get current user", - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "responses": { "200": { "$ref": "#/components/responses/UserResponse" }, "401": { "$ref": "#/components/responses/Unauthorized" } @@ -184,7 +167,7 @@ "post": { "tags": ["User"], "summary": "Send email need help", - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "requestBody": { "required": true, "content": { @@ -232,7 +215,7 @@ "patch": { "tags": ["User"], "summary": "Edit user profile", - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "requestBody": { "required": true, "content": { @@ -286,7 +269,7 @@ "get": { "tags": ["Board"], "summary": "Get all boards", - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "responses": { "200": { "$ref": "#/components/responses/AllBoardsResponse" }, "401": { "$ref": "#/components/responses/Unauthorized" } @@ -295,7 +278,7 @@ "post": { "tags": ["Board"], "summary": "Add new board", - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "requestBody": { "required": true, "content": { @@ -354,7 +337,7 @@ } } ], - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "responses": { "200": { "$ref": "#/components/responses/BoardByIdResponse" }, "401": { "$ref": "#/components/responses/Unauthorized" }, @@ -375,7 +358,7 @@ } } ], - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "requestBody": { "required": true, "content": { @@ -432,7 +415,7 @@ } } ], - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "responses": { "204": { "description": "The resource was deleted successfully." }, "401": { "$ref": "#/components/responses/Unauthorized" }, @@ -455,7 +438,7 @@ } } ], - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "requestBody": { "required": true, "content": { @@ -497,7 +480,7 @@ } } ], - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "requestBody": { "required": true, "content": { @@ -548,7 +531,7 @@ } } ], - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "requestBody": { "required": true, "content": { @@ -587,7 +570,7 @@ } } ], - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "responses": { "204": { "description": "The resource was deleted successfully." }, "401": { "$ref": "#/components/responses/Unauthorized" }, @@ -610,7 +593,7 @@ } } ], - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "requestBody": { "required": true, "content": { @@ -666,7 +649,7 @@ } } ], - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "requestBody": { "required": true, "content": { @@ -714,7 +697,7 @@ } } ], - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "requestBody": { "required": true, "content": { @@ -767,7 +750,7 @@ } } ], - "security": [{ "Bearer": [] }], + "security": [{ "CookieAuth": [] }], "responses": { "204": { "description": "The resource was deleted successfully." }, "401": { "$ref": "#/components/responses/Unauthorized" }, @@ -812,16 +795,9 @@ "AuthResponseSchema": { "type": "object", "properties": { - "user": { "$ref": "#/components/schemas/User" }, - "accessToken": { - "type": "string", - "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY3NDcyMzcxOWI0N2ZkMDhlNmEyZDUxNyIsInNpZCI6IjY3NDcyMzcyOWI0N2ZkMDhlNmEyZDUxOCIsImlhdCI6MTczMjcxNTM3OCwiZXhwIjoxNzMyNzE4OTc4fQ.ZCaaWh4rc4AHzTSljDbc7mq5gbHvjMx54y6LoJsXX-4" - }, - "refreshToken": { - "type": "string", - "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY3NDcyMzcxOWI0N2ZkMDhlNmEyZDUxNyIsInNpZCI6IjY3NDcyMzcyOWI0N2ZkMDhlNmEyZDUxOCIsImlhdCI6MTczMjcxNTM3OCwiZXhwIjoxNzMzMzIwMTc4fQ.y17k3eWBJ4WeqNZeuguOh_5UQDiyaCPYFmn_Ir-Ftog" - } - } + "user": { "$ref": "#/components/schemas/User" } + }, + "description": "User object returned upon successful authentication. Access and refresh tokens are set as HTTP-only cookies. In production, they are also secure cookies." }, "BoardBackground": { "type": "object", @@ -1009,6 +985,14 @@ "application/json": { "schema": { "$ref": "#/components/schemas/AuthResponseSchema" } } + }, + "headers": { + "Set-Cookie": { + "schema": { + "type": "string", + "example": "accessToken=eyJhbGci...; Path=/; HttpOnly; SameSite=Lax; Secure=true (only in production), refreshToken=eyJhbGci...; Path=/; HttpOnly; SameSite=Lax; Secure=true (only in production)" + } + } } }, "GoogleInitiateResponse": { @@ -1055,6 +1039,14 @@ ] } } + }, + "headers": { + "Set-Cookie": { + "schema": { + "type": "string", + "example": "accessToken=eyJhbGci...; Path=/; HttpOnly; SameSite=Lax; Secure=true (only in production), refreshToken=eyJhbGci...; Path=/; HttpOnly; SameSite=Lax; Secure=true (only in production)" + } + } } }, "RefreshResponse": { @@ -1063,17 +1055,21 @@ "schema": { "type": "object", "properties": { - "acesssToken": { - "type": "string", - "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NzE3NDNkYjg1Yzk2NDUzZTA0YTY4NCIsInNpZCI6IjY2NzE3OWE0YTgxZmI1MjIzOTg0NmY2MSIsImlhdCI6MTcxODcxMjc0MCwiZXhwIjoxNzE4NzE2MzQwfQ.hwdlZg0fft0PjwN63qwfjFTg1ZeyOOukFdZVbF0VOUU" - }, - "refreshToken": { + "message": { "type": "string", - "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NzE3NDNkYjg1Yzk2NDUzZTA0YTY4NCIsInNpZCI6IjY2NzE3OWE0YTgxZmI1MjIzOTg0NmY2MSIsImlhdCI6MTcxODcxMjc0MCwiZXhwIjoxNzE5MzE3NTQwfQ.B8htZY5kU0kvX2UYsEN0u7ZUPVxTKfCs5ASAocTc-P4" + "example": "Tokens refreshed successfully" } } } } + }, + "headers": { + "Set-Cookie": { + "schema": { + "type": "string", + "example": "accessToken=eyJhbGci...; Path=/; HttpOnly; SameSite=Lax; Secure=true (only in production), refreshToken=eyJhbGci...; Path=/; HttpOnly; SameSite=Lax; Secure=true (only in production)" + } + } } }, "UserResponse": { @@ -1233,7 +1229,12 @@ } }, "securitySchemes": { - "Bearer": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" } + "CookieAuth": { + "type": "apiKey", + "in": "cookie", + "name": "accessToken", + "description": "Access token is sent as an HTTP-only cookie. In production, it is also a secure cookie." + } } } } diff --git a/yarn.lock b/yarn.lock index 2f632ac..db80df8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -565,6 +565,11 @@ dependencies: "@types/node" "*" +"@types/cookie-parser@^1.4.9": + version "1.4.9" + resolved "https://registry.yarnpkg.com/@types/cookie-parser/-/cookie-parser-1.4.9.tgz#f0e79c766a58ee7369a52e7509b3840222f68ed2" + integrity sha512-tGZiZ2Gtc4m3wIdLkZ8mkj1T6CEHb35+VApbL2T14Dew8HA7c+04dmKqsKRNC+8RJPm16JEK0tFSwdZqubfc4g== + "@types/cors@^2.8.19": version "2.8.19" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.19.tgz#d93ea2673fd8c9f697367f5eeefc2bbfa94f0342" @@ -1235,12 +1240,25 @@ conventional-commits-parser@^5.0.0: meow "^12.0.1" split2 "^4.0.0" +cookie-parser@^1.4.7: + version "1.4.7" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.7.tgz#e2125635dfd766888ffe90d60c286404fa0e7b26" + integrity sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw== + dependencies: + cookie "0.7.2" + cookie-signature "1.0.6" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + cookie-signature@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.2.2.tgz#57c7fc3cc293acab9fec54d73e15690ebe4a1793" integrity sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg== -cookie@^0.7.1: +cookie@0.7.2, cookie@^0.7.1: version "0.7.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== From 1284d3762e9fec37b849e1bab38ef52ddd94a0ef Mon Sep 17 00:00:00 2001 From: chertik77 Date: Fri, 1 Aug 2025 13:58:29 +0100 Subject: [PATCH 2/6] chore: update deps --- app/config/env.config.ts | 39 +- app/controllers/auth.controller.ts | 6 +- app/controllers/board.controller.ts | 6 +- app/controllers/card.controller.ts | 2 +- app/controllers/column.controller.ts | 2 +- app/controllers/user.controller.ts | 2 +- app/middlewares/index.ts | 1 + app/middlewares/validate-request.ts | 57 +++ app/routes/api/auth.ts | 2 +- app/routes/api/board.ts | 3 +- app/routes/api/card.ts | 3 +- app/routes/api/column.ts | 3 +- app/routes/api/user.ts | 3 +- app/schemas/auth.schema.ts | 5 +- app/schemas/board.schema.ts | 14 +- app/schemas/card.schema.ts | 18 +- app/schemas/user.schema.ts | 11 +- app/types/index.ts | 6 + app/types/request.ts | 30 ++ package.json | 35 +- yarn.lock | 695 +++++++++++++++++++-------- 21 files changed, 649 insertions(+), 294 deletions(-) create mode 100644 app/middlewares/validate-request.ts create mode 100644 app/types/request.ts diff --git a/app/config/env.config.ts b/app/config/env.config.ts index d64b55d..b302905 100644 --- a/app/config/env.config.ts +++ b/app/config/env.config.ts @@ -8,44 +8,37 @@ const envSchema = z.object({ CLOUDINARY_API_KEY: z.string(), CLOUDINARY_API_SECRET: z.string(), CLOUDINARY_CLOUD_NAME: z.string(), - DATABASE_URL: z.string().url(), - FRONTEND_URL: z.string().url(), + DATABASE_URL: z.url(), + FRONTEND_URL: z.url(), GOOGLE_CLIENT_ID: z.string(), GOOGLE_CLIENT_SECRET: z.string(), - GOOGLE_REDIRECT_URI: z.string().url(), + GOOGLE_REDIRECT_URI: z.url(), REDIS_USERNAME: z.string(), REDIS_PASSWORD: z.string(), REDIS_HOST: z.string(), - REDIS_PORT: z.preprocess( - v => (v ? v : undefined), - z.coerce.number().int().positive() - ), + REDIS_PORT: z.coerce.number().int().positive().min(1000).max(65535), NODE_ENV: z.enum(['development', 'production']), - COOKIE_HTTP_ONLY: z - .enum(['true', 'false']) - .transform(value => value === 'true'), - COOKIE_SECURE: z.enum(['true', 'false']).transform(value => value === 'true'), + COOKIE_HTTP_ONLY: z.stringbool(), + COOKIE_SECURE: z.stringbool(), COOKIE_SAME_SITE: z.enum(['lax', 'strict', 'none']), COOKIE_DOMAIN: z.string(), ACCESS_JWT_SECRET: z.string().transform(v => new TextEncoder().encode(v)), REFRESH_JWT_SECRET: z.string().transform(v => new TextEncoder().encode(v)), - PORT: z.preprocess( - v => (v ? v : undefined), - z.coerce.number().int().positive() - ), + PORT: z.coerce.number().int().positive().min(1000).max(65535), API_PREFIX: z.string(), ALLOWED_ORIGINS: z .string() .transform(v => v.split(',')) - .pipe(z.array(z.string().url())), + .pipe(z.array(z.url())), EMAIL_HOST: z.string(), - EMAIL_PORT: z - .number({ coerce: true }) - .refine(v => availableEmailPorts.includes(v), { - message: `Email port must be one of the following: ${availableEmailPorts.join(', ')}` - }), - EMAIL_USER: z.string().email(), - EMAIL_RECEIVER: z.string().email(), + EMAIL_PORT: z.coerce + .number() + .refine( + v => availableEmailPorts.includes(v), + `Email port must be one of the following: ${availableEmailPorts.join(', ')}` + ), + EMAIL_USER: z.email(), + EMAIL_RECEIVER: z.email(), EMAIL_PASSWORD: z.string(), ACCESS_JWT_EXPIRES_IN: z.string(), REFRESH_JWT_EXPIRES_IN: z.string(), diff --git a/app/controllers/auth.controller.ts b/app/controllers/auth.controller.ts index d9d08f0..769e3e1 100644 --- a/app/controllers/auth.controller.ts +++ b/app/controllers/auth.controller.ts @@ -1,11 +1,7 @@ import crypto from 'crypto' import type { GoogleCodeSchema, SigninSchema, SignupSchema } from '@/schemas' -import type { JwtPayload } from '@/types' +import type { JwtPayload, TypedRequestBody, TypedRequestQuery } from '@/types' import type { NextFunction, Request, Response } from 'express' -import type { - TypedRequestBody, - TypedRequestQuery -} from 'zod-express-middleware' import { prisma } from '@/prisma' import { hash, verify } from 'argon2' diff --git a/app/controllers/board.controller.ts b/app/controllers/board.controller.ts index ee60b4f..a13cac0 100644 --- a/app/controllers/board.controller.ts +++ b/app/controllers/board.controller.ts @@ -3,13 +3,13 @@ import type { BoardParamsSchema, EditBoardSchema } from '@/schemas' -import type { NextFunction, Request, Response } from 'express' -import type { ZodType } from 'zod' import type { TypedRequest, TypedRequestBody, TypedRequestParams -} from 'zod-express-middleware' +} from '@/types' +import type { NextFunction, Request, Response } from 'express' +import type { ZodType } from 'zod' import { prisma } from '@/prisma' import { NotFound } from 'http-errors' diff --git a/app/controllers/card.controller.ts b/app/controllers/card.controller.ts index 55d0e01..b36f823 100644 --- a/app/controllers/card.controller.ts +++ b/app/controllers/card.controller.ts @@ -5,9 +5,9 @@ import type { EditCardSchema, UpdateCardOrderSchema } from '@/schemas' +import type { TypedRequest, TypedRequestParams } from '@/types' import type { NextFunction, Response } from 'express' import type { ZodType } from 'zod' -import type { TypedRequest, TypedRequestParams } from 'zod-express-middleware' import { prisma } from '@/prisma' import { BadRequest, NotFound } from 'http-errors' diff --git a/app/controllers/column.controller.ts b/app/controllers/column.controller.ts index a92596d..a971884 100644 --- a/app/controllers/column.controller.ts +++ b/app/controllers/column.controller.ts @@ -5,9 +5,9 @@ import type { EditColumnSchema, UpdateColumnOrderSchema } from '@/schemas' +import type { TypedRequest, TypedRequestParams } from '@/types' import type { NextFunction, Response } from 'express' import type { ZodType } from 'zod' -import type { TypedRequest, TypedRequestParams } from 'zod-express-middleware' import { prisma } from '@/prisma' import { BadRequest, NotFound } from 'http-errors' diff --git a/app/controllers/user.controller.ts b/app/controllers/user.controller.ts index b2483c0..75f56e0 100644 --- a/app/controllers/user.controller.ts +++ b/app/controllers/user.controller.ts @@ -1,8 +1,8 @@ import type { EditUserSchema, NeedHelpSchema } from '@/schemas' +import type { TypedRequestBody } from '@/types' import type { User } from '@prisma/client' import type { NextFunction, Request, Response } from 'express' import type { Options } from 'nodemailer/lib/mailer' -import type { TypedRequestBody } from 'zod-express-middleware' import { prisma } from '@/prisma' import { hash } from 'argon2' diff --git a/app/middlewares/index.ts b/app/middlewares/index.ts index 422dcf7..e8713da 100644 --- a/app/middlewares/index.ts +++ b/app/middlewares/index.ts @@ -1,4 +1,5 @@ export { authenticate } from './authenticate' export { upload } from './multer' export { globalLimiter } from './limiter' +export { validateRequest } from './validate-request' export { notFoundHandler, globalErrorHandler } from './errorHandler' diff --git a/app/middlewares/validate-request.ts b/app/middlewares/validate-request.ts new file mode 100644 index 0000000..6135142 --- /dev/null +++ b/app/middlewares/validate-request.ts @@ -0,0 +1,57 @@ +import type { RequestHandler } from 'express' +import type * as z from 'zod' + +import createHttpError from 'http-errors' + +type RequestValidation = { + params?: z.ZodType

+ query?: z.ZodType + body?: z.ZodType +} + +export const validateRequest: ( + schemas: RequestValidation +) => RequestHandler = + ({ params, query, body }) => + (req, _, next) => { + const errors: Record = {} + + if (params) { + const parsed = params.safeParse(req.params) + + if (!parsed.success) { + parsed.error.issues.forEach(({ path, message }) => { + const errorPath = `${path.join('.')}` + errors[errorPath] = message + }) + } + } + + if (query) { + const parsed = query.safeParse(req.query) + + if (!parsed.success) { + parsed.error.issues.forEach(({ path, message }) => { + const errorPath = `${path.join('.')}` + errors[errorPath] = message + }) + } + } + + if (body) { + const parsed = body.safeParse(req.body) + + if (!parsed.success) { + parsed.error.issues.forEach(({ path, message }) => { + const errorPath = `${path.join('.')}` + errors[errorPath] = message + }) + } + } + + if (Object.keys(errors).length > 0) { + return next(createHttpError(400, { message: errors })) + } + + return next() + } diff --git a/app/routes/api/auth.ts b/app/routes/api/auth.ts index f58752b..bd18b3c 100644 --- a/app/routes/api/auth.ts +++ b/app/routes/api/auth.ts @@ -1,9 +1,9 @@ import { Router } from 'express' -import { validateRequest } from 'zod-express-middleware' import { authController } from '@/controllers' import { authenticate } from '@/middlewares' +import { validateRequest } from '@/middlewares/validate-request' import { GoogleCodeSchema, SigninSchema, SignupSchema } from '@/schemas' diff --git a/app/routes/api/board.ts b/app/routes/api/board.ts index 88bff04..6172ed3 100644 --- a/app/routes/api/board.ts +++ b/app/routes/api/board.ts @@ -1,9 +1,8 @@ import { Router } from 'express' -import { validateRequest } from 'zod-express-middleware' import { boardController } from '@/controllers' -import { authenticate } from '@/middlewares' +import { authenticate, validateRequest } from '@/middlewares' import { AddBoardSchema, BoardParamsSchema, EditBoardSchema } from '@/schemas' diff --git a/app/routes/api/card.ts b/app/routes/api/card.ts index 0e4685c..e680870 100644 --- a/app/routes/api/card.ts +++ b/app/routes/api/card.ts @@ -1,9 +1,8 @@ import { Router } from 'express' -import { validateRequest } from 'zod-express-middleware' import { cardController } from '@/controllers' -import { authenticate } from '@/middlewares' +import { authenticate, validateRequest } from '@/middlewares' import { AddCardSchema, diff --git a/app/routes/api/column.ts b/app/routes/api/column.ts index 6bf168b..c8cdf5d 100644 --- a/app/routes/api/column.ts +++ b/app/routes/api/column.ts @@ -1,9 +1,8 @@ import { Router } from 'express' -import { validateRequest } from 'zod-express-middleware' import { columnController } from '@/controllers' -import { authenticate } from '@/middlewares' +import { authenticate, validateRequest } from '@/middlewares' import { AddColumnSchema, diff --git a/app/routes/api/user.ts b/app/routes/api/user.ts index 55a00d5..abc9dfb 100644 --- a/app/routes/api/user.ts +++ b/app/routes/api/user.ts @@ -1,9 +1,8 @@ import { Router } from 'express' -import { validateRequest } from 'zod-express-middleware' import { userController } from '@/controllers' -import { authenticate, upload } from '@/middlewares' +import { authenticate, upload, validateRequest } from '@/middlewares' import { EditUserSchema, NeedHelpSchema } from '@/schemas' diff --git a/app/schemas/auth.schema.ts b/app/schemas/auth.schema.ts index 08012e6..1aff9c0 100644 --- a/app/schemas/auth.schema.ts +++ b/app/schemas/auth.schema.ts @@ -1,14 +1,15 @@ import * as z from 'zod' export const SigninSchema = z.object({ - email: z.string().email({ message: 'Email is invalid' }), + email: z.email('Email is invalid'), password: z .string() .min(8, 'Password must be at least 8 characters') .max(64, 'Password must be at most 64 characters') }) -export const SignupSchema = SigninSchema.extend({ +export const SignupSchema = z.object({ + ...SigninSchema.shape, name: z.string().min(2, 'Name must be at least 2 characters') }) diff --git a/app/schemas/board.schema.ts b/app/schemas/board.schema.ts index 0dcccda..dc6bc5b 100644 --- a/app/schemas/board.schema.ts +++ b/app/schemas/board.schema.ts @@ -5,18 +5,18 @@ import boardImages from '@/data/board-bg-images.json' import { objectIdSchema } from './object-id.schema' -function zodEnumFromObjKeys( - obj: Record -): z.ZodEnum<[K, ...K[]]> { - const [firstKey, ...otherKeys] = Object.keys(obj) as K[] +function zObjectKeys>(obj: T) { + const keys = Object.keys(obj) as Extract[] - return z.enum([firstKey, ...otherKeys]) + return z.enum( + keys as [Extract, ...Extract[]] + ) } export const AddBoardSchema = z.object({ title: z.string().min(3, 'Title must be at least 3 characters'), - icon: z.nativeEnum(Icon), - background: zodEnumFromObjKeys(boardImages) + icon: z.enum(Icon), + background: zObjectKeys(boardImages) }) export const EditBoardSchema = AddBoardSchema.partial() diff --git a/app/schemas/card.schema.ts b/app/schemas/card.schema.ts index de42de2..50dcc16 100644 --- a/app/schemas/card.schema.ts +++ b/app/schemas/card.schema.ts @@ -6,15 +6,19 @@ import { objectIdSchema } from './object-id.schema' export const AddCardSchema = z.object({ title: z.string().min(3, 'Title must be at least 3 characters'), description: z.string().min(3, 'Description must be at least 3 characters'), - priority: z.nativeEnum(Priority, { - message: 'Priority must be one of the following: Without, Low, Medium, High' - }), - deadline: z.coerce.date({ message: 'Deadline must be a valid date' }) + priority: z.enum( + Priority, + 'Priority must be one of the following: Without, Low, Medium, High' + ), + deadline: z.iso.datetime('Deadline must be a valid datetime') }) -export const EditCardSchema = AddCardSchema.extend({ - columnId: objectIdSchema() -}).partial() +export const EditCardSchema = z + .object({ + ...AddCardSchema.shape, + columnId: objectIdSchema() + }) + .partial() export const CardParamsSchema = z.object({ cardId: objectIdSchema() }) diff --git a/app/schemas/user.schema.ts b/app/schemas/user.schema.ts index 483184f..7436f89 100644 --- a/app/schemas/user.schema.ts +++ b/app/schemas/user.schema.ts @@ -2,20 +2,21 @@ import { Theme } from '@prisma/client' import * as z from 'zod' export const NeedHelpSchema = z.object({ - email: z.string().email({ message: 'Email is invalid' }), + email: z.email('Email is invalid'), comment: z.string().min(5, 'Comment must be at least 5 characters') }) export const EditUserSchema = z .object({ name: z.string().min(2, 'Name must be at least 2 characters'), - email: z.string().email({ message: 'Email is invalid' }), + email: z.email('Email is invalid'), password: z .string() .min(8, 'Password must be at least 8 characters') .max(64, 'Password must be at most 64 characters'), - theme: z.nativeEnum(Theme, { - message: 'Theme must be one of the following: light, dark, violet' - }) + theme: z.enum( + Theme, + 'Theme must be one of the following: light, dark, violet' + ) }) .partial() diff --git a/app/types/index.ts b/app/types/index.ts index 8c80982..624e2f9 100644 --- a/app/types/index.ts +++ b/app/types/index.ts @@ -1 +1,7 @@ export type { JwtPayload } from './jwt-payload' +export type { + TypedRequest, + TypedRequestBody, + TypedRequestQuery, + TypedRequestParams +} from './request' diff --git a/app/types/request.ts b/app/types/request.ts new file mode 100644 index 0000000..4b74569 --- /dev/null +++ b/app/types/request.ts @@ -0,0 +1,30 @@ +import type { Request } from 'express' +import type { ParamsDictionary } from 'express-serve-static-core' +import type * as z from 'zod' + +export type TypedRequest< + P extends z.ZodType, + Q extends z.ZodType, + B extends z.ZodType +> = Request, unknown, z.infer, z.infer> + +export type TypedRequestBody = Request< + ParamsDictionary, + unknown, + z.infer, + unknown +> + +export type TypedRequestParams

= Request< + z.infer

, + unknown, + unknown, + unknown +> + +export type TypedRequestQuery = Request< + ParamsDictionary, + unknown, + unknown, + z.infer +> diff --git a/package.json b/package.json index b7a6600..05e6149 100644 --- a/package.json +++ b/package.json @@ -17,52 +17,51 @@ "schema": "./prisma" }, "dependencies": { - "@prisma/client": "^6.11.1", - "argon2": "^0.43.0", + "@prisma/client": "^6.13.0", + "argon2": "^0.43.1", "cloudinary": "^2.7.0", "cookie-parser": "^1.4.7", "cors": "2.8.5", - "dotenv": "^17.0.1", + "dotenv": "^17.2.1", "express": "^5.1.0", "express-rate-limit": "^8.0.1", - "google-auth-library": "^10.1.0", + "google-auth-library": "^10.2.0", "helmet": "^8.1.0", "http-errors": "^2.0.0", - "ioredis": "^5.6.1", - "jose": "^6.0.11", - "morgan": "1.10.0", - "multer": "^2.0.1", - "nodemailer": "^7.0.4", + "ioredis": "^5.7.0", + "jose": "^6.0.12", + "morgan": "1.10.1", + "multer": "^2.0.2", + "nodemailer": "^7.0.5", "rate-limit-redis": "^4.2.1", "swagger-ui-express": "^5.0.1", - "zod": "^3.25.74", - "zod-express-middleware": "^1.4.0" + "zod": "^4.0.14" }, "devDependencies": { "@commitlint/cli": "^19.8.1", "@commitlint/config-conventional": "^19.8.1", - "@ianvs/prettier-plugin-sort-imports": "^4.4.2", + "@ianvs/prettier-plugin-sort-imports": "^4.5.1", "@types/cookie-parser": "^1.4.9", "@types/cors": "^2.8.19", "@types/express": "5.0.3", "@types/morgan": "^1.9.10", "@types/multer": "^2.0.0", - "@types/node": "^24.0.10", + "@types/node": "^24.1.0", "@types/nodemailer": "^6.4.17", "@types/swagger-ui-express": "^4.1.8", - "eslint": "^9.30.1", + "eslint": "^9.32.0", "eslint-formatter-mo": "^2.3.0", "globals": "^16.3.0", "husky": "^9.1.7", - "jiti": "^2.4.2", + "jiti": "^2.5.1", "lint-staged": "^16.1.2", "prettier": "^3.6.2", - "prisma": "^6.11.1", + "prisma": "^6.13.0", "ts-node": "^10.9.2", "ts-node-dev": "^2.0.0", "tsc-files": "^1.1.4", "tsconfig-paths": "^4.2.0", - "typescript": "^5.8.3", - "typescript-eslint": "^8.35.1" + "typescript": "^5.9.2", + "typescript-eslint": "^8.38.0" } } diff --git a/yarn.lock b/yarn.lock index db80df8..1e5e261 100644 --- a/yarn.lock +++ b/yarn.lock @@ -264,10 +264,10 @@ resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.3.0.tgz#3e09a90dfb87e0005c7694791e58e97077271286" integrity sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw== -"@eslint/core@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.14.0.tgz#326289380968eaf7e96f364e1e4cf8f3adf2d003" - integrity sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg== +"@eslint/core@^0.15.0", "@eslint/core@^0.15.1": + version "0.15.1" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.15.1.tgz#d530d44209cbfe2f82ef86d6ba08760196dd3b60" + integrity sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA== dependencies: "@types/json-schema" "^7.0.15" @@ -286,22 +286,22 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.30.1": - version "9.30.1" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.30.1.tgz#ebe9dd52a38345784c486300175a28c6013c088d" - integrity sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg== +"@eslint/js@9.32.0": + version "9.32.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.32.0.tgz#a02916f58bd587ea276876cb051b579a3d75d091" + integrity sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg== "@eslint/object-schema@^2.1.6": version "2.1.6" resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f" integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA== -"@eslint/plugin-kit@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz#b71b037b2d4d68396df04a8c35a49481e5593067" - integrity sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w== +"@eslint/plugin-kit@^0.3.4": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz#c6b9f165e94bf4d9fdd493f1c028a94aaf5fc1cc" + integrity sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw== dependencies: - "@eslint/core" "^0.14.0" + "@eslint/core" "^0.15.1" levn "^0.4.1" "@humanfs/core@^0.19.1": @@ -332,10 +332,10 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.2.tgz#1860473de7dfa1546767448f333db80cb0ff2161" integrity sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ== -"@ianvs/prettier-plugin-sort-imports@^4.4.2": - version "4.4.2" - resolved "https://registry.yarnpkg.com/@ianvs/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.4.2.tgz#b4e0fa40249ffe5b80a3d65b294b1c49f0a7757e" - integrity sha512-KkVFy3TLh0OFzimbZglMmORi+vL/i2OFhEs5M07R9w0IwWAGpsNNyE4CY/2u0YoMF5bawKC2+8/fUH60nnNtjw== +"@ianvs/prettier-plugin-sort-imports@^4.5.1": + version "4.5.1" + resolved "https://registry.yarnpkg.com/@ianvs/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.5.1.tgz#9d6063fc327ec71cf14bcfe1e8b31e14f7f47316" + integrity sha512-vOQwIyQHnHz0ikvHEQDzwUkNfX74o/7qNEpm9LiPtyBvCg/AU/DOkhwe1o92chPS1QzS6G7HeiO+OwIt8a358A== dependencies: "@babel/generator" "^7.26.2" "@babel/parser" "^7.26.2" @@ -343,10 +343,10 @@ "@babel/types" "^7.26.0" semver "^7.5.2" -"@ioredis/commands@^1.1.1": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" - integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== +"@ioredis/commands@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.3.0.tgz#4dc3ae9bfa7146b63baf27672a61db0ea86e35e5" + integrity sha512-M/T6Zewn7sDaBQEqIZ8Rb+i9y8qfGmq+5SDFSf9sA2lUZTmdDLVdOiQaeDp+Q4wElZ9HG1GAX5KhDaidp6LQsQ== "@jridgewell/gen-mapping@^0.3.5": version "0.3.8" @@ -414,53 +414,56 @@ resolved "https://registry.yarnpkg.com/@phc/format/-/format-1.0.0.tgz#b5627003b3216dc4362125b13f48a4daa76680e4" integrity sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ== -"@prisma/client@^6.11.1": - version "6.11.1" - resolved "https://registry.yarnpkg.com/@prisma/client/-/client-6.11.1.tgz#ef97454d8b0bb192b26ec4111def83ddee4615e3" - integrity sha512-5CLFh8QP6KxRm83pJ84jaVCeSVPQr8k0L2SEtOJHwdkS57/VQDcI/wQpGmdyOZi+D9gdNabdo8tj1Uk+w+upsQ== - -"@prisma/config@6.11.1": - version "6.11.1" - resolved "https://registry.yarnpkg.com/@prisma/config/-/config-6.11.1.tgz#c0a952d5d30b009fef390371fd359e7b4d55d956" - integrity sha512-z6rCTQN741wxDq82cpdzx2uVykpnQIXalLhrWQSR0jlBVOxCIkz3HZnd8ern3uYTcWKfB3IpVAF7K2FU8t/8AQ== - dependencies: - jiti "2.4.2" - -"@prisma/debug@6.11.1": - version "6.11.1" - resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-6.11.1.tgz#88e912b8a265445d207cc0ce1823fe69cd689a05" - integrity sha512-lWRb/YSWu8l4Yum1UXfGLtqFzZkVS2ygkWYpgkbgMHn9XJlMITIgeMvJyX5GepChzhmxuSuiq/MY/kGFweOpGw== - -"@prisma/engines-version@6.11.1-1.f40f79ec31188888a2e33acda0ecc8fd10a853a9": - version "6.11.1-1.f40f79ec31188888a2e33acda0ecc8fd10a853a9" - resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-6.11.1-1.f40f79ec31188888a2e33acda0ecc8fd10a853a9.tgz#a242978dc1cb09024fc738a40962c70bb81b6b33" - integrity sha512-swFJTOOg4tHyOM1zB/pHb3MeH0i6t7jFKn5l+ZsB23d9AQACuIRo9MouvuKGvnDogzkcjbWnXi/NvOZ0+n5Jfw== - -"@prisma/engines@6.11.1": - version "6.11.1" - resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-6.11.1.tgz#6e8cdc2a90017ceeb8a6b7c3eb6ac397fe794726" - integrity sha512-6eKEcV6V8W2eZAUwX2xTktxqPM4vnx3sxz3SDtpZwjHKpC6lhOtc4vtAtFUuf5+eEqBk+dbJ9Dcaj6uQU+FNNg== - dependencies: - "@prisma/debug" "6.11.1" - "@prisma/engines-version" "6.11.1-1.f40f79ec31188888a2e33acda0ecc8fd10a853a9" - "@prisma/fetch-engine" "6.11.1" - "@prisma/get-platform" "6.11.1" - -"@prisma/fetch-engine@6.11.1": - version "6.11.1" - resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-6.11.1.tgz#796fa38a420f18bd5df6b06eaff77b0f44da80e9" - integrity sha512-NBYzmkXTkj9+LxNPRSndaAeALOL1Gr3tjvgRYNqruIPlZ6/ixLeuE/5boYOewant58tnaYFZ5Ne0jFBPfGXHpQ== - dependencies: - "@prisma/debug" "6.11.1" - "@prisma/engines-version" "6.11.1-1.f40f79ec31188888a2e33acda0ecc8fd10a853a9" - "@prisma/get-platform" "6.11.1" - -"@prisma/get-platform@6.11.1": - version "6.11.1" - resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-6.11.1.tgz#5543da490916b05fdaf880933c6cf29d15b26961" - integrity sha512-b2Z8oV2gwvdCkFemBTFd0x4lsL4O2jLSx8lB7D+XqoFALOQZPa7eAPE1NU0Mj1V8gPHRxIsHnyUNtw2i92psUw== - dependencies: - "@prisma/debug" "6.11.1" +"@prisma/client@^6.13.0": + version "6.13.0" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-6.13.0.tgz#7073ab6ccf10c0c99ab7582e39aa7a1422c6a7db" + integrity sha512-8m2+I3dQovkV8CkDMluiwEV1TxV9EXdT6xaCz39O6jYw7mkf5gwfmi+cL4LJsEPwz5tG7sreBwkRpEMJedGYUQ== + +"@prisma/config@6.13.0": + version "6.13.0" + resolved "https://registry.yarnpkg.com/@prisma/config/-/config-6.13.0.tgz#1cb5a84f082cb2f0c66f173e85c5eb55fbe8ac99" + integrity sha512-OYMM+pcrvj/NqNWCGESSxVG3O7kX6oWuGyvufTUNnDw740KIQvNyA4v0eILgkpuwsKIDU36beZCkUtIt0naTog== + dependencies: + c12 "3.1.0" + deepmerge-ts "7.1.5" + effect "3.16.12" + read-package-up "11.0.0" + +"@prisma/debug@6.13.0": + version "6.13.0" + resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-6.13.0.tgz#3d91b8a8be60c77f790c0ccaa4ef9d8713536c06" + integrity sha512-um+9pfKJW0ihmM83id9FXGi5qEbVJ0Vxi1Gm0xpYsjwUBnw6s2LdPBbrsG9QXRX46K4CLWCTNvskXBup4i9hlw== + +"@prisma/engines-version@6.13.0-35.361e86d0ea4987e9f53a565309b3eed797a6bcbd": + version "6.13.0-35.361e86d0ea4987e9f53a565309b3eed797a6bcbd" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-6.13.0-35.361e86d0ea4987e9f53a565309b3eed797a6bcbd.tgz#e0cee50da9a762af524b56db3dad6dad9e814504" + integrity sha512-MpPyKSzBX7P/ZY9odp9TSegnS/yH3CSbchQE9f0yBg3l2QyN59I6vGXcoYcqKC9VTniS1s18AMmhyr1OWavjHg== + +"@prisma/engines@6.13.0": + version "6.13.0" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-6.13.0.tgz#b55a2912aab2ccc97454c11f7483711c03c7163d" + integrity sha512-D+1B79LFvtWA0KTt8ALekQ6A/glB9w10ETknH5Y9g1k2NYYQOQy93ffiuqLn3Pl6IPJG3EsK/YMROKEaq8KBrA== + dependencies: + "@prisma/debug" "6.13.0" + "@prisma/engines-version" "6.13.0-35.361e86d0ea4987e9f53a565309b3eed797a6bcbd" + "@prisma/fetch-engine" "6.13.0" + "@prisma/get-platform" "6.13.0" + +"@prisma/fetch-engine@6.13.0": + version "6.13.0" + resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-6.13.0.tgz#d4a9406f75b85a1a8dea7d2fa0943055263949e2" + integrity sha512-grmmq+4FeFKmaaytA8Ozc2+Tf3BC8xn/DVJos6LL022mfRlMZYjT3hZM0/xG7+5fO95zFG9CkDUs0m1S2rXs5Q== + dependencies: + "@prisma/debug" "6.13.0" + "@prisma/engines-version" "6.13.0-35.361e86d0ea4987e9f53a565309b3eed797a6bcbd" + "@prisma/get-platform" "6.13.0" + +"@prisma/get-platform@6.13.0": + version "6.13.0" + resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-6.13.0.tgz#b80e1a506555f8796bd748c9bbce93c0fb32f7fd" + integrity sha512-Nii2pX50fY4QKKxQwm7/vvqT6Ku8yYJLZAFX4e2vzHwRdMqjugcOG5hOSLjxqoXb0cvOspV70TOhMzrw8kqAnw== + dependencies: + "@prisma/debug" "6.13.0" "@scarf/scarf@=1.4.0": version "1.4.0" @@ -523,6 +526,11 @@ resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz#a90ab31d0cc1dfb54c66a69e515bf624fa7b2224" integrity sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg== +"@standard-schema/spec@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c" + integrity sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA== + "@tsconfig/node10@^1.0.7": version "1.0.11" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" @@ -660,10 +668,10 @@ dependencies: undici-types "~6.20.0" -"@types/node@^24.0.10": - version "24.0.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.0.10.tgz#f65a169779bf0d70203183a1890be7bee8ca2ddb" - integrity sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA== +"@types/node@^24.1.0": + version "24.1.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.1.0.tgz#0993f7dc31ab5cc402d112315b463e383d68a49c" + integrity sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w== dependencies: undici-types "~7.8.0" @@ -674,6 +682,11 @@ dependencies: "@types/node" "*" +"@types/normalize-package-data@^2.4.3": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== + "@types/qs@*": version "6.9.18" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.18.tgz#877292caa91f7c1b213032b34626505b746624c2" @@ -729,78 +742,79 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c" integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== -"@typescript-eslint/eslint-plugin@8.35.1": - version "8.35.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz#06b1129fe26d6532abd58fb2b3fe9810bd016935" - integrity sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg== +"@typescript-eslint/eslint-plugin@8.38.0": + version "8.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz#6e5220d16f2691ab6d983c1737dd5b36e17641b7" + integrity sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "8.35.1" - "@typescript-eslint/type-utils" "8.35.1" - "@typescript-eslint/utils" "8.35.1" - "@typescript-eslint/visitor-keys" "8.35.1" + "@typescript-eslint/scope-manager" "8.38.0" + "@typescript-eslint/type-utils" "8.38.0" + "@typescript-eslint/utils" "8.38.0" + "@typescript-eslint/visitor-keys" "8.38.0" graphemer "^1.4.0" ignore "^7.0.0" natural-compare "^1.4.0" ts-api-utils "^2.1.0" -"@typescript-eslint/parser@8.35.1": - version "8.35.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.35.1.tgz#787312e80f0f337d85f4c2a569411c469e852d44" - integrity sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w== +"@typescript-eslint/parser@8.38.0": + version "8.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.38.0.tgz#6723a5ea881e1777956b1045cba30be5ea838293" + integrity sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ== dependencies: - "@typescript-eslint/scope-manager" "8.35.1" - "@typescript-eslint/types" "8.35.1" - "@typescript-eslint/typescript-estree" "8.35.1" - "@typescript-eslint/visitor-keys" "8.35.1" + "@typescript-eslint/scope-manager" "8.38.0" + "@typescript-eslint/types" "8.38.0" + "@typescript-eslint/typescript-estree" "8.38.0" + "@typescript-eslint/visitor-keys" "8.38.0" debug "^4.3.4" -"@typescript-eslint/project-service@8.35.1": - version "8.35.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.35.1.tgz#815bb771f2f6c97780e44299434ece3c2e526127" - integrity sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q== +"@typescript-eslint/project-service@8.38.0": + version "8.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.38.0.tgz#4900771f943163027fd7d2020a062892056b5e2f" + integrity sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg== dependencies: - "@typescript-eslint/tsconfig-utils" "^8.35.1" - "@typescript-eslint/types" "^8.35.1" + "@typescript-eslint/tsconfig-utils" "^8.38.0" + "@typescript-eslint/types" "^8.38.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@8.35.1": - version "8.35.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz#b19f9be65c8d1059e88a323a1a6567dbfe0a1a4e" - integrity sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg== +"@typescript-eslint/scope-manager@8.38.0": + version "8.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz#5a0efcb5c9cf6e4121b58f87972f567c69529226" + integrity sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ== dependencies: - "@typescript-eslint/types" "8.35.1" - "@typescript-eslint/visitor-keys" "8.35.1" + "@typescript-eslint/types" "8.38.0" + "@typescript-eslint/visitor-keys" "8.38.0" -"@typescript-eslint/tsconfig-utils@8.35.1", "@typescript-eslint/tsconfig-utils@^8.35.1": - version "8.35.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz#c2db8714c181cc0700216c1a2e3cf55719c58006" - integrity sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ== +"@typescript-eslint/tsconfig-utils@8.38.0", "@typescript-eslint/tsconfig-utils@^8.38.0": + version "8.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz#6de4ce224a779601a8df667db56527255c42c4d0" + integrity sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ== -"@typescript-eslint/type-utils@8.35.1": - version "8.35.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz#4f9a07d6efa0e617a67e1890d28117e68ce154bd" - integrity sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ== +"@typescript-eslint/type-utils@8.38.0": + version "8.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz#a56cd84765fa6ec135fe252b5db61e304403a85b" + integrity sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg== dependencies: - "@typescript-eslint/typescript-estree" "8.35.1" - "@typescript-eslint/utils" "8.35.1" + "@typescript-eslint/types" "8.38.0" + "@typescript-eslint/typescript-estree" "8.38.0" + "@typescript-eslint/utils" "8.38.0" debug "^4.3.4" ts-api-utils "^2.1.0" -"@typescript-eslint/types@8.35.1", "@typescript-eslint/types@^8.35.1": - version "8.35.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.35.1.tgz#4344dcf934495bbf25a9f83a06dd9fe2acf15780" - integrity sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ== +"@typescript-eslint/types@8.38.0", "@typescript-eslint/types@^8.38.0": + version "8.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.38.0.tgz#297351c994976b93c82ac0f0e206c8143aa82529" + integrity sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw== -"@typescript-eslint/typescript-estree@8.35.1": - version "8.35.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz#b80e85fcb6bfbcbacb3224b1367f6ca3f03e6183" - integrity sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g== +"@typescript-eslint/typescript-estree@8.38.0": + version "8.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz#82262199eb6778bba28a319e25ad05b1158957df" + integrity sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ== dependencies: - "@typescript-eslint/project-service" "8.35.1" - "@typescript-eslint/tsconfig-utils" "8.35.1" - "@typescript-eslint/types" "8.35.1" - "@typescript-eslint/visitor-keys" "8.35.1" + "@typescript-eslint/project-service" "8.38.0" + "@typescript-eslint/tsconfig-utils" "8.38.0" + "@typescript-eslint/types" "8.38.0" + "@typescript-eslint/visitor-keys" "8.38.0" debug "^4.3.4" fast-glob "^3.3.2" is-glob "^4.0.3" @@ -808,22 +822,22 @@ semver "^7.6.0" ts-api-utils "^2.1.0" -"@typescript-eslint/utils@8.35.1": - version "8.35.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.35.1.tgz#a9a0ceeb81c9d132f3f75537ad2ca7f6ca266523" - integrity sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ== +"@typescript-eslint/utils@8.38.0": + version "8.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.38.0.tgz#5f10159899d30eb92ba70e642ca6f754bddbf15a" + integrity sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg== dependencies: "@eslint-community/eslint-utils" "^4.7.0" - "@typescript-eslint/scope-manager" "8.35.1" - "@typescript-eslint/types" "8.35.1" - "@typescript-eslint/typescript-estree" "8.35.1" + "@typescript-eslint/scope-manager" "8.38.0" + "@typescript-eslint/types" "8.38.0" + "@typescript-eslint/typescript-estree" "8.38.0" -"@typescript-eslint/visitor-keys@8.35.1": - version "8.35.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz#aac78ab2265dd11927bc6af3f9c5a021bbc1670a" - integrity sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw== +"@typescript-eslint/visitor-keys@8.38.0": + version "8.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz#a9765a527b082cb8fc60fd8a16e47c7ad5b60ea5" + integrity sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g== dependencies: - "@typescript-eslint/types" "8.35.1" + "@typescript-eslint/types" "8.38.0" eslint-visitor-keys "^4.2.1" "@ungap/structured-clone@^1.0.0": @@ -948,13 +962,13 @@ arg@^4.1.0: resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== -argon2@^0.43.0: - version "0.43.0" - resolved "https://registry.yarnpkg.com/argon2/-/argon2-0.43.0.tgz#4a5d8943506923ce7450f4e9069e03e134c7473e" - integrity sha512-u/HKLcbWShVDhkfwI4hWyiUf3qyX8QhTfaIv2cWE18uqhXCmR5hb6Ed7oqYi2KCQegeAnRhiFzbjzm7i5yl1GA== +argon2@^0.43.1: + version "0.43.1" + resolved "https://registry.yarnpkg.com/argon2/-/argon2-0.43.1.tgz#8155ae67fd4ca2a7364364ca3e45e0d8fbbc0ee9" + integrity sha512-TfOzvDWUaQPurCT1hOwIeFNkgrAJDpbBGBGWDgzDsm11nNhImc13WhdGdCU6K7brkp8VpeY07oGtSex0Wmhg8w== dependencies: "@phc/format" "^1.0.0" - node-addon-api "^8.3.1" + node-addon-api "^8.4.0" node-gyp-build "^4.8.4" argparse@^2.0.1: @@ -1053,6 +1067,24 @@ bytes@3.1.2, bytes@^3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +c12@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/c12/-/c12-3.1.0.tgz#9e237970e1d3b74ebae51d25945cb59664c12c89" + integrity sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw== + dependencies: + chokidar "^4.0.3" + confbox "^0.2.2" + defu "^6.1.4" + dotenv "^16.6.1" + exsolve "^1.0.7" + giget "^2.0.0" + jiti "^2.4.2" + ohash "^2.0.11" + pathe "^2.0.3" + perfect-debounce "^1.0.0" + pkg-types "^2.2.0" + rc9 "^2.1.2" + call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" @@ -1117,6 +1149,20 @@ chokidar@^3.5.1: optionalDependencies: fsevents "~2.3.2" +chokidar@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" + integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== + dependencies: + readdirp "^4.0.1" + +citty@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/citty/-/citty-0.1.6.tgz#0f7904da1ed4625e1a9ea7e0fa780981aab7c5e4" + integrity sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ== + dependencies: + consola "^3.2.3" + cli-cursor@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-5.0.0.tgz#24a4831ecf5a6b01ddeb32fb71a4b2088b0dce38" @@ -1204,6 +1250,16 @@ concat-stream@^2.0.0: readable-stream "^3.0.2" typedarray "^0.0.6" +confbox@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.2.2.tgz#8652f53961c74d9e081784beed78555974a9c110" + integrity sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ== + +consola@^3.2.3, consola@^3.4.0, consola@^3.4.2: + version "3.4.2" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.4.2.tgz#5af110145397bb67afdab77013fdc34cae590ea7" + integrity sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA== + content-disposition@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-1.0.0.tgz#844426cb398f934caefcbb172200126bc7ceace2" @@ -1338,6 +1394,16 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deepmerge-ts@7.1.5: + version "7.1.5" + resolved "https://registry.yarnpkg.com/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz#ff818564007f5c150808d2b7b732cac83aa415ab" + integrity sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw== + +defu@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" + integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== + denque@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" @@ -1353,6 +1419,11 @@ dequal@^2.0.0: resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== +destr@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.5.tgz#7d112ff1b925fb8d2079fac5bdb4a90973b51fdb" + integrity sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA== + devlop@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" @@ -1372,10 +1443,15 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" -dotenv@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-17.0.1.tgz#79bc4d232fadb42a4092685ff1206d31b2a43f95" - integrity sha512-GLjkduuAL7IMJg/ZnOPm9AnWKJ82mSE2tzXLaJ/6hD6DhwGfZaXG77oB8qbReyiczNxnbxQKyh0OE5mXq0bAHA== +dotenv@^16.6.1: + version "16.6.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.6.1.tgz#773f0e69527a8315c7285d5ee73c4459d20a8020" + integrity sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow== + +dotenv@^17.2.1: + version "17.2.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-17.2.1.tgz#6f32e10faf014883515538dc922a0fb8765d9b32" + integrity sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ== dunder-proto@^1.0.1: version "1.0.1" @@ -1405,6 +1481,14 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== +effect@3.16.12: + version "3.16.12" + resolved "https://registry.yarnpkg.com/effect/-/effect-3.16.12.tgz#3762f745846cfa4905512e397e17f683438addbe" + integrity sha512-N39iBk0K71F9nb442TLbTkjl24FLUzuvx2i1I2RsEAQsdAdUTuUoW0vlfUXgkMTUOnYqKnWcFfqw4hK4Pw27hg== + dependencies: + "@standard-schema/spec" "^1.0.0" + fast-check "^3.23.1" + emoji-regex-xs@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz#e8af22e5d9dbd7f7f22d280af3d19d2aab5b0724" @@ -1511,19 +1595,19 @@ eslint-visitor-keys@^4.2.1: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1" integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== -eslint@^9.30.1: - version "9.30.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.30.1.tgz#d4107b39964412acd9b5c0744f1c6df514fa1211" - integrity sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ== +eslint@^9.32.0: + version "9.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.32.0.tgz#4ea28df4a8dbc454e1251e0f3aed4bcf4ce50a47" + integrity sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.12.1" "@eslint/config-array" "^0.21.0" "@eslint/config-helpers" "^0.3.0" - "@eslint/core" "^0.14.0" + "@eslint/core" "^0.15.0" "@eslint/eslintrc" "^3.3.1" - "@eslint/js" "9.30.1" - "@eslint/plugin-kit" "^0.3.1" + "@eslint/js" "9.32.0" + "@eslint/plugin-kit" "^0.3.4" "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" "@humanwhocodes/retry" "^0.4.2" @@ -1644,11 +1728,23 @@ express@^5.1.0: type-is "^2.0.1" vary "^1.1.2" +exsolve@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/exsolve/-/exsolve-1.0.7.tgz#3b74e4c7ca5c5f9a19c3626ca857309fa99f9e9e" + integrity sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw== + extend@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +fast-check@^3.23.1: + version "3.23.2" + resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-3.23.2.tgz#0129f1eb7e4f500f58e8290edc83c670e4a574a2" + integrity sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A== + dependencies: + pure-rand "^6.1.0" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -1721,6 +1817,11 @@ finalhandler@^2.1.0: parseurl "^1.3.3" statuses "^2.0.1" +find-up-simple@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/find-up-simple/-/find-up-simple-1.0.1.tgz#18fb90ad49e45252c4d7fca56baade04fa3fca1e" + integrity sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ== + find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -1835,6 +1936,18 @@ get-proto@^1.0.1: dunder-proto "^1.0.1" es-object-atoms "^1.0.0" +giget@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/giget/-/giget-2.0.0.tgz#395fc934a43f9a7a29a29d55b99f23e30c14f195" + integrity sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA== + dependencies: + citty "^0.1.6" + consola "^3.4.0" + defu "^6.1.4" + node-fetch-native "^1.6.6" + nypm "^0.6.0" + pathe "^2.0.3" + git-raw-commits@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-4.0.0.tgz#b212fd2bff9726d27c1283a1157e829490593285" @@ -1892,10 +2005,10 @@ globals@^16.3.0: resolved "https://registry.yarnpkg.com/globals/-/globals-16.3.0.tgz#66118e765ddaf9e2d880f7e17658543f93f1f667" integrity sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ== -google-auth-library@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-10.1.0.tgz#5412fa2b7f2c4fe169c6cc56b9425319137e17e9" - integrity sha512-GspVjZj1RbyRWpQ9FbAXMKjFGzZwDKnUHi66JJ+tcjcu5/xYAP1pdlWotCuIkMwjfVsxxDvsGZXGLzRt72D0sQ== +google-auth-library@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-10.2.0.tgz#cdcee27c6021cf610fde6c1dd9abe85217b1bf6e" + integrity sha512-gy/0hRx8+Ye0HlUm3GrfpR4lbmJQ6bJ7F44DmN7GtMxxzWSojLzx0Bhv/hj7Wlj7a2On0FcT8jrz8Y1c1nxCyg== dependencies: base64-js "^1.3.0" ecdsa-sig-formatter "^1.0.11" @@ -1982,6 +2095,13 @@ helmet@^8.1.0: resolved "https://registry.yarnpkg.com/helmet/-/helmet-8.1.0.tgz#f96d23fedc89e9476ecb5198181009c804b8b38c" integrity sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg== +hosted-git-info@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-7.0.2.tgz#9b751acac097757667f30114607ef7b661ff4f17" + integrity sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w== + dependencies: + lru-cache "^10.0.1" + html-void-elements@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" @@ -2046,6 +2166,11 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== +index-to-position@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/index-to-position/-/index-to-position-1.1.0.tgz#2e50bd54c8040bdd6d9b3d95ec2a8fedf86b4d44" + integrity sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -2064,12 +2189,12 @@ ini@4.1.1: resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.1.tgz#d95b3d843b1e906e56d6747d5447904ff50ce7a1" integrity sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g== -ioredis@^5.6.1: - version "5.6.1" - resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.6.1.tgz#1ed7dc9131081e77342503425afceaf7357ae599" - integrity sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA== +ioredis@^5.7.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.7.0.tgz#be8f4a09bfb67bfa84ead297ff625973a5dcefc3" + integrity sha512-NUcA93i1lukyXU+riqEyPtSEkyFq8tX90uL659J+qpCZ3rEdViB/APC58oAhIh3+bJln2hzdlZbBZsGNrlsR8g== dependencies: - "@ioredis/commands" "^1.1.1" + "@ioredis/commands" "^1.3.0" cluster-key-slot "^1.1.0" debug "^4.3.4" denque "^2.1.0" @@ -2169,15 +2294,20 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -jiti@2.4.2, jiti@^2.4.1, jiti@^2.4.2: +jiti@^2.4.1, jiti@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.4.2.tgz#d19b7732ebb6116b06e2038da74a55366faef560" integrity sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A== -jose@^6.0.11: - version "6.0.11" - resolved "https://registry.yarnpkg.com/jose/-/jose-6.0.11.tgz#0b7ea8b3b21a1bda5e00255a044c3a0e43270882" - integrity sha512-QxG7EaliDARm1O1S8BGakqncGT9s25bKL1WSf6/oa17Tkqwi8D2ZNglqCF+DsYF88/rV66Q/Q2mFAy697E1DUg== +jiti@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.5.1.tgz#bd099c1c2be1c59bbea4e5adcd127363446759d0" + integrity sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w== + +jose@^6.0.12: + version "6.0.12" + resolved "https://registry.yarnpkg.com/jose/-/jose-6.0.12.tgz#56253d94d46bd784addc4bde3691c323552fe7e4" + integrity sha512-T8xypXs8CpmiIi78k0E+Lk7T2zlK4zDyg+o1CZ4AkOHgDg98ogdP2BeZ61lTFKFyoEwJ9RgAgN+SdM3iPgNonQ== js-tokens@^4.0.0: version "4.0.0" @@ -2393,6 +2523,11 @@ log-update@^6.1.0: strip-ansi "^7.1.0" wrap-ansi "^9.0.0" +lru-cache@^10.0.1: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" @@ -2543,16 +2678,16 @@ mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -morgan@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" - integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== +morgan@1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.1.tgz#4e02e6a4465a48e26af540191593955d17f61570" + integrity sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A== dependencies: basic-auth "~2.0.1" debug "2.6.9" depd "~2.0.0" on-finished "~2.3.0" - on-headers "~1.0.2" + on-headers "~1.1.0" ms@2.0.0: version "2.0.0" @@ -2564,10 +2699,10 @@ ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/multer/-/multer-2.0.1.tgz#3ed335ed2b96240e3df9e23780c91cfcf5d29202" - integrity sha512-Ug8bXeTIUlxurg8xLTEskKShvcKDZALo1THEX5E41pYCD2sCVub5/kIRIGqWNoqV6szyLyQKV6mD4QUrWE5GCQ== +multer@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/multer/-/multer-2.0.2.tgz#08a8aa8255865388c387aaf041426b0c87bf58dd" + integrity sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw== dependencies: append-field "^1.0.0" busboy "^1.6.0" @@ -2592,16 +2727,21 @@ negotiator@^1.0.0: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== -node-addon-api@^8.3.1: - version "8.3.1" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.3.1.tgz#53bc8a4f8dbde3de787b9828059da94ba9fd4eed" - integrity sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA== +node-addon-api@^8.4.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.5.0.tgz#c91b2d7682fa457d2e1c388150f0dff9aafb8f3f" + integrity sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A== node-domexception@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== +node-fetch-native@^1.6.6: + version "1.6.6" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.6.tgz#ae1d0e537af35c2c0b0de81cbff37eedd410aa37" + integrity sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ== + node-fetch@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b" @@ -2616,16 +2756,36 @@ node-gyp-build@^4.8.4: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== -nodemailer@^7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-7.0.4.tgz#1204ca673026e93155d4a46eaa7c498a30fdd72a" - integrity sha512-9O00Vh89/Ld2EcVCqJ/etd7u20UhME0f/NToPfArwPEe1Don1zy4mAIz6ariRr7mJ2RDxtaDzN0WJVdVXPtZaw== +nodemailer@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-7.0.5.tgz#3fa6607cab42401e4bedac9297e0aaa9ff84544b" + integrity sha512-nsrh2lO3j4GkLLXoeEksAMgAOqxOv6QumNRVQTJwKH4nuiww6iC2y7GyANs9kRAxCexg3+lTWM3PZ91iLlVjfg== + +normalize-package-data@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-6.0.2.tgz#a7bc22167fe24025412bcff0a9651eb768b03506" + integrity sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g== + dependencies: + hosted-git-info "^7.0.0" + semver "^7.3.5" + validate-npm-package-license "^3.0.4" normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +nypm@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/nypm/-/nypm-0.6.1.tgz#4905b419641073de25ef0f19fb47c5658ada0c35" + integrity sha512-hlacBiRiv1k9hZFiphPUkfSQ/ZfQzZDzC+8z0wL3lvDAOUu/2NnChkKuMoMjNur/9OpKuz2QsIeiPVN0xM5Q0w== + dependencies: + citty "^0.1.6" + consola "^3.4.2" + pathe "^2.0.3" + pkg-types "^2.2.0" + tinyexec "^1.0.1" + object-assign@^4, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2636,6 +2796,11 @@ object-inspect@^1.13.3: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== +ohash@^2.0.11: + version "2.0.11" + resolved "https://registry.yarnpkg.com/ohash/-/ohash-2.0.11.tgz#60b11e8cff62ca9dee88d13747a5baa145f5900b" + integrity sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ== + on-finished@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -2650,10 +2815,10 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== +on-headers@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.1.0.tgz#59da4f91c45f5f989c6e4bcedc5a3b0aed70ff65" + integrity sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A== once@^1.3.0, once@^1.4.0: version "1.4.0" @@ -2735,6 +2900,15 @@ parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse-json@^8.0.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-8.3.0.tgz#88a195a2157025139a2317a4f2f9252b61304ed5" + integrity sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ== + dependencies: + "@babel/code-frame" "^7.26.2" + index-to-position "^1.1.0" + type-fest "^4.39.1" + parseurl@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -2770,6 +2944,16 @@ path-to-regexp@^8.0.0: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-8.2.0.tgz#73990cc29e57a3ff2a0d914095156df5db79e8b4" integrity sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ== +pathe@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716" + integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== + +perfect-debounce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a" + integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA== + picocolors@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" @@ -2785,6 +2969,15 @@ pidtree@^0.6.0: resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== +pkg-types@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-2.2.0.tgz#049bf404f82a66c465200149457acf0c5fb0fb2d" + integrity sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ== + dependencies: + confbox "^0.2.2" + exsolve "^1.0.7" + pathe "^2.0.3" + plur@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/plur/-/plur-5.1.0.tgz#bff58c9f557b9061d60d8ebf93959cf4b08594ae" @@ -2802,13 +2995,13 @@ prettier@^3.6.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.6.2.tgz#ccda02a1003ebbb2bfda6f83a074978f608b9393" integrity sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ== -prisma@^6.11.1: - version "6.11.1" - resolved "https://registry.yarnpkg.com/prisma/-/prisma-6.11.1.tgz#496fde4da3a9fc79ecc95f6a615c3a9025b37e17" - integrity sha512-VzJToRlV0s9Vu2bfqHiRJw73hZNCG/AyJeX+kopbu4GATTjTUdEWUteO3p4BLYoHpMS4o8pD3v6tF44BHNZI1w== +prisma@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-6.13.0.tgz#a1b88c9b9a11e8ffcba12870b9abac04b7d10ae8" + integrity sha512-dfzORf0AbcEyyzxuv2lEwG8g+WRGF/qDQTpHf/6JoHsyF5MyzCEZwClVaEmw3WXcobgadosOboKUgQU0kFs9kw== dependencies: - "@prisma/config" "6.11.1" - "@prisma/engines" "6.11.1" + "@prisma/config" "6.13.0" + "@prisma/engines" "6.13.0" property-information@^7.0.0: version "7.0.0" @@ -2828,6 +3021,11 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== +pure-rand@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" + integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== + q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -2865,6 +3063,34 @@ raw-body@^3.0.0: iconv-lite "0.6.3" unpipe "1.0.0" +rc9@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/rc9/-/rc9-2.1.2.tgz#6282ff638a50caa0a91a31d76af4a0b9cbd1080d" + integrity sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg== + dependencies: + defu "^6.1.4" + destr "^2.0.3" + +read-package-up@11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/read-package-up/-/read-package-up-11.0.0.tgz#71fb879fdaac0e16891e6e666df22de24a48d5ba" + integrity sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ== + dependencies: + find-up-simple "^1.0.0" + read-pkg "^9.0.0" + type-fest "^4.6.0" + +read-pkg@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-9.0.1.tgz#b1b81fb15104f5dbb121b6bbdee9bbc9739f569b" + integrity sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA== + dependencies: + "@types/normalize-package-data" "^2.4.3" + normalize-package-data "^6.0.0" + parse-json "^8.0.0" + type-fest "^4.6.0" + unicorn-magic "^0.1.0" + readable-stream@^3.0.2: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" @@ -2874,6 +3100,11 @@ readable-stream@^3.0.2: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readdirp@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d" + integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg== + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -3000,6 +3231,11 @@ safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +semver@^7.3.5: + version "7.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== + semver@^7.5.2, semver@^7.6.0: version "7.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" @@ -3142,6 +3378,32 @@ space-separated-tokens@^2.0.0: resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.21" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz#6d6e980c9df2b6fc905343a3b2d702a6239536c3" + integrity sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg== + split2@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" @@ -3286,7 +3548,7 @@ tinycolor2@^1.0.0: resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e" integrity sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw== -tinyexec@^1.0.0: +tinyexec@^1.0.0, tinyexec@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.0.1.tgz#70c31ab7abbb4aea0a24f55d120e5990bfa1e0b1" integrity sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw== @@ -3397,6 +3659,11 @@ type-fest@^1.0.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== +type-fest@^4.39.1, type-fest@^4.6.0: + version "4.41.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" + integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== + type-is@^1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -3419,19 +3686,20 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typescript-eslint@^8.35.1: - version "8.35.1" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.35.1.tgz#4ddeda5c5777a7bd86516280d8099ada06055f2f" - integrity sha512-xslJjFzhOmHYQzSB/QTeASAHbjmxOGEP6Coh93TXmUBFQoJ1VU35UHIDmG06Jd6taf3wqqC1ntBnCMeymy5Ovw== +typescript-eslint@^8.38.0: + version "8.38.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.38.0.tgz#e73af7618139f07b16e2fae715eedaabb41ee8b0" + integrity sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg== dependencies: - "@typescript-eslint/eslint-plugin" "8.35.1" - "@typescript-eslint/parser" "8.35.1" - "@typescript-eslint/utils" "8.35.1" + "@typescript-eslint/eslint-plugin" "8.38.0" + "@typescript-eslint/parser" "8.38.0" + "@typescript-eslint/typescript-estree" "8.38.0" + "@typescript-eslint/utils" "8.38.0" -typescript@^5.8.3: - version "5.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" - integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== +typescript@^5.9.2: + version "5.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" + integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== undici-types@~6.20.0: version "6.20.0" @@ -3508,6 +3776,14 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== +validate-npm-package-license@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + vary@^1, vary@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -3617,15 +3893,10 @@ yocto-queue@^1.0.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.1.tgz#36d7c4739f775b3cbc28e6136e21aa057adec418" integrity sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg== -zod-express-middleware@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/zod-express-middleware/-/zod-express-middleware-1.4.0.tgz#6ee1e5854d6f339c3bd3d562ab523d281621bc56" - integrity sha512-C1pBbwbuotitG1L3I1cr9QD/nuepHAdZEUbVn7y1o2cJq0oaUuS7gTVGby1+DGHL4t2P4eEZKCX0QQDv6hEs3A== - -zod@^3.25.74: - version "3.25.74" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.74.tgz#9368a3986fe756bd94b9a5baad9919660ff3f250" - integrity sha512-J8poo92VuhKjNknViHRAIuuN6li/EwFbAC8OedzI8uxpEPGiXHGQu9wemIAioIpqgfB4SySaJhdk0mH5Y4ICBg== +zod@^4.0.14: + version "4.0.14" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.0.14.tgz#cc3a0a21981e63e0f99c0f4f1decd92ec3be7e9f" + integrity sha512-nGFJTnJN6cM2v9kXL+SOBq3AtjQby3Mv5ySGFof5UGRHrRioSJ5iG680cYNjE/yWk671nROcpPj4hAS8nyLhSw== zwitch@^2.0.4: version "2.0.4" From f389c34fb32e111c37dd5b8c65a4ca6fc8ff56d6 Mon Sep 17 00:00:00 2001 From: chertik77 Date: Fri, 1 Aug 2025 14:17:27 +0100 Subject: [PATCH 3/6] chore: update swagger --- swagger.json | 79 +++++++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/swagger.json b/swagger.json index 0bb340f..2c220bb 100644 --- a/swagger.json +++ b/swagger.json @@ -87,40 +87,53 @@ } } }, - "/auth/google/initiate": { - "get": { + "/auth/google/redirect": { + "post": { "tags": ["Auth"], - "summary": "Get redirect url for Google authentication", + "summary": "Redirects the user to the Google consent screen", "responses": { - "200": { "$ref": "#/components/responses/GoogleInitiateResponse" } + "302": { + "description": "Redirects to Google's authentication URL.", + "headers": { + "Location": { + "description": "The URL to which the client should be redirected for Google authentication.", + "schema": { + "type": "string", + "format": "uri", + "example": "https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=profile%20email&response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI" + } + } + } + } } } }, "/auth/google/callback": { - "post": { + "get": { "tags": ["Auth"], - "summary": "Handle Google OAuth callback and sign-in/sign-up", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": ["code", "state"], - "properties": { - "code": { - "type": "string", - "example": "4/0AT5xKif_S_..." - }, - "state": { - "type": "string", - "example": "1d73efc8d4f8d426a3e51f6337ee7cb7" - } - } - } + "summary": "Receives the authorization code from Google's redirect", + "parameters": [ + { + "name": "code", + "in": "query", + "required": true, + "description": "The authorization code provided by Google.", + "schema": { + "type": "string", + "example": "4/0AT5xKif_S_..." + } + }, + { + "name": "state", + "in": "query", + "required": false, + "description": "An opaque value used to maintain state between the request and callback.", + "schema": { + "type": "string", + "example": "4552c8890bb4d9d44e971653..." } } - }, + ], "responses": { "200": { "$ref": "#/components/responses/GoogleResponse" }, "400": { "$ref": "#/components/responses/BadRequestError" }, @@ -995,22 +1008,6 @@ } } }, - "GoogleInitiateResponse": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "redirectUrl": { - "type": "string", - "format": "url", - "example": "https://accounts.google.com/o/oauth2/v2/auth?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=email%20profile&access_type=offline" - } - } - } - } - } - }, "GoogleResponse": { "content": { "application/json": { From 7d57da58a2abf8846328cebe0cc82330f8d5cba1 Mon Sep 17 00:00:00 2001 From: chertik77 Date: Fri, 1 Aug 2025 14:29:31 +0100 Subject: [PATCH 4/6] fix: minor updates & improvements --- app/config/default-user-avatars.config.ts | 9 ++++++ app/config/index.ts | 1 + app/controllers/auth.controller.ts | 31 ++++++++++--------- .../user-with-default-avatar.extension.ts | 8 +---- app/schemas/auth.schema.ts | 2 +- 5 files changed, 28 insertions(+), 23 deletions(-) create mode 100644 app/config/default-user-avatars.config.ts diff --git a/app/config/default-user-avatars.config.ts b/app/config/default-user-avatars.config.ts new file mode 100644 index 0000000..df7b400 --- /dev/null +++ b/app/config/default-user-avatars.config.ts @@ -0,0 +1,9 @@ +import type { Theme } from '@prisma/client' + +export const defaultUserAvatars: Record = { + light: + 'https://res.cloudinary.com/dmbnnewoy/image/upload/v1706958682/TaskPro/user_avatar_default/user_light.png', + dark: 'https://res.cloudinary.com/dmbnnewoy/image/upload/v1706958682/TaskPro/user_avatar_default/user_dark.png', + violet: + 'https://res.cloudinary.com/dmbnnewoy/image/upload/v1706958682/TaskPro/user_avatar_default/user_violet.png' +} diff --git a/app/config/index.ts b/app/config/index.ts index c8f3fa8..5eb408f 100644 --- a/app/config/index.ts +++ b/app/config/index.ts @@ -2,3 +2,4 @@ export { transport } from './mailer.config' export { default } from './cloudinary.config' export { env } from './env.config' export { redisClient } from './redis.config' +export { defaultUserAvatars } from './default-user-avatars.config' diff --git a/app/controllers/auth.controller.ts b/app/controllers/auth.controller.ts index 769e3e1..a28ff0e 100644 --- a/app/controllers/auth.controller.ts +++ b/app/controllers/auth.controller.ts @@ -10,7 +10,7 @@ import { Conflict, Forbidden, Unauthorized } from 'http-errors' import { jwtVerify, SignJWT } from 'jose' import { JWTExpired } from 'jose/errors' -import { env, redisClient } from '@/config' +import { defaultUserAvatars, env, redisClient } from '@/config' const { ACCESS_JWT_EXPIRES_IN, @@ -120,12 +120,14 @@ class AuthController { ) => { const { code, state: receivedState } = req.query - const redisStateKey = `oauth_state:${receivedState}` + if (receivedState) { + const redisStateKey = `oauth_state:${receivedState}` - const storedState = await redisClient.get(redisStateKey) + const storedState = await redisClient.get(redisStateKey) - if (storedState) { - await redisClient.del(redisStateKey) + if (storedState) { + await redisClient.del(redisStateKey) + } } const { tokens } = await this.googleClient.getToken(code) @@ -133,25 +135,24 @@ class AuthController { if (!tokens.id_token) return next(Forbidden()) const ticket = await this.googleClient.verifyIdToken({ - idToken: tokens.id_token, - audience: GOOGLE_CLIENT_ID + idToken: tokens.id_token }) const payload = ticket.getPayload() - if (!payload || !payload.email || !payload.name || !payload.picture) { - return next(Forbidden('Invalid token')) - } + if (!payload || !payload.email) return next(Forbidden('Invalid token')) - const { name, email, picture } = payload + const { + email, + name = 'Guest', + picture = defaultUserAvatars.light + } = payload - const user = await prisma.user.findUnique({ - where: { email } - }) + const user = await prisma.user.findUnique({ where: { email } }) if (!user) { const user = await prisma.user.create({ - data: { name, email, avatar: picture } + data: { email, name, avatar: picture } }) const newSession = await prisma.session.create({ diff --git a/app/prisma/extensions/user-with-default-avatar.extension.ts b/app/prisma/extensions/user-with-default-avatar.extension.ts index 73ecbd4..4561d49 100644 --- a/app/prisma/extensions/user-with-default-avatar.extension.ts +++ b/app/prisma/extensions/user-with-default-avatar.extension.ts @@ -1,12 +1,6 @@ import { Prisma } from '@prisma/client' -const defaultUserAvatars = { - light: - 'https://res.cloudinary.com/dmbnnewoy/image/upload/v1706958682/TaskPro/user_avatar_default/user_light.png', - dark: 'https://res.cloudinary.com/dmbnnewoy/image/upload/v1706958682/TaskPro/user_avatar_default/user_dark.png', - violet: - 'https://res.cloudinary.com/dmbnnewoy/image/upload/v1706958682/TaskPro/user_avatar_default/user_violet.png' -} +import { defaultUserAvatars } from '@/config' export const userWithDefaultAvatar = Prisma.defineExtension(client => client.$extends({ diff --git a/app/schemas/auth.schema.ts b/app/schemas/auth.schema.ts index 1aff9c0..c600159 100644 --- a/app/schemas/auth.schema.ts +++ b/app/schemas/auth.schema.ts @@ -15,5 +15,5 @@ export const SignupSchema = z.object({ export const GoogleCodeSchema = z.object({ code: z.string().min(1, 'Code is required'), - state: z.string().min(1, 'State is required') + state: z.optional(z.string()) }) From 2d3e6576c871117b5ddfe7788c19a5fec648b4a7 Mon Sep 17 00:00:00 2001 From: chertik77 Date: Fri, 1 Aug 2025 16:49:52 +0100 Subject: [PATCH 5/6] fix: update google auth --- app/controllers/auth.controller.ts | 4 ++-- app/routes/api/auth.ts | 2 +- swagger.json | 34 +++++++++++++++++------------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/app/controllers/auth.controller.ts b/app/controllers/auth.controller.ts index a28ff0e..cd159f9 100644 --- a/app/controllers/auth.controller.ts +++ b/app/controllers/auth.controller.ts @@ -99,7 +99,7 @@ class AuthController { res.json({ user: userWithoutPassword }) } - googleRedirect = async (_: Request, res: Response) => { + googleInitiate = async (_: Request, res: Response) => { const state = crypto.randomBytes(32).toString('hex') await redisClient.set(`oauth_state:${state}`, 'true', 'EX', 5 * 60) @@ -110,7 +110,7 @@ class AuthController { scope: ['profile', 'email'] }) - res.redirect(url) + res.json({ redirectUrl: url }) } googleCallback = async ( diff --git a/app/routes/api/auth.ts b/app/routes/api/auth.ts index bd18b3c..1fd994d 100644 --- a/app/routes/api/auth.ts +++ b/app/routes/api/auth.ts @@ -21,7 +21,7 @@ authRouter.post( authController.signin ) -authRouter.post('/google/redirect', authController.googleRedirect) +authRouter.post('/google/initiate', authController.googleInitiate) authRouter.get( '/google/callback', diff --git a/swagger.json b/swagger.json index 2c220bb..fbf60c7 100644 --- a/swagger.json +++ b/swagger.json @@ -87,24 +87,12 @@ } } }, - "/auth/google/redirect": { + "/auth/google/initiate": { "post": { "tags": ["Auth"], - "summary": "Redirects the user to the Google consent screen", + "summary": "Get redirect url for Google authentication", "responses": { - "302": { - "description": "Redirects to Google's authentication URL.", - "headers": { - "Location": { - "description": "The URL to which the client should be redirected for Google authentication.", - "schema": { - "type": "string", - "format": "uri", - "example": "https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=profile%20email&response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI" - } - } - } - } + "200": { "$ref": "#/components/responses/GoogleInitiateResponse" } } } }, @@ -1008,6 +996,22 @@ } } }, + "GoogleInitiateResponse": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "redirectUrl": { + "type": "string", + "format": "url", + "example": "https://accounts.google.com/o/oauth2/v2/auth?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=email%20profile&access_type=offline" + } + } + } + } + } + }, "GoogleResponse": { "content": { "application/json": { From b0aadb292cc6ba88138211d152b73fa9736effbf Mon Sep 17 00:00:00 2001 From: chertik77 Date: Fri, 1 Aug 2025 18:33:50 +0100 Subject: [PATCH 6/6] fix: minor updates & improvements --- app/app.ts | 1 - app/middlewares/index.ts | 1 - app/middlewares/limiter.ts | 18 ------------------ package.json | 2 -- yarn.lock | 17 ----------------- 5 files changed, 39 deletions(-) delete mode 100644 app/middlewares/limiter.ts diff --git a/app/app.ts b/app/app.ts index d41bca0..dac49e1 100644 --- a/app/app.ts +++ b/app/app.ts @@ -12,7 +12,6 @@ export const app = express() app.use(helmet()) app.use(cors({ origin: env.ALLOWED_ORIGINS, credentials: true })) -// app.use(globalLimiter) app.use(logger(env.NODE_ENV === 'development' ? 'dev' : 'combined')) app.use(cookieParser()) app.use(express.json()) diff --git a/app/middlewares/index.ts b/app/middlewares/index.ts index e8713da..afb6da8 100644 --- a/app/middlewares/index.ts +++ b/app/middlewares/index.ts @@ -1,5 +1,4 @@ export { authenticate } from './authenticate' export { upload } from './multer' -export { globalLimiter } from './limiter' export { validateRequest } from './validate-request' export { notFoundHandler, globalErrorHandler } from './errorHandler' diff --git a/app/middlewares/limiter.ts b/app/middlewares/limiter.ts deleted file mode 100644 index 4116dd8..0000000 --- a/app/middlewares/limiter.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { RedisReply } from 'rate-limit-redis' - -import rateLimit from 'express-rate-limit' -import RedisStore from 'rate-limit-redis' - -import { redisClient } from '@/config' - -export const globalLimiter = rateLimit({ - windowMs: 15 * 60 * 1000, - max: 100, - message: 'Too many requests from this IP, please try again after 15 minutes', - standardHeaders: true, - legacyHeaders: false, - store: new RedisStore({ - sendCommand: (command: string, ...args: string[]) => - redisClient.call(command, ...args) as Promise - }) -}) diff --git a/package.json b/package.json index 05e6149..77a1829 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "cors": "2.8.5", "dotenv": "^17.2.1", "express": "^5.1.0", - "express-rate-limit": "^8.0.1", "google-auth-library": "^10.2.0", "helmet": "^8.1.0", "http-errors": "^2.0.0", @@ -33,7 +32,6 @@ "morgan": "1.10.1", "multer": "^2.0.2", "nodemailer": "^7.0.5", - "rate-limit-redis": "^4.2.1", "swagger-ui-express": "^5.0.1", "zod": "^4.0.14" }, diff --git a/yarn.lock b/yarn.lock index 1e5e261..563ad23 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1688,13 +1688,6 @@ eventemitter3@^5.0.1: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== -express-rate-limit@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-8.0.1.tgz#3bc13aaf9f448085686180ef60679a68ea89654d" - integrity sha512-aZVCnybn7TVmxO4BtlmnvX+nuz8qHW124KKJ8dumsBsmv5ZLxE0pYu7S2nwyRBGHHCAzdmnGyrc5U/rksSPO7Q== - dependencies: - ip-address "10.0.1" - express@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/express/-/express-5.1.0.tgz#d31beaf715a0016f0d53f47d3b4d7acf28c75cc9" @@ -2204,11 +2197,6 @@ ioredis@^5.7.0: redis-parser "^3.0.0" standard-as-callback "^2.1.0" -ip-address@10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.0.1.tgz#a8180b783ce7788777d796286d61bce4276818ed" - integrity sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA== - ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -3048,11 +3036,6 @@ range-parser@^1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -rate-limit-redis@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/rate-limit-redis/-/rate-limit-redis-4.2.1.tgz#ab753706f4727fddc08742cfa7600d07d943abc7" - integrity sha512-JsUsVmRVI6G/XrlYtfGV1NMCbGS/CVYayHkxD5Ism5FaL8qpFHCXbFkUeIi5WJ/onJOKWCgtB/xtCLa6qSXb4g== - raw-body@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-3.0.0.tgz#25b3476f07a51600619dae3fe82ddc28a36e5e0f"