feat: Organization services
This commit is contained in:
@@ -24,7 +24,12 @@ export class HttpExceptionFilter implements ExceptionFilter<HttpException> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status === 404) {
|
||||||
|
exception.message = `${exception.message} not found`;
|
||||||
|
}
|
||||||
|
|
||||||
response.status(status).json({
|
response.status(status).json({
|
||||||
|
success: false,
|
||||||
message: exception.message,
|
message: exception.message,
|
||||||
statusCode: status,
|
statusCode: status,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { DataResponse, MessageResponse } from 'common/http';
|
import { DataResponse, MessageResponse } from 'common/http';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { catchError, map } from 'rxjs/operators';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ResponseInterceptor<T> implements NestInterceptor<T, any> {
|
export class ResponseInterceptor<T> implements NestInterceptor<T, any> {
|
||||||
|
|||||||
26
common/validators/at-least-one-field.ts
Normal file
26
common/validators/at-least-one-field.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import {
|
||||||
|
registerDecorator,
|
||||||
|
ValidationArguments,
|
||||||
|
ValidationOptions,
|
||||||
|
} from 'class-validator';
|
||||||
|
|
||||||
|
export function AtLeastOneField(validationOptions?: ValidationOptions) {
|
||||||
|
return function (constructor: Function) {
|
||||||
|
registerDecorator({
|
||||||
|
name: 'atLeastOneField',
|
||||||
|
target: constructor,
|
||||||
|
propertyName: undefined as any, // important for class-level
|
||||||
|
options: validationOptions,
|
||||||
|
validator: {
|
||||||
|
validate(_: any, args: ValidationArguments) {
|
||||||
|
const object = args.object as Record<string, any>;
|
||||||
|
|
||||||
|
return Object.values(object).some((value) => value !== undefined);
|
||||||
|
},
|
||||||
|
defaultMessage() {
|
||||||
|
return 'At least one field must be provided';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
1
common/validators/index.ts
Normal file
1
common/validators/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './at-least-one-field';
|
||||||
6
common/validators/query-uuid.dto.ts
Normal file
6
common/validators/query-uuid.dto.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { IsUUID } from 'class-validator';
|
||||||
|
|
||||||
|
export class UUIDQueryDTO {
|
||||||
|
@IsUUID()
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||||
import { AsyncLocalStorage } from 'async_hooks';
|
import { AsyncLocalStorage } from 'async_hooks';
|
||||||
import { RequestContext } from './request-context.type';
|
import { RequestContext } from './request-context.type';
|
||||||
|
|
||||||
@@ -31,7 +31,9 @@ export class RequestContextService {
|
|||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
get user() {
|
get user() {
|
||||||
return this.get().user;
|
const user = this.get().user;
|
||||||
|
if (!user) throw new UnauthorizedException();
|
||||||
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
get tx() {
|
get tx() {
|
||||||
|
|||||||
@@ -36,6 +36,13 @@ export type EnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel = never> = {
|
|||||||
not?: Prisma.NestedEnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel> | $Enums.ORGANIZATION_JOIN_REQUEST
|
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> = {
|
export type DateTimeFilter<$PrismaModel = never> = {
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
@@ -95,6 +102,16 @@ export type EnumORGANIZATION_JOIN_REQUESTWithAggregatesFilter<$PrismaModel = nev
|
|||||||
_max?: 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> = {
|
export type DateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
@@ -220,6 +237,13 @@ export type NestedEnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel = never> = {
|
|||||||
not?: Prisma.NestedEnumORGANIZATION_JOIN_REQUESTFilter<$PrismaModel> | $Enums.ORGANIZATION_JOIN_REQUEST
|
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> = {
|
export type NestedDateTimeFilter<$PrismaModel = never> = {
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
@@ -283,6 +307,16 @@ export type NestedEnumORGANIZATION_JOIN_REQUESTWithAggregatesFilter<$PrismaModel
|
|||||||
_max?: 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> = {
|
export type NestedDateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
|
|||||||
@@ -18,9 +18,18 @@ export const ORGANIZATION_JOIN_REQUEST = {
|
|||||||
export type ORGANIZATION_JOIN_REQUEST = (typeof ORGANIZATION_JOIN_REQUEST)[keyof typeof ORGANIZATION_JOIN_REQUEST]
|
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 = {
|
export const ORG_ROLE = {
|
||||||
|
owner: 'owner',
|
||||||
admin: 'admin',
|
admin: 'admin',
|
||||||
user: 'user'
|
member: 'member'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export type ORG_ROLE = (typeof ORG_ROLE)[keyof typeof ORG_ROLE]
|
export type ORG_ROLE = (typeof ORG_ROLE)[keyof typeof ORG_ROLE]
|
||||||
@@ -28,7 +37,7 @@ export type ORG_ROLE = (typeof ORG_ROLE)[keyof typeof ORG_ROLE]
|
|||||||
|
|
||||||
export const USER_ROLE = {
|
export const USER_ROLE = {
|
||||||
superadmin: 'superadmin',
|
superadmin: 'superadmin',
|
||||||
ordinary: 'ordinary'
|
user: 'user'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export type USER_ROLE = (typeof USER_ROLE)[keyof typeof USER_ROLE]
|
export type USER_ROLE = (typeof USER_ROLE)[keyof typeof USER_ROLE]
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const config: runtime.GetPrismaClientConfig = {
|
|||||||
"clientVersion": "7.3.0",
|
"clientVersion": "7.3.0",
|
||||||
"engineVersion": "9d6ad21cbbceab97458517b147a6a09ff43aa735",
|
"engineVersion": "9d6ad21cbbceab97458517b147a6a09ff43aa735",
|
||||||
"activeProvider": "postgresql",
|
"activeProvider": "postgresql",
|
||||||
"inlineSchema": "model OrganizationJoinRequest {\n userId String\n orgId String\n status ORGANIZATION_JOIN_REQUEST @default(PENDING)\n requestedOn DateTime @default(now())\n rejectReason String?\n\n @@unique([userId, orgId])\n @@map(\"organization_join_request\")\n}\n\nenum ORGANIZATION_JOIN_REQUEST {\n PENDING\n ACCEPTED\n REJECTED\n}\n\nmodel OrganizationUserJoinTable {\n userId String\n orgId String\n role ORG_ROLE @default(user)\n joinedDate DateTime @default(now())\n\n @@unique([userId, orgId])\n @@map(\"organization_user_join\")\n}\n\nenum ORG_ROLE {\n admin\n user\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 @@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(ordinary)\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 @@map(\"user\")\n}\n\nenum USER_ROLE {\n superadmin\n ordinary\n}\n",
|
"inlineSchema": "model OrganizationJoinRequest {\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 rejectReason String?\n\n @@unique([userId, orgId])\n @@map(\"organization_join_request\")\n}\n\nenum ORGANIZATION_JOIN_REQUEST {\n PENDING\n ACCEPTED\n REJECTED\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 @@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 @@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 @@map(\"user\")\n}\n\nenum USER_ROLE {\n superadmin\n user\n}\n",
|
||||||
"runtimeDataModel": {
|
"runtimeDataModel": {
|
||||||
"models": {},
|
"models": {},
|
||||||
"enums": {},
|
"enums": {},
|
||||||
@@ -28,7 +28,7 @@ const config: runtime.GetPrismaClientConfig = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config.runtimeDataModel = JSON.parse("{\"models\":{\"OrganizationJoinRequest\":{\"fields\":[{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"orgId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"ORGANIZATION_JOIN_REQUEST\"},{\"name\":\"requestedOn\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"rejectReason\",\"kind\":\"scalar\",\"type\":\"String\"}],\"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\"}],\"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\"}],\"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\"}],\"dbName\":\"user\"}},\"enums\":{},\"types\":{}}")
|
config.runtimeDataModel = JSON.parse("{\"models\":{\"OrganizationJoinRequest\":{\"fields\":[{\"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\":\"rejectReason\",\"kind\":\"scalar\",\"type\":\"String\"}],\"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\"}],\"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\"}],\"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\"}],\"dbName\":\"user\"}},\"enums\":{},\"types\":{}}")
|
||||||
|
|
||||||
async function decodeBase64AsWasm(wasmBase64: string): Promise<WebAssembly.Module> {
|
async function decodeBase64AsWasm(wasmBase64: string): Promise<WebAssembly.Module> {
|
||||||
const { Buffer } = await import('node:buffer')
|
const { Buffer } = await import('node:buffer')
|
||||||
|
|||||||
@@ -746,6 +746,7 @@ export const OrganizationJoinRequestScalarFieldEnum = {
|
|||||||
userId: 'userId',
|
userId: 'userId',
|
||||||
orgId: 'orgId',
|
orgId: 'orgId',
|
||||||
status: 'status',
|
status: 'status',
|
||||||
|
requestType: 'requestType',
|
||||||
requestedOn: 'requestedOn',
|
requestedOn: 'requestedOn',
|
||||||
rejectReason: 'rejectReason'
|
rejectReason: 'rejectReason'
|
||||||
} as const
|
} as const
|
||||||
@@ -852,6 +853,20 @@ export type ListEnumORGANIZATION_JOIN_REQUESTFieldRefInput<$PrismaModel> = Field
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to a field of type 'ORGANIZATION_JOIN_REQUEST_TYPE'
|
||||||
|
*/
|
||||||
|
export type EnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ORGANIZATION_JOIN_REQUEST_TYPE'>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to a field of type 'ORGANIZATION_JOIN_REQUEST_TYPE[]'
|
||||||
|
*/
|
||||||
|
export type ListEnumORGANIZATION_JOIN_REQUEST_TYPEFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ORGANIZATION_JOIN_REQUEST_TYPE[]'>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to a field of type 'DateTime'
|
* Reference to a field of type 'DateTime'
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ export const OrganizationJoinRequestScalarFieldEnum = {
|
|||||||
userId: 'userId',
|
userId: 'userId',
|
||||||
orgId: 'orgId',
|
orgId: 'orgId',
|
||||||
status: 'status',
|
status: 'status',
|
||||||
|
requestType: 'requestType',
|
||||||
requestedOn: 'requestedOn',
|
requestedOn: 'requestedOn',
|
||||||
rejectReason: 'rejectReason'
|
rejectReason: 'rejectReason'
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ export type OrganizationJoinRequestMinAggregateOutputType = {
|
|||||||
userId: string | null
|
userId: string | null
|
||||||
orgId: string | null
|
orgId: string | null
|
||||||
status: $Enums.ORGANIZATION_JOIN_REQUEST | null
|
status: $Enums.ORGANIZATION_JOIN_REQUEST | null
|
||||||
|
requestType: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE | null
|
||||||
requestedOn: Date | null
|
requestedOn: Date | null
|
||||||
rejectReason: string | null
|
rejectReason: string | null
|
||||||
}
|
}
|
||||||
@@ -36,6 +37,7 @@ export type OrganizationJoinRequestMaxAggregateOutputType = {
|
|||||||
userId: string | null
|
userId: string | null
|
||||||
orgId: string | null
|
orgId: string | null
|
||||||
status: $Enums.ORGANIZATION_JOIN_REQUEST | null
|
status: $Enums.ORGANIZATION_JOIN_REQUEST | null
|
||||||
|
requestType: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE | null
|
||||||
requestedOn: Date | null
|
requestedOn: Date | null
|
||||||
rejectReason: string | null
|
rejectReason: string | null
|
||||||
}
|
}
|
||||||
@@ -44,6 +46,7 @@ export type OrganizationJoinRequestCountAggregateOutputType = {
|
|||||||
userId: number
|
userId: number
|
||||||
orgId: number
|
orgId: number
|
||||||
status: number
|
status: number
|
||||||
|
requestType: number
|
||||||
requestedOn: number
|
requestedOn: number
|
||||||
rejectReason: number
|
rejectReason: number
|
||||||
_all: number
|
_all: number
|
||||||
@@ -54,6 +57,7 @@ export type OrganizationJoinRequestMinAggregateInputType = {
|
|||||||
userId?: true
|
userId?: true
|
||||||
orgId?: true
|
orgId?: true
|
||||||
status?: true
|
status?: true
|
||||||
|
requestType?: true
|
||||||
requestedOn?: true
|
requestedOn?: true
|
||||||
rejectReason?: true
|
rejectReason?: true
|
||||||
}
|
}
|
||||||
@@ -62,6 +66,7 @@ export type OrganizationJoinRequestMaxAggregateInputType = {
|
|||||||
userId?: true
|
userId?: true
|
||||||
orgId?: true
|
orgId?: true
|
||||||
status?: true
|
status?: true
|
||||||
|
requestType?: true
|
||||||
requestedOn?: true
|
requestedOn?: true
|
||||||
rejectReason?: true
|
rejectReason?: true
|
||||||
}
|
}
|
||||||
@@ -70,6 +75,7 @@ export type OrganizationJoinRequestCountAggregateInputType = {
|
|||||||
userId?: true
|
userId?: true
|
||||||
orgId?: true
|
orgId?: true
|
||||||
status?: true
|
status?: true
|
||||||
|
requestType?: true
|
||||||
requestedOn?: true
|
requestedOn?: true
|
||||||
rejectReason?: true
|
rejectReason?: true
|
||||||
_all?: true
|
_all?: true
|
||||||
@@ -151,6 +157,7 @@ export type OrganizationJoinRequestGroupByOutputType = {
|
|||||||
userId: string
|
userId: string
|
||||||
orgId: string
|
orgId: string
|
||||||
status: $Enums.ORGANIZATION_JOIN_REQUEST
|
status: $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn: Date
|
requestedOn: Date
|
||||||
rejectReason: string | null
|
rejectReason: string | null
|
||||||
_count: OrganizationJoinRequestCountAggregateOutputType | null
|
_count: OrganizationJoinRequestCountAggregateOutputType | null
|
||||||
@@ -180,6 +187,7 @@ export type OrganizationJoinRequestWhereInput = {
|
|||||||
userId?: Prisma.StringFilter<"OrganizationJoinRequest"> | string
|
userId?: Prisma.StringFilter<"OrganizationJoinRequest"> | string
|
||||||
orgId?: Prisma.StringFilter<"OrganizationJoinRequest"> | string
|
orgId?: Prisma.StringFilter<"OrganizationJoinRequest"> | string
|
||||||
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFilter<"OrganizationJoinRequest"> | $Enums.ORGANIZATION_JOIN_REQUEST
|
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFilter<"OrganizationJoinRequest"> | $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType?: Prisma.EnumORGANIZATION_JOIN_REQUEST_TYPEFilter<"OrganizationJoinRequest"> | $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn?: Prisma.DateTimeFilter<"OrganizationJoinRequest"> | Date | string
|
requestedOn?: Prisma.DateTimeFilter<"OrganizationJoinRequest"> | Date | string
|
||||||
rejectReason?: Prisma.StringNullableFilter<"OrganizationJoinRequest"> | string | null
|
rejectReason?: Prisma.StringNullableFilter<"OrganizationJoinRequest"> | string | null
|
||||||
}
|
}
|
||||||
@@ -188,6 +196,7 @@ export type OrganizationJoinRequestOrderByWithRelationInput = {
|
|||||||
userId?: Prisma.SortOrder
|
userId?: Prisma.SortOrder
|
||||||
orgId?: Prisma.SortOrder
|
orgId?: Prisma.SortOrder
|
||||||
status?: Prisma.SortOrder
|
status?: Prisma.SortOrder
|
||||||
|
requestType?: Prisma.SortOrder
|
||||||
requestedOn?: Prisma.SortOrder
|
requestedOn?: Prisma.SortOrder
|
||||||
rejectReason?: Prisma.SortOrderInput | Prisma.SortOrder
|
rejectReason?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@@ -200,6 +209,7 @@ export type OrganizationJoinRequestWhereUniqueInput = Prisma.AtLeast<{
|
|||||||
userId?: Prisma.StringFilter<"OrganizationJoinRequest"> | string
|
userId?: Prisma.StringFilter<"OrganizationJoinRequest"> | string
|
||||||
orgId?: Prisma.StringFilter<"OrganizationJoinRequest"> | string
|
orgId?: Prisma.StringFilter<"OrganizationJoinRequest"> | string
|
||||||
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFilter<"OrganizationJoinRequest"> | $Enums.ORGANIZATION_JOIN_REQUEST
|
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFilter<"OrganizationJoinRequest"> | $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType?: Prisma.EnumORGANIZATION_JOIN_REQUEST_TYPEFilter<"OrganizationJoinRequest"> | $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn?: Prisma.DateTimeFilter<"OrganizationJoinRequest"> | Date | string
|
requestedOn?: Prisma.DateTimeFilter<"OrganizationJoinRequest"> | Date | string
|
||||||
rejectReason?: Prisma.StringNullableFilter<"OrganizationJoinRequest"> | string | null
|
rejectReason?: Prisma.StringNullableFilter<"OrganizationJoinRequest"> | string | null
|
||||||
}, "userId_orgId">
|
}, "userId_orgId">
|
||||||
@@ -208,6 +218,7 @@ export type OrganizationJoinRequestOrderByWithAggregationInput = {
|
|||||||
userId?: Prisma.SortOrder
|
userId?: Prisma.SortOrder
|
||||||
orgId?: Prisma.SortOrder
|
orgId?: Prisma.SortOrder
|
||||||
status?: Prisma.SortOrder
|
status?: Prisma.SortOrder
|
||||||
|
requestType?: Prisma.SortOrder
|
||||||
requestedOn?: Prisma.SortOrder
|
requestedOn?: Prisma.SortOrder
|
||||||
rejectReason?: Prisma.SortOrderInput | Prisma.SortOrder
|
rejectReason?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
_count?: Prisma.OrganizationJoinRequestCountOrderByAggregateInput
|
_count?: Prisma.OrganizationJoinRequestCountOrderByAggregateInput
|
||||||
@@ -222,6 +233,7 @@ export type OrganizationJoinRequestScalarWhereWithAggregatesInput = {
|
|||||||
userId?: Prisma.StringWithAggregatesFilter<"OrganizationJoinRequest"> | string
|
userId?: Prisma.StringWithAggregatesFilter<"OrganizationJoinRequest"> | string
|
||||||
orgId?: Prisma.StringWithAggregatesFilter<"OrganizationJoinRequest"> | string
|
orgId?: Prisma.StringWithAggregatesFilter<"OrganizationJoinRequest"> | string
|
||||||
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTWithAggregatesFilter<"OrganizationJoinRequest"> | $Enums.ORGANIZATION_JOIN_REQUEST
|
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTWithAggregatesFilter<"OrganizationJoinRequest"> | $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType?: Prisma.EnumORGANIZATION_JOIN_REQUEST_TYPEWithAggregatesFilter<"OrganizationJoinRequest"> | $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn?: Prisma.DateTimeWithAggregatesFilter<"OrganizationJoinRequest"> | Date | string
|
requestedOn?: Prisma.DateTimeWithAggregatesFilter<"OrganizationJoinRequest"> | Date | string
|
||||||
rejectReason?: Prisma.StringNullableWithAggregatesFilter<"OrganizationJoinRequest"> | string | null
|
rejectReason?: Prisma.StringNullableWithAggregatesFilter<"OrganizationJoinRequest"> | string | null
|
||||||
}
|
}
|
||||||
@@ -230,6 +242,7 @@ export type OrganizationJoinRequestCreateInput = {
|
|||||||
userId: string
|
userId: string
|
||||||
orgId: string
|
orgId: string
|
||||||
status?: $Enums.ORGANIZATION_JOIN_REQUEST
|
status?: $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn?: Date | string
|
requestedOn?: Date | string
|
||||||
rejectReason?: string | null
|
rejectReason?: string | null
|
||||||
}
|
}
|
||||||
@@ -238,6 +251,7 @@ export type OrganizationJoinRequestUncheckedCreateInput = {
|
|||||||
userId: string
|
userId: string
|
||||||
orgId: string
|
orgId: string
|
||||||
status?: $Enums.ORGANIZATION_JOIN_REQUEST
|
status?: $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn?: Date | string
|
requestedOn?: Date | string
|
||||||
rejectReason?: string | null
|
rejectReason?: string | null
|
||||||
}
|
}
|
||||||
@@ -246,6 +260,7 @@ export type OrganizationJoinRequestUpdateInput = {
|
|||||||
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
orgId?: Prisma.StringFieldUpdateOperationsInput | string
|
orgId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST
|
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType?: Prisma.EnumORGANIZATION_JOIN_REQUEST_TYPEFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
requestedOn?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
rejectReason?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
rejectReason?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
}
|
}
|
||||||
@@ -254,6 +269,7 @@ export type OrganizationJoinRequestUncheckedUpdateInput = {
|
|||||||
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
orgId?: Prisma.StringFieldUpdateOperationsInput | string
|
orgId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST
|
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType?: Prisma.EnumORGANIZATION_JOIN_REQUEST_TYPEFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
requestedOn?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
rejectReason?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
rejectReason?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
}
|
}
|
||||||
@@ -262,6 +278,7 @@ export type OrganizationJoinRequestCreateManyInput = {
|
|||||||
userId: string
|
userId: string
|
||||||
orgId: string
|
orgId: string
|
||||||
status?: $Enums.ORGANIZATION_JOIN_REQUEST
|
status?: $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn?: Date | string
|
requestedOn?: Date | string
|
||||||
rejectReason?: string | null
|
rejectReason?: string | null
|
||||||
}
|
}
|
||||||
@@ -270,6 +287,7 @@ export type OrganizationJoinRequestUpdateManyMutationInput = {
|
|||||||
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
orgId?: Prisma.StringFieldUpdateOperationsInput | string
|
orgId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST
|
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType?: Prisma.EnumORGANIZATION_JOIN_REQUEST_TYPEFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
requestedOn?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
rejectReason?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
rejectReason?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
}
|
}
|
||||||
@@ -278,6 +296,7 @@ export type OrganizationJoinRequestUncheckedUpdateManyInput = {
|
|||||||
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
orgId?: Prisma.StringFieldUpdateOperationsInput | string
|
orgId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST
|
status?: Prisma.EnumORGANIZATION_JOIN_REQUESTFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType?: Prisma.EnumORGANIZATION_JOIN_REQUEST_TYPEFieldUpdateOperationsInput | $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
requestedOn?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
rejectReason?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
rejectReason?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
}
|
}
|
||||||
@@ -291,6 +310,7 @@ export type OrganizationJoinRequestCountOrderByAggregateInput = {
|
|||||||
userId?: Prisma.SortOrder
|
userId?: Prisma.SortOrder
|
||||||
orgId?: Prisma.SortOrder
|
orgId?: Prisma.SortOrder
|
||||||
status?: Prisma.SortOrder
|
status?: Prisma.SortOrder
|
||||||
|
requestType?: Prisma.SortOrder
|
||||||
requestedOn?: Prisma.SortOrder
|
requestedOn?: Prisma.SortOrder
|
||||||
rejectReason?: Prisma.SortOrder
|
rejectReason?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@@ -299,6 +319,7 @@ export type OrganizationJoinRequestMaxOrderByAggregateInput = {
|
|||||||
userId?: Prisma.SortOrder
|
userId?: Prisma.SortOrder
|
||||||
orgId?: Prisma.SortOrder
|
orgId?: Prisma.SortOrder
|
||||||
status?: Prisma.SortOrder
|
status?: Prisma.SortOrder
|
||||||
|
requestType?: Prisma.SortOrder
|
||||||
requestedOn?: Prisma.SortOrder
|
requestedOn?: Prisma.SortOrder
|
||||||
rejectReason?: Prisma.SortOrder
|
rejectReason?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@@ -307,6 +328,7 @@ export type OrganizationJoinRequestMinOrderByAggregateInput = {
|
|||||||
userId?: Prisma.SortOrder
|
userId?: Prisma.SortOrder
|
||||||
orgId?: Prisma.SortOrder
|
orgId?: Prisma.SortOrder
|
||||||
status?: Prisma.SortOrder
|
status?: Prisma.SortOrder
|
||||||
|
requestType?: Prisma.SortOrder
|
||||||
requestedOn?: Prisma.SortOrder
|
requestedOn?: Prisma.SortOrder
|
||||||
rejectReason?: Prisma.SortOrder
|
rejectReason?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@@ -319,6 +341,10 @@ export type EnumORGANIZATION_JOIN_REQUESTFieldUpdateOperationsInput = {
|
|||||||
set?: $Enums.ORGANIZATION_JOIN_REQUEST
|
set?: $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type EnumORGANIZATION_JOIN_REQUEST_TYPEFieldUpdateOperationsInput = {
|
||||||
|
set?: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
|
}
|
||||||
|
|
||||||
export type DateTimeFieldUpdateOperationsInput = {
|
export type DateTimeFieldUpdateOperationsInput = {
|
||||||
set?: Date | string
|
set?: Date | string
|
||||||
}
|
}
|
||||||
@@ -333,6 +359,7 @@ export type OrganizationJoinRequestSelect<ExtArgs extends runtime.Types.Extensio
|
|||||||
userId?: boolean
|
userId?: boolean
|
||||||
orgId?: boolean
|
orgId?: boolean
|
||||||
status?: boolean
|
status?: boolean
|
||||||
|
requestType?: boolean
|
||||||
requestedOn?: boolean
|
requestedOn?: boolean
|
||||||
rejectReason?: boolean
|
rejectReason?: boolean
|
||||||
}, ExtArgs["result"]["organizationJoinRequest"]>
|
}, ExtArgs["result"]["organizationJoinRequest"]>
|
||||||
@@ -341,6 +368,7 @@ export type OrganizationJoinRequestSelectCreateManyAndReturn<ExtArgs extends run
|
|||||||
userId?: boolean
|
userId?: boolean
|
||||||
orgId?: boolean
|
orgId?: boolean
|
||||||
status?: boolean
|
status?: boolean
|
||||||
|
requestType?: boolean
|
||||||
requestedOn?: boolean
|
requestedOn?: boolean
|
||||||
rejectReason?: boolean
|
rejectReason?: boolean
|
||||||
}, ExtArgs["result"]["organizationJoinRequest"]>
|
}, ExtArgs["result"]["organizationJoinRequest"]>
|
||||||
@@ -349,6 +377,7 @@ export type OrganizationJoinRequestSelectUpdateManyAndReturn<ExtArgs extends run
|
|||||||
userId?: boolean
|
userId?: boolean
|
||||||
orgId?: boolean
|
orgId?: boolean
|
||||||
status?: boolean
|
status?: boolean
|
||||||
|
requestType?: boolean
|
||||||
requestedOn?: boolean
|
requestedOn?: boolean
|
||||||
rejectReason?: boolean
|
rejectReason?: boolean
|
||||||
}, ExtArgs["result"]["organizationJoinRequest"]>
|
}, ExtArgs["result"]["organizationJoinRequest"]>
|
||||||
@@ -357,11 +386,12 @@ export type OrganizationJoinRequestSelectScalar = {
|
|||||||
userId?: boolean
|
userId?: boolean
|
||||||
orgId?: boolean
|
orgId?: boolean
|
||||||
status?: boolean
|
status?: boolean
|
||||||
|
requestType?: boolean
|
||||||
requestedOn?: boolean
|
requestedOn?: boolean
|
||||||
rejectReason?: boolean
|
rejectReason?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OrganizationJoinRequestOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"userId" | "orgId" | "status" | "requestedOn" | "rejectReason", ExtArgs["result"]["organizationJoinRequest"]>
|
export type OrganizationJoinRequestOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"userId" | "orgId" | "status" | "requestType" | "requestedOn" | "rejectReason", ExtArgs["result"]["organizationJoinRequest"]>
|
||||||
|
|
||||||
export type $OrganizationJoinRequestPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
export type $OrganizationJoinRequestPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
name: "OrganizationJoinRequest"
|
name: "OrganizationJoinRequest"
|
||||||
@@ -370,6 +400,7 @@ export type $OrganizationJoinRequestPayload<ExtArgs extends runtime.Types.Extens
|
|||||||
userId: string
|
userId: string
|
||||||
orgId: string
|
orgId: string
|
||||||
status: $Enums.ORGANIZATION_JOIN_REQUEST
|
status: $Enums.ORGANIZATION_JOIN_REQUEST
|
||||||
|
requestType: $Enums.ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn: Date
|
requestedOn: Date
|
||||||
rejectReason: string | null
|
rejectReason: string | null
|
||||||
}, ExtArgs["result"]["organizationJoinRequest"]>
|
}, ExtArgs["result"]["organizationJoinRequest"]>
|
||||||
@@ -798,6 +829,7 @@ export interface OrganizationJoinRequestFieldRefs {
|
|||||||
readonly userId: Prisma.FieldRef<"OrganizationJoinRequest", 'String'>
|
readonly userId: Prisma.FieldRef<"OrganizationJoinRequest", 'String'>
|
||||||
readonly orgId: Prisma.FieldRef<"OrganizationJoinRequest", 'String'>
|
readonly orgId: Prisma.FieldRef<"OrganizationJoinRequest", 'String'>
|
||||||
readonly status: Prisma.FieldRef<"OrganizationJoinRequest", 'ORGANIZATION_JOIN_REQUEST'>
|
readonly status: Prisma.FieldRef<"OrganizationJoinRequest", 'ORGANIZATION_JOIN_REQUEST'>
|
||||||
|
readonly requestType: Prisma.FieldRef<"OrganizationJoinRequest", 'ORGANIZATION_JOIN_REQUEST_TYPE'>
|
||||||
readonly requestedOn: Prisma.FieldRef<"OrganizationJoinRequest", 'DateTime'>
|
readonly requestedOn: Prisma.FieldRef<"OrganizationJoinRequest", 'DateTime'>
|
||||||
readonly rejectReason: Prisma.FieldRef<"OrganizationJoinRequest", 'String'>
|
readonly rejectReason: Prisma.FieldRef<"OrganizationJoinRequest", 'String'>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- The values [user] on the enum `ORG_ROLE` will be removed. If these variants are still used in the database, this will fail.
|
||||||
|
- The values [ordinary] on the enum `USER_ROLE` will be removed. If these variants are still used in the database, this will fail.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
-- AlterEnum
|
||||||
|
BEGIN;
|
||||||
|
CREATE TYPE "ORG_ROLE_new" AS ENUM ('owner', 'admin', 'member');
|
||||||
|
ALTER TABLE "public"."organization_user_join" ALTER COLUMN "role" DROP DEFAULT;
|
||||||
|
ALTER TABLE "organization_user_join" ALTER COLUMN "role" TYPE "ORG_ROLE_new" USING ("role"::text::"ORG_ROLE_new");
|
||||||
|
ALTER TYPE "ORG_ROLE" RENAME TO "ORG_ROLE_old";
|
||||||
|
ALTER TYPE "ORG_ROLE_new" RENAME TO "ORG_ROLE";
|
||||||
|
DROP TYPE "public"."ORG_ROLE_old";
|
||||||
|
ALTER TABLE "organization_user_join" ALTER COLUMN "role" SET DEFAULT 'member';
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
-- AlterEnum
|
||||||
|
BEGIN;
|
||||||
|
CREATE TYPE "USER_ROLE_new" AS ENUM ('superadmin', 'user');
|
||||||
|
ALTER TABLE "public"."user" ALTER COLUMN "role" DROP DEFAULT;
|
||||||
|
ALTER TABLE "user" ALTER COLUMN "role" TYPE "USER_ROLE_new" USING ("role"::text::"USER_ROLE_new");
|
||||||
|
ALTER TYPE "USER_ROLE" RENAME TO "USER_ROLE_old";
|
||||||
|
ALTER TYPE "USER_ROLE_new" RENAME TO "USER_ROLE";
|
||||||
|
DROP TYPE "public"."USER_ROLE_old";
|
||||||
|
ALTER TABLE "user" ALTER COLUMN "role" SET DEFAULT 'user';
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "organization_user_join" ALTER COLUMN "role" SET DEFAULT 'member';
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "user" ALTER COLUMN "role" SET DEFAULT 'user';
|
||||||
1
prisma/migrations/20260221131903_new_enum/migration.sql
Normal file
1
prisma/migrations/20260221131903_new_enum/migration.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-- This is an empty migration.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- Added the required column `requestType` to the `organization_join_request` table without a default value. This is not possible if the table is not empty.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- CreateEnum
|
||||||
|
CREATE TYPE "ORGANIZATION_JOIN_REQUEST_TYPE" AS ENUM ('INVITED', 'REQUESTED');
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "organization_join_request" ADD COLUMN "requestType" "ORGANIZATION_JOIN_REQUEST_TYPE" NOT NULL;
|
||||||
@@ -2,7 +2,9 @@ model OrganizationJoinRequest {
|
|||||||
userId String
|
userId String
|
||||||
orgId String
|
orgId String
|
||||||
status ORGANIZATION_JOIN_REQUEST @default(PENDING)
|
status ORGANIZATION_JOIN_REQUEST @default(PENDING)
|
||||||
|
requestType ORGANIZATION_JOIN_REQUEST_TYPE
|
||||||
requestedOn DateTime @default(now())
|
requestedOn DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
rejectReason String?
|
rejectReason String?
|
||||||
|
|
||||||
@@unique([userId, orgId])
|
@@unique([userId, orgId])
|
||||||
@@ -14,3 +16,8 @@ enum ORGANIZATION_JOIN_REQUEST {
|
|||||||
ACCEPTED
|
ACCEPTED
|
||||||
REJECTED
|
REJECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ORGANIZATION_JOIN_REQUEST_TYPE {
|
||||||
|
INVITED
|
||||||
|
REQUESTED
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
model OrganizationUserJoinTable {
|
model OrganizationUserJoinTable {
|
||||||
userId String
|
userId String
|
||||||
orgId String
|
orgId String
|
||||||
role ORG_ROLE @default(user)
|
role ORG_ROLE @default(member)
|
||||||
joinedDate DateTime @default(now())
|
joinedDate DateTime @default(now())
|
||||||
|
|
||||||
@@unique([userId, orgId])
|
@@unique([userId, orgId])
|
||||||
@@ -9,6 +9,7 @@ model OrganizationUserJoinTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ORG_ROLE {
|
enum ORG_ROLE {
|
||||||
|
owner
|
||||||
admin
|
admin
|
||||||
user
|
member
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ model User {
|
|||||||
lastName String
|
lastName String
|
||||||
email String @unique
|
email String @unique
|
||||||
password String
|
password String
|
||||||
role USER_ROLE @default(ordinary)
|
role USER_ROLE @default(user)
|
||||||
isVerified Boolean? @default(false) // TODO: Email using queue
|
isVerified Boolean? @default(false) // TODO: Email using queue
|
||||||
refreshToken String?
|
refreshToken String?
|
||||||
profilePicture String?
|
profilePicture String?
|
||||||
@@ -20,5 +20,5 @@ model User {
|
|||||||
|
|
||||||
enum USER_ROLE {
|
enum USER_ROLE {
|
||||||
superadmin
|
superadmin
|
||||||
ordinary
|
user
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import { APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core';
|
|||||||
import { ResponseInterceptor } from 'common/interceptors/response.interceptor';
|
import { ResponseInterceptor } from 'common/interceptors/response.interceptor';
|
||||||
import { ExceptionsHandler } from '@nestjs/core/exceptions/exceptions-handler';
|
import { ExceptionsHandler } from '@nestjs/core/exceptions/exceptions-handler';
|
||||||
import { HttpExceptionFilter } from 'common/exceptions/exception-filter';
|
import { HttpExceptionFilter } from 'common/exceptions/exception-filter';
|
||||||
|
import { OrganizationModule } from './organization/organization.module';
|
||||||
|
import { OrganizationMembershipModule } from './organization-membership/organization-membership.module';
|
||||||
|
import { AuthorizationModule } from './authorization/authorization.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -21,6 +24,9 @@ import { HttpExceptionFilter } from 'common/exceptions/exception-filter';
|
|||||||
AuthModule,
|
AuthModule,
|
||||||
RequestContextModule,
|
RequestContextModule,
|
||||||
PrismaModule,
|
PrismaModule,
|
||||||
|
OrganizationModule,
|
||||||
|
OrganizationMembershipModule,
|
||||||
|
AuthorizationModule,
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [
|
providers: [
|
||||||
|
|||||||
@@ -15,8 +15,10 @@ import {
|
|||||||
} 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';
|
||||||
|
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
|
@Public()
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
constructor(private readonly authService: AuthService) {}
|
constructor(private readonly authService: AuthService) {}
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ import { RequestContextModule } from 'core/als/request-context.module';
|
|||||||
AuthService,
|
AuthService,
|
||||||
{
|
{
|
||||||
provide: APP_GUARD,
|
provide: APP_GUARD,
|
||||||
useFactory: () => AuthGuard,
|
useClass: AuthGuard,
|
||||||
inject: [Reflector],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
controllers: [AuthController],
|
controllers: [AuthController],
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
CanActivate,
|
CanActivate,
|
||||||
ExecutionContext,
|
ExecutionContext,
|
||||||
|
Injectable,
|
||||||
UnauthorizedException,
|
UnauthorizedException,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { RequestContextService } from 'core/als/request-context.service';
|
import { RequestContextService } from 'core/als/request-context.service';
|
||||||
@@ -10,6 +11,7 @@ import { Request } from 'express';
|
|||||||
import { Reflector } from '@nestjs/core';
|
import { Reflector } from '@nestjs/core';
|
||||||
import { PUBLIC_KEY } from 'common/keys';
|
import { PUBLIC_KEY } from 'common/keys';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
export class AuthGuard implements CanActivate {
|
export class AuthGuard implements CanActivate {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly reflector: Reflector,
|
private readonly reflector: Reflector,
|
||||||
@@ -30,7 +32,9 @@ export class AuthGuard implements CanActivate {
|
|||||||
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',
|
||||||
|
});
|
||||||
this.requestContext.set('user', payload);
|
this.requestContext.set('user', payload);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
10
src/authorization/authorization.module.ts
Normal file
10
src/authorization/authorization.module.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { AuthorizationService } from './authorization.service';
|
||||||
|
import { PrismaModule } from 'src/prisma/prisma.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
providers: [AuthorizationService],
|
||||||
|
imports: [PrismaModule],
|
||||||
|
exports: [AuthorizationService],
|
||||||
|
})
|
||||||
|
export class AuthorizationModule {}
|
||||||
18
src/authorization/authorization.service.spec.ts
Normal file
18
src/authorization/authorization.service.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { AuthorizationService } from './authorization.service';
|
||||||
|
|
||||||
|
describe('AuthorizationService', () => {
|
||||||
|
let service: AuthorizationService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [AuthorizationService],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<AuthorizationService>(AuthorizationService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
71
src/authorization/authorization.service.ts
Normal file
71
src/authorization/authorization.service.ts
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { PrismaService } from 'src/prisma/prisma.service';
|
||||||
|
import { USER_ORGANIZATION_OPERATIONS } from './operations';
|
||||||
|
import { ORG_ROLE } from 'prisma/generated/prisma/enums';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AuthorizationService {
|
||||||
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
|
// can perform operation
|
||||||
|
async canPerformOperation(
|
||||||
|
userId: string,
|
||||||
|
orgId: string,
|
||||||
|
operation: USER_ORGANIZATION_OPERATIONS,
|
||||||
|
) {
|
||||||
|
switch (operation) {
|
||||||
|
case USER_ORGANIZATION_OPERATIONS.DELETE_ORGANIZATION:
|
||||||
|
return await this.isOwner(userId, orgId);
|
||||||
|
case USER_ORGANIZATION_OPERATIONS.UPDATE_ORGANIZATION:
|
||||||
|
return await this.isOwner(userId, orgId);
|
||||||
|
case USER_ORGANIZATION_OPERATIONS.INVITE_USERS:
|
||||||
|
return await this.canInvite(userId, orgId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async isOwner(userId: string, orgId: string) {
|
||||||
|
const isUserPartOfOrganization = await this.isUserPartOfOrganization(
|
||||||
|
userId,
|
||||||
|
orgId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return isUserPartOfOrganization
|
||||||
|
? isUserPartOfOrganization.role === ORG_ROLE.owner
|
||||||
|
: !!isUserPartOfOrganization;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async canInvite(userId: string, orgId: string) {
|
||||||
|
const isUserPartOfOrganization = await this.isUserPartOfOrganization(
|
||||||
|
userId,
|
||||||
|
orgId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return isUserPartOfOrganization
|
||||||
|
? isUserPartOfOrganization.role === ORG_ROLE.admin ||
|
||||||
|
isUserPartOfOrganization.role === ORG_ROLE.owner
|
||||||
|
: !!isUserPartOfOrganization;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async isAdmin(userId: string, orgId: string) {
|
||||||
|
const isUserPartOfOrganization = await this.isUserPartOfOrganization(
|
||||||
|
userId,
|
||||||
|
orgId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return isUserPartOfOrganization
|
||||||
|
? isUserPartOfOrganization.role === ORG_ROLE.admin
|
||||||
|
: !!isUserPartOfOrganization;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HELPER FUNCTION
|
||||||
|
private async isUserPartOfOrganization(userId: string, orgId: string) {
|
||||||
|
return await this.prisma.organizationUserJoinTable.findUnique({
|
||||||
|
where: {
|
||||||
|
userId_orgId: {
|
||||||
|
orgId,
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
5
src/authorization/operations.ts
Normal file
5
src/authorization/operations.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export enum USER_ORGANIZATION_OPERATIONS {
|
||||||
|
UPDATE_ORGANIZATION = 'update_organization',
|
||||||
|
DELETE_ORGANIZATION = 'delete_organization',
|
||||||
|
INVITE_USERS = 'invite_users',
|
||||||
|
}
|
||||||
1
src/organization-membership/dto/index.ts
Normal file
1
src/organization-membership/dto/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './invite-to-org.dto';
|
||||||
16
src/organization-membership/dto/invite-to-org.dto.ts
Normal file
16
src/organization-membership/dto/invite-to-org.dto.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { IsEnum, IsNotEmpty, IsUUID } from 'class-validator';
|
||||||
|
import { ORG_ROLE } from 'prisma/generated/prisma/enums';
|
||||||
|
|
||||||
|
export class InviteUserToOrganizationRequestDTO {
|
||||||
|
@IsUUID()
|
||||||
|
@IsNotEmpty()
|
||||||
|
invitedUserId: string;
|
||||||
|
|
||||||
|
@IsUUID()
|
||||||
|
@IsNotEmpty()
|
||||||
|
orgId: string;
|
||||||
|
|
||||||
|
@IsEnum(ORG_ROLE)
|
||||||
|
@IsNotEmpty()
|
||||||
|
role: ORG_ROLE;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { OrganizationMembershipController } from './organization-membership.controller';
|
||||||
|
|
||||||
|
describe('OrganizationMembershipController', () => {
|
||||||
|
let controller: OrganizationMembershipController;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
controllers: [OrganizationMembershipController],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
controller = module.get<OrganizationMembershipController>(OrganizationMembershipController);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(controller).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import { Controller } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Controller('organization-membership')
|
||||||
|
export class OrganizationMembershipController {}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { OrganizationMembershipController } from './organization-membership.controller';
|
||||||
|
import { OrganizationMembershipService } from './organization-membership.service';
|
||||||
|
import { OrganizationModule } from 'src/organization/organization.module';
|
||||||
|
import { UserModule } from 'src/user/user.module';
|
||||||
|
import { PrismaModule } from 'src/prisma/prisma.module';
|
||||||
|
import { AuthorizationModule } from 'src/authorization/authorization.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [OrganizationMembershipController],
|
||||||
|
providers: [OrganizationMembershipService],
|
||||||
|
imports: [OrganizationModule, UserModule, PrismaModule, AuthorizationModule],
|
||||||
|
})
|
||||||
|
export class OrganizationMembershipModule {}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { OrganizationMembershipService } from './organization-membership.service';
|
||||||
|
|
||||||
|
describe('OrganizationMembershipService', () => {
|
||||||
|
let service: OrganizationMembershipService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [OrganizationMembershipService],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<OrganizationMembershipService>(OrganizationMembershipService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
148
src/organization-membership/organization-membership.service.ts
Normal file
148
src/organization-membership/organization-membership.service.ts
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
ForbiddenException,
|
||||||
|
Injectable,
|
||||||
|
NotFoundException,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { OrganizationService } from 'src/organization/organization.service';
|
||||||
|
import { UserService } from 'src/user/user.service';
|
||||||
|
import { InviteUserToOrganizationRequestDTO } from './dto';
|
||||||
|
import { PrismaService } from 'src/prisma/prisma.service';
|
||||||
|
import {
|
||||||
|
ORGANIZATION_JOIN_REQUEST,
|
||||||
|
ORGANIZATION_JOIN_REQUEST_TYPE,
|
||||||
|
} 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';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class OrganizationMembershipService {
|
||||||
|
constructor(
|
||||||
|
private readonly userService: UserService,
|
||||||
|
private readonly orgService: OrganizationService,
|
||||||
|
private readonly prisma: PrismaService,
|
||||||
|
private readonly authorization: AuthorizationService,
|
||||||
|
) {}
|
||||||
|
async inviteUserToOrg(
|
||||||
|
userId: string,
|
||||||
|
dto: InviteUserToOrganizationRequestDTO,
|
||||||
|
) {
|
||||||
|
const [orgExists, invitedUser] = await Promise.all([
|
||||||
|
this.orgService.findById(dto.orgId),
|
||||||
|
this.userService.getById(dto.invitedUserId),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!orgExists) throw new NotFoundException('Organization');
|
||||||
|
if (!invitedUser) throw new NotFoundException('User');
|
||||||
|
|
||||||
|
const userAlreadyPart =
|
||||||
|
await this.prisma.organizationUserJoinTable.findUnique({
|
||||||
|
where: {
|
||||||
|
userId_orgId: {
|
||||||
|
orgId: dto.orgId,
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (userAlreadyPart)
|
||||||
|
throw new BadRequestException('User already part of this organization');
|
||||||
|
|
||||||
|
const canInviteUser = await this.authorization.canPerformOperation(
|
||||||
|
userId,
|
||||||
|
dto.orgId,
|
||||||
|
USER_ORGANIZATION_OPERATIONS.INVITE_USERS,
|
||||||
|
);
|
||||||
|
if (!canInviteUser) throw new ForbiddenException('Insufficient Permission');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const invitation = await this.prisma.organizationJoinRequest.create({
|
||||||
|
data: {
|
||||||
|
...dto,
|
||||||
|
userId: dto.invitedUserId,
|
||||||
|
requestType: ORGANIZATION_JOIN_REQUEST_TYPE.INVITED,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return invitation;
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
||||||
|
if (err.code === 'P2002')
|
||||||
|
throw new BadRequestException('User invitation already sent.');
|
||||||
|
}
|
||||||
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requestToJoin() {}
|
||||||
|
|
||||||
|
// TODO: reject, rejectReason
|
||||||
|
async acceptInvite(userId: string, orgId: string) {
|
||||||
|
const orgExists = await this.orgService.findById(orgId);
|
||||||
|
if (!orgExists) throw new NotFoundException('Organization');
|
||||||
|
|
||||||
|
const [userAlreadyPart, isUserInvited] = await Promise.all([
|
||||||
|
this.prisma.organizationUserJoinTable.findUnique({
|
||||||
|
where: {
|
||||||
|
userId_orgId: {
|
||||||
|
orgId,
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
this.prisma.organizationJoinRequest.findUnique({
|
||||||
|
where: {
|
||||||
|
userId_orgId: {
|
||||||
|
orgId,
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
status: ORGANIZATION_JOIN_REQUEST.PENDING,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (userAlreadyPart)
|
||||||
|
throw new BadRequestException('User already part of this organization');
|
||||||
|
if (!isUserInvited)
|
||||||
|
throw new BadRequestException(
|
||||||
|
'User has no invitations from this organization',
|
||||||
|
);
|
||||||
|
|
||||||
|
return await this.prisma.$transaction(async (tx) => {
|
||||||
|
await tx.organizationJoinRequest.update({
|
||||||
|
where: {
|
||||||
|
userId_orgId: {
|
||||||
|
userId,
|
||||||
|
orgId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: ORGANIZATION_JOIN_REQUEST.ACCEPTED,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return await tx.organizationUserJoinTable.create({
|
||||||
|
data: {
|
||||||
|
orgId,
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getUserInvitations(
|
||||||
|
userId: string,
|
||||||
|
requestType: ORGANIZATION_JOIN_REQUEST_TYPE,
|
||||||
|
status: ORGANIZATION_JOIN_REQUEST = ORGANIZATION_JOIN_REQUEST.PENDING,
|
||||||
|
) {
|
||||||
|
return await this.prisma.organizationJoinRequest.findMany({
|
||||||
|
where: {
|
||||||
|
userId: userId,
|
||||||
|
status: status,
|
||||||
|
requestType: requestType,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
2
src/organization/dtos/index.ts
Normal file
2
src/organization/dtos/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from './organization.dto';
|
||||||
|
export * from './organization-response.dto';
|
||||||
15
src/organization/dtos/organization-response.dto.ts
Normal file
15
src/organization/dtos/organization-response.dto.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { Organization } from 'prisma/generated/prisma/client';
|
||||||
|
|
||||||
|
export class OrganizationDTO {
|
||||||
|
readonly name: string;
|
||||||
|
readonly description: string | null;
|
||||||
|
readonly createdAt: Date;
|
||||||
|
|
||||||
|
constructor(organization: Organization) {
|
||||||
|
this.name = organization.name;
|
||||||
|
this.description = organization.description;
|
||||||
|
this.createdAt = organization.createdAt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateNewOrganizationResponseDTO extends OrganizationDTO {}
|
||||||
30
src/organization/dtos/organization.dto.ts
Normal file
30
src/organization/dtos/organization.dto.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger';
|
||||||
|
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||||
|
import { AtLeastOneField } from 'common/validators';
|
||||||
|
|
||||||
|
export class CreateNewOrganizationRequestDTO {
|
||||||
|
@ApiProperty({
|
||||||
|
description: "Organization's name",
|
||||||
|
example: 'Lions',
|
||||||
|
type: 'string',
|
||||||
|
})
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Short description for organization',
|
||||||
|
example: 'A cool organization active for over 10 years.',
|
||||||
|
type: 'string',
|
||||||
|
})
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@AtLeastOneField({
|
||||||
|
message: 'Provide at least one field to update',
|
||||||
|
})
|
||||||
|
export class UpdateOrganizationRequestDTO extends PartialType(
|
||||||
|
CreateNewOrganizationRequestDTO,
|
||||||
|
) {}
|
||||||
18
src/organization/organization.controller.spec.ts
Normal file
18
src/organization/organization.controller.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { OrganizationController } from './organization.controller';
|
||||||
|
|
||||||
|
describe('OrganizationController', () => {
|
||||||
|
let controller: OrganizationController;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
controllers: [OrganizationController],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
controller = module.get<OrganizationController>(OrganizationController);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(controller).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
94
src/organization/organization.controller.ts
Normal file
94
src/organization/organization.controller.ts
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Delete,
|
||||||
|
Get,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
|
Put,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import {
|
||||||
|
CreateNewOrganizationRequestDTO,
|
||||||
|
OrganizationDTO,
|
||||||
|
UpdateOrganizationRequestDTO,
|
||||||
|
} from './dtos';
|
||||||
|
import { OrganizationService } from './organization.service';
|
||||||
|
import { RequestContextService } from 'core/als/request-context.service';
|
||||||
|
import { ApiBearerAuth } from '@nestjs/swagger';
|
||||||
|
import { DataResponse } from 'common/http';
|
||||||
|
|
||||||
|
@Controller('organization')
|
||||||
|
@ApiBearerAuth('access-token')
|
||||||
|
export class OrganizationController {
|
||||||
|
constructor(
|
||||||
|
private readonly orgService: OrganizationService,
|
||||||
|
private readonly requestContext: RequestContextService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Post('')
|
||||||
|
async createNewOrganization(
|
||||||
|
@Body() body: CreateNewOrganizationRequestDTO,
|
||||||
|
): Promise<DataResponse<OrganizationDTO>> {
|
||||||
|
const user = this.requestContext.user;
|
||||||
|
const newOrg = await this.orgService.createNewOrganization(
|
||||||
|
user.userId,
|
||||||
|
body,
|
||||||
|
);
|
||||||
|
|
||||||
|
return new DataResponse<OrganizationDTO>(
|
||||||
|
new OrganizationDTO(newOrg),
|
||||||
|
'Organization created successfully.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('')
|
||||||
|
async getOrganizations(): Promise<DataResponse<OrganizationDTO[]>> {
|
||||||
|
const organizations = await this.orgService.getOrganizations();
|
||||||
|
|
||||||
|
return new DataResponse(
|
||||||
|
organizations.map((organization) => new OrganizationDTO(organization)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
async getAnOrganization(
|
||||||
|
@Param('id') id: string,
|
||||||
|
): Promise<DataResponse<OrganizationDTO>> {
|
||||||
|
const organization = await this.orgService.getOrganizationById(id);
|
||||||
|
return new DataResponse(new OrganizationDTO(organization));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put(':id')
|
||||||
|
async updateAnOrganization(
|
||||||
|
@Param('id') orgId: string,
|
||||||
|
@Body() body: UpdateOrganizationRequestDTO,
|
||||||
|
): Promise<DataResponse<OrganizationDTO>> {
|
||||||
|
const user = this.requestContext.user;
|
||||||
|
const updatedOrg = await this.orgService.updateAnOrganization(
|
||||||
|
user.userId,
|
||||||
|
orgId,
|
||||||
|
body,
|
||||||
|
);
|
||||||
|
|
||||||
|
return new DataResponse<OrganizationDTO>(
|
||||||
|
new OrganizationDTO(updatedOrg),
|
||||||
|
'Organization updated successfully',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(':id')
|
||||||
|
async deleteAnOrganization(
|
||||||
|
@Param('id') orgId: string,
|
||||||
|
): Promise<DataResponse<OrganizationDTO>> {
|
||||||
|
const user = this.requestContext.user;
|
||||||
|
const deletedOrg = await this.orgService.deleteAnOrganization(
|
||||||
|
user.userId,
|
||||||
|
orgId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return new DataResponse<OrganizationDTO>(
|
||||||
|
new OrganizationDTO(deletedOrg),
|
||||||
|
'Organization deleted successfully',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/organization/organization.module.ts
Normal file
20
src/organization/organization.module.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { OrganizationController } from './organization.controller';
|
||||||
|
import { OrganizationService } from './organization.service';
|
||||||
|
import { PrismaModule } from 'src/prisma/prisma.module';
|
||||||
|
import { RequestContextModule } from 'core/als/request-context.module';
|
||||||
|
import { UserModule } from 'src/user/user.module';
|
||||||
|
import { AuthorizationModule } from 'src/authorization/authorization.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [OrganizationController],
|
||||||
|
providers: [OrganizationService],
|
||||||
|
imports: [
|
||||||
|
PrismaModule,
|
||||||
|
RequestContextModule,
|
||||||
|
UserModule,
|
||||||
|
AuthorizationModule,
|
||||||
|
],
|
||||||
|
exports: [OrganizationService],
|
||||||
|
})
|
||||||
|
export class OrganizationModule {}
|
||||||
18
src/organization/organization.service.spec.ts
Normal file
18
src/organization/organization.service.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { OrganizationService } from './organization.service';
|
||||||
|
|
||||||
|
describe('OrganizationService', () => {
|
||||||
|
let service: OrganizationService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [OrganizationService],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<OrganizationService>(OrganizationService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
120
src/organization/organization.service.ts
Normal file
120
src/organization/organization.service.ts
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import {
|
||||||
|
ForbiddenException,
|
||||||
|
Injectable,
|
||||||
|
NotFoundException,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import {
|
||||||
|
CreateNewOrganizationRequestDTO,
|
||||||
|
UpdateOrganizationRequestDTO,
|
||||||
|
} from './dtos';
|
||||||
|
import { PrismaService } from 'src/prisma/prisma.service';
|
||||||
|
import { RequestContextService } from 'core/als/request-context.service';
|
||||||
|
import { ORG_ROLE } from 'prisma/generated/prisma/enums';
|
||||||
|
import { AuthorizationService } from 'src/authorization/authorization.service';
|
||||||
|
import { USER_ORGANIZATION_OPERATIONS } from 'src/authorization/operations';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class OrganizationService {
|
||||||
|
constructor(
|
||||||
|
private readonly prisma: PrismaService,
|
||||||
|
// private readonly reqContext: RequestContextService,
|
||||||
|
private readonly authorization: AuthorizationService,
|
||||||
|
) {}
|
||||||
|
async createNewOrganization(
|
||||||
|
userId: string,
|
||||||
|
dto: CreateNewOrganizationRequestDTO,
|
||||||
|
) {
|
||||||
|
return await this.prisma.$transaction(async (tx) => {
|
||||||
|
const newOrganization = await tx.organization.create({
|
||||||
|
data: dto,
|
||||||
|
});
|
||||||
|
|
||||||
|
await tx.organizationUserJoinTable.create({
|
||||||
|
data: {
|
||||||
|
orgId: newOrganization.id,
|
||||||
|
userId: userId,
|
||||||
|
role: ORG_ROLE.owner,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return newOrganization;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Pagination
|
||||||
|
async getOrganizations() {
|
||||||
|
return await this.prisma.organization.findMany();
|
||||||
|
}
|
||||||
|
|
||||||
|
async getOrganizationById(orgId: string) {
|
||||||
|
const orgExists = await this.findById(orgId);
|
||||||
|
if (!orgExists) throw new NotFoundException('Organization');
|
||||||
|
|
||||||
|
return orgExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateAnOrganization(
|
||||||
|
userId: string,
|
||||||
|
orgId: string,
|
||||||
|
dto: UpdateOrganizationRequestDTO,
|
||||||
|
) {
|
||||||
|
const orgExists = await this.findById(orgId);
|
||||||
|
if (!orgExists) throw new NotFoundException('Organization');
|
||||||
|
|
||||||
|
const canUserUpdateOrganization =
|
||||||
|
await this.authorization.canPerformOperation(
|
||||||
|
userId,
|
||||||
|
orgId,
|
||||||
|
USER_ORGANIZATION_OPERATIONS.UPDATE_ORGANIZATION,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!canUserUpdateOrganization)
|
||||||
|
throw new ForbiddenException('Not enough permission');
|
||||||
|
|
||||||
|
return this.prisma.organization.update({
|
||||||
|
where: {
|
||||||
|
id: orgId,
|
||||||
|
},
|
||||||
|
data: dto,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Either empty or choose someone to be owner
|
||||||
|
async deleteAnOrganization(userId: string, orgId: string) {
|
||||||
|
const orgExists = await this.findById(orgId);
|
||||||
|
if (!orgExists) throw new NotFoundException('Organization');
|
||||||
|
|
||||||
|
const canUserDeleteOrganization =
|
||||||
|
await this.authorization.canPerformOperation(
|
||||||
|
userId,
|
||||||
|
orgId,
|
||||||
|
USER_ORGANIZATION_OPERATIONS.DELETE_ORGANIZATION,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!canUserDeleteOrganization)
|
||||||
|
throw new ForbiddenException('Not enough permission');
|
||||||
|
|
||||||
|
return await this.prisma.$transaction(async (tx) => {
|
||||||
|
const deletedOrganization = await tx.organization.delete({
|
||||||
|
where: {
|
||||||
|
id: orgId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await tx.organizationUserJoinTable.delete({
|
||||||
|
where: {
|
||||||
|
userId_orgId: {
|
||||||
|
userId,
|
||||||
|
orgId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return deletedOrganization;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async findById(orgId: string) {
|
||||||
|
return await this.prisma.organization.findUnique({ where: { id: orgId } });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,14 @@ export class UserService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getById(id: string) {
|
||||||
|
return await this.prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async updateRefreshToken(id: string, refreshToken: string) {
|
async updateRefreshToken(id: string, refreshToken: string) {
|
||||||
return await this.prisma.user.update({
|
return await this.prisma.user.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
|
|||||||
Reference in New Issue
Block a user