feat: templates and working oidc core

This commit is contained in:
Kakious 2024-07-26 02:31:29 -04:00
parent c65ba92322
commit b0a3fa82aa
21 changed files with 502 additions and 113 deletions

View file

@ -23,6 +23,19 @@ Once it is started, in the bottom pane of vscode, goto the PORTS tab and look fo
Either right click or copy the forwarded address to open it in your browser and then navigate to the path:
http://localhost:{PORT}/v1/api/ to ensure it has started correctly
## Documentation
Currently the documentation is a work in progress. The documentation is generated using the OpenAPI specification and can be found at the `/v1/api` path of the service.
The current defaults that are generated at initialization are:
Default Org Id: 1
Default Org Name: WaterWolf
Default Org Slug: waterwolf
The default user that is created is:
Username: admin
Password: changeme
## Installation
Use pnmp to install the required packages.
@ -43,6 +56,27 @@ pnpm start
This uses `@nestjs/config` which uses [dotenv](https://github.com/motdotla/dotenv).
Configuration can be done by using a `.env` file or environment variables.
Application Configuration
- `BASE_URL` - Base URL for the application
Database Configuration
- `DATABASE_HOST` - Hostname for the database
- `DATABASE_PORT` - Port for the database
- `DATABASE_USER` - Username for the database
- `DATABASE_PASSWORD` - Password for the database
- `DATABASE_NAME` - Name of the database
Database Debug Configuration
- `DATABASE_SYNCHRONIZE` - Synchronize the database schema
- `DATABASE_DISABLE_MIGRATIONS` - Disable migrations
- `DATABASE_DEBUG_LOGGING` - Enable debug logging for the database
Redis Configuration
- `REDIS_HOST` - Hostname for the Redis server
- `REDIS_PORT` - Port for the Redis server
- `REDIS_PASSWORD` - Password for the Redis server (Optional)
- `REDIS_DB` - Database number for the Redis server (Optional)
Mailing Configuration
- `POSTAL_BASE_URL` - Base URL for the Postal API
- `POSTAL_API_KEY` - API Key for the Postal API

BIN
assets/login.webm Normal file

Binary file not shown.

49
assets/styles.css Normal file
View file

@ -0,0 +1,49 @@
.video-bg {
position: fixed;
right: 0;
bottom: 0;
min-width: 100%;
min-height: 100%;
z-index: -1;
}
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: -1;
}
@media (max-width: 640px) {
.video-bg, .overlay {
display: none;
}
.reset-prompt {
margin-left: 0;
width: 100%;
max-width: none;
position: static;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
}
}
.shake {
animation: shake 0.3s ease-in-out;
}
@keyframes shake {
0%, 100% {
transform: translateX(0);
}
25% {
transform: translateX(-5px);
}
50% {
transform: translateX(5px);
}
75% {
transform: translateX(-5px);
}
}

View file

@ -32,6 +32,7 @@
"@nestjs/config": "^3.2.3",
"@nestjs/core": "^10.3.10",
"@nestjs/platform-express": "^10.3.10",
"@nestjs/serve-static": "^4.0.2",
"@nestjs/swagger": "^7.4.0",
"@nestjs/terminus": "^10.2.3",
"@nestjs/typeorm": "^10.0.2",
@ -80,7 +81,7 @@
"ts-node": "^10.9.2",
"ts-patch": "^3.2.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.5.3"
"typescript": "^5.5.2"
},
"jest": {
"moduleFileExtensions": [
@ -100,4 +101,4 @@
"testEnvironment": "node"
},
"packageManager": "pnpm@9.5.0+sha512.140036830124618d624a2187b50d04289d5a087f326c9edfc0ccd733d76c4f52c3a313d4fc148794a2a9d81553016004e6742e8cf850670268a7387fc220c903"
}
}

View file

@ -26,15 +26,18 @@ importers:
'@nestjs/platform-express':
specifier: ^10.3.10
version: 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10)
'@nestjs/serve-static':
specifier: ^4.0.2
version: 4.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(express@4.19.2)(fastify@4.28.1)
'@nestjs/swagger':
specifier: ^7.4.0
version: 7.4.0(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/typeorm@10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)))
version: 10.2.3(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/typeorm@10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)))
'@nestjs/typeorm':
specifier: ^10.0.2
version: 10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)))
version: 10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)))
'@opentelemetry/api':
specifier: ^1.9.0
version: 1.9.0
@ -67,7 +70,7 @@ importers:
version: 6.1.1(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))
nestjs-postal-client:
specifier: ^0.0.6
version: 0.0.6(rtrsvjp22aq2opwvwwi7bofxyi)
version: 0.0.6(cawqvsjzhg64rgfdjtb5cpgrqu)
oidc-provider:
specifier: ^8.5.1
version: 8.5.1
@ -85,10 +88,10 @@ importers:
version: 7.8.1
typeorm:
specifier: ^0.3.20
version: 0.3.20(ioredis@5.4.1)(mysql2@3.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
version: 0.3.20(ioredis@5.4.1)(mysql2@3.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
typia:
specifier: ^6.5.1
version: 6.5.1(typescript@5.5.3)
version: 6.5.1(typescript@5.5.2)
uuid:
specifier: ^10.0.0
version: 10.0.0
@ -101,7 +104,7 @@ importers:
version: 10.4.2
'@nestjs/schematics':
specifier: ^10.1.2
version: 10.1.2(chokidar@3.6.0)(typescript@5.5.3)
version: 10.1.2(chokidar@3.6.0)(typescript@5.5.2)
'@nestjs/testing':
specifier: ^10.3.10
version: 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10))
@ -119,10 +122,10 @@ importers:
version: 6.0.2
'@typescript-eslint/eslint-plugin':
specifier: ^7.16.1
version: 7.16.1(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)
version: 7.16.1(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)
'@typescript-eslint/parser':
specifier: ^7.16.1
version: 7.16.1(eslint@8.57.0)(typescript@5.5.3)
version: 7.16.1(eslint@8.57.0)(typescript@5.5.2)
eslint:
specifier: ^8.57.0
version: 8.57.0
@ -134,7 +137,7 @@ importers:
version: 5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3)
jest:
specifier: ^29.7.0
version: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
version: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
prettier:
specifier: ^3.3.3
version: 3.3.3
@ -149,16 +152,16 @@ importers:
version: 7.0.0
tailwindcss:
specifier: ^3.4.5
version: 3.4.5(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
version: 3.4.5(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
ts-jest:
specifier: ^29.2.2
version: 29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)))(typescript@5.5.3)
version: 29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)))(typescript@5.5.2)
ts-loader:
specifier: ^9.5.1
version: 9.5.1(typescript@5.5.3)(webpack@5.92.1)
version: 9.5.1(typescript@5.5.2)(webpack@5.92.1)
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@20.14.10)(typescript@5.5.3)
version: 10.9.2(@types/node@20.14.10)(typescript@5.5.2)
ts-patch:
specifier: ^3.2.1
version: 3.2.1
@ -166,8 +169,8 @@ importers:
specifier: ^4.2.0
version: 4.2.0
typescript:
specifier: ^5.5.3
version: 5.5.3
specifier: ^5.5.2
version: 5.5.2
packages:
@ -666,6 +669,22 @@ packages:
peerDependencies:
typescript: '>=4.8.2'
'@nestjs/serve-static@4.0.2':
resolution: {integrity: sha512-cT0vdWN5ar7jDI2NKbhf4LcwJzU4vS5sVpMkVrHuyLcltbrz6JdGi1TfIMMatP2pNiq5Ie/uUdPSFDVaZX/URQ==}
peerDependencies:
'@fastify/static': ^6.5.0 || ^7.0.0
'@nestjs/common': ^9.0.0 || ^10.0.0
'@nestjs/core': ^9.0.0 || ^10.0.0
express: ^4.18.1
fastify: ^4.7.0
peerDependenciesMeta:
'@fastify/static':
optional: true
express:
optional: true
fastify:
optional: true
'@nestjs/swagger@7.4.0':
resolution: {integrity: sha512-dCiwKkRxcR7dZs5jtrGspBAe/nqJd1AYzOBTzw9iCdbq3BGrLpwokelk6lFZPe4twpTsPQqzNKBwKzVbI6AR/g==}
peerDependencies:
@ -3061,6 +3080,9 @@ packages:
path-to-regexp@0.1.7:
resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
path-to-regexp@0.2.5:
resolution: {integrity: sha512-l6qtdDPIkmAmzEO6egquYDfqQGPMRNGjYtrU13HAXb3YSRrt7HSb1sJY0pKp6o2bAa86tSB6iwaW2JbthPKr7Q==}
path-to-regexp@3.2.0:
resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==}
@ -3879,8 +3901,8 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
typescript@5.5.3:
resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==}
typescript@5.5.2:
resolution: {integrity: sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==}
engines: {node: '>=14.17'}
hasBin: true
@ -4425,7 +4447,7 @@ snapshots:
jest-util: 29.7.0
slash: 3.0.0
'@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))':
'@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))':
dependencies:
'@jest/console': 29.7.0
'@jest/reporters': 29.7.0
@ -4439,7 +4461,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.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
jest-config: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
jest-haste-map: 29.7.0
jest-message-util: 29.7.0
jest-regex-util: 29.6.3
@ -4758,17 +4780,26 @@ snapshots:
transitivePeerDependencies:
- chokidar
'@nestjs/schematics@10.1.2(chokidar@3.6.0)(typescript@5.5.3)':
'@nestjs/schematics@10.1.2(chokidar@3.6.0)(typescript@5.5.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.5.3
typescript: 5.5.2
transitivePeerDependencies:
- chokidar
'@nestjs/serve-static@4.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(express@4.19.2)(fastify@4.28.1)':
dependencies:
'@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)
'@nestjs/core': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1)
path-to-regexp: 0.2.5
optionalDependencies:
express: 4.19.2
fastify: 4.28.1
'@nestjs/swagger@7.4.0(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)':
dependencies:
'@microsoft/tsdoc': 0.15.0
@ -4784,7 +4815,7 @@ snapshots:
class-transformer: 0.5.1
class-validator: 0.14.1
'@nestjs/terminus@10.2.3(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/typeorm@10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)))':
'@nestjs/terminus@10.2.3(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/typeorm@10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)))':
dependencies:
'@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)
'@nestjs/core': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1)
@ -4793,8 +4824,8 @@ snapshots:
reflect-metadata: 0.2.2
rxjs: 7.8.1
optionalDependencies:
'@nestjs/typeorm': 10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)))
typeorm: 0.3.20(ioredis@5.4.1)(mysql2@3.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
'@nestjs/typeorm': 10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)))
typeorm: 0.3.20(ioredis@5.4.1)(mysql2@3.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
'@nestjs/testing@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10))':
dependencies:
@ -4804,13 +4835,13 @@ snapshots:
optionalDependencies:
'@nestjs/platform-express': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10)
'@nestjs/typeorm@10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)))':
'@nestjs/typeorm@10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)))':
dependencies:
'@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)
'@nestjs/core': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
typeorm: 0.3.20(ioredis@5.4.1)(mysql2@3.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
uuid: 9.0.1
'@nodelib/fs.scandir@2.1.5':
@ -5023,34 +5054,34 @@ snapshots:
dependencies:
'@types/yargs-parser': 21.0.3
'@typescript-eslint/eslint-plugin@7.16.1(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)':
'@typescript-eslint/eslint-plugin@7.16.1(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)':
dependencies:
'@eslint-community/regexpp': 4.11.0
'@typescript-eslint/parser': 7.16.1(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/parser': 7.16.1(eslint@8.57.0)(typescript@5.5.2)
'@typescript-eslint/scope-manager': 7.16.1
'@typescript-eslint/type-utils': 7.16.1(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/utils': 7.16.1(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/type-utils': 7.16.1(eslint@8.57.0)(typescript@5.5.2)
'@typescript-eslint/utils': 7.16.1(eslint@8.57.0)(typescript@5.5.2)
'@typescript-eslint/visitor-keys': 7.16.1
eslint: 8.57.0
graphemer: 1.4.0
ignore: 5.3.1
natural-compare: 1.4.0
ts-api-utils: 1.3.0(typescript@5.5.3)
ts-api-utils: 1.3.0(typescript@5.5.2)
optionalDependencies:
typescript: 5.5.3
typescript: 5.5.2
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3)':
'@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.2)':
dependencies:
'@typescript-eslint/scope-manager': 7.16.1
'@typescript-eslint/types': 7.16.1
'@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3)
'@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.2)
'@typescript-eslint/visitor-keys': 7.16.1
debug: 4.3.5
eslint: 8.57.0
optionalDependencies:
typescript: 5.5.3
typescript: 5.5.2
transitivePeerDependencies:
- supports-color
@ -5059,21 +5090,21 @@ snapshots:
'@typescript-eslint/types': 7.16.1
'@typescript-eslint/visitor-keys': 7.16.1
'@typescript-eslint/type-utils@7.16.1(eslint@8.57.0)(typescript@5.5.3)':
'@typescript-eslint/type-utils@7.16.1(eslint@8.57.0)(typescript@5.5.2)':
dependencies:
'@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3)
'@typescript-eslint/utils': 7.16.1(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.2)
'@typescript-eslint/utils': 7.16.1(eslint@8.57.0)(typescript@5.5.2)
debug: 4.3.5
eslint: 8.57.0
ts-api-utils: 1.3.0(typescript@5.5.3)
ts-api-utils: 1.3.0(typescript@5.5.2)
optionalDependencies:
typescript: 5.5.3
typescript: 5.5.2
transitivePeerDependencies:
- supports-color
'@typescript-eslint/types@7.16.1': {}
'@typescript-eslint/typescript-estree@7.16.1(typescript@5.5.3)':
'@typescript-eslint/typescript-estree@7.16.1(typescript@5.5.2)':
dependencies:
'@typescript-eslint/types': 7.16.1
'@typescript-eslint/visitor-keys': 7.16.1
@ -5082,18 +5113,18 @@ snapshots:
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.6.2
ts-api-utils: 1.3.0(typescript@5.5.3)
ts-api-utils: 1.3.0(typescript@5.5.2)
optionalDependencies:
typescript: 5.5.3
typescript: 5.5.2
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@7.16.1(eslint@8.57.0)(typescript@5.5.3)':
'@typescript-eslint/utils@7.16.1(eslint@8.57.0)(typescript@5.5.2)':
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@typescript-eslint/scope-manager': 7.16.1
'@typescript-eslint/types': 7.16.1
'@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3)
'@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.2)
eslint: 8.57.0
transitivePeerDependencies:
- supports-color
@ -5733,13 +5764,13 @@ snapshots:
optionalDependencies:
typescript: 5.3.3
create-jest@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)):
create-jest@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.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.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
jest-config: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
jest-util: 29.7.0
prompts: 2.4.2
transitivePeerDependencies:
@ -6682,16 +6713,16 @@ snapshots:
- babel-plugin-macros
- supports-color
jest-cli@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)):
jest-cli@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)):
dependencies:
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
chalk: 4.1.2
create-jest: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
create-jest: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
exit: 0.1.2
import-local: 3.1.0
jest-config: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
jest-config: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
jest-util: 29.7.0
jest-validate: 29.7.0
yargs: 17.7.2
@ -6701,7 +6732,7 @@ snapshots:
- supports-color
- ts-node
jest-config@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)):
jest-config@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)):
dependencies:
'@babel/core': 7.24.9
'@jest/test-sequencer': 29.7.0
@ -6727,7 +6758,7 @@ snapshots:
strip-json-comments: 3.1.1
optionalDependencies:
'@types/node': 20.14.10
ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.5.3)
ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.5.2)
transitivePeerDependencies:
- babel-plugin-macros
- supports-color
@ -6953,12 +6984,12 @@ snapshots:
merge-stream: 2.0.0
supports-color: 8.1.1
jest@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)):
jest@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)):
dependencies:
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
'@jest/types': 29.6.3
import-local: 3.1.0
jest-cli: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
jest-cli: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
@ -7318,7 +7349,7 @@ snapshots:
'@opentelemetry/host-metrics': 0.35.3(@opentelemetry/api@1.9.0)
response-time: 2.3.2
nestjs-postal-client@0.0.6(rtrsvjp22aq2opwvwwi7bofxyi):
nestjs-postal-client@0.0.6(cawqvsjzhg64rgfdjtb5cpgrqu):
dependencies:
'@nestjs/cache-manager': 2.2.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(cache-manager@5.7.2)(rxjs@7.8.1)
'@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)
@ -7329,7 +7360,7 @@ snapshots:
kakious-nestjs-http-promise: 0.0.1(@nestjs/common@10.3.10(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.3.0(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(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.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))
typia: 6.5.1(typescript@5.5.3)
typia: 6.5.1(typescript@5.5.2)
transitivePeerDependencies:
- typescript
@ -7491,6 +7522,8 @@ snapshots:
path-to-regexp@0.1.7: {}
path-to-regexp@0.2.5: {}
path-to-regexp@3.2.0: {}
path-to-regexp@6.2.2: {}
@ -7546,13 +7579,13 @@ snapshots:
camelcase-css: 2.0.1
postcss: 8.4.39
postcss-load-config@4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)):
postcss-load-config@4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)):
dependencies:
lilconfig: 3.1.2
yaml: 2.4.5
optionalDependencies:
postcss: 8.4.39
ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.5.3)
ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.5.2)
postcss-nested@6.0.1(postcss@8.4.39):
dependencies:
@ -8066,7 +8099,7 @@ snapshots:
systeminformation@5.22.9: {}
tailwindcss@3.4.5(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)):
tailwindcss@3.4.5(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)):
dependencies:
'@alloc/quick-lru': 5.2.0
arg: 5.0.2
@ -8085,7 +8118,7 @@ snapshots:
postcss: 8.4.39
postcss-import: 15.1.0(postcss@8.4.39)
postcss-js: 4.0.1(postcss@8.4.39)
postcss-load-config: 4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
postcss-load-config: 4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
postcss-nested: 6.0.1(postcss@8.4.39)
postcss-selector-parser: 6.1.1
resolve: 1.22.8
@ -8160,24 +8193,24 @@ snapshots:
tree-kill@1.2.2: {}
ts-api-utils@1.3.0(typescript@5.5.3):
ts-api-utils@1.3.0(typescript@5.5.2):
dependencies:
typescript: 5.5.3
typescript: 5.5.2
ts-interface-checker@0.1.13: {}
ts-jest@29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)))(typescript@5.5.3):
ts-jest@29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)))(typescript@5.5.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.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
jest: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2))
jest-util: 29.7.0
json5: 2.2.3
lodash.memoize: 4.1.2
make-error: 1.3.6
semver: 7.6.2
typescript: 5.5.3
typescript: 5.5.2
yargs-parser: 21.1.1
optionalDependencies:
'@babel/core': 7.24.9
@ -8185,17 +8218,17 @@ snapshots:
'@jest/types': 29.6.3
babel-jest: 29.7.0(@babel/core@7.24.9)
ts-loader@9.5.1(typescript@5.5.3)(webpack@5.92.1):
ts-loader@9.5.1(typescript@5.5.2)(webpack@5.92.1):
dependencies:
chalk: 4.1.2
enhanced-resolve: 5.17.0
micromatch: 4.0.7
semver: 7.6.2
source-map: 0.7.4
typescript: 5.5.3
typescript: 5.5.2
webpack: 5.92.1
ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3):
ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11
@ -8209,7 +8242,7 @@ snapshots:
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
typescript: 5.5.3
typescript: 5.5.2
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
@ -8259,7 +8292,7 @@ snapshots:
typedarray@0.0.6: {}
typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)):
typeorm@0.3.20(ioredis@5.4.1)(mysql2@3.10.2)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2)):
dependencies:
'@sqltools/formatter': 1.2.5
app-root-path: 3.1.0
@ -8279,22 +8312,22 @@ snapshots:
optionalDependencies:
ioredis: 5.4.1
mysql2: 3.10.2
ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.5.3)
ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.5.2)
transitivePeerDependencies:
- supports-color
typescript@5.3.3: {}
typescript@5.5.3: {}
typescript@5.5.2: {}
typia@6.5.1(typescript@5.5.3):
typia@6.5.1(typescript@5.5.2):
dependencies:
'@samchon/openapi': 0.4.2
commander: 10.0.1
comment-json: 4.2.4
inquirer: 8.2.6
randexp: 0.5.3
typescript: 5.5.3
typescript: 5.5.2
uglify-js@3.18.0:
optional: true

