Compare commits
5 Commits
2f30be8c82
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4686e0abbc | ||
|
|
2f01adeade | ||
|
|
aa8deadf1f | ||
|
|
ab8b2ef353 | ||
|
|
4905c6f1d1 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -55,4 +55,7 @@ pids
|
|||||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
/generated/prisma
|
prisma/generated
|
||||||
|
|
||||||
|
dump.rdb
|
||||||
|
|
||||||
|
|||||||
1
.woodpecker.yml
Normal file
1
.woodpecker.yml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
service:
|
||||||
@@ -1,3 +1,141 @@
|
|||||||
|
export const authOTP = (otp: number) => (
|
||||||
|
`
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Your Verification Code</title>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body{
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||||
|
background:#f4f7fb;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
color:#374151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container{
|
||||||
|
max-width:600px;
|
||||||
|
margin:40px auto;
|
||||||
|
background:#ffffff;
|
||||||
|
border-radius:10px;
|
||||||
|
padding:40px;
|
||||||
|
box-shadow:0 8px 25px rgba(0,0,0,0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo{
|
||||||
|
text-align:center;
|
||||||
|
font-size:24px;
|
||||||
|
font-weight:700;
|
||||||
|
color:#2563eb;
|
||||||
|
margin-bottom:30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
font-size:22px;
|
||||||
|
margin-bottom:10px;
|
||||||
|
color:#111827;
|
||||||
|
}
|
||||||
|
|
||||||
|
p{
|
||||||
|
font-size:15px;
|
||||||
|
color:#4b5563;
|
||||||
|
line-height:1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.otp-box{
|
||||||
|
margin:35px 0;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.otp{
|
||||||
|
display:inline-block;
|
||||||
|
font-size:32px;
|
||||||
|
letter-spacing:8px;
|
||||||
|
font-weight:700;
|
||||||
|
background:#f1f5ff;
|
||||||
|
color:#1d4ed8;
|
||||||
|
padding:18px 30px;
|
||||||
|
border-radius:8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expiry{
|
||||||
|
margin-top:12px;
|
||||||
|
font-size:13px;
|
||||||
|
color:#6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning{
|
||||||
|
margin-top:20px;
|
||||||
|
font-size:13px;
|
||||||
|
color:#6b7280;
|
||||||
|
background:#f9fafb;
|
||||||
|
padding:12px;
|
||||||
|
border-radius:6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer{
|
||||||
|
text-align:center;
|
||||||
|
font-size:12px;
|
||||||
|
color:#9ca3af;
|
||||||
|
margin-top:35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider{
|
||||||
|
height:1px;
|
||||||
|
background:#e5e7eb;
|
||||||
|
margin:30px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<div class="logo">MultiTenant SaaS</div>
|
||||||
|
|
||||||
|
<h1>Your Verification Code</h1>
|
||||||
|
|
||||||
|
<p>Hello,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Use the following One-Time Password (OTP) to continue signing in to your
|
||||||
|
<strong>MultiTenant SaaS</strong> account.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="otp-box">
|
||||||
|
<div class="otp">${otp}</div>
|
||||||
|
<div class="expiry">This code is valid for <strong>5 minutes</strong> only.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Enter this code in the verification screen to complete your login or signup.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="warning">
|
||||||
|
For security reasons, never share this code with anyone. Our team will never ask you for your OTP.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="divider"></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you did not request this code, you can safely ignore this email.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
© 2026 MultiTenant SaaS. All rights reserved.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
||||||
export const welcomeToApp =
|
export const welcomeToApp =
|
||||||
`
|
`
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { welcomeToApp } from "./auth"
|
import { welcomeToApp, authOTP } from "./auth"
|
||||||
|
|
||||||
const EmailTemplates = {
|
const EmailTemplates = {
|
||||||
|
signup_otp: (otp: number) => ({
|
||||||
|
subject: "Your MultiTenant SaaS Verification Code",
|
||||||
|
body: authOTP(otp)
|
||||||
|
}),
|
||||||
signup_completed: {
|
signup_completed: {
|
||||||
subject: "Welcome to app",
|
subject: "Welcome to app",
|
||||||
body: welcomeToApp
|
body: welcomeToApp
|
||||||
|
|||||||
@@ -9,13 +9,14 @@ import { Request, Response } from 'express';
|
|||||||
|
|
||||||
@Catch(HttpException) // What exception to catch
|
@Catch(HttpException) // What exception to catch
|
||||||
export class HttpExceptionFilter implements ExceptionFilter<HttpException> {
|
export class HttpExceptionFilter implements ExceptionFilter<HttpException> {
|
||||||
constructor(private readonly logger: Logger) {}
|
constructor(private readonly logger: Logger) { }
|
||||||
catch(exception: HttpException, host: ArgumentsHost) {
|
catch(exception: HttpException, host: ArgumentsHost) {
|
||||||
const ctx = host.switchToHttp();
|
const ctx = host.switchToHttp();
|
||||||
const request: Request = ctx.getRequest();
|
const request: Request = ctx.getRequest();
|
||||||
const response: Response = ctx.getResponse();
|
const response: Response = ctx.getResponse();
|
||||||
const status = exception.getStatus();
|
const status = exception.getStatus();
|
||||||
|
|
||||||
|
|
||||||
if (status >= 500) {
|
if (status >= 500) {
|
||||||
this.logger.warn({
|
this.logger.warn({
|
||||||
method: request.method,
|
method: request.method,
|
||||||
@@ -28,10 +29,11 @@ export class HttpExceptionFilter implements ExceptionFilter<HttpException> {
|
|||||||
exception.message = `${exception.message} not found`;
|
exception.message = `${exception.message} not found`;
|
||||||
}
|
}
|
||||||
|
|
||||||
response.status(status).json({
|
|
||||||
success: false,
|
// response.status(status).json({
|
||||||
message: exception.message,
|
// success: false,
|
||||||
statusCode: status,
|
// message: exception.message,
|
||||||
});
|
// statusCode: status,
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
common/exceptions/websocket.ts
Normal file
29
common/exceptions/websocket.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { Catch, ArgumentsHost } from '@nestjs/common';
|
||||||
|
import { BaseWsExceptionFilter, WsException } from '@nestjs/websockets';
|
||||||
|
|
||||||
|
@Catch()
|
||||||
|
export class WsValidationExceptionFilter extends BaseWsExceptionFilter {
|
||||||
|
catch(exception: unknown, host: ArgumentsHost) {
|
||||||
|
const client = host.switchToWs().getClient();
|
||||||
|
if (exception instanceof WsException) {
|
||||||
|
client.emit('exception', {
|
||||||
|
status: 'error',
|
||||||
|
message: exception.getError(),
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle ValidationPipe errors (they come as plain objects, not WsException)
|
||||||
|
if (
|
||||||
|
Array.isArray((exception as any)?.response?.message)
|
||||||
|
) {
|
||||||
|
client.emit('exception', {
|
||||||
|
status: 'error',
|
||||||
|
message: (exception as any).response.message,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.catch(exception, host);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,3 +3,4 @@ export const ROLE_KEY = '__ROLE_KEY__';
|
|||||||
export const ORG_ROLE_KEY = '__ORG_ROLE_KEY__'
|
export const ORG_ROLE_KEY = '__ORG_ROLE_KEY__'
|
||||||
export const ORG_ROLES_ALL_KEY = '__ORG_ROLE_ALL_KEY__';
|
export const ORG_ROLES_ALL_KEY = '__ORG_ROLE_ALL_KEY__';
|
||||||
export const CAN_PERFORM_KEY = '__CAN_PERFORM_KEY__';
|
export const CAN_PERFORM_KEY = '__CAN_PERFORM_KEY__';
|
||||||
|
export const TEMP_TOKEN_KEY = '__TEMP_TOKEN_KEY__';
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
||||||
"start": "nest start",
|
"start": "nest start",
|
||||||
"start:dev": "nest start --watch",
|
"start:dev": "nest start --watch",
|
||||||
|
"dev": "nest start --watch",
|
||||||
"start:debug": "nest start --debug --watch",
|
"start:debug": "nest start --debug --watch",
|
||||||
"start:prod": "node dist/main",
|
"start:prod": "node dist/main",
|
||||||
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
||||||
@@ -32,7 +33,9 @@
|
|||||||
"@nestjs/event-emitter": "^3.0.1",
|
"@nestjs/event-emitter": "^3.0.1",
|
||||||
"@nestjs/jwt": "^11.0.2",
|
"@nestjs/jwt": "^11.0.2",
|
||||||
"@nestjs/platform-express": "^11.0.1",
|
"@nestjs/platform-express": "^11.0.1",
|
||||||
|
"@nestjs/platform-socket.io": "^11.1.18",
|
||||||
"@nestjs/swagger": "^11.2.6",
|
"@nestjs/swagger": "^11.2.6",
|
||||||
|
"@nestjs/websockets": "^11.1.18",
|
||||||
"@prisma/adapter-pg": "^7.3.0",
|
"@prisma/adapter-pg": "^7.3.0",
|
||||||
"@prisma/client": "^7.3.0",
|
"@prisma/client": "^7.3.0",
|
||||||
"bcrypt": "^6.0.0",
|
"bcrypt": "^6.0.0",
|
||||||
|
|||||||
198
pnpm-lock.yaml
generated
198
pnpm-lock.yaml
generated
@@ -22,7 +22,7 @@ importers:
|
|||||||
version: 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
version: 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nestjs/core':
|
'@nestjs/core':
|
||||||
specifier: ^11.0.1
|
specifier: ^11.0.1
|
||||||
version: 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
version: 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nestjs/event-emitter':
|
'@nestjs/event-emitter':
|
||||||
specifier: ^3.0.1
|
specifier: ^3.0.1
|
||||||
version: 3.0.1(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
version: 3.0.1(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
||||||
@@ -32,9 +32,15 @@ importers:
|
|||||||
'@nestjs/platform-express':
|
'@nestjs/platform-express':
|
||||||
specifier: ^11.0.1
|
specifier: ^11.0.1
|
||||||
version: 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
version: 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
||||||
|
'@nestjs/platform-socket.io':
|
||||||
|
specifier: ^11.1.18
|
||||||
|
version: 11.1.18(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(rxjs@7.8.2)
|
||||||
'@nestjs/swagger':
|
'@nestjs/swagger':
|
||||||
specifier: ^11.2.6
|
specifier: ^11.2.6
|
||||||
version: 11.2.6(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)
|
version: 11.2.6(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)
|
||||||
|
'@nestjs/websockets':
|
||||||
|
specifier: ^11.1.18
|
||||||
|
version: 11.1.18(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(@nestjs/platform-socket.io@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@prisma/adapter-pg':
|
'@prisma/adapter-pg':
|
||||||
specifier: ^7.3.0
|
specifier: ^7.3.0
|
||||||
version: 7.3.0
|
version: 7.3.0
|
||||||
@@ -1003,6 +1009,13 @@ packages:
|
|||||||
'@nestjs/common': ^11.0.0
|
'@nestjs/common': ^11.0.0
|
||||||
'@nestjs/core': ^11.0.0
|
'@nestjs/core': ^11.0.0
|
||||||
|
|
||||||
|
'@nestjs/platform-socket.io@11.1.18':
|
||||||
|
resolution: {integrity: sha512-DiFRpMIdFaHqZQFwqLqGHMdNurrKVkRkMHxIrecjooPHJNNIMgrbpYZ+oJW8hpwifUyZUL4r4uXXRy4+yFEMjA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@nestjs/common': ^11.0.0
|
||||||
|
'@nestjs/websockets': ^11.0.0
|
||||||
|
rxjs: ^7.1.0
|
||||||
|
|
||||||
'@nestjs/schematics@11.0.9':
|
'@nestjs/schematics@11.0.9':
|
||||||
resolution: {integrity: sha512-0NfPbPlEaGwIT8/TCThxLzrlz3yzDNkfRNpbL7FiplKq3w4qXpJg0JYwqgMEJnLQZm3L/L/5XjoyfJHUO3qX9g==}
|
resolution: {integrity: sha512-0NfPbPlEaGwIT8/TCThxLzrlz3yzDNkfRNpbL7FiplKq3w4qXpJg0JYwqgMEJnLQZm3L/L/5XjoyfJHUO3qX9g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1038,6 +1051,18 @@ packages:
|
|||||||
'@nestjs/platform-express':
|
'@nestjs/platform-express':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@nestjs/websockets@11.1.18':
|
||||||
|
resolution: {integrity: sha512-HLO/QGlJoJaMMDphgjbcIwW7/8EA8nnFQjf+qPvA+wWLLfPKoiFPUezc5m9YgN2A7jmzwo6YmEAXeHyqO9tvTw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@nestjs/common': ^11.0.0
|
||||||
|
'@nestjs/core': ^11.0.0
|
||||||
|
'@nestjs/platform-socket.io': ^11.0.0
|
||||||
|
reflect-metadata: ^0.1.12 || ^0.2.0
|
||||||
|
rxjs: ^7.1.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@nestjs/platform-socket.io':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@noble/hashes@1.8.0':
|
'@noble/hashes@1.8.0':
|
||||||
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
|
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
|
||||||
engines: {node: ^14.21.3 || >=16}
|
engines: {node: ^14.21.3 || >=16}
|
||||||
@@ -1149,6 +1174,9 @@ packages:
|
|||||||
'@sinonjs/fake-timers@10.3.0':
|
'@sinonjs/fake-timers@10.3.0':
|
||||||
resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==}
|
resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==}
|
||||||
|
|
||||||
|
'@socket.io/component-emitter@3.1.2':
|
||||||
|
resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==}
|
||||||
|
|
||||||
'@standard-schema/spec@1.1.0':
|
'@standard-schema/spec@1.1.0':
|
||||||
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
|
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
|
||||||
|
|
||||||
@@ -1293,6 +1321,9 @@ packages:
|
|||||||
'@types/cookiejar@2.1.5':
|
'@types/cookiejar@2.1.5':
|
||||||
resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==}
|
resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==}
|
||||||
|
|
||||||
|
'@types/cors@2.8.19':
|
||||||
|
resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==}
|
||||||
|
|
||||||
'@types/eslint-scope@3.7.7':
|
'@types/eslint-scope@3.7.7':
|
||||||
resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
|
resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
|
||||||
|
|
||||||
@@ -1377,6 +1408,9 @@ packages:
|
|||||||
'@types/validator@13.15.10':
|
'@types/validator@13.15.10':
|
||||||
resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==}
|
resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==}
|
||||||
|
|
||||||
|
'@types/ws@8.18.1':
|
||||||
|
resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
|
||||||
|
|
||||||
'@types/yargs-parser@21.0.3':
|
'@types/yargs-parser@21.0.3':
|
||||||
resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
|
resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
|
||||||
|
|
||||||
@@ -1533,6 +1567,10 @@ packages:
|
|||||||
'@xtuc/long@4.2.2':
|
'@xtuc/long@4.2.2':
|
||||||
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
|
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
|
||||||
|
|
||||||
|
accepts@1.3.8:
|
||||||
|
resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
|
||||||
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
accepts@2.0.0:
|
accepts@2.0.0:
|
||||||
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
|
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
@@ -1695,6 +1733,10 @@ packages:
|
|||||||
base64-js@1.5.1:
|
base64-js@1.5.1:
|
||||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||||
|
|
||||||
|
base64id@2.0.0:
|
||||||
|
resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==}
|
||||||
|
engines: {node: ^4.5.0 || >= 5.9}
|
||||||
|
|
||||||
baseline-browser-mapping@2.9.19:
|
baseline-browser-mapping@2.9.19:
|
||||||
resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==}
|
resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -2117,6 +2159,14 @@ packages:
|
|||||||
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
|
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
|
engine.io-parser@5.2.3:
|
||||||
|
resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==}
|
||||||
|
engines: {node: '>=10.0.0'}
|
||||||
|
|
||||||
|
engine.io@6.6.6:
|
||||||
|
resolution: {integrity: sha512-U2SN0w3OpjFRVlrc17E6TMDmH58Xl9rai1MblNjAdwWp07Kk+llmzX0hjDpQdrDGzwmvOtgM5yI+meYX6iZ2xA==}
|
||||||
|
engines: {node: '>=10.2.0'}
|
||||||
|
|
||||||
enhanced-resolve@5.19.0:
|
enhanced-resolve@5.19.0:
|
||||||
resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==}
|
resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
@@ -3120,6 +3170,10 @@ packages:
|
|||||||
natural-compare@1.4.0:
|
natural-compare@1.4.0:
|
||||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||||
|
|
||||||
|
negotiator@0.6.3:
|
||||||
|
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
|
||||||
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
negotiator@1.0.0:
|
negotiator@1.0.0:
|
||||||
resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
|
resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
@@ -3179,6 +3233,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
object-hash@3.0.0:
|
||||||
|
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
object-inspect@1.13.4:
|
object-inspect@1.13.4:
|
||||||
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
|
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -3634,6 +3692,17 @@ packages:
|
|||||||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
socket.io-adapter@2.5.6:
|
||||||
|
resolution: {integrity: sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==}
|
||||||
|
|
||||||
|
socket.io-parser@4.2.6:
|
||||||
|
resolution: {integrity: sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==}
|
||||||
|
engines: {node: '>=10.0.0'}
|
||||||
|
|
||||||
|
socket.io@4.8.3:
|
||||||
|
resolution: {integrity: sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==}
|
||||||
|
engines: {node: '>=10.2.0'}
|
||||||
|
|
||||||
sort-keys-length@1.0.1:
|
sort-keys-length@1.0.1:
|
||||||
resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==}
|
resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -4047,6 +4116,18 @@ packages:
|
|||||||
resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==}
|
resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==}
|
||||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||||
|
|
||||||
|
ws@8.18.3:
|
||||||
|
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
|
||||||
|
engines: {node: '>=10.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
bufferutil: ^4.0.1
|
||||||
|
utf-8-validate: '>=5.0.2'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
bufferutil:
|
||||||
|
optional: true
|
||||||
|
utf-8-validate:
|
||||||
|
optional: true
|
||||||
|
|
||||||
xtend@4.0.2:
|
xtend@4.0.2:
|
||||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||||
engines: {node: '>=0.4'}
|
engines: {node: '>=0.4'}
|
||||||
@@ -4351,7 +4432,7 @@ snapshots:
|
|||||||
'@bull-board/api': 6.20.6(@bull-board/ui@6.20.6)
|
'@bull-board/api': 6.20.6(@bull-board/ui@6.20.6)
|
||||||
'@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
'@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
||||||
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
reflect-metadata: 0.2.2
|
reflect-metadata: 0.2.2
|
||||||
rxjs: 7.8.2
|
rxjs: 7.8.2
|
||||||
|
|
||||||
@@ -4919,21 +5000,21 @@ snapshots:
|
|||||||
'@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)':
|
'@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
'@nestjs/bullmq@11.0.4(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(bullmq@5.73.0)':
|
'@nestjs/bullmq@11.0.4(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(bullmq@5.73.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
'@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
||||||
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
bullmq: 5.73.0
|
bullmq: 5.73.0
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
'@nestjs/cache-manager@3.1.0(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(cache-manager@7.2.8)(keyv@5.6.0)(rxjs@7.8.2)':
|
'@nestjs/cache-manager@3.1.0(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(cache-manager@7.2.8)(keyv@5.6.0)(rxjs@7.8.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
cache-manager: 7.2.8
|
cache-manager: 7.2.8
|
||||||
keyv: 5.6.0
|
keyv: 5.6.0
|
||||||
rxjs: 7.8.2
|
rxjs: 7.8.2
|
||||||
@@ -4990,7 +5071,7 @@ snapshots:
|
|||||||
lodash: 4.17.23
|
lodash: 4.17.23
|
||||||
rxjs: 7.8.2
|
rxjs: 7.8.2
|
||||||
|
|
||||||
'@nestjs/core@11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)':
|
'@nestjs/core@11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nuxt/opencollective': 0.4.1
|
'@nuxt/opencollective': 0.4.1
|
||||||
@@ -5003,11 +5084,12 @@ snapshots:
|
|||||||
uid: 2.0.2
|
uid: 2.0.2
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@nestjs/platform-express': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
'@nestjs/platform-express': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
||||||
|
'@nestjs/websockets': 11.1.18(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(@nestjs/platform-socket.io@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
|
|
||||||
'@nestjs/event-emitter@3.0.1(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)':
|
'@nestjs/event-emitter@3.0.1(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
eventemitter2: 6.4.9
|
eventemitter2: 6.4.9
|
||||||
|
|
||||||
'@nestjs/jwt@11.0.2(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))':
|
'@nestjs/jwt@11.0.2(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))':
|
||||||
@@ -5027,7 +5109,7 @@ snapshots:
|
|||||||
'@nestjs/platform-express@11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)':
|
'@nestjs/platform-express@11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
cors: 2.8.6
|
cors: 2.8.6
|
||||||
express: 5.2.1
|
express: 5.2.1
|
||||||
multer: 2.0.2
|
multer: 2.0.2
|
||||||
@@ -5036,6 +5118,18 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
'@nestjs/platform-socket.io@11.1.18(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(rxjs@7.8.2)':
|
||||||
|
dependencies:
|
||||||
|
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
|
'@nestjs/websockets': 11.1.18(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(@nestjs/platform-socket.io@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
|
rxjs: 7.8.2
|
||||||
|
socket.io: 4.8.3
|
||||||
|
tslib: 2.8.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- supports-color
|
||||||
|
- utf-8-validate
|
||||||
|
|
||||||
'@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.9.3)':
|
'@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@angular-devkit/core': 19.2.17(chokidar@4.0.3)
|
'@angular-devkit/core': 19.2.17(chokidar@4.0.3)
|
||||||
@@ -5051,7 +5145,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@microsoft/tsdoc': 0.16.0
|
'@microsoft/tsdoc': 0.16.0
|
||||||
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)
|
'@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)
|
||||||
js-yaml: 4.1.1
|
js-yaml: 4.1.1
|
||||||
lodash: 4.17.23
|
lodash: 4.17.23
|
||||||
@@ -5065,11 +5159,23 @@ snapshots:
|
|||||||
'@nestjs/testing@11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(@nestjs/platform-express@11.1.13)':
|
'@nestjs/testing@11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(@nestjs/platform-express@11.1.13)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@nestjs/platform-express': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
'@nestjs/platform-express': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)
|
||||||
|
|
||||||
|
'@nestjs/websockets@11.1.18(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.13)(@nestjs/platform-socket.io@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)':
|
||||||
|
dependencies:
|
||||||
|
'@nestjs/common': 11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
|
'@nestjs/core': 11.1.13(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
|
iterare: 1.2.1
|
||||||
|
object-hash: 3.0.0
|
||||||
|
reflect-metadata: 0.2.2
|
||||||
|
rxjs: 7.8.2
|
||||||
|
tslib: 2.8.1
|
||||||
|
optionalDependencies:
|
||||||
|
'@nestjs/platform-socket.io': 11.1.18(@nestjs/common@11.1.13(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(rxjs@7.8.2)
|
||||||
|
|
||||||
'@noble/hashes@1.8.0': {}
|
'@noble/hashes@1.8.0': {}
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
@@ -5199,6 +5305,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@sinonjs/commons': 3.0.1
|
'@sinonjs/commons': 3.0.1
|
||||||
|
|
||||||
|
'@socket.io/component-emitter@3.1.2': {}
|
||||||
|
|
||||||
'@standard-schema/spec@1.1.0': {}
|
'@standard-schema/spec@1.1.0': {}
|
||||||
|
|
||||||
'@swc/cli@0.6.0(@swc/core@1.15.11)(chokidar@4.0.3)':
|
'@swc/cli@0.6.0(@swc/core@1.15.11)(chokidar@4.0.3)':
|
||||||
@@ -5337,6 +5445,10 @@ snapshots:
|
|||||||
|
|
||||||
'@types/cookiejar@2.1.5': {}
|
'@types/cookiejar@2.1.5': {}
|
||||||
|
|
||||||
|
'@types/cors@2.8.19':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 22.19.10
|
||||||
|
|
||||||
'@types/eslint-scope@3.7.7':
|
'@types/eslint-scope@3.7.7':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/eslint': 9.6.1
|
'@types/eslint': 9.6.1
|
||||||
@@ -5443,6 +5555,10 @@ snapshots:
|
|||||||
|
|
||||||
'@types/validator@13.15.10': {}
|
'@types/validator@13.15.10': {}
|
||||||
|
|
||||||
|
'@types/ws@8.18.1':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 22.19.10
|
||||||
|
|
||||||
'@types/yargs-parser@21.0.3': {}
|
'@types/yargs-parser@21.0.3': {}
|
||||||
|
|
||||||
'@types/yargs@17.0.35':
|
'@types/yargs@17.0.35':
|
||||||
@@ -5715,6 +5831,11 @@ snapshots:
|
|||||||
|
|
||||||
'@xtuc/long@4.2.2': {}
|
'@xtuc/long@4.2.2': {}
|
||||||
|
|
||||||
|
accepts@1.3.8:
|
||||||
|
dependencies:
|
||||||
|
mime-types: 2.1.35
|
||||||
|
negotiator: 0.6.3
|
||||||
|
|
||||||
accepts@2.0.0:
|
accepts@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
mime-types: 3.0.2
|
mime-types: 3.0.2
|
||||||
@@ -5871,6 +5992,8 @@ snapshots:
|
|||||||
|
|
||||||
base64-js@1.5.1: {}
|
base64-js@1.5.1: {}
|
||||||
|
|
||||||
|
base64id@2.0.0: {}
|
||||||
|
|
||||||
baseline-browser-mapping@2.9.19: {}
|
baseline-browser-mapping@2.9.19: {}
|
||||||
|
|
||||||
bcrypt@6.0.0:
|
bcrypt@6.0.0:
|
||||||
@@ -6274,6 +6397,25 @@ snapshots:
|
|||||||
|
|
||||||
encodeurl@2.0.0: {}
|
encodeurl@2.0.0: {}
|
||||||
|
|
||||||
|
engine.io-parser@5.2.3: {}
|
||||||
|
|
||||||
|
engine.io@6.6.6:
|
||||||
|
dependencies:
|
||||||
|
'@types/cors': 2.8.19
|
||||||
|
'@types/node': 22.19.10
|
||||||
|
'@types/ws': 8.18.1
|
||||||
|
accepts: 1.3.8
|
||||||
|
base64id: 2.0.0
|
||||||
|
cookie: 0.7.2
|
||||||
|
cors: 2.8.6
|
||||||
|
debug: 4.4.3
|
||||||
|
engine.io-parser: 5.2.3
|
||||||
|
ws: 8.18.3
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- supports-color
|
||||||
|
- utf-8-validate
|
||||||
|
|
||||||
enhanced-resolve@5.19.0:
|
enhanced-resolve@5.19.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
@@ -7499,6 +7641,8 @@ snapshots:
|
|||||||
|
|
||||||
natural-compare@1.4.0: {}
|
natural-compare@1.4.0: {}
|
||||||
|
|
||||||
|
negotiator@0.6.3: {}
|
||||||
|
|
||||||
negotiator@1.0.0: {}
|
negotiator@1.0.0: {}
|
||||||
|
|
||||||
neo-async@2.6.2: {}
|
neo-async@2.6.2: {}
|
||||||
@@ -7542,6 +7686,8 @@ snapshots:
|
|||||||
|
|
||||||
object-assign@4.1.1: {}
|
object-assign@4.1.1: {}
|
||||||
|
|
||||||
|
object-hash@3.0.0: {}
|
||||||
|
|
||||||
object-inspect@1.13.4: {}
|
object-inspect@1.13.4: {}
|
||||||
|
|
||||||
ohash@2.0.11: {}
|
ohash@2.0.11: {}
|
||||||
@@ -7984,6 +8130,36 @@ snapshots:
|
|||||||
|
|
||||||
slash@3.0.0: {}
|
slash@3.0.0: {}
|
||||||
|
|
||||||
|
socket.io-adapter@2.5.6:
|
||||||
|
dependencies:
|
||||||
|
debug: 4.4.3
|
||||||
|
ws: 8.18.3
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- supports-color
|
||||||
|
- utf-8-validate
|
||||||
|
|
||||||
|
socket.io-parser@4.2.6:
|
||||||
|
dependencies:
|
||||||
|
'@socket.io/component-emitter': 3.1.2
|
||||||
|
debug: 4.4.3
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
socket.io@4.8.3:
|
||||||
|
dependencies:
|
||||||
|
accepts: 1.3.8
|
||||||
|
base64id: 2.0.0
|
||||||
|
cors: 2.8.6
|
||||||
|
debug: 4.4.3
|
||||||
|
engine.io: 6.6.6
|
||||||
|
socket.io-adapter: 2.5.6
|
||||||
|
socket.io-parser: 4.2.6
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- supports-color
|
||||||
|
- utf-8-validate
|
||||||
|
|
||||||
sort-keys-length@1.0.1:
|
sort-keys-length@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
sort-keys: 1.1.2
|
sort-keys: 1.1.2
|
||||||
@@ -8408,6 +8584,8 @@ snapshots:
|
|||||||
imurmurhash: 0.1.4
|
imurmurhash: 0.1.4
|
||||||
signal-exit: 3.0.7
|
signal-exit: 3.0.7
|
||||||
|
|
||||||
|
ws@8.18.3: {}
|
||||||
|
|
||||||
xtend@4.0.2: {}
|
xtend@4.0.2: {}
|
||||||
|
|
||||||
y18n@5.0.8: {}
|
y18n@5.0.8: {}
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* This file should be your main import to use Prisma-related types and utilities in a browser.
|
|
||||||
* Use it to get access to models, enums, and input types.
|
|
||||||
*
|
|
||||||
* This file does not contain a `PrismaClient` class, nor several other helpers that are intended as server-side only.
|
|
||||||
* See `client.ts` for the standard, server-side entry point.
|
|
||||||
*
|
|
||||||
* 🟢 You can import this file directly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as Prisma from './internal/prismaNamespaceBrowser'
|
|
||||||
export { Prisma }
|
|
||||||
export * as $Enums from './enums'
|
|
||||||
export * from './enums';
|
|
||||||
/**
|
|
||||||
* Model OrganizationJoinRequest
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type OrganizationJoinRequest = Prisma.OrganizationJoinRequestModel
|
|
||||||
/**
|
|
||||||
* Model OrganizationUserJoinTable
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type OrganizationUserJoinTable = Prisma.OrganizationUserJoinTableModel
|
|
||||||
/**
|
|
||||||
* Model Organization
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type Organization = Prisma.OrganizationModel
|
|
||||||
/**
|
|
||||||
* Model User
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type User = Prisma.UserModel
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* This file should be your main import to use Prisma. Through it you get access to all the models, enums, and input types.
|
|
||||||
* If you're looking for something you can import in the client-side of your application, please refer to the `browser.ts` file instead.
|
|
||||||
*
|
|
||||||
* 🟢 You can import this file directly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as process from 'node:process'
|
|
||||||
import * as path from 'node:path'
|
|
||||||
|
|
||||||
import * as runtime from "@prisma/client/runtime/client"
|
|
||||||
import * as $Enums from "./enums"
|
|
||||||
import * as $Class from "./internal/class"
|
|
||||||
import * as Prisma from "./internal/prismaNamespace"
|
|
||||||
|
|
||||||
export * as $Enums from './enums'
|
|
||||||
export * from "./enums"
|
|
||||||
/**
|
|
||||||
* ## Prisma Client
|
|
||||||
*
|
|
||||||
* Type-safe database client for TypeScript
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const prisma = new PrismaClient()
|
|
||||||
* // Fetch zero or more OrganizationJoinRequests
|
|
||||||
* const organizationJoinRequests = await prisma.organizationJoinRequest.findMany()
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://pris.ly/d/client).
|
|
||||||
*/
|
|
||||||
export const PrismaClient = $Class.getPrismaClientClass()
|
|
||||||
export type PrismaClient<LogOpts extends Prisma.LogLevel = never, OmitOpts extends Prisma.PrismaClientOptions["omit"] = Prisma.PrismaClientOptions["omit"], ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = $Class.PrismaClient<LogOpts, OmitOpts, ExtArgs>
|
|
||||||
export { Prisma }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Model OrganizationJoinRequest
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type OrganizationJoinRequest = Prisma.OrganizationJoinRequestModel
|
|
||||||
/**
|
|
||||||
* Model OrganizationUserJoinTable
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type OrganizationUserJoinTable = Prisma.OrganizationUserJoinTableModel
|
|
||||||
/**
|
|
||||||
* Model Organization
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type Organization = Prisma.OrganizationModel
|
|
||||||
/**
|
|
||||||
* Model User
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type User = Prisma.UserModel
|
|
||||||
@@ -1,434 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* This file exports various common sort, input & filter types that are not directly linked to a particular model.
|
|
||||||
*
|
|
||||||
* 🟢 You can import this file directly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type * as runtime from "@prisma/client/runtime/client"
|
|
||||||
import * as $Enums from "./enums"
|
|
||||||
import type * as Prisma from "./internal/prismaNamespace"
|
|
||||||
|
|
||||||
|
|
||||||
export type StringFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
mode?: Prisma.QueryMode
|
|
||||||
not?: Prisma.NestedStringFilter<$PrismaModel> | string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORGANIZATION_JOIN_REQUEST | Prisma.EnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORGANIZATION_JOIN_REQUEST[] | Prisma.ListEnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORGANIZATION_JOIN_REQUEST[] | Prisma.ListEnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel> | $Enums.ORGANIZATION_JOIN_REQUEST
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EnumORGANIZATION_JOIN_REQUEST_TYPEFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE | Prisma.EnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE[] | Prisma.ListEnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE[] | Prisma.ListEnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORGANIZATION_JOIN_REQUEST_TYPEFilter<$PrismaModel> | $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DateTimeFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EnumORG_ROLEFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORG_ROLE | Prisma.EnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORG_ROLE[] | Prisma.ListEnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORG_ROLE[] | Prisma.ListEnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORG_ROLEFilter<$PrismaModel> | $Enums.ORG_ROLE
|
|
||||||
}
|
|
||||||
|
|
||||||
export type StringNullableFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
mode?: Prisma.QueryMode
|
|
||||||
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SortOrderInput = {
|
|
||||||
sort: Prisma.SortOrder
|
|
||||||
nulls?: Prisma.NullsOrder
|
|
||||||
}
|
|
||||||
|
|
||||||
export type StringWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
mode?: Prisma.QueryMode
|
|
||||||
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedStringFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedStringFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EnumORGANIZATION_JOIN_REQUESTWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORGANIZATION_JOIN_REQUEST | Prisma.EnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORGANIZATION_JOIN_REQUEST[] | Prisma.ListEnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORGANIZATION_JOIN_REQUEST[] | Prisma.ListEnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORGANIZATION_JOIN_REQUESTWithAggregatesFilter<$PrismaModel> | $Enums.ORGANIZATION_JOIN_REQUEST
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedEnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedEnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EnumORGANIZATION_JOIN_REQUEST_TYPEWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE | Prisma.EnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE[] | Prisma.ListEnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE[] | Prisma.ListEnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORGANIZATION_JOIN_REQUEST_TYPEWithAggregatesFilter<$PrismaModel> | $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedEnumORGANIZATION_JOIN_REQUEST_TYPEFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedEnumORGANIZATION_JOIN_REQUEST_TYPEFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EnumORG_ROLEWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORG_ROLE | Prisma.EnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORG_ROLE[] | Prisma.ListEnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORG_ROLE[] | Prisma.ListEnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORG_ROLEWithAggregatesFilter<$PrismaModel> | $Enums.ORG_ROLE
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedEnumORG_ROLEFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedEnumORG_ROLEFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type StringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
mode?: Prisma.QueryMode
|
|
||||||
not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null
|
|
||||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EnumUSER_ROLEFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.USER_ROLE | Prisma.EnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.USER_ROLE[] | Prisma.ListEnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.USER_ROLE[] | Prisma.ListEnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumUSER_ROLEFilter<$PrismaModel> | $Enums.USER_ROLE
|
|
||||||
}
|
|
||||||
|
|
||||||
export type BoolNullableFilter<$PrismaModel = never> = {
|
|
||||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel> | null
|
|
||||||
not?: Prisma.NestedBoolNullableFilter<$PrismaModel> | boolean | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DateTimeNullableFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> | Date | string | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EnumUSER_ROLEWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.USER_ROLE | Prisma.EnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.USER_ROLE[] | Prisma.ListEnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.USER_ROLE[] | Prisma.ListEnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumUSER_ROLEWithAggregatesFilter<$PrismaModel> | $Enums.USER_ROLE
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedEnumUSER_ROLEFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedEnumUSER_ROLEFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type BoolNullableWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel> | null
|
|
||||||
not?: Prisma.NestedBoolNullableWithAggregatesFilter<$PrismaModel> | boolean | null
|
|
||||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedBoolNullableFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedBoolNullableFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null
|
|
||||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedStringFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedStringFilter<$PrismaModel> | string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedEnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORGANIZATION_JOIN_REQUEST | Prisma.EnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORGANIZATION_JOIN_REQUEST[] | Prisma.ListEnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORGANIZATION_JOIN_REQUEST[] | Prisma.ListEnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel> | $Enums.ORGANIZATION_JOIN_REQUEST
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedEnumORGANIZATION_JOIN_REQUEST_TYPEFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE | Prisma.EnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE[] | Prisma.ListEnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE[] | Prisma.ListEnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORGANIZATION_JOIN_REQUEST_TYPEFilter<$PrismaModel> | $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedDateTimeFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedEnumORG_ROLEFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORG_ROLE | Prisma.EnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORG_ROLE[] | Prisma.ListEnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORG_ROLE[] | Prisma.ListEnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORG_ROLEFilter<$PrismaModel> | $Enums.ORG_ROLE
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedStringNullableFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedStringWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedStringFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedStringFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedIntFilter<$PrismaModel = never> = {
|
|
||||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
|
||||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedIntFilter<$PrismaModel> | number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedEnumORGANIZATION_JOIN_REQUESTWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORGANIZATION_JOIN_REQUEST | Prisma.EnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORGANIZATION_JOIN_REQUEST[] | Prisma.ListEnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORGANIZATION_JOIN_REQUEST[] | Prisma.ListEnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORGANIZATION_JOIN_REQUESTWithAggregatesFilter<$PrismaModel> | $Enums.ORGANIZATION_JOIN_REQUEST
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedEnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedEnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedEnumORGANIZATION_JOIN_REQUEST_TYPEWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE | Prisma.EnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE[] | Prisma.ListEnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE[] | Prisma.ListEnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORGANIZATION_JOIN_REQUEST_TYPEWithAggregatesFilter<$PrismaModel> | $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedEnumORGANIZATION_JOIN_REQUEST_TYPEFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedEnumORGANIZATION_JOIN_REQUEST_TYPEFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedDateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedEnumORG_ROLEWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.ORG_ROLE | Prisma.EnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.ORG_ROLE[] | Prisma.ListEnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.ORG_ROLE[] | Prisma.ListEnumORG_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumORG_ROLEWithAggregatesFilter<$PrismaModel> | $Enums.ORG_ROLE
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedEnumORG_ROLEFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedEnumORG_ROLEFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedStringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null
|
|
||||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedIntNullableFilter<$PrismaModel = never> = {
|
|
||||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
|
||||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
|
||||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
|
||||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedEnumUSER_ROLEFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.USER_ROLE | Prisma.EnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.USER_ROLE[] | Prisma.ListEnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.USER_ROLE[] | Prisma.ListEnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumUSER_ROLEFilter<$PrismaModel> | $Enums.USER_ROLE
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedBoolNullableFilter<$PrismaModel = never> = {
|
|
||||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel> | null
|
|
||||||
not?: Prisma.NestedBoolNullableFilter<$PrismaModel> | boolean | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedDateTimeNullableFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> | Date | string | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedEnumUSER_ROLEWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: $Enums.USER_ROLE | Prisma.EnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
in?: $Enums.USER_ROLE[] | Prisma.ListEnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: $Enums.USER_ROLE[] | Prisma.ListEnumUSER_ROLEFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedEnumUSER_ROLEWithAggregatesFilter<$PrismaModel> | $Enums.USER_ROLE
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedEnumUSER_ROLEFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedEnumUSER_ROLEFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedBoolNullableWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel> | null
|
|
||||||
not?: Prisma.NestedBoolNullableWithAggregatesFilter<$PrismaModel> | boolean | null
|
|
||||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedBoolNullableFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedBoolNullableFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedDateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null
|
|
||||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* This file exports all enum related types from the schema.
|
|
||||||
*
|
|
||||||
* 🟢 You can import this file directly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const ORGANIZATION_JOIN_REQUEST = {
|
|
||||||
PENDING: 'PENDING',
|
|
||||||
ACCEPTED: 'ACCEPTED',
|
|
||||||
REJECTED: 'REJECTED',
|
|
||||||
CANCELLED: 'CANCELLED'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type ORGANIZATION_JOIN_REQUEST = (typeof ORGANIZATION_JOIN_REQUEST)[keyof typeof ORGANIZATION_JOIN_REQUEST]
|
|
||||||
|
|
||||||
|
|
||||||
export const ORGANIZATION_JOIN_REQUEST_TYPE = {
|
|
||||||
INVITED: 'INVITED',
|
|
||||||
REQUESTED: 'REQUESTED'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type ORGANIZATION_JOIN_REQUEST_TYPE = (typeof ORGANIZATION_JOIN_REQUEST_TYPE)[keyof typeof ORGANIZATION_JOIN_REQUEST_TYPE]
|
|
||||||
|
|
||||||
|
|
||||||
export const ORG_ROLE = {
|
|
||||||
owner: 'owner',
|
|
||||||
admin: 'admin',
|
|
||||||
member: 'member'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type ORG_ROLE = (typeof ORG_ROLE)[keyof typeof ORG_ROLE]
|
|
||||||
|
|
||||||
|
|
||||||
export const USER_ROLE = {
|
|
||||||
superadmin: 'superadmin',
|
|
||||||
user: 'user'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type USER_ROLE = (typeof USER_ROLE)[keyof typeof USER_ROLE]
|
|
||||||
@@ -1,222 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* WARNING: This is an internal file that is subject to change!
|
|
||||||
*
|
|
||||||
* 🛑 Under no circumstances should you import this file directly! 🛑
|
|
||||||
*
|
|
||||||
* Please import the `PrismaClient` class from the `client.ts` file instead.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as runtime from "@prisma/client/runtime/client"
|
|
||||||
import type * as Prisma from "./prismaNamespace"
|
|
||||||
|
|
||||||
|
|
||||||
const config: runtime.GetPrismaClientConfig = {
|
|
||||||
"previewFeatures": [],
|
|
||||||
"clientVersion": "7.3.0",
|
|
||||||
"engineVersion": "9d6ad21cbbceab97458517b147a6a09ff43aa735",
|
|
||||||
"activeProvider": "postgresql",
|
|
||||||
"inlineSchema": "model OrganizationJoinRequest {\n id String @id @default(uuid())\n userId String\n orgId String\n status ORGANIZATION_JOIN_REQUEST @default(PENDING)\n requestType ORGANIZATION_JOIN_REQUEST_TYPE\n requestedOn DateTime @default(now())\n role ORG_ROLE @default(member)\n updatedAt DateTime @updatedAt\n rejectReason String?\n requestMessage String?\n\n organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n // @@unique([userId, orgId])\n @@index([userId, orgId])\n @@map(\"organization_join_request\")\n}\n\nenum ORGANIZATION_JOIN_REQUEST {\n PENDING\n ACCEPTED\n REJECTED\n CANCELLED\n}\n\nenum ORGANIZATION_JOIN_REQUEST_TYPE {\n INVITED\n REQUESTED\n}\n\nmodel OrganizationUserJoinTable {\n userId String\n orgId String\n role ORG_ROLE @default(member)\n joinedDate DateTime @default(now())\n\n organization Organization @relation(fields: [orgId], references: [id], onDelete: Restrict)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([userId, orgId])\n @@map(\"organization_user_join\")\n}\n\nenum ORG_ROLE {\n owner\n admin\n member\n}\n\nmodel Organization {\n id String @id @default(uuid())\n name String\n description String?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n members OrganizationUserJoinTable[]\n requestingMembers OrganizationJoinRequest[]\n\n @@map(\"organization\")\n}\n\n// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"../generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel User {\n id String @id @default(uuid())\n firstName String\n middleName String?\n lastName String\n email String @unique\n password String\n role USER_ROLE @default(user)\n isVerified Boolean? @default(false) // TODO: Email using queue\n refreshToken String?\n profilePicture String?\n isDeleted Boolean? @default(false)\n deletedAt DateTime?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n organizations OrganizationUserJoinTable[]\n organizationsRequested OrganizationJoinRequest[]\n\n @@map(\"user\")\n}\n\nenum USER_ROLE {\n superadmin\n user\n}\n",
|
|
||||||
"runtimeDataModel": {
|
|
||||||
"models": {},
|
|
||||||
"enums": {},
|
|
||||||
"types": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config.runtimeDataModel = JSON.parse("{\"models\":{\"OrganizationJoinRequest\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"orgId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"ORGANIZATION_JOIN_REQUEST\"},{\"name\":\"requestType\",\"kind\":\"enum\",\"type\":\"ORGANIZATION_JOIN_REQUEST_TYPE\"},{\"name\":\"requestedOn\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"ORG_ROLE\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"rejectReason\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"requestMessage\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"organization\",\"kind\":\"object\",\"type\":\"Organization\",\"relationName\":\"OrganizationToOrganizationJoinRequest\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"OrganizationJoinRequestToUser\"}],\"dbName\":\"organization_join_request\"},\"OrganizationUserJoinTable\":{\"fields\":[{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"orgId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"ORG_ROLE\"},{\"name\":\"joinedDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"organization\",\"kind\":\"object\",\"type\":\"Organization\",\"relationName\":\"OrganizationToOrganizationUserJoinTable\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"OrganizationUserJoinTableToUser\"}],\"dbName\":\"organization_user_join\"},\"Organization\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"members\",\"kind\":\"object\",\"type\":\"OrganizationUserJoinTable\",\"relationName\":\"OrganizationToOrganizationUserJoinTable\"},{\"name\":\"requestingMembers\",\"kind\":\"object\",\"type\":\"OrganizationJoinRequest\",\"relationName\":\"OrganizationToOrganizationJoinRequest\"}],\"dbName\":\"organization\"},\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"firstName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"middleName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"lastName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"USER_ROLE\"},{\"name\":\"isVerified\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"refreshToken\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profilePicture\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"isDeleted\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"organizations\",\"kind\":\"object\",\"type\":\"OrganizationUserJoinTable\",\"relationName\":\"OrganizationUserJoinTableToUser\"},{\"name\":\"organizationsRequested\",\"kind\":\"object\",\"type\":\"OrganizationJoinRequest\",\"relationName\":\"OrganizationJoinRequestToUser\"}],\"dbName\":\"user\"}},\"enums\":{},\"types\":{}}")
|
|
||||||
|
|
||||||
async function decodeBase64AsWasm(wasmBase64: string): Promise<WebAssembly.Module> {
|
|
||||||
const { Buffer } = await import('node:buffer')
|
|
||||||
const wasmArray = Buffer.from(wasmBase64, 'base64')
|
|
||||||
return new WebAssembly.Module(wasmArray)
|
|
||||||
}
|
|
||||||
|
|
||||||
config.compilerWasm = {
|
|
||||||
getRuntime: async () => await import("@prisma/client/runtime/query_compiler_fast_bg.postgresql.js"),
|
|
||||||
|
|
||||||
getQueryCompilerWasmModule: async () => {
|
|
||||||
const { wasm } = await import("@prisma/client/runtime/query_compiler_fast_bg.postgresql.wasm-base64.js")
|
|
||||||
return await decodeBase64AsWasm(wasm)
|
|
||||||
},
|
|
||||||
|
|
||||||
importName: "./query_compiler_fast_bg.js"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export type LogOptions<ClientOptions extends Prisma.PrismaClientOptions> =
|
|
||||||
'log' extends keyof ClientOptions ? ClientOptions['log'] extends Array<Prisma.LogLevel | Prisma.LogDefinition> ? Prisma.GetEvents<ClientOptions['log']> : never : never
|
|
||||||
|
|
||||||
export interface PrismaClientConstructor {
|
|
||||||
/**
|
|
||||||
* ## Prisma Client
|
|
||||||
*
|
|
||||||
* Type-safe database client for TypeScript
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const prisma = new PrismaClient()
|
|
||||||
* // Fetch zero or more OrganizationJoinRequests
|
|
||||||
* const organizationJoinRequests = await prisma.organizationJoinRequest.findMany()
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://pris.ly/d/client).
|
|
||||||
*/
|
|
||||||
|
|
||||||
new <
|
|
||||||
Options extends Prisma.PrismaClientOptions = Prisma.PrismaClientOptions,
|
|
||||||
LogOpts extends LogOptions<Options> = LogOptions<Options>,
|
|
||||||
OmitOpts extends Prisma.PrismaClientOptions['omit'] = Options extends { omit: infer U } ? U : Prisma.PrismaClientOptions['omit'],
|
|
||||||
ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs
|
|
||||||
>(options: Prisma.Subset<Options, Prisma.PrismaClientOptions> ): PrismaClient<LogOpts, OmitOpts, ExtArgs>
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ## Prisma Client
|
|
||||||
*
|
|
||||||
* Type-safe database client for TypeScript
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const prisma = new PrismaClient()
|
|
||||||
* // Fetch zero or more OrganizationJoinRequests
|
|
||||||
* const organizationJoinRequests = await prisma.organizationJoinRequest.findMany()
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://pris.ly/d/client).
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface PrismaClient<
|
|
||||||
in LogOpts extends Prisma.LogLevel = never,
|
|
||||||
in out OmitOpts extends Prisma.PrismaClientOptions['omit'] = undefined,
|
|
||||||
in out ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs
|
|
||||||
> {
|
|
||||||
[K: symbol]: { types: Prisma.TypeMap<ExtArgs>['other'] }
|
|
||||||
|
|
||||||
$on<V extends LogOpts>(eventType: V, callback: (event: V extends 'query' ? Prisma.QueryEvent : Prisma.LogEvent) => void): PrismaClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connect with the database
|
|
||||||
*/
|
|
||||||
$connect(): runtime.Types.Utils.JsPromise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disconnect from the database
|
|
||||||
*/
|
|
||||||
$disconnect(): runtime.Types.Utils.JsPromise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes a prepared raw query and returns the number of affected rows.
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const result = await prisma.$executeRaw`UPDATE User SET cool = ${true} WHERE email = ${'user@email.com'};`
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://pris.ly/d/raw-queries).
|
|
||||||
*/
|
|
||||||
$executeRaw<T = unknown>(query: TemplateStringsArray | Prisma.Sql, ...values: any[]): Prisma.PrismaPromise<number>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes a raw query and returns the number of affected rows.
|
|
||||||
* Susceptible to SQL injections, see documentation.
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const result = await prisma.$executeRawUnsafe('UPDATE User SET cool = $1 WHERE email = $2 ;', true, 'user@email.com')
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://pris.ly/d/raw-queries).
|
|
||||||
*/
|
|
||||||
$executeRawUnsafe<T = unknown>(query: string, ...values: any[]): Prisma.PrismaPromise<number>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs a prepared raw query and returns the `SELECT` data.
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const result = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${1} OR email = ${'user@email.com'};`
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://pris.ly/d/raw-queries).
|
|
||||||
*/
|
|
||||||
$queryRaw<T = unknown>(query: TemplateStringsArray | Prisma.Sql, ...values: any[]): Prisma.PrismaPromise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs a raw query and returns the `SELECT` data.
|
|
||||||
* Susceptible to SQL injections, see documentation.
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const result = await prisma.$queryRawUnsafe('SELECT * FROM User WHERE id = $1 OR email = $2;', 1, 'user@email.com')
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://pris.ly/d/raw-queries).
|
|
||||||
*/
|
|
||||||
$queryRawUnsafe<T = unknown>(query: string, ...values: any[]): Prisma.PrismaPromise<T>;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the running of a sequence of read/write operations that are guaranteed to either succeed or fail as a whole.
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const [george, bob, alice] = await prisma.$transaction([
|
|
||||||
* prisma.user.create({ data: { name: 'George' } }),
|
|
||||||
* prisma.user.create({ data: { name: 'Bob' } }),
|
|
||||||
* prisma.user.create({ data: { name: 'Alice' } }),
|
|
||||||
* ])
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://www.prisma.io/docs/concepts/components/prisma-client/transactions).
|
|
||||||
*/
|
|
||||||
$transaction<P extends Prisma.PrismaPromise<any>[]>(arg: [...P], options?: { isolationLevel?: Prisma.TransactionIsolationLevel }): runtime.Types.Utils.JsPromise<runtime.Types.Utils.UnwrapTuple<P>>
|
|
||||||
|
|
||||||
$transaction<R>(fn: (prisma: Omit<PrismaClient, runtime.ITXClientDenyList>) => runtime.Types.Utils.JsPromise<R>, options?: { maxWait?: number, timeout?: number, isolationLevel?: Prisma.TransactionIsolationLevel }): runtime.Types.Utils.JsPromise<R>
|
|
||||||
|
|
||||||
$extends: runtime.Types.Extensions.ExtendsHook<"extends", Prisma.TypeMapCb<OmitOpts>, ExtArgs, runtime.Types.Utils.Call<Prisma.TypeMapCb<OmitOpts>, {
|
|
||||||
extArgs: ExtArgs
|
|
||||||
}>>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `prisma.organizationJoinRequest`: Exposes CRUD operations for the **OrganizationJoinRequest** model.
|
|
||||||
* Example usage:
|
|
||||||
* ```ts
|
|
||||||
* // Fetch zero or more OrganizationJoinRequests
|
|
||||||
* const organizationJoinRequests = await prisma.organizationJoinRequest.findMany()
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
get organizationJoinRequest(): Prisma.OrganizationJoinRequestDelegate<ExtArgs, { omit: OmitOpts }>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `prisma.organizationUserJoinTable`: Exposes CRUD operations for the **OrganizationUserJoinTable** model.
|
|
||||||
* Example usage:
|
|
||||||
* ```ts
|
|
||||||
* // Fetch zero or more OrganizationUserJoinTables
|
|
||||||
* const organizationUserJoinTables = await prisma.organizationUserJoinTable.findMany()
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
get organizationUserJoinTable(): Prisma.OrganizationUserJoinTableDelegate<ExtArgs, { omit: OmitOpts }>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `prisma.organization`: Exposes CRUD operations for the **Organization** model.
|
|
||||||
* Example usage:
|
|
||||||
* ```ts
|
|
||||||
* // Fetch zero or more Organizations
|
|
||||||
* const organizations = await prisma.organization.findMany()
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
get organization(): Prisma.OrganizationDelegate<ExtArgs, { omit: OmitOpts }>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `prisma.user`: Exposes CRUD operations for the **User** model.
|
|
||||||
* Example usage:
|
|
||||||
* ```ts
|
|
||||||
* // Fetch zero or more Users
|
|
||||||
* const users = await prisma.user.findMany()
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
get user(): Prisma.UserDelegate<ExtArgs, { omit: OmitOpts }>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getPrismaClientClass(): PrismaClientConstructor {
|
|
||||||
return runtime.getPrismaClient(config) as unknown as PrismaClientConstructor
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,155 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* WARNING: This is an internal file that is subject to change!
|
|
||||||
*
|
|
||||||
* 🛑 Under no circumstances should you import this file directly! 🛑
|
|
||||||
*
|
|
||||||
* All exports from this file are wrapped under a `Prisma` namespace object in the browser.ts file.
|
|
||||||
* While this enables partial backward compatibility, it is not part of the stable public API.
|
|
||||||
*
|
|
||||||
* If you are looking for your Models, Enums, and Input Types, please import them from the respective
|
|
||||||
* model files in the `model` directory!
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as runtime from "@prisma/client/runtime/index-browser"
|
|
||||||
|
|
||||||
export type * from '../models'
|
|
||||||
export type * from './prismaNamespace'
|
|
||||||
|
|
||||||
export const Decimal = runtime.Decimal
|
|
||||||
|
|
||||||
|
|
||||||
export const NullTypes = {
|
|
||||||
DbNull: runtime.NullTypes.DbNull as (new (secret: never) => typeof runtime.DbNull),
|
|
||||||
JsonNull: runtime.NullTypes.JsonNull as (new (secret: never) => typeof runtime.JsonNull),
|
|
||||||
AnyNull: runtime.NullTypes.AnyNull as (new (secret: never) => typeof runtime.AnyNull),
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Helper for filtering JSON entries that have `null` on the database (empty on the db)
|
|
||||||
*
|
|
||||||
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
||||||
*/
|
|
||||||
export const DbNull = runtime.DbNull
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for filtering JSON entries that have JSON `null` values (not empty on the db)
|
|
||||||
*
|
|
||||||
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
||||||
*/
|
|
||||||
export const JsonNull = runtime.JsonNull
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for filtering JSON entries that are `Prisma.DbNull` or `Prisma.JsonNull`
|
|
||||||
*
|
|
||||||
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
||||||
*/
|
|
||||||
export const AnyNull = runtime.AnyNull
|
|
||||||
|
|
||||||
|
|
||||||
export const ModelName = {
|
|
||||||
OrganizationJoinRequest: 'OrganizationJoinRequest',
|
|
||||||
OrganizationUserJoinTable: 'OrganizationUserJoinTable',
|
|
||||||
Organization: 'Organization',
|
|
||||||
User: 'User'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enums
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const TransactionIsolationLevel = runtime.makeStrictEnum({
|
|
||||||
ReadUncommitted: 'ReadUncommitted',
|
|
||||||
ReadCommitted: 'ReadCommitted',
|
|
||||||
RepeatableRead: 'RepeatableRead',
|
|
||||||
Serializable: 'Serializable'
|
|
||||||
} as const)
|
|
||||||
|
|
||||||
export type TransactionIsolationLevel = (typeof TransactionIsolationLevel)[keyof typeof TransactionIsolationLevel]
|
|
||||||
|
|
||||||
|
|
||||||
export const OrganizationJoinRequestScalarFieldEnum = {
|
|
||||||
id: 'id',
|
|
||||||
userId: 'userId',
|
|
||||||
orgId: 'orgId',
|
|
||||||
status: 'status',
|
|
||||||
requestType: 'requestType',
|
|
||||||
requestedOn: 'requestedOn',
|
|
||||||
role: 'role',
|
|
||||||
updatedAt: 'updatedAt',
|
|
||||||
rejectReason: 'rejectReason',
|
|
||||||
requestMessage: 'requestMessage'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type OrganizationJoinRequestScalarFieldEnum = (typeof OrganizationJoinRequestScalarFieldEnum)[keyof typeof OrganizationJoinRequestScalarFieldEnum]
|
|
||||||
|
|
||||||
|
|
||||||
export const OrganizationUserJoinTableScalarFieldEnum = {
|
|
||||||
userId: 'userId',
|
|
||||||
orgId: 'orgId',
|
|
||||||
role: 'role',
|
|
||||||
joinedDate: 'joinedDate'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type OrganizationUserJoinTableScalarFieldEnum = (typeof OrganizationUserJoinTableScalarFieldEnum)[keyof typeof OrganizationUserJoinTableScalarFieldEnum]
|
|
||||||
|
|
||||||
|
|
||||||
export const OrganizationScalarFieldEnum = {
|
|
||||||
id: 'id',
|
|
||||||
name: 'name',
|
|
||||||
description: 'description',
|
|
||||||
createdAt: 'createdAt',
|
|
||||||
updatedAt: 'updatedAt'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type OrganizationScalarFieldEnum = (typeof OrganizationScalarFieldEnum)[keyof typeof OrganizationScalarFieldEnum]
|
|
||||||
|
|
||||||
|
|
||||||
export const UserScalarFieldEnum = {
|
|
||||||
id: 'id',
|
|
||||||
firstName: 'firstName',
|
|
||||||
middleName: 'middleName',
|
|
||||||
lastName: 'lastName',
|
|
||||||
email: 'email',
|
|
||||||
password: 'password',
|
|
||||||
role: 'role',
|
|
||||||
isVerified: 'isVerified',
|
|
||||||
refreshToken: 'refreshToken',
|
|
||||||
profilePicture: 'profilePicture',
|
|
||||||
isDeleted: 'isDeleted',
|
|
||||||
deletedAt: 'deletedAt',
|
|
||||||
createdAt: 'createdAt',
|
|
||||||
updatedAt: 'updatedAt'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type UserScalarFieldEnum = (typeof UserScalarFieldEnum)[keyof typeof UserScalarFieldEnum]
|
|
||||||
|
|
||||||
|
|
||||||
export const SortOrder = {
|
|
||||||
asc: 'asc',
|
|
||||||
desc: 'desc'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder]
|
|
||||||
|
|
||||||
|
|
||||||
export const QueryMode = {
|
|
||||||
default: 'default',
|
|
||||||
insensitive: 'insensitive'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode]
|
|
||||||
|
|
||||||
|
|
||||||
export const NullsOrder = {
|
|
||||||
first: 'first',
|
|
||||||
last: 'last'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type NullsOrder = (typeof NullsOrder)[keyof typeof NullsOrder]
|
|
||||||
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* This is a barrel export file for all models and their related types.
|
|
||||||
*
|
|
||||||
* 🟢 You can import this file directly.
|
|
||||||
*/
|
|
||||||
export type * from './models/OrganizationJoinRequest'
|
|
||||||
export type * from './models/OrganizationUserJoinTable'
|
|
||||||
export type * from './models/Organization'
|
|
||||||
export type * from './models/User'
|
|
||||||
export type * from './commonInputTypes'
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
|||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "user_otp" (
|
||||||
|
"email" TEXT NOT NULL,
|
||||||
|
"otp" INTEGER NOT NULL,
|
||||||
|
"generatedOn" TIMESTAMP(3) NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "user_otp_email_key" ON "user_otp"("email");
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `firstName` on the `user` table. All the data in the column will be lost.
|
||||||
|
- You are about to drop the column `lastName` on the `user` table. All the data in the column will be lost.
|
||||||
|
- You are about to drop the column `middleName` on the `user` table. All the data in the column will be lost.
|
||||||
|
- You are about to drop the column `profilePicture` on the `user` table. All the data in the column will be lost.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "user" DROP COLUMN "firstName",
|
||||||
|
DROP COLUMN "lastName",
|
||||||
|
DROP COLUMN "middleName",
|
||||||
|
DROP COLUMN "profilePicture";
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "UserAdditionalInformation" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"userId" TEXT NOT NULL,
|
||||||
|
"firstName" TEXT NOT NULL,
|
||||||
|
"middleName" TEXT,
|
||||||
|
"lastName" TEXT NOT NULL,
|
||||||
|
"profilePicture" TEXT,
|
||||||
|
"address" TEXT,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "UserAdditionalInformation_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "UserAdditionalInformation_userId_key" ON "UserAdditionalInformation"("userId");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "UserAdditionalInformation" ADD CONSTRAINT "UserAdditionalInformation_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `isVerified` on the `user` table. All the data in the column will be lost.
|
||||||
|
- You are about to drop the column `generatedOn` on the `user_otp` table. All the data in the column will be lost.
|
||||||
|
- Added the required column `expiresAt` to the `user_otp` table without a default value. This is not possible if the table is not empty.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- CreateEnum
|
||||||
|
CREATE TYPE "USER_ACCOUNT_STATUS" AS ENUM ('pending', 'active', 'suspended', 'deleted');
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "user" DROP COLUMN "isVerified",
|
||||||
|
ADD COLUMN "status" "USER_ACCOUNT_STATUS" NOT NULL DEFAULT 'pending',
|
||||||
|
ALTER COLUMN "password" DROP NOT NULL;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "user_otp" DROP COLUMN "generatedOn",
|
||||||
|
ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
ADD COLUMN "expiresAt" TIMESTAMP(3) NOT NULL;
|
||||||
@@ -1,27 +1,57 @@
|
|||||||
model User {
|
model User {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
firstName String
|
email String @unique
|
||||||
middleName String?
|
password String?
|
||||||
lastName String
|
role USER_ROLE @default(user)
|
||||||
email String @unique
|
refreshToken String?
|
||||||
password String
|
status USER_ACCOUNT_STATUS @default(pending)
|
||||||
role USER_ROLE @default(user)
|
isDeleted Boolean? @default(false)
|
||||||
isVerified Boolean? @default(false) // TODO: Email using queue
|
deletedAt DateTime?
|
||||||
refreshToken String?
|
|
||||||
profilePicture String?
|
|
||||||
isDeleted Boolean? @default(false)
|
|
||||||
deletedAt DateTime?
|
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
organizations OrganizationUserJoinTable[]
|
organizations OrganizationUserJoinTable[]
|
||||||
organizationsRequested OrganizationJoinRequest[]
|
organizationsRequested OrganizationJoinRequest[]
|
||||||
|
userAdditionalInformation UserAdditionalInformation?
|
||||||
|
|
||||||
@@map("user")
|
@@map("user")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model UserAdditionalInformation {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
userId String @unique
|
||||||
|
firstName String
|
||||||
|
middleName String?
|
||||||
|
lastName String
|
||||||
|
profilePicture String?
|
||||||
|
address String?
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
}
|
||||||
|
|
||||||
|
model UserOTP {
|
||||||
|
email String @unique
|
||||||
|
otp Int
|
||||||
|
// ExipresAt is also saved so its easier to check and also
|
||||||
|
// run cron job to remove expired OTPs
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
expiresAt DateTime
|
||||||
|
|
||||||
|
@@map("user_otp")
|
||||||
|
}
|
||||||
|
|
||||||
enum USER_ROLE {
|
enum USER_ROLE {
|
||||||
superadmin
|
superadmin
|
||||||
user
|
user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum USER_ACCOUNT_STATUS {
|
||||||
|
pending
|
||||||
|
active
|
||||||
|
suspended
|
||||||
|
deleted
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
2. Also an API of my own
|
2. Also an API of my own
|
||||||
3. Production and testing env diff
|
3. Production and testing env diff
|
||||||
|
4. Testing
|
||||||
|
|
||||||
# 🏗️ SaaS Architect’s Roadmap: NestJS & DevOps
|
# 🏗️ SaaS Architect’s Roadmap: NestJS & DevOps
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { Logger, MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
import { Logger, MiddlewareConsumer, Module, NestModule, ValidationPipe } from '@nestjs/common';
|
||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { UserModule } from './user/user.module';
|
import { UserModule } from './user/user.module';
|
||||||
import { AuthModule } from './auth/auth.module';
|
import { AuthModule } from './auth/auth.module';
|
||||||
import { RequestContextMiddleware } from 'core/als/request-context.middleware';
|
import { RequestContextMiddleware } from 'core/als/request-context.middleware';
|
||||||
import { RequestContextModule } from 'core/als/request-context.module';
|
import { RequestContextModule } from 'core/als/request-context.module';
|
||||||
import { ConfigModule } from '@nestjs/config';
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
import { PrismaModule } from './prisma/prisma.module';
|
import { PrismaModule } from './prisma/prisma.module';
|
||||||
import { APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core';
|
import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core';
|
||||||
import { ResponseInterceptor } from 'common/interceptors/response.interceptor';
|
import { ResponseInterceptor } from 'common/interceptors/response.interceptor';
|
||||||
import { HttpExceptionFilter } from 'common/exceptions/exception-filter';
|
import { HttpExceptionFilter } from 'common/exceptions/exception-filter';
|
||||||
import { OrganizationModule } from './organization/organization.module';
|
import { OrganizationModule } from './organization/organization.module';
|
||||||
@@ -20,6 +20,7 @@ import { BullModule } from '@nestjs/bullmq';
|
|||||||
import { BullBoardModule } from '@bull-board/nestjs';
|
import { BullBoardModule } from '@bull-board/nestjs';
|
||||||
import { BullMQAdapter } from '@bull-board/api/bullMQAdapter';
|
import { BullMQAdapter } from '@bull-board/api/bullMQAdapter';
|
||||||
import { ExpressAdapter } from '@bull-board/express';
|
import { ExpressAdapter } from '@bull-board/express';
|
||||||
|
import { NotificationModule } from './notification/notification.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -34,12 +35,12 @@ import { ExpressAdapter } from '@bull-board/express';
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
BullBoardModule.forRoot({
|
BullBoardModule.forRoot({
|
||||||
route: '/queues', // 👈 dashboard URL
|
route: '/queues', // Dashboard URL
|
||||||
adapter: ExpressAdapter,
|
adapter: ExpressAdapter,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
BullBoardModule.forFeature({
|
BullBoardModule.forFeature({
|
||||||
name: 'mail', // 👈 register each queue you want visible
|
name: 'mail', // Register each queue you want visible
|
||||||
adapter: BullMQAdapter,
|
adapter: BullMQAdapter,
|
||||||
}),
|
}),
|
||||||
UserModule,
|
UserModule,
|
||||||
@@ -51,6 +52,7 @@ import { ExpressAdapter } from '@bull-board/express';
|
|||||||
AuthorizationModule,
|
AuthorizationModule,
|
||||||
CacheModule,
|
CacheModule,
|
||||||
MailModule,
|
MailModule,
|
||||||
|
NotificationModule,
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [
|
providers: [
|
||||||
@@ -61,9 +63,13 @@ import { ExpressAdapter } from '@bull-board/express';
|
|||||||
useClass: ResponseInterceptor,
|
useClass: ResponseInterceptor,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: APP_FILTER,
|
provide: APP_PIPE,
|
||||||
useClass: HttpExceptionFilter,
|
useClass: ValidationPipe,
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// provide: APP_FILTER,
|
||||||
|
// useClass: HttpExceptionFilter,
|
||||||
|
// },
|
||||||
// NOTE: Auto cache controller response
|
// NOTE: Auto cache controller response
|
||||||
// {
|
// {
|
||||||
// provide: APP_INTERCEPTOR,
|
// provide: APP_INTERCEPTOR,
|
||||||
@@ -72,7 +78,26 @@ import { ExpressAdapter } from '@bull-board/express';
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AppModule implements NestModule {
|
export class AppModule implements NestModule {
|
||||||
|
constructor(private readonly configService: ConfigService) { };
|
||||||
|
|
||||||
configure(consumer: MiddlewareConsumer) {
|
configure(consumer: MiddlewareConsumer) {
|
||||||
consumer.apply(RequestContextMiddleware).forRoutes('*paths');
|
consumer.apply(RequestContextMiddleware).forRoutes('*paths');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure all required env vars are present
|
||||||
|
onModuleInit() {
|
||||||
|
const requiredEnvVars = [
|
||||||
|
"TOKEN_SECRET",
|
||||||
|
"DATABASE_URL",
|
||||||
|
"BULL_MQ_REDIS_HOST",
|
||||||
|
"BULL_MQ_REDIS_PORT"
|
||||||
|
]
|
||||||
|
|
||||||
|
const missingEnvVars = requiredEnvVars.filter((envVar) => !(this.configService.get<string | number>(envVar)))
|
||||||
|
|
||||||
|
if (missingEnvVars.length > 0) {
|
||||||
|
Logger.error(`One or more env variables are missing. Add: ${missingEnvVars.join(', ')} to env file.`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,22 +5,26 @@ import {
|
|||||||
HttpStatus,
|
HttpStatus,
|
||||||
Post,
|
Post,
|
||||||
Res,
|
Res,
|
||||||
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { ApiOperation } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
|
||||||
import {
|
import {
|
||||||
|
CompleteProfileSetupRequestDTO,
|
||||||
LoginUserRequestDTO,
|
LoginUserRequestDTO,
|
||||||
LoginUserResponseDTO,
|
LoginUserResponseDTO,
|
||||||
RegisterUserRequestDTO,
|
RegisterUserRequestDTO,
|
||||||
|
ValidateUserRegisterOTPRequestDTO,
|
||||||
} from './dto';
|
} from './dto';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import { DataResponse } from 'common/http';
|
import { DataResponse } from 'common/http';
|
||||||
import { Public } from './decorators';
|
import { IsTempToken, Public } from './decorators';
|
||||||
|
import { AuthGuard } from './guards/auth.guard';
|
||||||
|
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
@Public()
|
@Public()
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
constructor(private readonly authService: AuthService) {}
|
constructor(private readonly authService: AuthService) { }
|
||||||
|
|
||||||
@ApiOperation({ summary: 'User login' })
|
@ApiOperation({ summary: 'User login' })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@@ -41,17 +45,53 @@ export class AuthController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation({ summary: 'User register' })
|
@ApiOperation({ summary: 'User register' })
|
||||||
@HttpCode(HttpStatus.CREATED)
|
|
||||||
@Post('/register')
|
@Post('/register')
|
||||||
async register(@Body() body: RegisterUserRequestDTO): Promise<string> {
|
async register(@Body() body: RegisterUserRequestDTO): Promise<string> {
|
||||||
await this.authService.register(body);
|
await this.authService.register(body);
|
||||||
|
|
||||||
return 'Registered successfully. Login to continue.';
|
return 'Check your email for OTP';
|
||||||
}
|
}
|
||||||
|
|
||||||
logout() {}
|
|
||||||
|
|
||||||
forgotPassword() {}
|
// TODO: Assign Temp Token
|
||||||
|
@ApiOperation({ summary: 'Validate OTP' })
|
||||||
|
@Post('/validate-otp')
|
||||||
|
async validateOTP(@Body() body: ValidateUserRegisterOTPRequestDTO) {
|
||||||
|
const { accessToken, refreshToken } = await this.authService.validateOtp(body);
|
||||||
|
|
||||||
regenTokens() {}
|
return {
|
||||||
|
message: 'Continue with the rest of profile setup',
|
||||||
|
data: {
|
||||||
|
accessToken,
|
||||||
|
refreshToken
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Assign Temp Token
|
||||||
|
@ApiOperation({ summary: 'Complete Profile' })
|
||||||
|
@ApiBearerAuth("access-token")
|
||||||
|
@Public(false)
|
||||||
|
@IsTempToken()
|
||||||
|
@UseGuards(AuthGuard)
|
||||||
|
@Post('/complete-profile')
|
||||||
|
async completeUserProfile(@Body() body: CompleteProfileSetupRequestDTO) {
|
||||||
|
const { accessToken, refreshToken, user } = await this.authService.completeProfileSetup(body);
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: "Welcome to our app",
|
||||||
|
data: {
|
||||||
|
accessToken,
|
||||||
|
refreshToken,
|
||||||
|
user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logout() { }
|
||||||
|
|
||||||
|
forgotPassword() { }
|
||||||
|
|
||||||
|
regenTokens() { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ import { AuthController } from './auth.controller';
|
|||||||
import { APP_GUARD } from '@nestjs/core';
|
import { APP_GUARD } from '@nestjs/core';
|
||||||
import { AuthGuard } from './guards/auth.guard';
|
import { AuthGuard } from './guards/auth.guard';
|
||||||
import { UserModule } from 'src/user/user.module';
|
import { UserModule } from 'src/user/user.module';
|
||||||
import { JwtModule } from '@nestjs/jwt';
|
|
||||||
import { RequestContextModule } from 'core/als/request-context.module';
|
import { RequestContextModule } from 'core/als/request-context.module';
|
||||||
import { BullModule } from '@nestjs/bullmq';
|
import { BullModule } from '@nestjs/bullmq';
|
||||||
import { Queue } from 'bullmq';
|
import { PrismaModule } from 'src/prisma/prisma.module';
|
||||||
|
import { JwtModule } from '@nestjs/jwt';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Global()
|
@Global()
|
||||||
@Module({
|
@Module({
|
||||||
@@ -23,9 +24,18 @@ import { Queue } from 'bullmq';
|
|||||||
BullModule.registerQueue({
|
BullModule.registerQueue({
|
||||||
name: "mail"
|
name: "mail"
|
||||||
}),
|
}),
|
||||||
|
JwtModule.registerAsync({
|
||||||
|
global: true,
|
||||||
|
imports: [ConfigModule],
|
||||||
|
inject: [ConfigService],
|
||||||
|
useFactory: (config: ConfigService) => ({
|
||||||
|
secret: config.get<string>("TOKEN_SECRET"),
|
||||||
|
signOptions: { expiresIn: '7d' }
|
||||||
|
})
|
||||||
|
}),
|
||||||
UserModule,
|
UserModule,
|
||||||
JwtModule,
|
|
||||||
RequestContextModule,
|
RequestContextModule,
|
||||||
|
PrismaModule
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AuthModule { }
|
export class AuthModule { }
|
||||||
|
|||||||
@@ -1,12 +1,25 @@
|
|||||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
ConflictException,
|
||||||
|
Injectable,
|
||||||
|
InternalServerErrorException,
|
||||||
|
UnauthorizedException
|
||||||
|
} from '@nestjs/common';
|
||||||
import { Public } from './decorators';
|
import { Public } from './decorators';
|
||||||
import { LoginUserRequestDTO, RegisterUserRequestDTO } from './dto';
|
import {
|
||||||
|
CompleteProfileSetupRequestDTO,
|
||||||
|
LoginUserRequestDTO,
|
||||||
|
RegisterUserRequestDTO,
|
||||||
|
ValidateUserRegisterOTPRequestDTO
|
||||||
|
} from './dto';
|
||||||
import * as bcrypt from 'bcrypt';
|
import * as bcrypt from 'bcrypt';
|
||||||
import { UserService } from 'src/user/user.service';
|
import { UserService } from 'src/user/user.service';
|
||||||
import { TokenInputType } from './types';
|
import { OTPTokenInputType, TokenInputType } from './types';
|
||||||
import { JwtService } from '@nestjs/jwt';
|
import { JwtService } from '@nestjs/jwt';
|
||||||
import { Queue } from 'bullmq';
|
import { Queue } from 'bullmq';
|
||||||
import { InjectQueue } from '@nestjs/bullmq';
|
import { InjectQueue } from '@nestjs/bullmq';
|
||||||
|
import { PrismaService } from 'src/prisma/prisma.service';
|
||||||
|
import { RequestContextService } from 'core/als/request-context.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@Public()
|
@Public()
|
||||||
@@ -14,18 +27,125 @@ export class AuthService {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly userService: UserService,
|
private readonly userService: UserService,
|
||||||
private readonly jwtService: JwtService,
|
private readonly jwtService: JwtService,
|
||||||
|
private readonly prismaService: PrismaService,
|
||||||
|
private readonly requestContext: RequestContextService,
|
||||||
@InjectQueue('mail') private readonly mailQueue: Queue
|
@InjectQueue('mail') private readonly mailQueue: Queue
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
// Generate OTP
|
||||||
async register(dto: RegisterUserRequestDTO) {
|
async register(dto: RegisterUserRequestDTO) {
|
||||||
|
const [userExists, otpExists] = await Promise.all([
|
||||||
|
this.userService.findByEmail(dto.email),
|
||||||
|
this.userService.findByEmailInOTP(dto.email),
|
||||||
|
])
|
||||||
|
|
||||||
|
if (userExists)
|
||||||
|
throw new ConflictException("User with this email already exists");
|
||||||
|
else if (otpExists) {
|
||||||
|
/* *
|
||||||
|
* If OTP was last generated more than 2 minutes ago, regen.
|
||||||
|
* Else, do nothing
|
||||||
|
* */
|
||||||
|
const now = Number(new Date()) / 1000;
|
||||||
|
const generatedPlusTwoMin = (Number(otpExists.createdAt) / 1000) + 60 * 2;
|
||||||
|
|
||||||
|
if (generatedPlusTwoMin > now) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const otp = this.genOtp()
|
||||||
|
|
||||||
|
await this.prismaService.$transaction(async (tx) => {
|
||||||
|
this.requestContext.tx = tx;
|
||||||
|
await this.userService.updateOTPByEmail(dto.email, otp);
|
||||||
|
})
|
||||||
|
|
||||||
|
this.mailQueue.add('send-register-otp-email', {
|
||||||
|
email: dto.email,
|
||||||
|
otp: otp
|
||||||
|
}, {
|
||||||
|
attempts: 3,
|
||||||
|
backoff: {
|
||||||
|
type: "exponential",
|
||||||
|
delay: 3000
|
||||||
|
},
|
||||||
|
removeOnComplete: true, // clean up Redis after success
|
||||||
|
removeOnFail: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate OTP
|
||||||
|
async validateOtp(dto: ValidateUserRegisterOTPRequestDTO) {
|
||||||
|
const otpExists = await this.userService.findByEmailInOTP(dto.email)
|
||||||
|
const now = Number(new Date()) / 1000;
|
||||||
|
|
||||||
|
if (!otpExists)
|
||||||
|
throw new BadRequestException("No OTP request found")
|
||||||
|
else if (otpExists.otp !== dto.otp)
|
||||||
|
throw new BadRequestException("Invalid OTP")
|
||||||
|
else if ((Number(otpExists.expiresAt) / 1000 < now)) {
|
||||||
|
await this.userService.removeByEmailInOTP(dto.email);
|
||||||
|
throw new BadRequestException("OTP has expired")
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await this.prismaService.$transaction(async (tx) => {
|
||||||
|
this.requestContext.tx = tx;
|
||||||
|
await this.userService.removeByEmailInOTP(dto.email);
|
||||||
|
return await this.userService.initializeUserWithEmail(dto.email)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!user)
|
||||||
|
throw new InternalServerErrorException()
|
||||||
|
|
||||||
|
const token = {
|
||||||
|
userId: user.id,
|
||||||
|
email: user.email,
|
||||||
|
status: user.status
|
||||||
|
}
|
||||||
|
|
||||||
|
const tokens = this.genSignedTempToken(token)
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complete rest of singup process
|
||||||
|
async completeProfileSetup(dto: CompleteProfileSetupRequestDTO) {
|
||||||
|
const user = this.requestContext.user;
|
||||||
|
if (!user)
|
||||||
|
throw new UnauthorizedException("User")
|
||||||
|
|
||||||
const hashedPassword = await bcrypt.hash(dto.password, 10);
|
const hashedPassword = await bcrypt.hash(dto.password, 10);
|
||||||
await this.userService.createUserWithPassword({
|
|
||||||
...dto,
|
const {
|
||||||
password: hashedPassword,
|
newUser,
|
||||||
});
|
userAdditionalInfo: _
|
||||||
|
} = await this.prismaService.$transaction(async (tx) => {
|
||||||
|
this.requestContext.tx = tx;
|
||||||
|
|
||||||
|
const newUser = await this.userService.createUserWithPassword(
|
||||||
|
user.email,
|
||||||
|
hashedPassword,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!newUser)
|
||||||
|
throw new UnauthorizedException()
|
||||||
|
|
||||||
|
const userAdditionalInfo = await this.userService.createUserAdditionalInformation(
|
||||||
|
newUser?.id,
|
||||||
|
dto
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
newUser,
|
||||||
|
userAdditionalInfo,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
this.mailQueue.add('send-welcome-email', {
|
this.mailQueue.add('send-welcome-email', {
|
||||||
email: dto.email
|
email: user.email,
|
||||||
}, {
|
}, {
|
||||||
attempts: 3,
|
attempts: 3,
|
||||||
backoff: {
|
backoff: {
|
||||||
@@ -36,12 +156,39 @@ export class AuthService {
|
|||||||
removeOnFail: false,
|
removeOnFail: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
return true;
|
const token = {
|
||||||
|
userId: newUser.id,
|
||||||
|
email: newUser.email,
|
||||||
|
role: newUser.role,
|
||||||
|
status: newUser.status
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
accessToken,
|
||||||
|
refreshToken
|
||||||
|
} = await this.genSignedTokens(token)
|
||||||
|
|
||||||
|
return {
|
||||||
|
accessToken,
|
||||||
|
refreshToken,
|
||||||
|
user: newUser
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async login(dto: LoginUserRequestDTO) {
|
async login(dto: LoginUserRequestDTO) {
|
||||||
const user = await this.userService.findUserForAuth(dto.email);
|
const user = await this.userService.findUserForAuth(dto.email);
|
||||||
if (!user) throw new UnauthorizedException('Invalid credentials.');
|
if (!user) throw new UnauthorizedException('Invalid credentials.');
|
||||||
|
else if (!user.password) {
|
||||||
|
const token = {
|
||||||
|
userId: user.id,
|
||||||
|
email: user.email,
|
||||||
|
status: user.status
|
||||||
|
}
|
||||||
|
|
||||||
|
const { accessToken, refreshToken } = await this.genSignedTempToken(token)
|
||||||
|
|
||||||
|
return { accessToken, refreshToken, user };
|
||||||
|
}
|
||||||
|
|
||||||
const passwordMatch = await bcrypt.compare(dto.password, user.password);
|
const passwordMatch = await bcrypt.compare(dto.password, user.password);
|
||||||
if (!passwordMatch) throw new UnauthorizedException('Invalid credentials.');
|
if (!passwordMatch) throw new UnauthorizedException('Invalid credentials.');
|
||||||
@@ -50,6 +197,7 @@ export class AuthService {
|
|||||||
userId: user.id,
|
userId: user.id,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
|
status: user.status
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Store more info: orgId, orgRole, etc
|
// TODO: Store more info: orgId, orgRole, etc
|
||||||
@@ -69,21 +217,36 @@ export class AuthService {
|
|||||||
|
|
||||||
resetPassword() { }
|
resetPassword() { }
|
||||||
|
|
||||||
// TODO: Use nest jwt
|
// TODO: If remember me is there, sign for like 30d maybe
|
||||||
private async genSignedTokens(token: TokenInputType) {
|
private async genSignedTokens(token: TokenInputType) {
|
||||||
const accessToken = await this.jwtService.signAsync(token, {
|
const accessToken = await this.jwtService.signAsync(token);
|
||||||
secret: 'demo',
|
|
||||||
});
|
|
||||||
|
|
||||||
const refreshToken = await this.jwtService.signAsync(
|
const refreshToken = await this.jwtService.signAsync(
|
||||||
{
|
{
|
||||||
userId: token.userId,
|
userId: token.userId,
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return { accessToken, refreshToken };
|
||||||
|
}
|
||||||
|
|
||||||
|
private async genSignedTempToken(token: OTPTokenInputType) {
|
||||||
|
const accessToken = await this.jwtService.signAsync(token);
|
||||||
|
|
||||||
|
const refreshToken = await this.jwtService.signAsync(
|
||||||
{
|
{
|
||||||
secret: 'demo',
|
userId: token.userId,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return { accessToken, refreshToken };
|
return { accessToken, refreshToken };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
genOtp(): number {
|
||||||
|
const array = new Uint32Array(1);
|
||||||
|
crypto.getRandomValues(array);
|
||||||
|
const otp = array[0] % 900000 + 100000;
|
||||||
|
return otp;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from './public.decorator';
|
export * from './public.decorator';
|
||||||
export * from './role.decorator';
|
export * from './role.decorator';
|
||||||
export * from './authorization.decorator';
|
export * from './authorization.decorator';
|
||||||
|
export * from './isTemp.decorator'
|
||||||
|
|||||||
4
src/auth/decorators/isTemp.decorator.ts
Normal file
4
src/auth/decorators/isTemp.decorator.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { SetMetadata } from "@nestjs/common";
|
||||||
|
import { TEMP_TOKEN_KEY } from "common/keys";
|
||||||
|
|
||||||
|
export const IsTempToken = () => SetMetadata(TEMP_TOKEN_KEY, true)
|
||||||
42
src/auth/dto/complete-setup.dto.ts
Normal file
42
src/auth/dto/complete-setup.dto.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
|
||||||
|
import { IsNotEmpty, IsOptional, IsString, MinLength } from "class-validator";
|
||||||
|
|
||||||
|
export class CompleteProfileSetupRequestDTO {
|
||||||
|
@ApiProperty({
|
||||||
|
description: "User's firstName",
|
||||||
|
example: 'John',
|
||||||
|
type: 'string',
|
||||||
|
})
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
firstName: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: "User's middleName",
|
||||||
|
example: 'Kumar',
|
||||||
|
type: 'string',
|
||||||
|
})
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
middleName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: "User's lastName",
|
||||||
|
example: 'Doe',
|
||||||
|
type: 'string',
|
||||||
|
})
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
lastName: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: "User's password",
|
||||||
|
example: '123456',
|
||||||
|
type: 'string',
|
||||||
|
minLength: 6,
|
||||||
|
})
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@MinLength(6)
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
export * from './register-user.dto';
|
export * from './register-user.dto';
|
||||||
export * from './login-user.dto';
|
export * from './login-user.dto';
|
||||||
export * from './login-response.dto';
|
export * from './login-response.dto';
|
||||||
|
export * from "./validate-otp.dto";
|
||||||
|
export * from "./complete-setup.dto";
|
||||||
|
|||||||
@@ -2,39 +2,9 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|||||||
import {
|
import {
|
||||||
IsEmail,
|
IsEmail,
|
||||||
IsNotEmpty,
|
IsNotEmpty,
|
||||||
IsOptional,
|
|
||||||
IsString,
|
|
||||||
MinLength,
|
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
export class RegisterUserRequestDTO {
|
export class RegisterUserRequestDTO {
|
||||||
@ApiProperty({
|
|
||||||
description: "User's firstName",
|
|
||||||
example: 'John',
|
|
||||||
type: 'string',
|
|
||||||
})
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
firstName: string;
|
|
||||||
|
|
||||||
@ApiPropertyOptional({
|
|
||||||
description: "User's middleName",
|
|
||||||
example: 'Kumar',
|
|
||||||
type: 'string',
|
|
||||||
})
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
middleName?: string;
|
|
||||||
|
|
||||||
@ApiProperty({
|
|
||||||
description: "User's lastName",
|
|
||||||
example: 'Doe',
|
|
||||||
type: 'string',
|
|
||||||
})
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
lastName: string;
|
|
||||||
|
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: "User's email",
|
description: "User's email",
|
||||||
example: 'user@example.com',
|
example: 'user@example.com',
|
||||||
@@ -43,15 +13,4 @@ export class RegisterUserRequestDTO {
|
|||||||
@IsEmail()
|
@IsEmail()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
email: string;
|
email: string;
|
||||||
|
|
||||||
@ApiProperty({
|
|
||||||
description: "User's password",
|
|
||||||
example: '123456',
|
|
||||||
type: 'string',
|
|
||||||
minLength: 6,
|
|
||||||
})
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@MinLength(6)
|
|
||||||
password: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/auth/dto/validate-otp.dto.ts
Normal file
22
src/auth/dto/validate-otp.dto.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
|
import { IsEmail, IsNotEmpty, IsNumber } from "class-validator";
|
||||||
|
|
||||||
|
export class ValidateUserRegisterOTPRequestDTO {
|
||||||
|
@ApiProperty({
|
||||||
|
description: "Register OTP",
|
||||||
|
example: 123456,
|
||||||
|
type: 'number',
|
||||||
|
})
|
||||||
|
@IsNumber()
|
||||||
|
@IsNotEmpty()
|
||||||
|
otp: number
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: "User's email",
|
||||||
|
example: 'user@example.com',
|
||||||
|
type: 'string',
|
||||||
|
})
|
||||||
|
@IsEmail()
|
||||||
|
@IsNotEmpty()
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
CanActivate,
|
CanActivate,
|
||||||
ExecutionContext,
|
ExecutionContext,
|
||||||
|
ForbiddenException,
|
||||||
Injectable,
|
Injectable,
|
||||||
UnauthorizedException,
|
UnauthorizedException,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
@@ -9,8 +10,10 @@ import { JwtService } from '@nestjs/jwt';
|
|||||||
import { JwtPayload } from '../types';
|
import { JwtPayload } from '../types';
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
import { Reflector } from '@nestjs/core';
|
import { Reflector } from '@nestjs/core';
|
||||||
import { PUBLIC_KEY } from 'common/keys';
|
import { PUBLIC_KEY, TEMP_TOKEN_KEY } from 'common/keys';
|
||||||
import { UserService } from 'src/user/user.service';
|
import { UserService } from 'src/user/user.service';
|
||||||
|
import { USER_ACCOUNT_STATUS } from 'prisma/generated/prisma/enums';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthGuard implements CanActivate {
|
export class AuthGuard implements CanActivate {
|
||||||
@@ -19,7 +22,8 @@ export class AuthGuard implements CanActivate {
|
|||||||
private readonly jwtService: JwtService,
|
private readonly jwtService: JwtService,
|
||||||
private readonly requestContext: RequestContextService,
|
private readonly requestContext: RequestContextService,
|
||||||
private readonly userService: UserService,
|
private readonly userService: UserService,
|
||||||
) {}
|
private readonly configService: ConfigService,
|
||||||
|
) { }
|
||||||
|
|
||||||
async canActivate(context: ExecutionContext) {
|
async canActivate(context: ExecutionContext) {
|
||||||
const request = context.switchToHttp().getRequest();
|
const request = context.switchToHttp().getRequest();
|
||||||
@@ -30,17 +34,33 @@ export class AuthGuard implements CanActivate {
|
|||||||
);
|
);
|
||||||
if (isPublicRoute) return true;
|
if (isPublicRoute) return true;
|
||||||
|
|
||||||
|
const isTempToken = this.reflector.getAllAndOverride<boolean>(
|
||||||
|
TEMP_TOKEN_KEY,
|
||||||
|
[context.getHandler(), context.getClass()],
|
||||||
|
)
|
||||||
|
|
||||||
const token = this.extractTokenFromHeader(request);
|
const token = this.extractTokenFromHeader(request);
|
||||||
if (!token) throw new UnauthorizedException();
|
if (!token) throw new UnauthorizedException();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const payload: JwtPayload = await this.jwtService.verifyAsync(token, {
|
const payload: JwtPayload = await this.jwtService.verifyAsync(token, {
|
||||||
secret: 'demo',
|
secret: this.configService.get<string>("TOKEN_SECRET"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (isTempToken && payload.status !== USER_ACCOUNT_STATUS.pending)
|
||||||
|
throw new UnauthorizedException()
|
||||||
|
|
||||||
|
|
||||||
// TODO: Redis + Org too, blacklist token
|
// TODO: Redis + Org too, blacklist token
|
||||||
const userExists = await this.userService.findById(payload.userId);
|
const userExists = await this.userService.findById(payload.userId);
|
||||||
if (!userExists) throw new UnauthorizedException();
|
if (!userExists) throw new UnauthorizedException();
|
||||||
|
|
||||||
|
// NOTE: Add more checks here (other account status)
|
||||||
|
if (userExists.status !== USER_ACCOUNT_STATUS.active) {
|
||||||
|
if (userExists.status === USER_ACCOUNT_STATUS.pending && isTempToken === undefined)
|
||||||
|
throw new ForbiddenException()
|
||||||
|
}
|
||||||
|
|
||||||
this.requestContext.set('user', payload);
|
this.requestContext.set('user', payload);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { ORG_ROLE, USER_ROLE } from 'prisma/generated/prisma/enums';
|
import { ORG_ROLE, USER_ACCOUNT_STATUS, USER_ROLE } from 'prisma/generated/prisma/enums';
|
||||||
|
|
||||||
export interface JwtPayload {
|
export interface JwtPayload {
|
||||||
iat?: number;
|
iat?: number;
|
||||||
exp?: number;
|
exp?: number;
|
||||||
orgId?: string;
|
orgId?: string;
|
||||||
orgRole?: ORG_ROLE;
|
orgRole?: ORG_ROLE;
|
||||||
|
status: USER_ACCOUNT_STATUS;
|
||||||
userId: string;
|
userId: string;
|
||||||
email: string;
|
email: string;
|
||||||
role: USER_ROLE;
|
role: USER_ROLE;
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
|
import { USER_ACCOUNT_STATUS } from "prisma/generated/prisma/enums";
|
||||||
|
|
||||||
export interface TokenInputType {
|
export interface TokenInputType {
|
||||||
userId: string;
|
userId: string;
|
||||||
email: string;
|
email: string;
|
||||||
role: string;
|
role: string;
|
||||||
|
status: USER_ACCOUNT_STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AccessTokenPayloadType extends TokenInputType {}
|
export interface OTPTokenInputType {
|
||||||
|
userId: string;
|
||||||
|
email: string;
|
||||||
|
status: USER_ACCOUNT_STATUS
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AccessTokenPayloadType extends TokenInputType { }
|
||||||
|
|
||||||
export interface RefreshTokenPayloadType {
|
export interface RefreshTokenPayloadType {
|
||||||
userId: string;
|
userId: string;
|
||||||
|
|||||||
4
src/mail/mail-job-names.ts
Normal file
4
src/mail/mail-job-names.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export const MAIL_JOBS_NAME = {
|
||||||
|
WELCOME: 'send-welcome-email',
|
||||||
|
REGISTER_OTP: 'send-register-otp-email'
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import { Processor, WorkerHost } from "@nestjs/bullmq";
|
import { Processor, WorkerHost } from "@nestjs/bullmq";
|
||||||
import { Job } from "bullmq";
|
import { Job } from "bullmq";
|
||||||
import { MailService } from "./mail.service";
|
import { MailService } from "./mail.service";
|
||||||
|
import { MAIL_JOBS_NAME } from "./mail-job-names";
|
||||||
|
import { RegisterOtpEmailJob, WelcomeEmailJob } from "./mail.interface";
|
||||||
|
|
||||||
@Processor('mail')
|
@Processor('mail')
|
||||||
export class MailConsumer extends WorkerHost {
|
export class MailConsumer extends WorkerHost {
|
||||||
@@ -8,11 +10,35 @@ export class MailConsumer extends WorkerHost {
|
|||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
async process(job: Job<{ email: string }>) {
|
// This runs, so we define handlers here
|
||||||
switch (job.name) {
|
async process(job: Job) {
|
||||||
case 'send-welcome-email':
|
const handlers: Record<string, (job: Job) => Promise<void>> = {
|
||||||
await this.mailService.sendWelcomeMail({ to: job.data.email })
|
[MAIL_JOBS_NAME.REGISTER_OTP]: (j: Job<RegisterOtpEmailJob>) =>
|
||||||
break;
|
this.handleSendOTPMail(j),
|
||||||
|
|
||||||
|
[MAIL_JOBS_NAME.WELCOME]: (j: Job<WelcomeEmailJob>) =>
|
||||||
|
this.handleSendWelcomeMail(j),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handler = handlers[job.name];
|
||||||
|
if (!handler) throw new Error(`No handler for job: ${job.name}`);
|
||||||
|
await handler(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are seperated. Using switch-case is not scalable, couldn't define types
|
||||||
|
* when there were multiple types of emails to be sent
|
||||||
|
* */
|
||||||
|
async handleSendOTPMail(job: Job<RegisterOtpEmailJob>) {
|
||||||
|
await this.mailService.sendOTPMail({
|
||||||
|
to: job.data.email,
|
||||||
|
otp: job.data.otp
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleSendWelcomeMail(job: Job<WelcomeEmailJob>) {
|
||||||
|
await this.mailService.sendWelcomeMail({ to: job.data.email })
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/mail/mail.interface.ts
Normal file
8
src/mail/mail.interface.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export interface WelcomeEmailJob {
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RegisterOtpEmailJob {
|
||||||
|
email: string;
|
||||||
|
otp: number;
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import { MailConsumer } from './mail.consumer';
|
|||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
BullModule.registerQueue({
|
BullModule.registerQueue({
|
||||||
name: "welcome_mail"
|
name: "mail"
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
providers: [MailService, MailConsumer],
|
providers: [MailService, MailConsumer],
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ export class MailService {
|
|||||||
if (!mailId || !mailPass)
|
if (!mailId || !mailPass)
|
||||||
throw new Error("Make sure MAIL_ID and MAIL_PASS environment variables are set")
|
throw new Error("Make sure MAIL_ID and MAIL_PASS environment variables are set")
|
||||||
|
|
||||||
// Use secure in prod
|
|
||||||
// TODO: A table for failed emails to retry later(actually bullmq)
|
|
||||||
this.transporter = nodemailer.createTransport({
|
this.transporter = nodemailer.createTransport({
|
||||||
host: "smtp.gmail.com",
|
host: "smtp.gmail.com",
|
||||||
port: 587,
|
port: 587,
|
||||||
@@ -49,6 +47,21 @@ export class MailService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendOTPMail({ to, otp }: { to: string, otp: number }) {
|
||||||
|
if (!this.mailServiceAvailable)
|
||||||
|
throw new Error("Mail service not available")
|
||||||
|
|
||||||
|
const email = EmailTemplates.signup_otp(otp);
|
||||||
|
|
||||||
|
await this.transporter.sendMail(
|
||||||
|
{
|
||||||
|
to,
|
||||||
|
subject: email.subject,
|
||||||
|
html: email.body
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
sendMail({ to, subject, body }: { to: string, subject: string, body: string }) {
|
sendMail({ to, subject, body }: { to: string, subject: string, body: string }) {
|
||||||
if (!this.mailServiceAvailable)
|
if (!this.mailServiceAvailable)
|
||||||
throw new Error("Mail service not available")
|
throw new Error("Mail service not available")
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { NestFactory } from '@nestjs/core';
|
|||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
||||||
import { Logger } from '@nestjs/common';
|
import { Logger, ValidationPipe } from '@nestjs/common';
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
|
|||||||
19
src/notification/notification.dto.ts
Normal file
19
src/notification/notification.dto.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import {
|
||||||
|
IsNotEmpty,
|
||||||
|
IsOptional,
|
||||||
|
IsString
|
||||||
|
} from "class-validator"
|
||||||
|
|
||||||
|
export class NotificationDTO {
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
email: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
18
src/notification/notification.gateway.spec.ts
Normal file
18
src/notification/notification.gateway.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { NotificationGateway } from './notification.gateway';
|
||||||
|
|
||||||
|
describe('NotificationGateway', () => {
|
||||||
|
let gateway: NotificationGateway;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [NotificationGateway],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
gateway = module.get<NotificationGateway>(NotificationGateway);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(gateway).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
29
src/notification/notification.gateway.ts
Normal file
29
src/notification/notification.gateway.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import {
|
||||||
|
ConnectedSocket,
|
||||||
|
MessageBody,
|
||||||
|
SubscribeMessage,
|
||||||
|
WebSocketGateway
|
||||||
|
} from "@nestjs/websockets";
|
||||||
|
import { Socket } from "net";
|
||||||
|
import { NotificationDTO } from "./notification.dto";
|
||||||
|
import { UseFilters, UsePipes, ValidationPipe } from "@nestjs/common";
|
||||||
|
import { WsValidationExceptionFilter } from "../../common/exceptions/websocket";
|
||||||
|
|
||||||
|
@WebSocketGateway()
|
||||||
|
@UsePipes(new ValidationPipe({
|
||||||
|
whitelist: true,
|
||||||
|
forbidNonWhitelisted: true,
|
||||||
|
transform: true,
|
||||||
|
}))
|
||||||
|
@UseFilters(new WsValidationExceptionFilter())
|
||||||
|
export class NotificationGateway {
|
||||||
|
|
||||||
|
@SubscribeMessage('hello')
|
||||||
|
handleHello(
|
||||||
|
@MessageBody() body: NotificationDTO,
|
||||||
|
@ConnectedSocket() client: Socket
|
||||||
|
) {
|
||||||
|
console.log(body);
|
||||||
|
client.emit("hello", "Hi")
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/notification/notification.module.ts
Normal file
8
src/notification/notification.module.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { NotificationService } from './notification.service';
|
||||||
|
import { NotificationGateway } from './notification.gateway';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
providers: [NotificationService, NotificationGateway]
|
||||||
|
})
|
||||||
|
export class NotificationModule {}
|
||||||
18
src/notification/notification.service.spec.ts
Normal file
18
src/notification/notification.service.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { NotificationService } from './notification.service';
|
||||||
|
|
||||||
|
describe('NotificationService', () => {
|
||||||
|
let service: NotificationService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [NotificationService],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<NotificationService>(NotificationService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
4
src/notification/notification.service.ts
Normal file
4
src/notification/notification.service.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class NotificationService {}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
ForbiddenException,
|
|
||||||
Injectable,
|
Injectable,
|
||||||
NotFoundException,
|
NotFoundException,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
@@ -12,8 +11,6 @@ import {
|
|||||||
ORGANIZATION_JOIN_REQUEST,
|
ORGANIZATION_JOIN_REQUEST,
|
||||||
ORGANIZATION_JOIN_REQUEST_TYPE,
|
ORGANIZATION_JOIN_REQUEST_TYPE,
|
||||||
} from 'prisma/generated/prisma/enums';
|
} from 'prisma/generated/prisma/enums';
|
||||||
import { AuthorizationService } from 'src/authorization/authorization.service';
|
|
||||||
import { USER_ORGANIZATION_OPERATIONS } from 'src/authorization/operations';
|
|
||||||
import { Prisma } from 'prisma/generated/prisma/client';
|
import { Prisma } from 'prisma/generated/prisma/client';
|
||||||
import { JoinRequestToOrganizationRequestDTO } from './dto/join-request.dto';
|
import { JoinRequestToOrganizationRequestDTO } from './dto/join-request.dto';
|
||||||
import { USER_ORG_ACCEPT_REJECT_ACTION } from './constants';
|
import { USER_ORG_ACCEPT_REJECT_ACTION } from './constants';
|
||||||
@@ -24,7 +21,6 @@ export class OrganizationMembershipService {
|
|||||||
private readonly userService: UserService,
|
private readonly userService: UserService,
|
||||||
private readonly orgService: OrganizationService,
|
private readonly orgService: OrganizationService,
|
||||||
private readonly prisma: PrismaService,
|
private readonly prisma: PrismaService,
|
||||||
private readonly authorization: AuthorizationService,
|
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
/* *
|
/* *
|
||||||
@@ -121,7 +117,12 @@ export class OrganizationMembershipService {
|
|||||||
requestType: joinReqType,
|
requestType: joinReqType,
|
||||||
status: ORGANIZATION_JOIN_REQUEST.PENDING
|
status: ORGANIZATION_JOIN_REQUEST.PENDING
|
||||||
},
|
},
|
||||||
include: { user: { select: { firstName: true, email: true } } }
|
include: {
|
||||||
|
user: {
|
||||||
|
include: { userAdditionalInformation: { select: { firstName: true } } },
|
||||||
|
select: { email: true }
|
||||||
|
},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,9 +443,9 @@ export class OrganizationMembershipService {
|
|||||||
include: {
|
include: {
|
||||||
user: {
|
user: {
|
||||||
select: {
|
select: {
|
||||||
firstName: true,
|
|
||||||
email: true
|
email: true
|
||||||
}
|
},
|
||||||
|
include: { userAdditionalInformation: { select: { firstName: true } } },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,18 +4,21 @@ import {
|
|||||||
OnModuleDestroy,
|
OnModuleDestroy,
|
||||||
OnModuleInit,
|
OnModuleInit,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { PrismaClient } from 'prisma/generated/prisma/client';
|
import { Prisma, PrismaClient } from 'prisma/generated/prisma/client';
|
||||||
import { Pool } from 'pg';
|
import { Pool } from 'pg';
|
||||||
import { PrismaPg } from '@prisma/adapter-pg';
|
import { PrismaPg } from '@prisma/adapter-pg';
|
||||||
import { RequestContextService } from 'core/als/request-context.service';
|
import { RequestContextService } from 'core/als/request-context.service';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
import { TransactionClient } from 'prisma/generated/prisma/internal/prismaNamespace';
|
||||||
|
|
||||||
@Global()
|
@Global()
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PrismaService
|
export class PrismaService
|
||||||
extends PrismaClient
|
extends PrismaClient
|
||||||
implements OnModuleDestroy, OnModuleInit
|
implements OnModuleDestroy, OnModuleInit {
|
||||||
{
|
|
||||||
|
private readonly db: PrismaClient;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly ctx: RequestContextService,
|
private readonly ctx: RequestContextService,
|
||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
@@ -31,6 +34,8 @@ export class PrismaService
|
|||||||
adapter: adapter,
|
adapter: adapter,
|
||||||
log: ['info', 'warn'],
|
log: ['info', 'warn'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.db = new PrismaClient({ adapter, log: ['warn', 'info', 'error'] })
|
||||||
}
|
}
|
||||||
async onModuleInit() {
|
async onModuleInit() {
|
||||||
try {
|
try {
|
||||||
@@ -50,7 +55,7 @@ export class PrismaService
|
|||||||
* For shared transaction across services. If present, return the transaction.
|
* For shared transaction across services. If present, return the transaction.
|
||||||
* Else returns itself.
|
* Else returns itself.
|
||||||
* */
|
* */
|
||||||
get client() {
|
get client(): TransactionClient {
|
||||||
return this.ctx.get().tx ?? this;
|
return this.ctx.tx ?? this.db;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,15 @@
|
|||||||
import { User } from 'prisma/generated/prisma/client';
|
import { User, USER_ACCOUNT_STATUS } from 'prisma/generated/prisma/client';
|
||||||
|
|
||||||
export class UserDTO {
|
export class UserDTO {
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly email: string;
|
readonly email: string;
|
||||||
readonly firstName: string;
|
|
||||||
readonly middleName: string | null;
|
|
||||||
readonly lastName: string;
|
|
||||||
readonly role: string;
|
readonly role: string;
|
||||||
readonly profilePicture: string | null;
|
readonly status: USER_ACCOUNT_STATUS;
|
||||||
|
|
||||||
constructor(user: User) {
|
constructor(user: User) {
|
||||||
this.id = user.id;
|
this.id = user.id;
|
||||||
this.email = user.email;
|
this.email = user.email;
|
||||||
this.firstName = user.firstName;
|
|
||||||
this.lastName = user.lastName;
|
|
||||||
this.middleName = user.middleName;
|
|
||||||
this.role = user.role;
|
this.role = user.role;
|
||||||
this.profilePicture = user.profilePicture;
|
this.status = user.status
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,50 @@
|
|||||||
import { ConflictException, Injectable } from '@nestjs/common';
|
import { ConflictException, Injectable } from '@nestjs/common';
|
||||||
import { Prisma } from 'prisma/generated/prisma/client';
|
import { Prisma, USER_ACCOUNT_STATUS } from 'prisma/generated/prisma/client';
|
||||||
import { RegisterUserRequestDTO } from 'src/auth/dto';
|
import { CompleteProfileSetupRequestDTO } from 'src/auth/dto';
|
||||||
import { PrismaService } from 'src/prisma/prisma.service';
|
import { PrismaService } from 'src/prisma/prisma.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
constructor(private readonly prisma: PrismaService) {}
|
constructor(
|
||||||
|
private readonly prisma: PrismaService,
|
||||||
|
) { }
|
||||||
|
|
||||||
async createUserWithPassword(dto: RegisterUserRequestDTO) {
|
async initializeUserWithEmail(email: string) {
|
||||||
try {
|
try {
|
||||||
return await this.prisma.user.create({
|
return await this.prisma.client.user.create({
|
||||||
data: dto,
|
data: {
|
||||||
|
email,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
||||||
|
if (err.code === 'P2002') {
|
||||||
|
throw new ConflictException('User already exists');
|
||||||
|
}
|
||||||
|
} else throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async createUserWithPassword(email: string, password: string) {
|
||||||
|
return await this.prisma.client.user.update({
|
||||||
|
where: {
|
||||||
|
email,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
password,
|
||||||
|
status: USER_ACCOUNT_STATUS.active
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async createUserAdditionalInformation(userId: string, dto: CompleteProfileSetupRequestDTO) {
|
||||||
|
const { password, ...rest } = dto;
|
||||||
|
try {
|
||||||
|
return await this.prisma.client.userAdditionalInformation.create({
|
||||||
|
data: {
|
||||||
|
userId,
|
||||||
|
...rest
|
||||||
|
},
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
||||||
@@ -22,14 +56,14 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findUserForAuth(email: string) {
|
async findUserForAuth(email: string) {
|
||||||
return await this.prisma.user.findUnique({
|
return await this.prisma.client.user.findUnique({
|
||||||
where: { email },
|
where: { email },
|
||||||
omit: { password: false }, // Password is omitted by default, we are just reverting it
|
omit: { password: false }, // Password is omitted by default, we are just reverting it
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async findById(id: string) {
|
async findById(id: string) {
|
||||||
return await this.prisma.user.findUnique({
|
return await this.prisma.client.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
id: id,
|
id: id,
|
||||||
},
|
},
|
||||||
@@ -37,7 +71,7 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findByEmail(email: string) {
|
async findByEmail(email: string) {
|
||||||
return await this.prisma.user.findUnique({
|
return await this.prisma.client.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
email: email,
|
email: email,
|
||||||
},
|
},
|
||||||
@@ -45,9 +79,47 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateRefreshToken(id: string, refreshToken: string) {
|
async updateRefreshToken(id: string, refreshToken: string) {
|
||||||
return await this.prisma.user.update({
|
return await this.prisma.client.user.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data: { refreshToken },
|
data: { refreshToken },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USER OTP SERVICES
|
||||||
|
* */
|
||||||
|
async findByEmailInOTP(email: string) {
|
||||||
|
return await this.prisma.client.userOTP.findUnique({
|
||||||
|
where: {
|
||||||
|
email,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeByEmailInOTP(email: string) {
|
||||||
|
return await this.prisma.client.userOTP.delete({
|
||||||
|
where: {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateOTPByEmail(email: string, otp: number) {
|
||||||
|
return await this.prisma.client.userOTP.upsert({
|
||||||
|
where: {
|
||||||
|
email
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
email,
|
||||||
|
otp,
|
||||||
|
createdAt: new Date(),
|
||||||
|
expiresAt: new Date(Date.now() + 5 * 60 * 1000)
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
otp,
|
||||||
|
createdAt: new Date(),
|
||||||
|
expiresAt: new Date(Date.now() + 5 * 60 * 1000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user