HSB-439 feature: invite link with SMTP optional (#4078)

* feat: env variable added in infra-config for smtp enable status

* feat: event emitter added

* feat: added advance mailer configurations from infra config

* test: fix test cases

* feat: added query to see is smtp enabled or not

* feat: email auth provider disabled on smtp disable

* chore: restrict on update directly instead of dedicated mutation

* fix: feedback resolved

* chore: modify mailer module

* chore: error handle in mailer functions

* chore: removed unused imports

* chore: remove event-emit

* chore: update env example

* test: fix broken test cases

* chore: feedback resolved

* chore: isSMTPEnabled moved to infra config resolver

* fix: email can not reenable if smtp not enabled
This commit is contained in:
Mir Arif Hasan
2024-06-27 18:23:40 +06:00
committed by GitHub
parent b3e42bf7c3
commit fa2f73ee40
22 changed files with 13099 additions and 14968 deletions

View File

@@ -35,9 +35,20 @@ MICROSOFT_SCOPE="user.read"
MICROSOFT_TENANT="common"
# Mailer config
MAILER_SMTP_URL="smtps://user@domain.com:pass@smtp.domain.com"
MAILER_SMTP_ENABLE="true"
MAILER_USE_CUSTOM_CONFIGS="false"
MAILER_ADDRESS_FROM='"From Name Here" <from@example.com>'
MAILER_SMTP_URL="smtps://user@domain.com:pass@smtp.domain.com" # used if custom mailer configs is false
# The following are used if custom mailer configs is true
MAILER_SMTP_HOST="smtp.domain.com"
MAILER_SMTP_PORT="587"
MAILER_SMTP_SECURE="true"
MAILER_SMTP_USER="user@domain.com"
MAILER_SMTP_PASSWORD="pass"
MAILER_TLS_REJECT_UNAUTHORIZED="true"
# Rate Limit Config
RATE_LIMIT_TTL=60 # In seconds
RATE_LIMIT_MAX=100 # Max requests per IP

View File

@@ -30,6 +30,7 @@ const user: AuthUser = {
currentGQLSession: {},
currentRESTSession: {},
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
};
const PATCreatedOn = new Date();

View File

@@ -75,6 +75,7 @@ const dbAdminUsers: DbUser[] = [
currentRESTSession: '',
currentGQLSession: '',
lastLoggedOn: new Date(),
lastActiveOn: new Date(),
createdOn: new Date(),
},
{
@@ -87,6 +88,7 @@ const dbAdminUsers: DbUser[] = [
currentRESTSession: '',
currentGQLSession: '',
lastLoggedOn: new Date(),
lastActiveOn: new Date(),
createdOn: new Date(),
},
];

View File

@@ -359,4 +359,23 @@ export class InfraResolver {
return true;
}
@Mutation(() => Boolean, {
description: 'Enable or Disable SMTP for sending emails',
})
@UseGuards(GqlAuthGuard, GqlAdminGuard)
async toggleSMTP(
@Args({
name: 'status',
type: () => ServiceStatus,
description: 'Toggle SMTP',
})
status: ServiceStatus,
) {
const isUpdated = await this.infraConfigService.enableAndDisableSMTP(
status,
);
if (E.isLeft(isUpdated)) throwErr(isUpdated.left);
return true;
}
}

View File