View file

@ -1,4 +1,4 @@
import { Controller, Get, Render } from '@nestjs/common';
import { Controller, Get, Redirect, Render } from '@nestjs/common';
import { AppService } from './app.service';
import { PostalClientService } from 'nestjs-postal-client';
@ -10,9 +10,9 @@ export class AppController {
) {}
@Get()
@Render('home/index')
home() {
return { message: 'Hello world!'}
@Redirect('/auth/login')
getHello(): any {
return;
}
@Get('email_test')

View file

@ -1,15 +1,22 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
import { ConfigModule, ConfigService } from '@nestjs/config';
import config from './config/config';
import { MailModule } from './mail/mail.module';
import { RedisModule } from './redis/redis.module';
import { OpenTelemetryModule } from 'nestjs-otel';
import databaseConfig from './config/database.config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TypeOrmConfigService } from './database/database-config.service';
import { AuthModule } from './auth/auth.module';
import { UserModule } from './user/user.module';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
@Module({
imports: [
OpenTelemetryModule.forRoot({
OpenTelemetryModule.forRoot({
metrics: {
apiMetrics: {
enable: true,
@ -30,11 +37,21 @@ import { OpenTelemetryModule } from 'nestjs-otel';
ConfigModule.forRoot({
cache: true,
isGlobal: true,
load: [config],
load: [config, databaseConfig],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useClass: TypeOrmConfigService,
inject: [ConfigService],
}),
ServeStaticModule.forRoot({
serveRoot: '/assets',
rootPath: join(__dirname, '..', 'assets'),
}),
MailModule,
RedisModule,
UserModule,
AuthModule,
],
controllers: [AppController],
providers: [AppService],

View file

@ -1,10 +1,15 @@
import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { OidcController } from './controllers/oidc.controller';
import { OidcService } from './oidc/core.service';
import { UserModule } from '../user/user.module';
import { RedisModule } from '../redis/redis.module';
import { AuthController } from './controllers/auth.controller';
@Module({
imports: [],
controllers: [],
providers: [ConfigService],
imports: [UserModule, RedisModule],
controllers: [OidcController, AuthController],
providers: [ConfigService, OidcService],
exports: [],
})
export class AuthModule {}

View file

@ -0,0 +1,74 @@
import { BadRequestException, Body, Controller, Get, Post, Render, Res } from '@nestjs/common';
import { ApiExcludeEndpoint } from '@nestjs/swagger';
import { Response } from 'express';
@Controller('auth')
export class AuthController {
constructor() {}
@Post('login')
// TODO: Implement RateLimit
public async postHello(@Body() body: any): Promise<any> {
return body;
}
// TODO: Implement RateLimit
@Post('register')
public async postRegister(@Body() body: any): Promise<any> {
return body;
}
// TODO: Implement RateLimit
@Post('reset-password')
public async postForgotPassword(@Body('email') email: string): Promise<any> {
const user = await this.findUserByEmail(email);
if (!user) {
throw new BadRequestException({ error: true, message: 'User not found' });
} else {
await this.sendPasswordResetEmail(email);
return { error: false, message: 'Password reset email sent' };
}
}
// Render pages
@Get('login')
@Render('auth/login')
@ApiExcludeEndpoint()
public async getHello(): Promise<any> {
return {
forgot_password: 'forgot-password',
register: 'register',
//background_image: 'https://waterwolf.club/static/img/portal/portal7.jpg',
};
}
@Get('register')
@Render('auth/register')
@ApiExcludeEndpoint()
public async getRegister(): Promise<any> {
return {
login: 'login',
};
}
@Get('forgot-password')
@Render('auth/forgot-password')
@ApiExcludeEndpoint()
public async getForgotPassword(): Promise<any> {
return {
login: 'login',
};
}
// Helper Functions
private async findUserByEmail(email: string) {
// Implement this method to find the user by email
return false;
}
private async sendPasswordResetEmail(email: string) {
// Implement this method to send the password reset email
}
}

View file

@ -3,7 +3,7 @@ import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { promises as fs } from 'fs';
import type Provider from 'oidc-provider';
import psl from 'psl';
import type { Configuration, errors } from 'oidc-provider';
import type { Configuration, errors, KoaContextWithOIDC } from 'oidc-provider';
import { createOidcAdapter } from './adapter';
import wildcard from 'wildcard';
import {
@ -24,6 +24,7 @@ import { RedisService } from '../../redis/redis.service';
import { UserService } from 'src/user/user.service';
import { Span } from 'nestjs-otel';
import generateId from './helper/nanoid.helper';
import { context, trace } from '@opentelemetry/api';
// This is an async import for the oidc-provider package as it's now only esm and we need to use it in a commonjs environment.
async function getProvider(): Promise<{
@ -204,8 +205,7 @@ export class OidcService implements OnModuleInit {
cookies: {
keys: this.cookies,
},
// TODO: FUCKING IMPLEMENT THIS AHHHHHHHHHH
findAccount: this.userService.oidcFindAccount.bind(this),
findAccount: this.findAccount.bind(this),
ttl: {
AccessToken: ACCESS_TOKEN_LIFE,
RefreshToken: function RefreshTokenTTL(ctx, token, client) {
@ -403,7 +403,7 @@ export class OidcService implements OnModuleInit {
if (process.env.NODE_ENV === 'production') {
return __dirname + '/../../../../';
}
return __dirname + '/../../../../';
return __dirname + '/../../../';
}
/**
@ -414,4 +414,35 @@ export class OidcService implements OnModuleInit {
async generateJti(): Promise<string> {
return await generateId();
}
/**
* Fetch a user for the OIDC provider
*/
@Span()
async findAccount(ctx: KoaContextWithOIDC, sub: string) {
const user = await this.userService.getUserById(sub);
const span = trace.getSpan(context.active());
span?.setAttribute('currentSubject', user.id);
return {
accountId: user.id,
async claims(
_use: string,
scope: string,
_claims: Record<string, null | any>,
_rejected: string[],
) {
const scopes = scope.split(' ');
return {
sub: user.id,
name: scopes.includes('profile') ? user.displayName : undefined,
preferred_username: scopes.includes('profile') ? user.username : undefined,
picture: scopes.includes('profile') ? user.avatar : undefined,
email: scopes.includes('email') ? user.email : undefined,
email_verified: scopes.includes('email') ? user.emailVerified : undefined,
};
},
};
}
}

View file

@ -1,12 +1,11 @@
export default async () => ({
base: {
port: process.env.PORT || 3000,
host: process.env.HOST || 'localhost',
localUrl: `${process.env.BASE_URL}`,
},
redis: {
host: process.env['REDIS_HOST'] ?? 'localhost',
port: process.env['REDIS_POST'] ?? 6379,
password: process.env['REDIS_PASSWORD'] ?? '',
db: process.env['REDIS_DB'] ?? 0
}
db: process.env['REDIS_DB'] ?? 0,
},
});

View file

@ -0,0 +1,30 @@
import { registerAs } from '@nestjs/config';
import type { TypeOrmModuleOptions } from '@nestjs/typeorm';
export default registerAs('database', () => {
const conf: TypeOrmModuleOptions = {
type: 'mysql',
autoLoadEntities: true,
host: process.env['DATABASE_HOST'],
port: parseInt(process.env['DATABASE_PORT'] || '0', 10),
database: process.env['DATABASE_NAME'],
username: process.env['DATABASE_USERNAME'],
password: process.env['DATABASE_PASSWORD'],
logging: process.env['DATABASE_DEBUG_LOGGING'] === 'true',
migrationsRun: process.env['DATABASE_DISABLE_MIGRATIONS'] !== 'true',
synchronize: process.env['DATABASE_SYNCHRONIZE'] === 'true',
charset: 'utf8mb4',
entities: [__dirname + '/../database/*.model{.ts,.js}'],
};
console.log(__dirname + '/../database/*.model{.ts,.js}');
// Error throwing
if (!conf.host) {
throw new Error('DATABASE_HOST is not set');
}
if (!conf.port) {
throw new Error('DATABASE_PORT is not set');
}
return conf;
});

View file

@ -0,0 +1,20 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import type { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm';
import { DATABASE_MIGRATION } from './database.migration';
@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
constructor(private configService: ConfigService) {}
createTypeOrmOptions(): TypeOrmModuleOptions {
return {
...this.configService.getOrThrow<TypeOrmModuleOptions>('database', {
infer: true,
}),
migrations: DATABASE_MIGRATION,
};
}
}

View file

@ -1,4 +1,5 @@
import { ApiKey } from './models/api_keys.model';
import { User } from './models/user.model';
// Database Entities Array
export const DATABASE_ENTITIES = [User];
export const DATABASE_ENTITIES = [User, ApiKey];

View file

@ -31,7 +31,7 @@ export class User {
@Column({ length: MAX_STRING_LENGTH, nullable: true })
avatar: string;
@Column({ length: 15, enum: UserRole, default: UserRole.USER })
@Column({ length: 15, type: String })
role: UserRole;
@Column({ name: 'disabled', default: false })

View file

@ -7,4 +7,4 @@ import { RedisService } from './redis.service';
providers: [RedisService, ConfigService],
exports: [RedisService],
})
export class RedisModule {}
export class RedisModule {}

View file

@ -21,9 +21,9 @@ export class RedisService implements OnApplicationShutdown {
private readonly metricService: MetricService,
) {
this.host = configService.getOrThrow('redis.host');
this.port = +configService.get('redis.port') ?? 6789;
this.password = configService.get('redis.password') ?? '';
this.db = +configService.get('redis.db') ?? 0;
this.port = +configService.getOrThrow('redis.port');
this.password = configService.getOrThrow('redis.password');
this.db = +configService.getOrThrow('redis.db');
this.serviceConnectedObservableGauge = this.metricService.getObservableGauge(
'service.connected',
@ -44,7 +44,9 @@ export class RedisService implements OnApplicationShutdown {
});
this._ioredis.on('error', (err) => {
this.logger.error(err, 'Redis error');
// remove Error: from the error message
const errMessage = err.message.replace('Error: ', '');
this.logger.error(errMessage);
});
this.serviceConnectedObservableGauge.addCallback((result) => {

View file

@ -1,13 +1,14 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from '../database/models/user.model';
import { RedisModule } from '../redis/redis.module';
import { UserService } from './user.service';
import { DATABASE_ENTITIES } from 'src/database/database.entities';
@Module({
imports: [TypeOrmModule.forFeature([User]), RedisModule],
imports: [TypeOrmModule.forFeature(DATABASE_ENTITIES), RedisModule],
controllers: [],
providers: [],
exports: [],
providers: [UserService],
exports: [UserService],
})
export class UserModule {}

View file

@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Password Reset Page</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link href="/assets/styles.css" rel="stylesheet">
</head>
<body class="relative flex items-center justify-start min-h-screen">
<video autoplay muted loop class="video-bg">
<source src="/assets/login.webm" type="video/webm">
Your browser does not support the video tag.
</video>
<div class="overlay"></div>
<div class="relative bg-gray-800 p-8 rounded-lg shadow-lg w-full max-w-md ml-16 reset-prompt">
<h2 class="text-2xl font-bold mb-2 text-white text-center">Reset Your Password</h2>
<p class="text-gray-400 mb-6 text-center">Enter your email address and we'll send you a link to reset your password.</p>
<form id="resetForm" action="/auth/reset-password" method="POST" class="space-y-6">
<div>
<label for="email" class="block text-sm font-medium text-gray-400">Email</label>
<input type="email" id="email" name="email" required class="mt-1 block w-full px-3 py-2 bg-gray-700 text-white border border-gray-600 rounded-md shadow-sm placeholder-gray-500 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
</div>
<div>
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Reset Password</button>
</div>
</form>
<div class="mt-4 text-sm text-center">
<span class="text-gray-400">Remembered your password? </span><a href="/auth/login" class="font-medium text-indigo-500 hover:text-indigo-400">Log In</a>
</div>
<div class="mt-6 flex items-center justify-center text-gray-400 text-xs">
<svg class="w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 204.73 204.47">
<style>
.cls-1 {
fill: #fff;
stroke-width: 0px;
}
</style>
<g id="svg">
<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"/>
</g>
</g>
</svg>
Powered by Waterwolf
</div>
</div>
<script>
document.getElementById('resetForm').addEventListener('submit', async function(event) {
event.preventDefault();
const emailInput = document.getElementById('email');
const email = emailInput.value;
const response = await fetch('/auth/reset-password', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email })
});
if (!response.ok) {
emailInput.classList.add('border-red-500', 'shake');
setTimeout(() => {
emailInput.classList.remove('shake');
}, 300);
} else {
window.location.href = '/auth/login?message=Password+Reset+Email+Sent';
}
});
</script>
</body>
</html>

View file

@ -41,22 +41,26 @@
</style>
</head>
<body class="relative flex items-center justify-start min-h-screen">
{{#if background_image}}
<div class="absolute top-0 left-0 w-full h-full bg-cover bg-center bg-no-repeat" style="background-image: url('{{background_image}}')"></div>
{{else}}
<video autoplay muted loop class="video-bg">
<source src="file:///C:/Users/kakious/Desktop/login.webm" type="video/webm">
<source src="/assets/login.webm" type="video/webm">
Your browser does not support the video tag.
</video>
{{/if}}
<div class="overlay"></div>
<div class="relative bg-gray-800 p-8 rounded-lg shadow-lg w-full max-w-md ml-16 login-prompt">
<h2 class="text-2xl font-bold mb-2 text-white text-center">Welcome back!</h2>
<p class="text-gray-400 mb-6 text-center">We're so excited to see you again!</p>
<form action="{{ login_url }}" method="POST" class="space-y-6">
<div>
<label for="email" class="block text-sm font-medium text-gray-400">EMAIL OR USERNAME</label>
<input type="text" id="email" name="email" required class="mt-1 block w-full px-3 py-2 bg-gray-700 text-white border border-gray-600 rounded-md shadow-sm placeholder-gray-500 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<label for="email" class="block text-sm font-medium text-gray-400">Email or Username</label>
<input type="text" placeholder="yip@yap.yop" name="email" required class="mt-1 block w-full px-3 py-2 bg-gray-700 text-white border border-gray-600 rounded-md shadow-sm placeholder-gray-500 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
</div>
<div>
<label for="password" class="block text-sm font-medium text-gray-400">PASSWORD</label>
<input type="password" id="password" name="password" required class="mt-1 block w-full px-3 py-2 bg-gray-700 text-white border border-gray-600 rounded-md shadow-sm placeholder-gray-500 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<label for="password" class="block text-sm font-medium text-gray-400">Password</label>
<input type="password" placeholder="**********" id="password" name="password" required class="mt-1 block w-full px-3 py-2 bg-gray-700 text-white border border-gray-600 rounded-md shadow-sm placeholder-gray-500 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
</div>
<div class="flex items-center justify-between">
<div class="text-sm">

13
views/base/theme.hbs Normal file
View file

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en-us">
<head>
{{#block "head"}}
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link href="/assets/styles.css" rel="stylesheet">
{{/block}}
</head>
{{#block "body"}}
{{/block}}
</html>