chore: cleanup

This commit is contained in:
Kakious 2024-10-15 23:36:15 -04:00
parent 9df9e15953
commit 53393daba3
30 changed files with 334 additions and 184 deletions

View file

0
.github/workflows/release.yml vendored Normal file
View file

View file

@ -1,58 +1,39 @@
# base environment # Setup Base Env
FROM node:22.4.1-alpine3.20 AS base-stage FROM node:20.18.0-alpine3.20 AS base
RUN mkdir /app && chown -R node:node /app
WORKDIR /app
ENV PNPM_HOME="/pnpm" ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH" ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable RUN corepack enable
COPY . /app
WORKDIR /app
# dependency environment # Install Prod Dependencies
FROM base-stage AS dependency-stage FROM base AS prod-deps
USER node RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install typia ts-patch -g
COPY --link --chown=1000:1000 package*.json pnpm-lock.yaml ./ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
# Install all Dependencies
FROM base AS all-deps
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
# test stage to stop at for testing
FROM dependency-stage AS all-source-stage
COPY --link --chown=1000:1000 . .
# lint # lint
FROM all-source-stage AS lint FROM all-deps AS lint
RUN npm run lint -- --no-fix RUN npm run lint -- --no-fix
# test-e2e
FROM all-source-stage AS test-e2e
USER root
RUN mkdir /keys
USER node
RUN --mount=type=secret,id=cookies,target=/keys/cookies.json,uid=1000,gid=1000,required=true \
--mount=type=secret,id=jwks,target=/keys/jwks.json,uid=1000,gid=1000,required=true \
npm run test:e2e:cov -- --ci --json --testLocationInResults --outputFile=/tmp/report.json
# Just the e2e report file #Build the app
FROM scratch AS test-stage FROM all-deps AS build
COPY --link --from=test-e2e /tmp/report.json / RUN pnpm run build
# build environment
FROM dependency-stage AS build-stage
COPY --link --chown=1000:1000 . .
RUN npm run build
# prod dependency environment #Build final image
FROM build-stage AS production-dependency-stage FROM base
RUN npm prune --production
# production environment
FROM base-stage AS production-stage
RUN apk add --no-cache tini RUN apk add --no-cache tini
USER node COPY --from=prod-deps /app/node_modules /app/node_modules
COPY --from=build /app/dist /app/dist
COPY --link --chown=1000:1000 --from=production-dependency-stage /app /app
ENV NODE_ENV=production ENV NODE_ENV=production
EXPOSE 3000
ENTRYPOINT ["/sbin/tini", "--"] ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "/app/.dist/src/main.js"] CMD ["node", "/app/dist/main.js"]
ARG VERSION ARG VERSION
ENV VERSION=${VERSION} ENV VERSION=${VERSION}

View file

@ -16,5 +16,18 @@ services:
restart: unless-stopped restart: unless-stopped
ports: ports:
- "6379:6379" - "6379:6379"
waterwolf-auth:
build: .
restart: unless-stopped
ports:
- "3000:3000"
depends_on:
- mysql
- redis
env_file:
- .env
volumes:
- ./keys:/keys
volumes: volumes:
mysql-data: mysql-data:

View file

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -7,30 +8,48 @@
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<style> <style>
body { body {
background-color: #f3f4f6; /* Tailwind class 'bg-gray-100' */ background-color: #f3f4f6;
/* Tailwind class 'bg-gray-100' */
} }
.container { .container {
max-width: 28rem; /* Tailwind class 'max-w-md' */ max-width: 28rem;
margin: 2rem auto; /* Tailwind classes 'mx-auto' 'mt-8' */ /* Tailwind class 'max-w-md' */
padding: 1.5rem; /* Tailwind class 'p-6' */ margin: 2rem auto;
background-color: #ffffff; /* Tailwind class 'bg-white' */ /* Tailwind classes 'mx-auto' 'mt-8' */
border-radius: 0.5rem; /* Tailwind class 'rounded-lg' */ padding: 1.5rem;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* Tailwind class 'shadow-md' */ /* Tailwind class 'p-6' */
background-color: #ffffff;
/* Tailwind class 'bg-white' */
border-radius: 0.5rem;
/* Tailwind class 'rounded-lg' */
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
/* Tailwind class 'shadow-md' */
} }
.button { .button {
display: inline-block; display: inline-block;
background-color: #6366f1; /* Tailwind class 'bg-indigo-600' */ background-color: #1b92c9d1;
color: #ffffff; /* Tailwind class 'text-white' */ /* Tailwind class 'bg-indigo-600' */
font-weight: 700; /* Tailwind class 'font-bold' */ color: #ffffff;
padding: 0.5rem 1rem; /* Tailwind classes 'py-2' and 'px-4' */ /* Tailwind class 'text-white' */
border-radius: 0.375rem; /* Tailwind class 'rounded-md' */ font-weight: 700;
text-decoration: none; /* Remove underline for links */ /* Tailwind class 'font-bold' */
padding: 0.5rem 1rem;
/* Tailwind classes 'py-2' and 'px-4' */
border-radius: 0.375rem;
/* Tailwind class 'rounded-md' */
text-decoration: none;
/* Remove underline for links */
} }
.button:hover { .button:hover {
background-color: #4f46e5; /* Tailwind class 'hover:bg-indigo-700' */ background-color: #4f46e5;
/* Tailwind class 'hover:bg-indigo-700' */
} }
</style> </style>
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<h1 class="text-2xl font-semibold text-gray-800">Verify Your Email Address</h1> <h1 class="text-2xl font-semibold text-gray-800">Verify Your Email Address</h1>
@ -58,7 +77,8 @@
</style> </style>
<g id="svg"> <g id="svg">
<g id="svgg"> <g id="svgg">
<path id="path0" class="cls-1" d="M87.69,1.22C25.89,11.33-13.11,71.52,4.06,130.27c2.91,9.95,2.81,9.92,5.07,1.07,1.11-4.32,2.34-8.7,2.74-9.73.5-1.27.5-3.66,0-7.51C1.85,36.65,88.31-16.64,153.44,26.86c67.68,45.2,44.99,151.23-35.36,165.24-10.87,1.9-10.31,2.09-18.71-6.25-8.16-8.1-8-8.17-4.75,2.22l1.64,5.26-4.77-.51c-7.24-.77-18.02-3.71-19.82-5.4-4.91-4.61-8.76-19.09-9.26-34.81-.18-5.6-.57-10.2-.87-10.23-3.89-.28-13.29,4.17-19.89,9.41-5.97,4.74-6.02,4.7-3.91-3.57,6.93-27.13,27.84-54.82,50.35-66.66l5.01-2.64-2.73-.51c-1.5-.28-5.67-.35-9.26-.14l-6.53.37,6.83-3.43c7.96-4,14.12-6.14,20.87-7.26,2.77-.46,4.82-1.16,4.82-1.64,0-3,19.12-26.83,21.52-26.83.35,0,.43,3.27.19,7.33-.55,9.09-.71,8.86,10.82,15.24,10.14,5.61,11.94,7.09,11.65,9.57-.35,3.02-2.34,2.57-4.44-1-2.17-3.7-4.25-4.99-9.58-5.96-4.45-.81-4.68-.56-3.68,3.9,1.24,5.55,4.55,7.99,13.36,9.85,10.08,2.14,26.65,9.16,26.14,11.07-.19.73.21,2.18.9,3.22,1.2,1.82,1.19,1.98-.18,3.83-4.8,6.48-11.34,7.82-18.59,3.82-15.61-8.62-25.89-12.19-36.77-12.79-10.3-.56-18.56,1.78-10.29,2.91,3.9.54,7.97,2.52,10.33,5.05l1.73,1.86h-3.52c-23.99.1-42.29,20.92-37.02,42.13,1.83,7.37,6.88,16.46,13.12,23.61,2.46,2.82,2.6,2.69,1.05-1.03-4.13-9.89-2.1-27.31,4-34.25,4.43-5.04,4.84-4.83,4.44,2.3-1.22,21.5,13.44,35.47,40.58,38.67,4.98.59,5.26.26,1.59-1.84-14.85-8.47-26.07-27.76-23.68-40.69,2.92-15.8,12.63-21.34,34.29-19.56l10.56.87,3.15-1.84c7.55-4.42,17.35-15.45,15.44-17.36-.58-.58-6.99-3.62-14.23-6.75l-13.18-5.69-.36-4.47c-.44-5.58-.41-5.53-6.84-9.87-4.85-3.27-5.31-3.79-5.31-6,0-6.16-3.48-18.85-4.93-17.96-.37.23-.9,3.95-1.18,8.27-.52,8.03-1.12,9.27-3.25,6.71-.68-.82-.96-3.68-.98-9.93-.03-9.38-.86-11.79-4.09-11.79-5.02,0-19.77,11.77-29.26,23.35-1.53,1.87-3.02,2.57-8.57,4.05-21.98,5.85-51.41,23.66-59.59,36.06-2.69,4.07-2.28,4.17,3.95.94,12.69-6.58,26.23-10.86,19.26-6.1-20.43,13.98-33.21,37.15-37.46,67.92-1.03,7.47,22.04,28.83,40.44,37.46,76.3,35.75,160.95-30.76,143.93-113.09C191.73,29.3,139.44-7.25,87.69,1.22"/> <path id="path0" class="cls-1"
d="M87.69,1.22C25.89,11.33-13.11,71.52,4.06,130.27c2.91,9.95,2.81,9.92,5.07,1.07,1.11-4.32,2.34-8.7,2.74-9.73.5-1.27.5-3.66,0-7.51C1.85,36.65,88.31-16.64,153.44,26.86c67.68,45.2,44.99,151.23-35.36,165.24-10.87,1.9-10.31,2.09-18.71-6.25-8.16-8.1-8-8.17-4.75,2.22l1.64,5.26-4.77-.51c-7.24-.77-18.02-3.71-19.82-5.4-4.91-4.61-8.76-19.09-9.26-34.81-.18-5.6-.57-10.2-.87-10.23-3.89-.28-13.29,4.17-19.89,9.41-5.97,4.74-6.02,4.7-3.91-3.57,6.93-27.13,27.84-54.82,50.35-66.66l5.01-2.64-2.73-.51c-1.5-.28-5.67-.35-9.26-.14l-6.53.37,6.83-3.43c7.96-4,14.12-6.14,20.87-7.26,2.77-.46,4.82-1.16,4.82-1.64,0-3,19.12-26.83,21.52-26.83.35,0,.43,3.27.19,7.33-.55,9.09-.71,8.86,10.82,15.24,10.14,5.61,11.94,7.09,11.65,9.57-.35,3.02-2.34,2.57-4.44-1-2.17-3.7-4.25-4.99-9.58-5.96-4.45-.81-4.68-.56-3.68,3.9,1.24,5.55,4.55,7.99,13.36,9.85,10.08,2.14,26.65,9.16,26.14,11.07-.19.73.21,2.18.9,3.22,1.2,1.82,1.19,1.98-.18,3.83-4.8,6.48-11.34,7.82-18.59,3.82-15.61-8.62-25.89-12.19-36.77-12.79-10.3-.56-18.56,1.78-10.29,2.91,3.9.54,7.97,2.52,10.33,5.05l1.73,1.86h-3.52c-23.99.1-42.29,20.92-37.02,42.13,1.83,7.37,6.88,16.46,13.12,23.61,2.46,2.82,2.6,2.69,1.05-1.03-4.13-9.89-2.1-27.31,4-34.25,4.43-5.04,4.84-4.83,4.44,2.3-1.22,21.5,13.44,35.47,40.58,38.67,4.98.59,5.26.26,1.59-1.84-14.85-8.47-26.07-27.76-23.68-40.69,2.92-15.8,12.63-21.34,34.29-19.56l10.56.87,3.15-1.84c7.55-4.42,17.35-15.45,15.44-17.36-.58-.58-6.99-3.62-14.23-6.75l-13.18-5.69-.36-4.47c-.44-5.58-.41-5.53-6.84-9.87-4.85-3.27-5.31-3.79-5.31-6,0-6.16-3.48-18.85-4.93-17.96-.37.23-.9,3.95-1.18,8.27-.52,8.03-1.12,9.27-3.25,6.71-.68-.82-.96-3.68-.98-9.93-.03-9.38-.86-11.79-4.09-11.79-5.02,0-19.77,11.77-29.26,23.35-1.53,1.87-3.02,2.57-8.57,4.05-21.98,5.85-51.41,23.66-59.59,36.06-2.69,4.07-2.28,4.17,3.95.94,12.69-6.58,26.23-10.86,19.26-6.1-20.43,13.98-33.21,37.15-37.46,67.92-1.03,7.47,22.04,28.83,40.44,37.46,76.3,35.75,160.95-30.76,143.93-113.09C191.73,29.3,139.44-7.25,87.69,1.22" />
</g> </g>
</g> </g>
</svg> </svg>
@ -66,4 +86,5 @@
</div> </div>
</div> </div>
</body> </body>
</html> </html>

View file

@ -34,10 +34,10 @@ importers:
version: 7.4.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2) version: 7.4.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)
'@nestjs/terminus': '@nestjs/terminus':
specifier: ^10.2.3 specifier: ^10.2.3
version: 10.2.3(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/typeorm@10.0.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))) version: 10.2.3(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/typeorm@10.0.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)))
'@nestjs/typeorm': '@nestjs/typeorm':
specifier: ^10.0.2 specifier: ^10.0.2
version: 10.0.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))) version: 10.0.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)))
'@opentelemetry/api': '@opentelemetry/api':
specifier: ^1.9.0 specifier: ^1.9.0
version: 1.9.0 version: 1.9.0
@ -85,7 +85,7 @@ importers:
version: 6.1.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1)) version: 6.1.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))
nestjs-postal-client: nestjs-postal-client:
specifier: ^0.0.6 specifier: ^0.0.6
version: 0.0.6(jrcpsu45e3dhzjv3azmojl75yy) version: 0.0.6(jdf445rhtpddlny4lqmttufnfe)
oidc-provider: oidc-provider:
specifier: ^8.5.1 specifier: ^8.5.1
version: 8.5.1 version: 8.5.1
@ -103,10 +103,10 @@ importers:
version: 7.8.1 version: 7.8.1
typeorm: typeorm:
specifier: ^0.3.20 specifier: ^0.3.20
version: 0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) version: 0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
typia: typia:
specifier: ^6.11.2 specifier: ^6.11.2
version: 6.11.2(typescript@5.6.3) version: 6.11.2(typescript@5.6.2)
uuid: uuid:
specifier: ^10.0.0 specifier: ^10.0.0
version: 10.0.0 version: 10.0.0
@ -119,7 +119,7 @@ importers:
version: 10.4.5 version: 10.4.5
'@nestjs/schematics': '@nestjs/schematics':
specifier: ^10.1.4 specifier: ^10.1.4
version: 10.1.4(chokidar@3.6.0)(typescript@5.6.3) version: 10.1.4(chokidar@3.6.0)(typescript@5.6.2)
'@nestjs/testing': '@nestjs/testing':
specifier: ^10.4.4 specifier: ^10.4.4
version: 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4)) version: 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4))
@ -146,10 +146,10 @@ importers:
version: 6.0.2 version: 6.0.2
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: ^7.18.0 specifier: ^7.18.0
version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2)
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: ^7.18.0 specifier: ^7.18.0
version: 7.18.0(eslint@8.57.1)(typescript@5.6.3) version: 7.18.0(eslint@8.57.1)(typescript@5.6.2)
eslint: eslint:
specifier: ^8.57.1 specifier: ^8.57.1
version: 8.57.1 version: 8.57.1
@ -161,7 +161,7 @@ importers:
version: 5.2.1(@types/eslint@9.6.0)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3) version: 5.2.1(@types/eslint@9.6.0)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3)
jest: jest:
specifier: ^29.7.0 specifier: ^29.7.0
version: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) version: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
prettier: prettier:
specifier: ^3.3.3 specifier: ^3.3.3
version: 3.3.3 version: 3.3.3
@ -176,16 +176,16 @@ importers:
version: 7.0.0 version: 7.0.0
tailwindcss: tailwindcss:
specifier: ^3.4.14 specifier: ^3.4.14
version: 3.4.14(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) version: 3.4.14(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
ts-jest: ts-jest:
specifier: ^29.2.5 specifier: ^29.2.5
version: 29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))(typescript@5.6.3) version: 29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)))(typescript@5.6.2)
ts-loader: ts-loader:
specifier: ^9.5.1 specifier: ^9.5.1
version: 9.5.1(typescript@5.6.3)(webpack@5.94.0) version: 9.5.1(typescript@5.6.2)(webpack@5.94.0)
ts-node: ts-node:
specifier: ^10.9.2 specifier: ^10.9.2
version: 10.9.2(@types/node@20.16.11)(typescript@5.6.3) version: 10.9.2(@types/node@20.16.11)(typescript@5.6.2)
ts-patch: ts-patch:
specifier: ^3.2.1 specifier: ^3.2.1
version: 3.2.1 version: 3.2.1
@ -193,8 +193,8 @@ importers:
specifier: ^4.2.0 specifier: ^4.2.0
version: 4.2.0 version: 4.2.0
typescript: typescript:
specifier: ^5.6.3 specifier: ^5.6.2
version: 5.6.3 version: 5.6.2
packages: packages:
@ -3974,8 +3974,8 @@ packages:
engines: {node: '>=14.17'} engines: {node: '>=14.17'}
hasBin: true hasBin: true
typescript@5.6.3: typescript@5.6.2:
resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==}
engines: {node: '>=14.17'} engines: {node: '>=14.17'}
hasBin: true hasBin: true
@ -4514,7 +4514,7 @@ snapshots:
jest-util: 29.7.0 jest-util: 29.7.0
slash: 3.0.0 slash: 3.0.0
'@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))': '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))':
dependencies: dependencies:
'@jest/console': 29.7.0 '@jest/console': 29.7.0
'@jest/reporters': 29.7.0 '@jest/reporters': 29.7.0
@ -4528,7 +4528,7 @@ snapshots:
exit: 0.1.2 exit: 0.1.2
graceful-fs: 4.2.11 graceful-fs: 4.2.11
jest-changed-files: 29.7.0 jest-changed-files: 29.7.0
jest-config: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) jest-config: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
jest-haste-map: 29.7.0 jest-haste-map: 29.7.0
jest-message-util: 29.7.0 jest-message-util: 29.7.0
jest-regex-util: 29.6.3 jest-regex-util: 29.6.3
@ -4847,14 +4847,14 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- chokidar - chokidar
'@nestjs/schematics@10.1.4(chokidar@3.6.0)(typescript@5.6.3)': '@nestjs/schematics@10.1.4(chokidar@3.6.0)(typescript@5.6.2)':
dependencies: dependencies:
'@angular-devkit/core': 17.3.8(chokidar@3.6.0) '@angular-devkit/core': 17.3.8(chokidar@3.6.0)
'@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0)
comment-json: 4.2.3 comment-json: 4.2.3
jsonc-parser: 3.3.1 jsonc-parser: 3.3.1
pluralize: 8.0.0 pluralize: 8.0.0
typescript: 5.6.3 typescript: 5.6.2
transitivePeerDependencies: transitivePeerDependencies:
- chokidar - chokidar
@ -4882,7 +4882,7 @@ snapshots:
class-transformer: 0.5.1 class-transformer: 0.5.1
class-validator: 0.14.1 class-validator: 0.14.1
'@nestjs/terminus@10.2.3(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/typeorm@10.0.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))': '@nestjs/terminus@10.2.3(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/typeorm@10.0.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)))':
dependencies: dependencies:
'@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)
'@nestjs/core': 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1)
@ -4891,8 +4891,8 @@ snapshots:
reflect-metadata: 0.2.2 reflect-metadata: 0.2.2
rxjs: 7.8.1 rxjs: 7.8.1
optionalDependencies: optionalDependencies:
'@nestjs/typeorm': 10.0.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))) '@nestjs/typeorm': 10.0.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)))
typeorm: 0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) typeorm: 0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
'@nestjs/testing@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4))': '@nestjs/testing@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4))':
dependencies: dependencies:
@ -4902,13 +4902,13 @@ snapshots:
optionalDependencies: optionalDependencies:
'@nestjs/platform-express': 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4) '@nestjs/platform-express': 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4)
'@nestjs/typeorm@10.0.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))': '@nestjs/typeorm@10.0.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)))':
dependencies: dependencies:
'@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)
'@nestjs/core': 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1)
reflect-metadata: 0.2.2 reflect-metadata: 0.2.2
rxjs: 7.8.1 rxjs: 7.8.1
typeorm: 0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) typeorm: 0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
uuid: 9.0.1 uuid: 9.0.1
'@nodelib/fs.scandir@2.1.5': '@nodelib/fs.scandir@2.1.5':
@ -5160,34 +5160,34 @@ snapshots:
dependencies: dependencies:
'@types/yargs-parser': 21.0.3 '@types/yargs-parser': 21.0.3
'@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)': '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2)':
dependencies: dependencies:
'@eslint-community/regexpp': 4.11.1 '@eslint-community/regexpp': 4.11.1
'@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.2)
'@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.6.2)
'@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.2)
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0
eslint: 8.57.1 eslint: 8.57.1
graphemer: 1.4.0 graphemer: 1.4.0
ignore: 5.3.2 ignore: 5.3.2
natural-compare: 1.4.0 natural-compare: 1.4.0
ts-api-utils: 1.3.0(typescript@5.6.3) ts-api-utils: 1.3.0(typescript@5.6.2)
optionalDependencies: optionalDependencies:
typescript: 5.6.3 typescript: 5.6.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3)': '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.2)':
dependencies: dependencies:
'@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2)
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0
debug: 4.3.7 debug: 4.3.7
eslint: 8.57.1 eslint: 8.57.1
optionalDependencies: optionalDependencies:
typescript: 5.6.3 typescript: 5.6.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -5196,21 +5196,21 @@ snapshots:
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 7.18.0
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0
'@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.6.3)': '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.6.2)':
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2)
'@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.2)
debug: 4.3.7 debug: 4.3.7
eslint: 8.57.1 eslint: 8.57.1
ts-api-utils: 1.3.0(typescript@5.6.3) ts-api-utils: 1.3.0(typescript@5.6.2)
optionalDependencies: optionalDependencies:
typescript: 5.6.3 typescript: 5.6.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/types@7.18.0': {} '@typescript-eslint/types@7.18.0': {}
'@typescript-eslint/typescript-estree@7.18.0(typescript@5.6.3)': '@typescript-eslint/typescript-estree@7.18.0(typescript@5.6.2)':
dependencies: dependencies:
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 7.18.0
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0
@ -5219,18 +5219,18 @@ snapshots:
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 9.0.5 minimatch: 9.0.5
semver: 7.6.3 semver: 7.6.3
ts-api-utils: 1.3.0(typescript@5.6.3) ts-api-utils: 1.3.0(typescript@5.6.2)
optionalDependencies: optionalDependencies:
typescript: 5.6.3 typescript: 5.6.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.6.3)': '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.6.2)':
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1)
'@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2)
eslint: 8.57.1 eslint: 8.57.1
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -5884,13 +5884,13 @@ snapshots:
optionalDependencies: optionalDependencies:
typescript: 5.3.3 typescript: 5.3.3
create-jest@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)): create-jest@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)):
dependencies: dependencies:
'@jest/types': 29.6.3 '@jest/types': 29.6.3
chalk: 4.1.2 chalk: 4.1.2
exit: 0.1.2 exit: 0.1.2
graceful-fs: 4.2.11 graceful-fs: 4.2.11
jest-config: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) jest-config: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
jest-util: 29.7.0 jest-util: 29.7.0
prompts: 2.4.2 prompts: 2.4.2
transitivePeerDependencies: transitivePeerDependencies:
@ -6851,16 +6851,16 @@ snapshots:
- babel-plugin-macros - babel-plugin-macros
- supports-color - supports-color
jest-cli@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)): jest-cli@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)):
dependencies: dependencies:
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
'@jest/test-result': 29.7.0 '@jest/test-result': 29.7.0
'@jest/types': 29.6.3 '@jest/types': 29.6.3
chalk: 4.1.2 chalk: 4.1.2
create-jest: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) create-jest: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
exit: 0.1.2 exit: 0.1.2
import-local: 3.2.0 import-local: 3.2.0
jest-config: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) jest-config: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
jest-util: 29.7.0 jest-util: 29.7.0
jest-validate: 29.7.0 jest-validate: 29.7.0
yargs: 17.7.2 yargs: 17.7.2
@ -6870,7 +6870,7 @@ snapshots:
- supports-color - supports-color
- ts-node - ts-node
jest-config@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)): jest-config@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)):
dependencies: dependencies:
'@babel/core': 7.25.8 '@babel/core': 7.25.8
'@jest/test-sequencer': 29.7.0 '@jest/test-sequencer': 29.7.0
@ -6896,7 +6896,7 @@ snapshots:
strip-json-comments: 3.1.1 strip-json-comments: 3.1.1
optionalDependencies: optionalDependencies:
'@types/node': 20.16.11 '@types/node': 20.16.11
ts-node: 10.9.2(@types/node@20.16.11)(typescript@5.6.3) ts-node: 10.9.2(@types/node@20.16.11)(typescript@5.6.2)
transitivePeerDependencies: transitivePeerDependencies:
- babel-plugin-macros - babel-plugin-macros
- supports-color - supports-color
@ -7122,12 +7122,12 @@ snapshots:
merge-stream: 2.0.0 merge-stream: 2.0.0
supports-color: 8.1.1 supports-color: 8.1.1
jest@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)): jest@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)):
dependencies: dependencies:
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
'@jest/types': 29.6.3 '@jest/types': 29.6.3
import-local: 3.2.0 import-local: 3.2.0
jest-cli: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) jest-cli: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- babel-plugin-macros - babel-plugin-macros
@ -7484,7 +7484,7 @@ snapshots:
'@opentelemetry/host-metrics': 0.35.4(@opentelemetry/api@1.9.0) '@opentelemetry/host-metrics': 0.35.4(@opentelemetry/api@1.9.0)
response-time: 2.3.3 response-time: 2.3.3
nestjs-postal-client@0.0.6(jrcpsu45e3dhzjv3azmojl75yy): nestjs-postal-client@0.0.6(jdf445rhtpddlny4lqmttufnfe):
dependencies: dependencies:
'@nestjs/cache-manager': 2.2.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(cache-manager@5.7.2)(rxjs@7.8.1) '@nestjs/cache-manager': 2.2.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(cache-manager@5.7.2)(rxjs@7.8.1)
'@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)
@ -7495,7 +7495,7 @@ snapshots:
kakious-nestjs-http-promise: 0.0.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(axios@1.7.2) kakious-nestjs-http-promise: 0.0.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(axios@1.7.2)
nestjs-cls: 4.4.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1) nestjs-cls: 4.4.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)
nestjs-otel: 6.1.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1)) nestjs-otel: 6.1.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.2.2)(rxjs@7.8.1))
typia: 6.11.2(typescript@5.6.3) typia: 6.11.2(typescript@5.6.2)
transitivePeerDependencies: transitivePeerDependencies:
- typescript - typescript
@ -7719,13 +7719,13 @@ snapshots:
camelcase-css: 2.0.1 camelcase-css: 2.0.1
postcss: 8.4.47 postcss: 8.4.47
postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)): postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)):
dependencies: dependencies:
lilconfig: 3.1.2 lilconfig: 3.1.2
yaml: 2.6.0 yaml: 2.6.0
optionalDependencies: optionalDependencies:
postcss: 8.4.47 postcss: 8.4.47
ts-node: 10.9.2(@types/node@20.16.11)(typescript@5.6.3) ts-node: 10.9.2(@types/node@20.16.11)(typescript@5.6.2)
postcss-nested@6.2.0(postcss@8.4.47): postcss-nested@6.2.0(postcss@8.4.47):
dependencies: dependencies:
@ -8227,7 +8227,7 @@ snapshots:
systeminformation@5.22.9: {} systeminformation@5.22.9: {}
tailwindcss@3.4.14(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)): tailwindcss@3.4.14(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)):
dependencies: dependencies:
'@alloc/quick-lru': 5.2.0 '@alloc/quick-lru': 5.2.0
arg: 5.0.2 arg: 5.0.2
@ -8246,7 +8246,7 @@ snapshots:
postcss: 8.4.47 postcss: 8.4.47
postcss-import: 15.1.0(postcss@8.4.47) postcss-import: 15.1.0(postcss@8.4.47)
postcss-js: 4.0.1(postcss@8.4.47) postcss-js: 4.0.1(postcss@8.4.47)
postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
postcss-nested: 6.2.0(postcss@8.4.47) postcss-nested: 6.2.0(postcss@8.4.47)
postcss-selector-parser: 6.1.2 postcss-selector-parser: 6.1.2
resolve: 1.22.8 resolve: 1.22.8
@ -8321,24 +8321,24 @@ snapshots:
tree-kill@1.2.2: {} tree-kill@1.2.2: {}
ts-api-utils@1.3.0(typescript@5.6.3): ts-api-utils@1.3.0(typescript@5.6.2):
dependencies: dependencies:
typescript: 5.6.3 typescript: 5.6.2
ts-interface-checker@0.1.13: {} ts-interface-checker@0.1.13: {}
ts-jest@29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))(typescript@5.6.3): ts-jest@29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)))(typescript@5.6.2):
dependencies: dependencies:
bs-logger: 0.2.6 bs-logger: 0.2.6
ejs: 3.1.10 ejs: 3.1.10
fast-json-stable-stringify: 2.1.0 fast-json-stable-stringify: 2.1.0
jest: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) jest: 29.7.0(@types/node@20.16.11)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2))
jest-util: 29.7.0 jest-util: 29.7.0
json5: 2.2.3 json5: 2.2.3
lodash.memoize: 4.1.2 lodash.memoize: 4.1.2
make-error: 1.3.6 make-error: 1.3.6
semver: 7.6.3 semver: 7.6.3
typescript: 5.6.3 typescript: 5.6.2
yargs-parser: 21.1.1 yargs-parser: 21.1.1
optionalDependencies: optionalDependencies:
'@babel/core': 7.25.8 '@babel/core': 7.25.8
@ -8346,17 +8346,17 @@ snapshots:
'@jest/types': 29.6.3 '@jest/types': 29.6.3
babel-jest: 29.7.0(@babel/core@7.25.8) babel-jest: 29.7.0(@babel/core@7.25.8)
ts-loader@9.5.1(typescript@5.6.3)(webpack@5.94.0): ts-loader@9.5.1(typescript@5.6.2)(webpack@5.94.0):
dependencies: dependencies:
chalk: 4.1.2 chalk: 4.1.2
enhanced-resolve: 5.17.1 enhanced-resolve: 5.17.1
micromatch: 4.0.8 micromatch: 4.0.8
semver: 7.6.3 semver: 7.6.3
source-map: 0.7.4 source-map: 0.7.4
typescript: 5.6.3 typescript: 5.6.2
webpack: 5.94.0 webpack: 5.94.0
ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3): ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2):
dependencies: dependencies:
'@cspotcode/source-map-support': 0.8.1 '@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11 '@tsconfig/node10': 1.0.11
@ -8370,7 +8370,7 @@ snapshots:
create-require: 1.1.1 create-require: 1.1.1
diff: 4.0.2 diff: 4.0.2
make-error: 1.3.6 make-error: 1.3.6
typescript: 5.6.3 typescript: 5.6.2
v8-compile-cache-lib: 3.0.1 v8-compile-cache-lib: 3.0.1
yn: 3.1.1 yn: 3.1.1
@ -8422,7 +8422,7 @@ snapshots:
typedarray@0.0.6: {} typedarray@0.0.6: {}
typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)): typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.11.3)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.2)):
dependencies: dependencies:
'@sqltools/formatter': 1.2.5 '@sqltools/formatter': 1.2.5
app-root-path: 3.1.0 app-root-path: 3.1.0
@ -8442,15 +8442,15 @@ snapshots:
optionalDependencies: optionalDependencies:
ioredis: 5.4.1 ioredis: 5.4.1
mysql2: 3.11.3 mysql2: 3.11.3
ts-node: 10.9.2(@types/node@20.16.11)(typescript@5.6.3) ts-node: 10.9.2(@types/node@20.16.11)(typescript@5.6.2)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
typescript@5.3.3: {} typescript@5.3.3: {}
typescript@5.6.3: {} typescript@5.6.2: {}
typia@6.11.2(typescript@5.6.3): typia@6.11.2(typescript@5.6.2):
dependencies: dependencies:
'@samchon/openapi': 1.1.1 '@samchon/openapi': 1.1.1
commander: 10.0.1 commander: 10.0.1
@ -8458,7 +8458,7 @@ snapshots:
inquirer: 8.2.6 inquirer: 8.2.6
package-manager-detector: 0.2.2 package-manager-detector: 0.2.2
randexp: 0.5.3 randexp: 0.5.3
typescript: 5.6.3 typescript: 5.6.2
uglify-js@3.19.3: uglify-js@3.19.3:
optional: true optional: true

View file

@ -1,7 +1,7 @@
import { Controller, Get, Redirect, UseGuards } from '@nestjs/common'; import { Controller, Get, Redirect, UseGuards } from '@nestjs/common';
import { AppService } from './app.service'; import { AppService } from './app.service';
import { LoginGuard } from './auth/guard/login.guard'; import { ViewLoginGuard } from './auth/guard/viewLogin.guard';
import { MailService } from './mail/mail.service'; import { MailService } from './mail/service/mail.service';
import { ApiExcludeController } from '@nestjs/swagger'; import { ApiExcludeController } from '@nestjs/swagger';
@Controller() @Controller()
@ -14,7 +14,7 @@ export class AppController {
@Get() @Get()
@Redirect('/auth/login') @Redirect('/auth/login')
@UseGuards(LoginGuard) @UseGuards(ViewLoginGuard)
getHello(): any { getHello(): any {
return; return;
} }

View file

@ -29,3 +29,10 @@ export const REGISTRATION_EXPIRATION = 60 * 60 * 24; // 24 hours
export const REGISTRATION_LIMIT = 10; export const REGISTRATION_LIMIT = 10;
export const getRegistrationKey = (ip: string): string => `${REGISTRATION_CACHE_KEY}${ip}`; export const getRegistrationKey = (ip: string): string => `${REGISTRATION_CACHE_KEY}${ip}`;
export enum AuthMethods {
ClientSecret = 'ClientSecret',
Session = 'Session',
AccessToken = 'AccessToken',
APIToken = 'APIToken',
}

View file

@ -5,8 +5,8 @@ import { AuthService } from '../services/auth.service';
import { ForgotPasswordDto } from '../dto/forgotPassword.dto'; import { ForgotPasswordDto } from '../dto/forgotPassword.dto';
import { CreateUserDto } from '../dto/register.dto'; import { CreateUserDto } from '../dto/register.dto';
import { LoginUserDto } from '../dto/loginUser.dto'; import { LoginUserDto } from '../dto/loginUser.dto';
import { User } from '../decorators/user.decorator'; import { CurrentUser } from '../decorators/user.decorator';
import { LoginGuard } from '../guard/login.guard'; import { ViewLoginGuard } from '../guard/viewLogin.guard';
import { Response, Request } from 'express'; import { Response, Request } from 'express';
import { LoginResponse } from '../dto/loginResponse.dto'; import { LoginResponse } from '../dto/loginResponse.dto';
@ -51,7 +51,7 @@ export class AuthController {
// ==== Render pages ==== // // ==== Render pages ==== //
@Get('verify-email') @Get('verify-email')
@UseGuards(LoginGuard) @UseGuards(ViewLoginGuard)
@ApiExcludeEndpoint() @ApiExcludeEndpoint()
public async verifyEmail(@Res() response: Response, @Query('code') code: string): Promise<any> { public async verifyEmail(@Res() response: Response, @Query('code') code: string): Promise<any> {
if (!code) { if (!code) {

View file

@ -12,12 +12,12 @@ import { ApiExcludeController } from '@nestjs/swagger';
import { AuthService } from '../services/auth.service'; import { AuthService } from '../services/auth.service';
import { User } from '../decorators/user.decorator'; import { CurrentUser } from '../decorators/user.decorator';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { InteractionService } from '../oidc/service/interaction.service'; import { InteractionService } from '../oidc/service/interaction.service';
import { OidcService } from '../oidc/service/core.service'; import { OidcService } from '../oidc/service/core.service';
import { InteractionParams, InteractionSession } from '../oidc/types/interaction.type'; import { InteractionParams, InteractionSession } from '../oidc/types/interaction.type';
import { User as UserObject } from 'src/database/models/user.model'; import { User } from '../../database/models/user.model';
@Controller('interaction') @Controller('interaction')
@ApiExcludeController() @ApiExcludeController()
@ -31,7 +31,7 @@ export class InteractionController {
logger = new Logger(InteractionController.name); logger = new Logger(InteractionController.name);
@Get(':id') @Get(':id')
async getUserInteraction(@Res() res: Response, @Req() req: Request, @User() user: UserObject) { async getUserInteraction(@Res() res: Response, @Req() req: Request, @CurrentUser() user: User) {
const details: { const details: {
session?: InteractionSession; session?: InteractionSession;
uid: string; uid: string;

View file

@ -1,8 +1,8 @@
import { createParamDecorator } from '@nestjs/common'; import { createParamDecorator } from '@nestjs/common';
import { ClsServiceManager } from 'nestjs-cls'; import { ClsServiceManager } from 'nestjs-cls';
import { User as UserObject } from 'src/database/models/user.model'; import { User } from 'src/database/models/user.model';
export const User = createParamDecorator((): UserObject | null => { export const CurrentUser = createParamDecorator((): User | null => {
const cls = ClsServiceManager.getClsService(); const cls = ClsServiceManager.getClsService();
const authType = cls.get('authType'); const authType = cls.get('authType');

View file

@ -0,0 +1,19 @@
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { ClsService } from 'nestjs-cls';
import { Observable } from 'rxjs';
import { Response } from 'express';
@Injectable()
export class APILoginGuard implements CanActivate {
constructor(private readonly clsService: ClsService) {}
canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
const authType = this.clsService.get('authType');
const response = context.switchToHttp().getResponse() as Response;
if (authType === 'session') {
response.redirect('/home');
return false;
}
return true;
}
}

View file

@ -4,17 +4,34 @@ import { Observable } from 'rxjs';
import { Response } from 'express'; import { Response } from 'express';
@Injectable() @Injectable()
export class LoginGuard implements CanActivate { export class ViewLoginGuard implements CanActivate {
constructor(private readonly clsService: ClsService) {} constructor(private readonly clsService: ClsService) {}
canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> { canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
const authType = this.clsService.get('authType'); const authType = this.clsService.get('authType');
const response = context.switchToHttp().getResponse() as Response; const response = context.switchToHttp().getResponse() as Response;
console.log('test'); const loginPages = [
if (authType === 'session') { '/auth/login',
response.redirect('/auth/auth-test'); '/auth/forgot-password',
return false; '/auth/reset-password',
'/auth/register',
'/auth/verify-email',
'/',
];
if (loginPages.includes(context.switchToHttp().getRequest().url)) {
if (authType === 'session') {
response.redirect('/home');
return false;
}
return true;
} }
return true;
if (authType === 'session') {
return true;
}
return false;
} }
} }

View file

@ -0,0 +1,30 @@
import {
BadRequestException,
CallHandler,
ExecutionContext,
Injectable,
NestInterceptor,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { AuthMethods } from '../auth.const';
import { ClsService } from 'nestjs-cls';
@Injectable()
export class UserSelfReflection implements NestInterceptor {
constructor(private readonly clsService: ClsService) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const request = context.switchToHttp().getRequest();
const authType = this.clsService.get('authType');
if (request.params.id === '@me' && request.path.includes('/user/')) {
if (authType === AuthMethods.ClientSecret) {
return throwError(
() => new BadRequestException('Unable to use @me without User Auth Session'),
);
}
request.params.id = this.clsService.get('user').id;
}
return next.handle().pipe();
}
}

View file

@ -8,7 +8,7 @@ import { Response, Request } from 'express';
import { UserService } from '../../user/service/user.service'; import { UserService } from '../../user/service/user.service';
import { RedisService } from '../../redis/service/redis.service'; import { RedisService } from '../../redis/service/redis.service';
import { MailService } from '../../mail/mail.service'; import { MailService } from '../../mail/service/mail.service';
import { import {
getEmailVerifyKey, getEmailVerifyKey,
getResetKey, getResetKey,

View file

@ -9,5 +9,6 @@ export default async () => ({
port: process.env['REDIS_POST'] ?? 6379, port: process.env['REDIS_POST'] ?? 6379,
password: process.env['REDIS_PASSWORD'] ?? '', password: process.env['REDIS_PASSWORD'] ?? '',
db: process.env['REDIS_DB'] ?? 0, db: process.env['REDIS_DB'] ?? 0,
searchDisabled: process.env['REDIS_SEARCH_DISABLED'] ?? false,
}, },
}); });

View file

@ -2,7 +2,7 @@ import { registerAs } from '@nestjs/config';
import type { tags } from 'typia'; import type { tags } from 'typia';
import typia from 'typia'; import typia from 'typia';
import { validateOrThrow } from '../util/validation.util'; import { validateOrThrow } from '../../util/validation.util';
export const POSTAL_CONFIG_KEY = 'postal'; export const POSTAL_CONFIG_KEY = 'postal';

View file

@ -1,9 +1,9 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config'; import { ConfigModule, ConfigService } from '@nestjs/config';
import { PostalClientModule } from 'nestjs-postal-client'; import { PostalClientModule } from 'nestjs-postal-client';
import postalConfig from './postal.config'; import postalConfig from './config/postal.config';
import { PostalConfigService } from './postal_config.service'; import { PostalConfigService } from './service/postal_config.service';
import { MailService } from './mail.service'; import { MailService } from './service/mail.service';
@Module({ @Module({
imports: [ imports: [

View file

@ -3,8 +3,8 @@ import type { PostalModuleOptions, PostalModuleOptionsFactory } from 'nestjs-pos
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import type { PostalConfig } from './postal.config'; import type { PostalConfig } from '../config/postal.config';
import { POSTAL_CONFIG_KEY } from './postal.config'; import { POSTAL_CONFIG_KEY } from '../config/postal.config';
@Injectable() @Injectable()
export class PostalConfigService implements PostalModuleOptionsFactory { export class PostalConfigService implements PostalModuleOptionsFactory {

View file

@ -11,6 +11,8 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule); const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.disable('x-powered-by');
app.setGlobalPrefix('api', { app.setGlobalPrefix('api', {
exclude: [ exclude: [
{ path: 'auth/login', method: RequestMethod.GET }, { path: 'auth/login', method: RequestMethod.GET },

View file

@ -3,8 +3,8 @@ import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { OrganizationService } from '../service/organization.service'; import { OrganizationService } from '../service/organization.service';
import { OrgSetFlagDto } from '../dto/orgSetFlag.dto'; import { OrgSetFlagDto } from '../dto/orgSetFlag.dto';
import { CreateOrgDto } from '../dto/orgCreate.dto'; import { CreateOrgDto } from '../dto/orgCreate.dto';
import { User as UserObject } from '../../database/models/user.model'; import { User } from '../../database/models/user.model';
import { User } from '../../auth/decorators/user.decorator'; import { CurrentUser } from '../../auth/decorators/user.decorator';
@Controller('organization') @Controller('organization')
@ApiTags('Organization') @ApiTags('Organization')
@ -41,7 +41,7 @@ export class OrganizationController {
@Post() @Post()
public async createOrganization( public async createOrganization(
@Body() body: CreateOrgDto, @Body() body: CreateOrgDto,
@User() user: UserObject, @CurrentUser() user: User,
): Promise<any> { ): Promise<any> {
return await this.organizationService.createOrganization(user.id, body); return await this.organizationService.createOrganization(user.id, body);
} }

1
src/redis/redis.const.ts Normal file
View file

@ -0,0 +1 @@
export const REDIS_SEARCH_DISABLED_ERROR = `Search is disabled.`;

View file

@ -1,14 +1,29 @@
import { Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common'; import { BadRequestException, Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common';
import { RedisService } from './redis.service'; import { RedisService } from './redis.service';
import { userCacheKey } from '../../user/user.constant'; import { userCacheKey } from '../../user/user.constant';
import { REDIS_SEARCH_DISABLED_ERROR } from '../redis.const';
import { ConfigService } from '@nestjs/config';
@Injectable() @Injectable()
export class SearchService implements OnApplicationBootstrap { export class SearchService implements OnApplicationBootstrap {
private readonly logger = new Logger(SearchService.name); private readonly logger = new Logger(SearchService.name);
constructor(private readonly redisService: RedisService) {}
searchDisabled = true;
constructor(
private readonly redisService: RedisService,
private readonly configService: ConfigService,
) {
this.searchDisabled = this.configService.getOrThrow<boolean>('redis.searchDisabled');
}
async onApplicationBootstrap() { async onApplicationBootstrap() {
this.logger.debug('Checking Index in Redis Serch'); if (this.searchDisabled) {
this.logger.warn(REDIS_SEARCH_DISABLED_ERROR);
return;
}
this.logger.debug('Checking Index in Redis Search');
if (!(await this.checkIndexExists('idx:users'))) { if (!(await this.checkIndexExists('idx:users'))) {
this.logger.log('Created users redis index'); this.logger.log('Created users redis index');
@ -35,9 +50,12 @@ export class SearchService implements OnApplicationBootstrap {
'TEXT', 'TEXT',
); );
} }
this.logger.log('Redis Search Initialized');
} }
public async createIndex(indexName: string, keyPrefix: string, ...schema: string[]) { public async createIndex(indexName: string, keyPrefix: string, ...schema: string[]) {
this.searchCheck();
this.redisService.ioredis.call( this.redisService.ioredis.call(
'FT.CREATE', 'FT.CREATE',
indexName, indexName,
@ -57,6 +75,7 @@ export class SearchService implements OnApplicationBootstrap {
* @returns boolean * @returns boolean
*/ */
public async checkIndexExists(indexName: string): Promise<boolean> { public async checkIndexExists(indexName: string): Promise<boolean> {
this.searchCheck();
try { try {
await this.redisService.ioredis.call('FT.INFO', indexName); await this.redisService.ioredis.call('FT.INFO', indexName);
return true; return true;
@ -67,7 +86,15 @@ export class SearchService implements OnApplicationBootstrap {
} }
} }
public async search(index: string, searchQuery: string, field?: string) { public async search(
index: string,
searchQuery: string,
field?: string,
): Promise<{
totalResults: number;
results: any[];
}> {
this.searchCheck();
let query: string = ''; let query: string = '';
searchQuery = searchQuery.replace(/[.@\\]/g, '\\$&'); searchQuery = searchQuery.replace(/[.@\\]/g, '\\$&');
@ -83,7 +110,10 @@ export class SearchService implements OnApplicationBootstrap {
const redisSearch = (await this.redisService.ioredis.call('FT.SEARCH', index, query)) as any; const redisSearch = (await this.redisService.ioredis.call('FT.SEARCH', index, query)) as any;
if (redisSearch[0] === 0) { if (redisSearch[0] === 0) {
return []; return {
totalResults: 0,
results: [],
};
} }
delete redisSearch[2][0]; delete redisSearch[2][0];
@ -105,4 +135,10 @@ export class SearchService implements OnApplicationBootstrap {
results: redisSearchResults, results: redisSearchResults,
}; };
} }
private searchCheck() {
if (this.searchDisabled) {
throw new BadRequestException(REDIS_SEARCH_DISABLED_ERROR);
}
}
} }

View file

@ -1,22 +1,28 @@
import { Controller, Delete, Get, Param, Patch, Post, Put, Query } from '@nestjs/common'; import {
Controller,
Delete,
Get,
Param,
Patch,
Post,
Put,
Query,
UseInterceptors,
} from '@nestjs/common';
import { ApiParam, ApiTags } from '@nestjs/swagger'; import { ApiParam, ApiTags } from '@nestjs/swagger';
import { UserService } from '../service/user.service'; import { UserService } from '../service/user.service';
import { RedisService } from '../../redis/service/redis.service';
import { SearchService } from '../../redis/service/search.service'; import { UserSelfReflection } from 'src/auth/interceptors/selfReflection.interceptor';
@Controller('user') @Controller('user')
@ApiTags('User') @ApiTags('User')
export class UserController { export class UserController {
constructor( constructor(private readonly userService: UserService) {}
private readonly userService: UserService,
private readonly redisService: RedisService,
private readonly searchService: SearchService,
) {}
@Get('/search') @Get('/search')
@ApiParam({ name: 'field', required: false }) @ApiParam({ name: 'field', required: false })
public async search(@Query('query') query: string, @Query('field') field?: string) { public async search(@Query('query') query: string, @Query('field') field?: string) {
return await this.searchService.search('idx:users', query, field); return await this.userService.search(query, field);
} }
@Get() @Get()
@ -28,6 +34,7 @@ export class UserController {
@Get(':id') @Get(':id')
// Authenticated : Has to be publicly seen due to org inviting. Filter amount of data unless your an admin. // Authenticated : Has to be publicly seen due to org inviting. Filter amount of data unless your an admin.
// Allow self reflection to get all user data. @me // Allow self reflection to get all user data. @me
@UseInterceptors(UserSelfReflection)
public async getUser(@Param('id') id: string): Promise<any> { public async getUser(@Param('id') id: string): Promise<any> {
return await this.userService.getUserById(id); return await this.userService.getUserById(id);
} }

View file

@ -20,6 +20,7 @@ import {
userCacheKeyGenerate, userCacheKeyGenerate,
} from '../user.constant'; } from '../user.constant';
import { ClsService } from 'nestjs-cls'; import { ClsService } from 'nestjs-cls';
import { SearchService } from '../../redis/service/search.service';
@Injectable() @Injectable()
export class UserService { export class UserService {
@ -27,6 +28,7 @@ export class UserService {
@InjectRepository(User) @InjectRepository(User)
private readonly userRepository: Repository<User>, private readonly userRepository: Repository<User>,
private readonly redisService: RedisService, private readonly redisService: RedisService,
private readonly searchService: SearchService,
private readonly clsService: ClsService, private readonly clsService: ClsService,
) {} ) {}
@ -98,6 +100,21 @@ export class UserService {
return user; return user;
} }
async search(query: string, field?: string): Promise<any> {
const result = await this.searchService.search('idx:users', query, field);
// iterate through the search results and only return the following fields from each one. username, id, displayName, avatar
result.results = result.results.map((user) => {
return {
id: user.id,
displayName: user.displayName || user.username,
avatar: user.avatar,
};
});
return result;
}
/** /**
* Validate that a username and email is unique * Validate that a username and email is unique
* @param username The username to validate * @param username The username to validate

View file

@ -1,9 +1,9 @@
import { Controller, Get, Render, UseGuards } from '@nestjs/common'; import { Controller, Get, Render, UseGuards } from '@nestjs/common';
import { ApiExcludeController, ApiExcludeEndpoint } from '@nestjs/swagger'; import { ApiExcludeController, ApiExcludeEndpoint } from '@nestjs/swagger';
import { LoginGuard } from '../../auth/guard/login.guard'; import { ViewLoginGuard } from '../../auth/guard/viewLogin.guard';
import { User } from '../../auth/decorators/user.decorator'; import { CurrentUser } from '../../auth/decorators/user.decorator';
import { User as UserObject } from '../../database/models/user.model'; import { User } from '../../database/models/user.model';
@ApiExcludeController() @ApiExcludeController()
@Controller() @Controller()
@ -11,7 +11,7 @@ export class ViewController {
@Get('auth/login') @Get('auth/login')
@Render('auth/login') @Render('auth/login')
@ApiExcludeEndpoint() @ApiExcludeEndpoint()
@UseGuards(LoginGuard) @UseGuards(ViewLoginGuard)
public async loginView(): Promise<any> { public async loginView(): Promise<any> {
return { return {
forgot_password: 'forgot-password', forgot_password: 'forgot-password',
@ -24,7 +24,7 @@ export class ViewController {
@Get('auth/login/totp') @Get('auth/login/totp')
@Render('auth/login-totp') @Render('auth/login-totp')
@ApiExcludeEndpoint() @ApiExcludeEndpoint()
@UseGuards(LoginGuard) @UseGuards(ViewLoginGuard)
public async getLoginTotp(): Promise<any> { public async getLoginTotp(): Promise<any> {
return { return {
login: 'login', login: 'login',
@ -35,7 +35,7 @@ export class ViewController {
@Get('auth/register') @Get('auth/register')
@Render('auth/register') @Render('auth/register')
@ApiExcludeEndpoint() @ApiExcludeEndpoint()
@UseGuards(LoginGuard) @UseGuards(ViewLoginGuard)
public async getRegister(): Promise<any> { public async getRegister(): Promise<any> {
return { return {
login: 'login', login: 'login',
@ -43,7 +43,7 @@ export class ViewController {
} }
@Get('auth/forgot-password') @Get('auth/forgot-password')
@UseGuards(LoginGuard) @UseGuards(ViewLoginGuard)
@Render('auth/forgot-password') @Render('auth/forgot-password')
@ApiExcludeEndpoint() @ApiExcludeEndpoint()
public async getForgotPassword(): Promise<any> { public async getForgotPassword(): Promise<any> {
@ -55,7 +55,8 @@ export class ViewController {
@Get('home') @Get('home')
@Render('home/index') @Render('home/index')
@ApiExcludeEndpoint() @ApiExcludeEndpoint()
public async getHomeView(@User() user: UserObject): Promise<any> { @UseGuards(ViewLoginGuard)
public async getHomeView(@CurrentUser() user: User): Promise<any> {
return { return {
user: { user: {
name: user.displayName ?? user.username, name: user.displayName ?? user.username,

0
src/worker.module.ts Normal file
View file

0
src/worker.ts Normal file
View file

View file

@ -16,9 +16,6 @@ describe('AppController (e2e)', () => {
}); });
it('/ (GET)', () => { it('/ (GET)', () => {
return request(app.getHttpServer()) return request(app.getHttpServer()).get('/').expect(200).expect('Hello World!');
.get('/')
.expect(200)
.expect('Hello World!');
}); });
}); });