@@ -52,6 +52,7 @@ const user: AuthUser = {
isAdmin: false,
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
currentGQLSession: {},
currentRESTSession: {},

View File

@@ -678,6 +678,19 @@ export const MAILER_SMTP_URL_UNDEFINED = 'mailer/smtp_url_undefined' as const;
export const MAILER_FROM_ADDRESS_UNDEFINED =
'mailer/from_address_undefined' as const;
/**
* MAILER_SMTP_USER environment variable is not defined
* (MailerModule)
*/
export const MAILER_SMTP_USER_UNDEFINED = 'mailer/smtp_user_undefined' as const;
/**
* MAILER_SMTP_PASSWORD environment variable is not defined
* (MailerModule)
*/
export const MAILER_SMTP_PASSWORD_UNDEFINED =
'mailer/smtp_password_undefined' as const;
/**
* SharedRequest invalid request JSON format
* (ShortcodeService)

View File

@@ -28,6 +28,7 @@ import { UserEnvsUserResolver } from './user-environment/user.resolver';
import { UserHistoryUserResolver } from './user-history/user.resolver';
import { UserSettingsUserResolver } from './user-settings/user.resolver';
import { InfraResolver } from './admin/infra.resolver';
import { InfraConfigResolver } from './infra-config/infra-config.resolver';
/**
* All the resolvers present in the application.
@@ -58,6 +59,7 @@ const RESOLVERS = [
UserRequestUserCollectionResolver,
UserSettingsResolver,
UserSettingsUserResolver,
InfraConfigResolver,
];
/**

View File

@@ -33,10 +33,17 @@ const AuthProviderConfigurations = {
InfraConfigEnum.MICROSOFT_SCOPE,
InfraConfigEnum.MICROSOFT_TENANT,
],
[AuthProvider.EMAIL]: [
InfraConfigEnum.MAILER_SMTP_URL,
InfraConfigEnum.MAILER_ADDRESS_FROM,
],
[AuthProvider.EMAIL]: !!process.env.MAILER_USE_CUSTOM_CONFIGS
? [
InfraConfigEnum.MAILER_SMTP_HOST,
InfraConfigEnum.MAILER_SMTP_PORT,
InfraConfigEnum.MAILER_SMTP_SECURE,
InfraConfigEnum.MAILER_SMTP_USER,
InfraConfigEnum.MAILER_SMTP_PASSWORD,
InfraConfigEnum.MAILER_TLS_REJECT_UNAUTHORIZED,
InfraConfigEnum.MAILER_ADDRESS_FROM,
]
: [InfraConfigEnum.MAILER_SMTP_URL, InfraConfigEnum.MAILER_ADDRESS_FROM],
};
/**
@@ -75,6 +82,14 @@ export async function getDefaultInfraConfigs(): Promise<
// Prepare rows for 'infra_config' table with default values (from .env) for each 'name'
const infraConfigDefaultObjs: { name: InfraConfigEnum; value: string }[] = [
{
name: InfraConfigEnum.MAILER_SMTP_ENABLE,
value: process.env.MAILER_SMTP_ENABLE ?? 'true',
},
{
name: InfraConfigEnum.MAILER_USE_CUSTOM_CONFIGS,
value: process.env.MAILER_USE_CUSTOM_CONFIGS ?? 'false',
},
{
name: InfraConfigEnum.MAILER_SMTP_URL,
value: process.env.MAILER_SMTP_URL,
@@ -83,6 +98,30 @@ export async function getDefaultInfraConfigs(): Promise<
name: InfraConfigEnum.MAILER_ADDRESS_FROM,
value: process.env.MAILER_ADDRESS_FROM,
},
{
name: InfraConfigEnum.MAILER_SMTP_HOST,
value: process.env.MAILER_SMTP_HOST,
},
{
name: InfraConfigEnum.MAILER_SMTP_PORT,
value: process.env.MAILER_SMTP_PORT,
},
{
name: InfraConfigEnum.MAILER_SMTP_SECURE,
value: process.env.MAILER_SMTP_SECURE,
},
{
name: InfraConfigEnum.MAILER_SMTP_USER,
value: process.env.MAILER_SMTP_USER,
},
{
name: InfraConfigEnum.MAILER_SMTP_PASSWORD,
value: process.env.MAILER_SMTP_PASSWORD,
},
{
name: InfraConfigEnum.MAILER_TLS_REJECT_UNAUTHORIZED,
value: process.env.MAILER_TLS_REJECT_UNAUTHORIZED,
},
{
name: InfraConfigEnum.GOOGLE_CLIENT_ID,
value: process.env.GOOGLE_CLIENT_ID,

View File

@@ -2,10 +2,11 @@ import { Module } from '@nestjs/common';
import { InfraConfigService } from './infra-config.service';
import { PrismaModule } from 'src/prisma/prisma.module';
import { SiteController } from './infra-config.controller';
import { InfraConfigResolver } from './infra-config.resolver';
@Module({
imports: [PrismaModule],
providers: [InfraConfigService],
providers: [InfraConfigResolver, InfraConfigService],
exports: [InfraConfigService],
controllers: [SiteController],
})

View File

@@ -0,0 +1,20 @@
import { UseGuards } from '@nestjs/common';
import { Query, Resolver } from '@nestjs/graphql';
import { GqlThrottlerGuard } from 'src/guards/gql-throttler.guard';
import { InfraConfig } from './infra-config.model';
import { InfraConfigService } from './infra-config.service';
import { GqlAuthGuard } from 'src/guards/gql-auth.guard';
@UseGuards(GqlThrottlerGuard)
@Resolver(() => InfraConfig)
export class InfraConfigResolver {
constructor(private infraConfigService: InfraConfigService) {}
@Query(() => Boolean, {
description: 'Check if the SMTP is enabled or not',
})
@UseGuards(GqlAuthGuard)
isSMTPEnabled() {
return this.infraConfigService.isSMTPEnabled();
}
}

View File

@@ -43,6 +43,7 @@ export class InfraConfigService implements OnModuleInit {
InfraConfigEnum.ALLOW_ANALYTICS_COLLECTION,
InfraConfigEnum.ANALYTICS_USER_ID,
InfraConfigEnum.IS_FIRST_TIME_INFRA_SETUP,
InfraConfigEnum.MAILER_SMTP_ENABLE,
];
// Following fields can not be fetched by `infraConfigs` Query. Use dedicated queries for these fields instead.
EXCLUDE_FROM_FETCH_CONFIGS = [
@@ -196,7 +197,20 @@ export class InfraConfigService implements OnModuleInit {
configMap.MICROSOFT_TENANT
);
case AuthProvider.EMAIL:
return configMap.MAILER_SMTP_URL && configMap.MAILER_ADDRESS_FROM;
if (configMap.MAILER_SMTP_ENABLE !== 'true') return false;
if (configMap.MAILER_USE_CUSTOM_CONFIGS === 'true') {
return (
configMap.MAILER_SMTP_HOST &&
configMap.MAILER_SMTP_PORT &&
configMap.MAILER_SMTP_SECURE &&
configMap.MAILER_SMTP_USER &&
configMap.MAILER_SMTP_PASSWORD &&
configMap.MAILER_TLS_REJECT_UNAUTHORIZED &&
configMap.MAILER_ADDRESS_FROM
);
} else {
return configMap.MAILER_SMTP_URL && configMap.MAILER_ADDRESS_FROM;
}
default:
return false;
}
@@ -218,6 +232,47 @@ export class InfraConfigService implements OnModuleInit {
return E.right(isUpdated.right.value === 'true');
}
/**
* Enable or Disable SMTP
* @param status Status to enable or disable
* @returns Either true or an error
*/
async enableAndDisableSMTP(status: ServiceStatus) {
const isUpdated = await this.toggleServiceStatus(
InfraConfigEnum.MAILER_SMTP_ENABLE,
status,
true,
);
if (E.isLeft(isUpdated)) return E.left(isUpdated.left);
if (status === ServiceStatus.DISABLE) {
this.enableAndDisableSSO([{ provider: AuthProvider.EMAIL, status }]);
}
return E.right(true);
}
/**
* Enable or Disable Service (i.e. ALLOW_AUDIT_LOGS, ALLOW_ANALYTICS_COLLECTION, ALLOW_DOMAIN_WHITELISTING, SITE_PROTECTION)
* @param configName Name of the InfraConfigEnum
* @param status Status to enable or disable
* @param restartEnabled If true, restart the app after updating the InfraConfig
* @returns Either true or an error
*/
async toggleServiceStatus(
configName: InfraConfigEnum,
status: ServiceStatus,
restartEnabled = false,
) {
const isUpdated = await this.update(
configName,
status === ServiceStatus.ENABLE ? 'true' : 'false',
restartEnabled,
);
if (E.isLeft(isUpdated)) return E.left(isUpdated.left);
return E.right(true);
}
/**
* Enable or Disable SSO for login/signup
* @param provider Auth Provider to enable or disable
@@ -316,6 +371,16 @@ export class InfraConfigService implements OnModuleInit {
.split(',');
}
/**
* Check if SMTP is enabled or not
* @returns boolean
*/
isSMTPEnabled() {
return (
this.configService.get<string>('INFRA.MAILER_SMTP_ENABLE') === 'true'
);
}
/**
* Reset all the InfraConfigs to their default values (from .env)
*/
@@ -363,6 +428,20 @@ export class InfraConfigService implements OnModuleInit {
) {
for (let i = 0; i < infraConfigs.length; i++) {
switch (infraConfigs[i].name) {
case InfraConfigEnum.MAILER_SMTP_ENABLE:
if (
infraConfigs[i].value !== 'true' &&
infraConfigs[i].value !== 'false'
)
return E.left(INFRA_CONFIG_INVALID_INPUT);
break;
case InfraConfigEnum.MAILER_USE_CUSTOM_CONFIGS:
if (
infraConfigs[i].value !== 'true' &&
infraConfigs[i].value !== 'false'
)
return E.left(INFRA_CONFIG_INVALID_INPUT);
break;
case InfraConfigEnum.MAILER_SMTP_URL:
const isValidUrl = validateSMTPUrl(infraConfigs[i].value);
if (!isValidUrl) return E.left(INFRA_CONFIG_INVALID_INPUT);
@@ -371,6 +450,32 @@ export class InfraConfigService implements OnModuleInit {
const isValidEmail = validateSMTPEmail(infraConfigs[i].value);
if (!isValidEmail) return E.left(INFRA_CONFIG_INVALID_INPUT);
break;
case InfraConfigEnum.MAILER_SMTP_HOST:
if (!infraConfigs[i].value) return E.left(INFRA_CONFIG_INVALID_INPUT);
break;
case InfraConfigEnum.MAILER_SMTP_PORT:
if (!infraConfigs[i].value) return E.left(INFRA_CONFIG_INVALID_INPUT);
break;
case InfraConfigEnum.MAILER_SMTP_SECURE:
if (
infraConfigs[i].value !== 'true' &&
infraConfigs[i].value !== 'false'
)
return E.left(INFRA_CONFIG_INVALID_INPUT);
break;
case InfraConfigEnum.MAILER_SMTP_USER:
if (!infraConfigs[i].value) return E.left(INFRA_CONFIG_INVALID_INPUT);
break;
case InfraConfigEnum.MAILER_SMTP_PASSWORD:
if (!infraConfigs[i].value) return E.left(INFRA_CONFIG_INVALID_INPUT);
break;
case InfraConfigEnum.MAILER_TLS_REJECT_UNAUTHORIZED:
if (
infraConfigs[i].value !== 'true' &&
infraConfigs[i].value !== 'false'
)
return E.left(INFRA_CONFIG_INVALID_INPUT);
break;
case InfraConfigEnum.GOOGLE_CLIENT_ID:
if (!infraConfigs[i].value) return E.left(INFRA_CONFIG_INVALID_INPUT);
break;

View File

@@ -0,0 +1,58 @@
import { TransportType } from '@nestjs-modules/mailer/dist/interfaces/mailer-options.interface';
import {
MAILER_SMTP_PASSWORD_UNDEFINED,
MAILER_SMTP_URL_UNDEFINED,
MAILER_SMTP_USER_UNDEFINED,
} from 'src/errors';
import { throwErr } from 'src/utils';
function isSMTPCustomConfigsEnabled(value) {
return value === 'true';
}
export function getMailerAddressFrom(env, config): string {
return (
env.INFRA.MAILER_ADDRESS_FROM ??
config.get('MAILER_ADDRESS_FROM') ??
throwErr(MAILER_SMTP_URL_UNDEFINED)
);
}
export function getTransportOption(env, config): TransportType {
const useCustomConfigs = isSMTPCustomConfigsEnabled(
env.INFRA.MAILER_USE_CUSTOM_CONFIGS ??
config.get('MAILER_USE_CUSTOM_CONFIGS'),
);
if (!useCustomConfigs) {
console.log('Using simple mailer configuration');
return (
env.INFRA.MAILER_SMTP_URL ??
config.get('MAILER_SMTP_URL') ??
throwErr(MAILER_SMTP_URL_UNDEFINED)
);
} else {
console.log('Using advanced mailer configuration');
return {
host: env.INFRA.MAILER_SMTP_HOST ?? config.get('MAILER_SMTP_HOST'),
port: +env.INFRA.MAILER_SMTP_PORT ?? +config.get('MAILER_SMTP_PORT'),
secure:
!!env.INFRA.MAILER_SMTP_SECURE ?? !!config.get('MAILER_SMTP_SECURE'),
auth: {
user:
env.INFRA.MAILER_SMTP_USER ??
config.get('MAILER_SMTP_USER') ??
throwErr(MAILER_SMTP_USER_UNDEFINED),
pass:
env.INFRA.MAILER_SMTP_PASSWORD ??
config.get('MAILER_SMTP_PASSWORD') ??
throwErr(MAILER_SMTP_PASSWORD_UNDEFINED),
},
tls: {
rejectUnauthorized:
!!env.INFRA.MAILER_TLS_REJECT_UNAUTHORIZED ??
!!config.get('MAILER_TLS_REJECT_UNAUTHORIZED'),
},
};
}
}

View File

@@ -2,13 +2,9 @@ import { Global, Module } from '@nestjs/common';
import { MailerModule as NestMailerModule } from '@nestjs-modules/mailer';
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { MailerService } from './mailer.service';
import { throwErr } from 'src/utils';
import {
MAILER_FROM_ADDRESS_UNDEFINED,
MAILER_SMTP_URL_UNDEFINED,
} from 'src/errors';
import { ConfigService } from '@nestjs/config';
import { loadInfraConfiguration } from 'src/infra-config/helper';
import { getMailerAddressFrom, getTransportOption } from './helper';
@Global()
@Module({
@@ -18,24 +14,31 @@ import { loadInfraConfiguration } from 'src/infra-config/helper';
})
export class MailerModule {
static async register() {
const config = new ConfigService();
const env = await loadInfraConfiguration();
let mailerSmtpUrl = env.INFRA.MAILER_SMTP_URL;
let mailerAddressFrom = env.INFRA.MAILER_ADDRESS_FROM;
if (!env.INFRA.MAILER_SMTP_URL || !env.INFRA.MAILER_ADDRESS_FROM) {
const config = new ConfigService();
mailerSmtpUrl = config.get('MAILER_SMTP_URL');
mailerAddressFrom = config.get('MAILER_ADDRESS_FROM');
// If mailer SMTP is DISABLED, return the module without any configuration (service, listener, etc.)
if (env.INFRA.MAILER_SMTP_ENABLE !== 'true') {
console.log('Mailer module is disabled');
return {
module: MailerModule,
};
}
// If mailer is ENABLED, return the module with configuration (service, etc.)
// Determine transport configuration based on custom config flag
let transportOption = getTransportOption(env, config);
// Get mailer address from environment or config
const mailerAddressFrom = getMailerAddressFrom(env, config);
return {
module: MailerModule,
imports: [
NestMailerModule.forRoot({
transport: mailerSmtpUrl ?? throwErr(MAILER_SMTP_URL_UNDEFINED),
transport: transportOption,
defaults: {
from: mailerAddressFrom ?? throwErr(MAILER_FROM_ADDRESS_UNDEFINED),
from: mailerAddressFrom,
},
template: {
dir: __dirname + '/templates',

View File

@@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
import { Injectable, Optional } from '@nestjs/common';
import {
AdminUserInvitationMailDescription,
MailDescription,
@@ -7,10 +7,14 @@ import {
import { throwErr } from 'src/utils';
import { EMAIL_FAILED } from 'src/errors';
import { MailerService as NestMailerService } from '@nestjs-modules/mailer';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class MailerService {
constructor(private readonly nestMailerService: NestMailerService) {}
constructor(
@Optional() private readonly nestMailerService: NestMailerService,
private readonly configService: ConfigService,
) {}
/**
* Takes an input mail description and spits out the Email subject required for it
@@ -42,6 +46,8 @@ export class MailerService {
to: string,
mailDesc: MailDescription | UserMagicLinkMailDescription,
) {
if (this.configService.get('INFRA.MAILER_SMTP_ENABLE') !== 'true') return;
try {
await this.nestMailerService.sendMail({
to,
@@ -50,6 +56,7 @@ export class MailerService {
context: mailDesc.variables,
});
} catch (error) {
console.log('Error from sendEmail:', error);
return throwErr(EMAIL_FAILED);
}
}
@@ -64,6 +71,8 @@ export class MailerService {
to: string,
mailDesc: AdminUserInvitationMailDescription,
) {
if (this.configService.get('INFRA.MAILER_SMTP_ENABLE') !== 'true') return;
try {
const res = await this.nestMailerService.sendMail({
to,
@@ -73,6 +82,7 @@ export class MailerService {
});
return res;
} catch (error) {
console.log('Error from sendUserInvitationEmail:', error);
return throwErr(EMAIL_FAILED);
}
}

View File

@@ -49,6 +49,7 @@ const user: AuthUser = {
isAdmin: false,
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: createdOn,
lastActiveOn: createdOn,
createdOn: createdOn,
currentGQLSession: {},
currentRESTSession: {},

View File

@@ -44,6 +44,7 @@ const user: AuthUser = {
isAdmin: false,
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
currentGQLSession: {},
currentRESTSession: {},

View File

@@ -1,7 +1,16 @@
export enum InfraConfigEnum {
MAILER_SMTP_ENABLE = 'MAILER_SMTP_ENABLE',
MAILER_USE_CUSTOM_CONFIGS = 'MAILER_USE_CUSTOM_CONFIGS',
MAILER_SMTP_URL = 'MAILER_SMTP_URL',
MAILER_ADDRESS_FROM = 'MAILER_ADDRESS_FROM',
MAILER_SMTP_HOST = 'MAILER_SMTP_HOST',
MAILER_SMTP_PORT = 'MAILER_SMTP_PORT',
MAILER_SMTP_SECURE = 'MAILER_SMTP_SECURE',
MAILER_SMTP_USER = 'MAILER_SMTP_USER',
MAILER_SMTP_PASSWORD = 'MAILER_SMTP_PASSWORD',
MAILER_TLS_REJECT_UNAUTHORIZED = 'MAILER_TLS_REJECT_UNAUTHORIZED',
GOOGLE_CLIENT_ID = 'GOOGLE_CLIENT_ID',
GOOGLE_CLIENT_SECRET = 'GOOGLE_CLIENT_SECRET',
GOOGLE_CALLBACK_URL = 'GOOGLE_CALLBACK_URL',

View File

@@ -39,6 +39,7 @@ const user: AuthUser = {
isAdmin: false,
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
currentGQLSession: {},
currentRESTSession: {},

View File

@@ -42,6 +42,7 @@ const user: AuthUser = {
isAdmin: false,
refreshToken: null,
lastLoggedOn: new Date(),
lastActiveOn: new Date(),
createdOn: new Date(),
currentGQLSession: null,
currentRESTSession: null,

View File

@@ -28,6 +28,7 @@ const user: AuthUser = {
currentGQLSession: {},
currentRESTSession: {},
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
};

View File

@@ -43,6 +43,7 @@ const user: AuthUser = {
currentGQLSession: {},
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
};
@@ -56,6 +57,7 @@ const adminUser: AuthUser = {
currentGQLSession: {},
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
};
@@ -70,6 +72,7 @@ const users: AuthUser[] = [
currentGQLSession: {},
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
},
{
@@ -82,6 +85,7 @@ const users: AuthUser[] = [
currentGQLSession: {},
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
},
{
@@ -94,6 +98,7 @@ const users: AuthUser[] = [
currentGQLSession: {},
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
},
];
@@ -109,6 +114,7 @@ const adminUsers: AuthUser[] = [
currentGQLSession: {},
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
},
{
@@ -121,6 +127,7 @@ const adminUsers: AuthUser[] = [
currentGQLSession: {},
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
},
{
@@ -133,6 +140,7 @@ const adminUsers: AuthUser[] = [
currentGQLSession: {},
refreshToken: 'hbfvdkhjbvkdvdfjvbnkhjb',
lastLoggedOn: currentTime,
lastActiveOn: currentTime,
createdOn: currentTime,
},
];

27714
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff