import { ObjectType, Field, ID, ArgsType, Int, InputType } from 'type-graphql'; import { BaseGraphModel } from '@seed/graphql/BaseGraphModel'; import { Permission } from '@seed/interfaces/permission'; import ImageComponent, { AccountGenderEnum } from '@seed/interfaces/components'; import { AddressComponent } from '@seed/interfaces/components.geo'; import { AccountTypeEnum } from '@src/accounts/account.components'; import { AvailableTranslation } from '@src/__components/components'; import { GetArgs } from '@seed/graphql/Request'; import { CodeRequest, OAuthTokens, SecurityLevelEnum, SecurityStatusComponent, SettingsComponent } from './account.components'; @ObjectType() export default class BaseAccountModel extends BaseGraphModel { public constructor(permissions: Permission) { super({ // ...init, collectionName: 'accounts', permissions: permissions, }); } // eslint-disable-next-line @typescript-eslint/no-unused-vars @Field(() => ID) readonly _id: string; @Field(() => [AccountTypeEnum]) types: AccountTypeEnum[]; @Field(() => [String], { nullable: true }) organisationIds?: string[]; @Field() email: string; @Field({ nullable: true }) userName?: string; @Field({ nullable: true }) firstName?: string; @Field({ nullable: true }) lastName?: string; @Field(() => ImageComponent, { nullable: true }) profilePicture?: ImageComponent; @Field({ nullable: true }) phoneNumber?: string; @Field(() => AccountGenderEnum, { nullable: true }) gender?: AccountGenderEnum; // @Field(() => Int, { nullable: true }) // age?: number; @Field({ nullable: true }) birthDate?: Date; @Field(() => Int, { nullable: true }) getAge(): number | undefined { if (this.birthDate) { const today = new Date(); let age = today.getFullYear() - this.birthDate.getFullYear(); const diff = today.getMonth() - this.birthDate.getMonth(); if (diff < 0 || (diff === 0 && today.getDate() < this.birthDate.getDate())) { age--; } return age; } } @Field(() => AddressComponent, { nullable: true }) address?: AddressComponent; @Field(() => AvailableTranslation, { nullable: true }) language: AvailableTranslation; @Field(() => [SettingsComponent], { nullable: true }) settings?: SettingsComponent[]; /* For Authorization codes */ authCodes?: CodeRequest[]; /* For OauthProvider codes */ oAuthTokens?: OAuthTokens; security?: SecurityStatusComponent; @Field() securityCheck(): boolean { // Check the level of security for this app const securityLevel: SecurityLevelEnum = (process.env.SECURITY_LEVEL as SecurityLevelEnum) || SecurityLevelEnum.nothing; switch (securityLevel) { case SecurityLevelEnum.nothing: console.error('[SECURITY] NO CONFIG'); break; case SecurityLevelEnum['email-only']: if (this.security?.emailVerified) return true; else return false; case SecurityLevelEnum['email-phone']: if (this.security?.emailVerified && this.security?.phoneVerified) return true; else return false; case SecurityLevelEnum['email-mfa']: console.error('[SECURITY] NOT IMPLEMENTED'); break; default: console.error('[SECURITY] BAD CONFIGURATION'); break; } return true; } // [x: string]: any; searchOptions(): string[] { return ['email', 'firstName', 'lastName', 'userName']; } filterOptions(): string[] { return ['email', 'firstName', 'lastName', 'userName']; } } @ArgsType() export class BaseAccountArgs { @Field(() => GetArgs, { nullable: true }) pagination?: GetArgs; @Field(() => AccountTypeEnum) types: AccountTypeEnum; } @InputType() export class NewAccountInputAdmin implements Partial { @Field(() => AccountTypeEnum) type: AccountTypeEnum; @Field(() => [String], { nullable: true }) organisationIds?: string[]; @Field() email: string; // @Field() // password: string; // @Field() // passwordConfirmation: string; @Field({ nullable: true }) userName?: string; @Field({ nullable: true }) firstName?: string; @Field({ nullable: true }) lastName?: string; @Field(() => ImageComponent, { nullable: true }) profilePicture?: ImageComponent; @Field({ nullable: true }) phoneNumber?: string; @Field(() => AccountGenderEnum, { nullable: true }) gender?: AccountGenderEnum; @Field({ nullable: true }) birthDate?: Date; @Field(() => AddressComponent, { nullable: true }) address?: AddressComponent; @Field(() => AvailableTranslation, { nullable: true }) language?: AvailableTranslation; @Field(() => [SettingsComponent], { nullable: true }) settings?: SettingsComponent[]; } @InputType() export class NewBaseAccountInput implements Partial { @Field() email: string; @Field() password: string; @Field() passwordConfirmation: string; @Field({ nullable: true }) userName?: string; @Field({ nullable: true }) firstName?: string; @Field({ nullable: true }) lastName?: string; @Field(() => ImageComponent, { nullable: true }) profilePicture?: ImageComponent; @Field({ nullable: true }) phoneNumber?: string; @Field(() => AccountGenderEnum, { nullable: true }) gender?: AccountGenderEnum; @Field({ nullable: true }) birthDate?: Date; @Field(() => AddressComponent, { nullable: true }) address?: AddressComponent; @Field(() => AvailableTranslation, { nullable: true }) language?: AvailableTranslation; @Field(() => [SettingsComponent], { nullable: true }) settings?: SettingsComponent[]; } @InputType() export class EditBaseAccountInput implements Partial { @Field({ nullable: true }) userName?: string; @Field({ nullable: true }) firstName?: string; @Field({ nullable: true }) lastName?: string; @Field(() => ImageComponent, { nullable: true }) profilePicture?: ImageComponent; @Field({ nullable: true }) phoneNumber?: string; @Field(() => AccountGenderEnum, { nullable: true }) gender?: AccountGenderEnum; @Field({ nullable: true }) birthDate?: Date; @Field(() => AddressComponent, { nullable: true }) address?: AddressComponent; @Field(() => AvailableTranslation, { nullable: true }) language?: AvailableTranslation; @Field(() => [SettingsComponent], { nullable: true }) settings?: SettingsComponent[]; }