diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml
new file mode 100644
index 0000000..e69de29
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..e69de29
diff --git a/Dockerfile b/Dockerfile
index b407e8a..d56e1de 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,58 +1,39 @@
-# base environment
-FROM node:22.4.1-alpine3.20 AS base-stage
-RUN mkdir /app && chown -R node:node /app
-WORKDIR /app
+# Setup Base Env
+FROM node:20.18.0-alpine3.20 AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
+COPY . /app
+WORKDIR /app
-# dependency environment
-FROM base-stage AS dependency-stage
-USER node
-COPY --link --chown=1000:1000 package*.json pnpm-lock.yaml ./
+# Install Prod Dependencies
+FROM base AS prod-deps
+RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install typia ts-patch -g
+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
-# test stage to stop at for testing
-FROM dependency-stage AS all-source-stage
-COPY --link --chown=1000:1000 . .
-
# lint
-FROM all-source-stage AS lint
+FROM all-deps AS lint
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
-FROM scratch AS test-stage
-COPY --link --from=test-e2e /tmp/report.json /
+#Build the app
+FROM all-deps AS build
+RUN pnpm run build
-# build environment
-FROM dependency-stage AS build-stage
-COPY --link --chown=1000:1000 . .
-RUN npm run build
-# prod dependency environment
-FROM build-stage AS production-dependency-stage
-RUN npm prune --production
-
-# production environment
-FROM base-stage AS production-stage
+#Build final image
+FROM base
RUN apk add --no-cache tini
-USER node
-
-COPY --link --chown=1000:1000 --from=production-dependency-stage /app /app
-
+COPY --from=prod-deps /app/node_modules /app/node_modules
+COPY --from=build /app/dist /app/dist
ENV NODE_ENV=production
-
+EXPOSE 3000
ENTRYPOINT ["/sbin/tini", "--"]
-CMD ["node", "/app/.dist/src/main.js"]
+CMD ["node", "/app/dist/main.js"]
ARG VERSION
ENV VERSION=${VERSION}
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 1595227..f034936 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -16,5 +16,18 @@ services:
restart: unless-stopped
ports:
- "6379:6379"
+
+ waterwolf-auth:
+ build: .
+ restart: unless-stopped
+ ports:
+ - "3000:3000"
+ depends_on:
+ - mysql
+ - redis
+ env_file:
+ - .env
+ volumes:
+ - ./keys:/keys
volumes:
mysql-data:
\ No newline at end of file
diff --git a/mail/html/verify-email.hbs b/mail/html/verify-email.hbs
index 3b9ef41..0bf239b 100644
--- a/mail/html/verify-email.hbs
+++ b/mail/html/verify-email.hbs
@@ -1,5 +1,6 @@
+
@@ -7,30 +8,48 @@
+
Verify Your Email Address
@@ -58,7 +77,8 @@
-
+
@@ -66,4 +86,5 @@
+
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index bddbec6..d6cf73d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -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)
'@nestjs/terminus':
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':
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':
specifier: ^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))
nestjs-postal-client:
specifier: ^0.0.6
- version: 0.0.6(jrcpsu45e3dhzjv3azmojl75yy)
+ version: 0.0.6(jdf445rhtpddlny4lqmttufnfe)
oidc-provider:
specifier: ^8.5.1
version: 8.5.1
@@ -103,10 +103,10 @@ importers:
version: 7.8.1
typeorm:
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:
specifier: ^6.11.2
- version: 6.11.2(typescript@5.6.3)
+ version: 6.11.2(typescript@5.6.2)
uuid:
specifier: ^10.0.0
version: 10.0.0
@@ -119,7 +119,7 @@ importers:
version: 10.4.5
'@nestjs/schematics':
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':
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))
@@ -146,10 +146,10 @@ importers:
version: 6.0.2
'@typescript-eslint/eslint-plugin':
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':
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:
specifier: ^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)
jest:
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:
specifier: ^3.3.3
version: 3.3.3
@@ -176,16 +176,16 @@ importers:
version: 7.0.0
tailwindcss:
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:
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:
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:
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:
specifier: ^3.2.1
version: 3.2.1
@@ -193,8 +193,8 @@ importers:
specifier: ^4.2.0
version: 4.2.0
typescript:
- specifier: ^5.6.3
- version: 5.6.3
+ specifier: ^5.6.2
+ version: 5.6.2
packages:
@@ -3974,8 +3974,8 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
- typescript@5.6.3:
- resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==}
+ typescript@5.6.2:
+ resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==}
engines: {node: '>=14.17'}
hasBin: true
@@ -4514,7 +4514,7 @@ snapshots:
jest-util: 29.7.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:
'@jest/console': 29.7.0
'@jest/reporters': 29.7.0
@@ -4528,7 +4528,7 @@ snapshots:
exit: 0.1.2
graceful-fs: 4.2.11
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-message-util: 29.7.0
jest-regex-util: 29.6.3
@@ -4847,14 +4847,14 @@ snapshots:
transitivePeerDependencies:
- 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:
'@angular-devkit/core': 17.3.8(chokidar@3.6.0)
'@angular-devkit/schematics': 17.3.8(chokidar@3.6.0)
comment-json: 4.2.3
jsonc-parser: 3.3.1
pluralize: 8.0.0
- typescript: 5.6.3
+ typescript: 5.6.2
transitivePeerDependencies:
- chokidar
@@ -4882,7 +4882,7 @@ snapshots:
class-transformer: 0.5.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:
'@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)
@@ -4891,8 +4891,8 @@ snapshots:
reflect-metadata: 0.2.2
rxjs: 7.8.1
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)))
- 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.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))':
dependencies:
@@ -4902,13 +4902,13 @@ snapshots:
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/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:
'@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))
+ 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
'@nodelib/fs.scandir@2.1.5':
@@ -5160,34 +5160,34 @@ snapshots:
dependencies:
'@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:
'@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/type-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.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.2)
'@typescript-eslint/visitor-keys': 7.18.0
eslint: 8.57.1
graphemer: 1.4.0
ignore: 5.3.2
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:
- typescript: 5.6.3
+ typescript: 5.6.2
transitivePeerDependencies:
- 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:
'@typescript-eslint/scope-manager': 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
debug: 4.3.7
eslint: 8.57.1
optionalDependencies:
- typescript: 5.6.3
+ typescript: 5.6.2
transitivePeerDependencies:
- supports-color
@@ -5196,21 +5196,21 @@ snapshots:
'@typescript-eslint/types': 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:
- '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3)
- '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(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.2)
debug: 4.3.7
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:
- typescript: 5.6.3
+ typescript: 5.6.2
transitivePeerDependencies:
- supports-color
'@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:
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/visitor-keys': 7.18.0
@@ -5219,18 +5219,18 @@ snapshots:
is-glob: 4.0.3
minimatch: 9.0.5
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:
- typescript: 5.6.3
+ typescript: 5.6.2
transitivePeerDependencies:
- 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:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1)
'@typescript-eslint/scope-manager': 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
transitivePeerDependencies:
- supports-color
@@ -5884,13 +5884,13 @@ snapshots:
optionalDependencies:
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:
'@jest/types': 29.6.3
chalk: 4.1.2
exit: 0.1.2
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
prompts: 2.4.2
transitivePeerDependencies:
@@ -6851,16 +6851,16 @@ snapshots:
- babel-plugin-macros
- 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:
- '@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/types': 29.6.3
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
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-validate: 29.7.0
yargs: 17.7.2
@@ -6870,7 +6870,7 @@ snapshots:
- supports-color
- 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:
'@babel/core': 7.25.8
'@jest/test-sequencer': 29.7.0
@@ -6896,7 +6896,7 @@ snapshots:
strip-json-comments: 3.1.1
optionalDependencies:
'@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:
- babel-plugin-macros
- supports-color
@@ -7122,12 +7122,12 @@ snapshots:
merge-stream: 2.0.0
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:
- '@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
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:
- '@types/node'
- babel-plugin-macros
@@ -7484,7 +7484,7 @@ snapshots:
'@opentelemetry/host-metrics': 0.35.4(@opentelemetry/api@1.9.0)
response-time: 2.3.3
- nestjs-postal-client@0.0.6(jrcpsu45e3dhzjv3azmojl75yy):
+ nestjs-postal-client@0.0.6(jdf445rhtpddlny4lqmttufnfe):
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/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)
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))
- typia: 6.11.2(typescript@5.6.3)
+ typia: 6.11.2(typescript@5.6.2)
transitivePeerDependencies:
- typescript
@@ -7719,13 +7719,13 @@ snapshots:
camelcase-css: 2.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)):
dependencies:
lilconfig: 3.1.2
yaml: 2.6.0
optionalDependencies:
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):
dependencies:
@@ -8227,7 +8227,7 @@ snapshots:
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:
'@alloc/quick-lru': 5.2.0
arg: 5.0.2
@@ -8246,7 +8246,7 @@ snapshots:
postcss: 8.4.47
postcss-import: 15.1.0(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-selector-parser: 6.1.2
resolve: 1.22.8
@@ -8321,24 +8321,24 @@ snapshots:
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:
- typescript: 5.6.3
+ typescript: 5.6.2
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:
bs-logger: 0.2.6
ejs: 3.1.10
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
json5: 2.2.3
lodash.memoize: 4.1.2
make-error: 1.3.6
semver: 7.6.3
- typescript: 5.6.3
+ typescript: 5.6.2
yargs-parser: 21.1.1
optionalDependencies:
'@babel/core': 7.25.8
@@ -8346,17 +8346,17 @@ snapshots:
'@jest/types': 29.6.3
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:
chalk: 4.1.2
enhanced-resolve: 5.17.1
micromatch: 4.0.8
semver: 7.6.3
source-map: 0.7.4
- typescript: 5.6.3
+ typescript: 5.6.2
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:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11
@@ -8370,7 +8370,7 @@ snapshots:
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
- typescript: 5.6.3
+ typescript: 5.6.2
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
@@ -8422,7 +8422,7 @@ snapshots:
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:
'@sqltools/formatter': 1.2.5
app-root-path: 3.1.0
@@ -8442,15 +8442,15 @@ snapshots:
optionalDependencies:
ioredis: 5.4.1
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:
- supports-color
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:
'@samchon/openapi': 1.1.1
commander: 10.0.1
@@ -8458,7 +8458,7 @@ snapshots:
inquirer: 8.2.6
package-manager-detector: 0.2.2
randexp: 0.5.3
- typescript: 5.6.3
+ typescript: 5.6.2
uglify-js@3.19.3:
optional: true
diff --git a/src/app.controller.ts b/src/app.controller.ts
index 5d4331d..3f68793 100644
--- a/src/app.controller.ts
+++ b/src/app.controller.ts
@@ -1,7 +1,7 @@
import { Controller, Get, Redirect, UseGuards } from '@nestjs/common';
import { AppService } from './app.service';
-import { LoginGuard } from './auth/guard/login.guard';
-import { MailService } from './mail/mail.service';
+import { ViewLoginGuard } from './auth/guard/viewLogin.guard';
+import { MailService } from './mail/service/mail.service';
import { ApiExcludeController } from '@nestjs/swagger';
@Controller()
@@ -14,7 +14,7 @@ export class AppController {
@Get()
@Redirect('/auth/login')
- @UseGuards(LoginGuard)
+ @UseGuards(ViewLoginGuard)
getHello(): any {
return;
}
diff --git a/src/auth/auth.const.ts b/src/auth/auth.const.ts
index 84ce056..48083a6 100644
--- a/src/auth/auth.const.ts
+++ b/src/auth/auth.const.ts
@@ -29,3 +29,10 @@ export const REGISTRATION_EXPIRATION = 60 * 60 * 24; // 24 hours
export const REGISTRATION_LIMIT = 10;
export const getRegistrationKey = (ip: string): string => `${REGISTRATION_CACHE_KEY}${ip}`;
+
+export enum AuthMethods {
+ ClientSecret = 'ClientSecret',
+ Session = 'Session',
+ AccessToken = 'AccessToken',
+ APIToken = 'APIToken',
+}
diff --git a/src/auth/controllers/auth.controller.ts b/src/auth/controllers/auth.controller.ts
index 8582673..ee137b0 100644
--- a/src/auth/controllers/auth.controller.ts
+++ b/src/auth/controllers/auth.controller.ts
@@ -5,8 +5,8 @@ import { AuthService } from '../services/auth.service';
import { ForgotPasswordDto } from '../dto/forgotPassword.dto';
import { CreateUserDto } from '../dto/register.dto';
import { LoginUserDto } from '../dto/loginUser.dto';
-import { User } from '../decorators/user.decorator';
-import { LoginGuard } from '../guard/login.guard';
+import { CurrentUser } from '../decorators/user.decorator';
+import { ViewLoginGuard } from '../guard/viewLogin.guard';
import { Response, Request } from 'express';
import { LoginResponse } from '../dto/loginResponse.dto';
@@ -51,7 +51,7 @@ export class AuthController {
// ==== Render pages ==== //
@Get('verify-email')
- @UseGuards(LoginGuard)
+ @UseGuards(ViewLoginGuard)
@ApiExcludeEndpoint()
public async verifyEmail(@Res() response: Response, @Query('code') code: string): Promise {
if (!code) {
diff --git a/src/auth/controllers/interaction.controller.ts b/src/auth/controllers/interaction.controller.ts
index 6e19304..0363679 100644
--- a/src/auth/controllers/interaction.controller.ts
+++ b/src/auth/controllers/interaction.controller.ts
@@ -12,12 +12,12 @@ import { ApiExcludeController } from '@nestjs/swagger';
import { AuthService } from '../services/auth.service';
-import { User } from '../decorators/user.decorator';
+import { CurrentUser } from '../decorators/user.decorator';
import { Request, Response } from 'express';
import { InteractionService } from '../oidc/service/interaction.service';
import { OidcService } from '../oidc/service/core.service';
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')
@ApiExcludeController()
@@ -31,7 +31,7 @@ export class InteractionController {
logger = new Logger(InteractionController.name);
@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: {
session?: InteractionSession;
uid: string;
diff --git a/src/auth/decorators/user.decorator.ts b/src/auth/decorators/user.decorator.ts
index 5846b73..9861c0f 100644
--- a/src/auth/decorators/user.decorator.ts
+++ b/src/auth/decorators/user.decorator.ts
@@ -1,8 +1,8 @@
import { createParamDecorator } from '@nestjs/common';
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 authType = cls.get('authType');
diff --git a/src/auth/guard/auth.guard.ts b/src/auth/guard/auth.guard.ts
index e69de29..0f8c637 100644
--- a/src/auth/guard/auth.guard.ts
+++ b/src/auth/guard/auth.guard.ts
@@ -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 | Observable {
+ const authType = this.clsService.get('authType');
+ const response = context.switchToHttp().getResponse() as Response;
+
+ if (authType === 'session') {
+ response.redirect('/home');
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/src/auth/guard/login.guard.ts b/src/auth/guard/viewLogin.guard.ts
similarity index 52%
rename from src/auth/guard/login.guard.ts
rename to src/auth/guard/viewLogin.guard.ts
index 2187bac..e7e0c74 100644
--- a/src/auth/guard/login.guard.ts
+++ b/src/auth/guard/viewLogin.guard.ts
@@ -4,17 +4,34 @@ import { Observable } from 'rxjs';
import { Response } from 'express';
@Injectable()
-export class LoginGuard implements CanActivate {
+export class ViewLoginGuard implements CanActivate {
constructor(private readonly clsService: ClsService) {}
canActivate(context: ExecutionContext): boolean | Promise | Observable {
const authType = this.clsService.get('authType');
const response = context.switchToHttp().getResponse() as Response;
- console.log('test');
- if (authType === 'session') {
- response.redirect('/auth/auth-test');
- return false;
+ const loginPages = [
+ '/auth/login',
+ '/auth/forgot-password',
+ '/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;
}
}
diff --git a/src/auth/interceptors/selfReflection.interceptor.ts b/src/auth/interceptors/selfReflection.interceptor.ts
new file mode 100644
index 0000000..f75d849
--- /dev/null
+++ b/src/auth/interceptors/selfReflection.interceptor.ts
@@ -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 {
+ 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();
+ }
+}
diff --git a/src/auth/services/auth.service.ts b/src/auth/services/auth.service.ts
index 9d94f41..5165c9f 100644
--- a/src/auth/services/auth.service.ts
+++ b/src/auth/services/auth.service.ts
@@ -8,7 +8,7 @@ import { Response, Request } from 'express';
import { UserService } from '../../user/service/user.service';
import { RedisService } from '../../redis/service/redis.service';
-import { MailService } from '../../mail/mail.service';
+import { MailService } from '../../mail/service/mail.service';
import {
getEmailVerifyKey,
getResetKey,
diff --git a/src/config/config.ts b/src/config/config.ts
index 438c29d..2b9391e 100644
--- a/src/config/config.ts
+++ b/src/config/config.ts
@@ -9,5 +9,6 @@ export default async () => ({
port: process.env['REDIS_POST'] ?? 6379,
password: process.env['REDIS_PASSWORD'] ?? '',
db: process.env['REDIS_DB'] ?? 0,
+ searchDisabled: process.env['REDIS_SEARCH_DISABLED'] ?? false,
},
});
diff --git a/src/mail/postal.config.ts b/src/mail/config/postal.config.ts
similarity index 90%
rename from src/mail/postal.config.ts
rename to src/mail/config/postal.config.ts
index 161d1c8..a13296a 100644
--- a/src/mail/postal.config.ts
+++ b/src/mail/config/postal.config.ts
@@ -2,7 +2,7 @@ import { registerAs } from '@nestjs/config';
import type { tags } from 'typia';
import typia from 'typia';
-import { validateOrThrow } from '../util/validation.util';
+import { validateOrThrow } from '../../util/validation.util';
export const POSTAL_CONFIG_KEY = 'postal';
diff --git a/src/mail/mail.module.ts b/src/mail/mail.module.ts
index e96c9f1..8d607aa 100644
--- a/src/mail/mail.module.ts
+++ b/src/mail/mail.module.ts
@@ -1,9 +1,9 @@
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { PostalClientModule } from 'nestjs-postal-client';
-import postalConfig from './postal.config';
-import { PostalConfigService } from './postal_config.service';
-import { MailService } from './mail.service';
+import postalConfig from './config/postal.config';
+import { PostalConfigService } from './service/postal_config.service';
+import { MailService } from './service/mail.service';
@Module({
imports: [
diff --git a/src/mail/mail.service.ts b/src/mail/service/mail.service.ts
similarity index 100%
rename from src/mail/mail.service.ts
rename to src/mail/service/mail.service.ts
diff --git a/src/mail/postal_config.service.ts b/src/mail/service/postal_config.service.ts
similarity index 85%
rename from src/mail/postal_config.service.ts
rename to src/mail/service/postal_config.service.ts
index b86be55..741c67e 100644
--- a/src/mail/postal_config.service.ts
+++ b/src/mail/service/postal_config.service.ts
@@ -3,8 +3,8 @@ import type { PostalModuleOptions, PostalModuleOptionsFactory } from 'nestjs-pos
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
-import type { PostalConfig } from './postal.config';
-import { POSTAL_CONFIG_KEY } from './postal.config';
+import type { PostalConfig } from '../config/postal.config';
+import { POSTAL_CONFIG_KEY } from '../config/postal.config';
@Injectable()
export class PostalConfigService implements PostalModuleOptionsFactory {
diff --git a/src/main.ts b/src/main.ts
index 1f726ef..9366e4b 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -11,6 +11,8 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
+ app.disable('x-powered-by');
+
app.setGlobalPrefix('api', {
exclude: [
{ path: 'auth/login', method: RequestMethod.GET },
diff --git a/src/organization/controller/organization.controller.ts b/src/organization/controller/organization.controller.ts
index 3a4d924..e37ce1d 100644
--- a/src/organization/controller/organization.controller.ts
+++ b/src/organization/controller/organization.controller.ts
@@ -3,8 +3,8 @@ import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { OrganizationService } from '../service/organization.service';
import { OrgSetFlagDto } from '../dto/orgSetFlag.dto';
import { CreateOrgDto } from '../dto/orgCreate.dto';
-import { User as UserObject } from '../../database/models/user.model';
-import { User } from '../../auth/decorators/user.decorator';
+import { User } from '../../database/models/user.model';
+import { CurrentUser } from '../../auth/decorators/user.decorator';
@Controller('organization')
@ApiTags('Organization')
@@ -41,7 +41,7 @@ export class OrganizationController {
@Post()
public async createOrganization(
@Body() body: CreateOrgDto,
- @User() user: UserObject,
+ @CurrentUser() user: User,
): Promise {
return await this.organizationService.createOrganization(user.id, body);
}
diff --git a/src/redis/redis.const.ts b/src/redis/redis.const.ts
new file mode 100644
index 0000000..ff33930
--- /dev/null
+++ b/src/redis/redis.const.ts
@@ -0,0 +1 @@
+export const REDIS_SEARCH_DISABLED_ERROR = `Search is disabled.`;
diff --git a/src/redis/service/search.service.ts b/src/redis/service/search.service.ts
index dbba7e8..742c0da 100644
--- a/src/redis/service/search.service.ts
+++ b/src/redis/service/search.service.ts
@@ -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 { userCacheKey } from '../../user/user.constant';
+import { REDIS_SEARCH_DISABLED_ERROR } from '../redis.const';
+import { ConfigService } from '@nestjs/config';
@Injectable()
export class SearchService implements OnApplicationBootstrap {
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('redis.searchDisabled');
+ }
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'))) {
this.logger.log('Created users redis index');
@@ -35,9 +50,12 @@ export class SearchService implements OnApplicationBootstrap {
'TEXT',
);
}
+
+ this.logger.log('Redis Search Initialized');
}
public async createIndex(indexName: string, keyPrefix: string, ...schema: string[]) {
+ this.searchCheck();
this.redisService.ioredis.call(
'FT.CREATE',
indexName,
@@ -57,6 +75,7 @@ export class SearchService implements OnApplicationBootstrap {
* @returns boolean
*/
public async checkIndexExists(indexName: string): Promise {
+ this.searchCheck();
try {
await this.redisService.ioredis.call('FT.INFO', indexName);
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 = '';
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;
if (redisSearch[0] === 0) {
- return [];
+ return {
+ totalResults: 0,
+ results: [],
+ };
}
delete redisSearch[2][0];
@@ -105,4 +135,10 @@ export class SearchService implements OnApplicationBootstrap {
results: redisSearchResults,
};
}
+
+ private searchCheck() {
+ if (this.searchDisabled) {
+ throw new BadRequestException(REDIS_SEARCH_DISABLED_ERROR);
+ }
+ }
}
diff --git a/src/user/controller/user.controller.ts b/src/user/controller/user.controller.ts
index 5aaa984..fc41617 100644
--- a/src/user/controller/user.controller.ts
+++ b/src/user/controller/user.controller.ts
@@ -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 { 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')
@ApiTags('User')
export class UserController {
- constructor(
- private readonly userService: UserService,
- private readonly redisService: RedisService,
- private readonly searchService: SearchService,
- ) {}
+ constructor(private readonly userService: UserService) {}
@Get('/search')
@ApiParam({ name: 'field', required: false })
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()
@@ -28,6 +34,7 @@ export class UserController {
@Get(':id')
// 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
+ @UseInterceptors(UserSelfReflection)
public async getUser(@Param('id') id: string): Promise {
return await this.userService.getUserById(id);
}
diff --git a/src/user/service/user.service.ts b/src/user/service/user.service.ts
index f004971..1333443 100644
--- a/src/user/service/user.service.ts
+++ b/src/user/service/user.service.ts
@@ -20,6 +20,7 @@ import {
userCacheKeyGenerate,
} from '../user.constant';
import { ClsService } from 'nestjs-cls';
+import { SearchService } from '../../redis/service/search.service';
@Injectable()
export class UserService {
@@ -27,6 +28,7 @@ export class UserService {
@InjectRepository(User)
private readonly userRepository: Repository,
private readonly redisService: RedisService,
+ private readonly searchService: SearchService,
private readonly clsService: ClsService,
) {}
@@ -98,6 +100,21 @@ export class UserService {
return user;
}
+ async search(query: string, field?: string): Promise {
+ 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
* @param username The username to validate
diff --git a/src/view/controllers/view.controller.ts b/src/view/controllers/view.controller.ts
index c5e30df..b7c6227 100644
--- a/src/view/controllers/view.controller.ts
+++ b/src/view/controllers/view.controller.ts
@@ -1,9 +1,9 @@
import { Controller, Get, Render, UseGuards } from '@nestjs/common';
import { ApiExcludeController, ApiExcludeEndpoint } from '@nestjs/swagger';
-import { LoginGuard } from '../../auth/guard/login.guard';
-import { User } from '../../auth/decorators/user.decorator';
-import { User as UserObject } from '../../database/models/user.model';
+import { ViewLoginGuard } from '../../auth/guard/viewLogin.guard';
+import { CurrentUser } from '../../auth/decorators/user.decorator';
+import { User } from '../../database/models/user.model';
@ApiExcludeController()
@Controller()
@@ -11,7 +11,7 @@ export class ViewController {
@Get('auth/login')
@Render('auth/login')
@ApiExcludeEndpoint()
- @UseGuards(LoginGuard)
+ @UseGuards(ViewLoginGuard)
public async loginView(): Promise {
return {
forgot_password: 'forgot-password',
@@ -24,7 +24,7 @@ export class ViewController {
@Get('auth/login/totp')
@Render('auth/login-totp')
@ApiExcludeEndpoint()
- @UseGuards(LoginGuard)
+ @UseGuards(ViewLoginGuard)
public async getLoginTotp(): Promise {
return {
login: 'login',
@@ -35,7 +35,7 @@ export class ViewController {
@Get('auth/register')
@Render('auth/register')
@ApiExcludeEndpoint()
- @UseGuards(LoginGuard)
+ @UseGuards(ViewLoginGuard)
public async getRegister(): Promise {
return {
login: 'login',
@@ -43,7 +43,7 @@ export class ViewController {
}
@Get('auth/forgot-password')
- @UseGuards(LoginGuard)
+ @UseGuards(ViewLoginGuard)
@Render('auth/forgot-password')
@ApiExcludeEndpoint()
public async getForgotPassword(): Promise {
@@ -55,7 +55,8 @@ export class ViewController {
@Get('home')
@Render('home/index')
@ApiExcludeEndpoint()
- public async getHomeView(@User() user: UserObject): Promise {
+ @UseGuards(ViewLoginGuard)
+ public async getHomeView(@CurrentUser() user: User): Promise {
return {
user: {
name: user.displayName ?? user.username,
diff --git a/src/worker.module.ts b/src/worker.module.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/worker.ts b/src/worker.ts
new file mode 100644
index 0000000..e69de29
diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts
index 50cda62..1a013be 100644
--- a/test/app.e2e-spec.ts
+++ b/test/app.e2e-spec.ts
@@ -16,9 +16,6 @@ describe('AppController (e2e)', () => {
});
it('/ (GET)', () => {
- return request(app.getHttpServer())
- .get('/')
- .expect(200)
- .expect('Hello World!');
+ return request(app.getHttpServer()).get('/').expect(200).expect('Hello World!');
});
});