diff --git a/Accounts/src/Reducers/ChangePassword.ts b/Accounts/src/Reducers/ChangePassword.ts index ef322d9311..eac83b9283 100755 --- a/Accounts/src/Reducers/ChangePassword.ts +++ b/Accounts/src/Reducers/ChangePassword.ts @@ -1,7 +1,7 @@ import ApiBase from 'CommonUI/src/Reducers/ApiBase'; -export default class ChangePassword extends ApiBase{ +export default class ChangePassword extends ApiBase { constructor() { - super("ChangePassword"); + super('ChangePassword'); } -} \ No newline at end of file +} diff --git a/Accounts/src/Reducers/Login.ts b/Accounts/src/Reducers/Login.ts index d54bb3e4b2..0122a55198 100755 --- a/Accounts/src/Reducers/Login.ts +++ b/Accounts/src/Reducers/Login.ts @@ -1,7 +1,7 @@ import ApiBase from 'CommonUI/src/Reducers/ApiBase'; -export default class ChangePassword extends ApiBase{ +export default class ChangePassword extends ApiBase { constructor() { - super("Login"); + super('Login'); } -} \ No newline at end of file +} diff --git a/Accounts/src/Reducers/Register.ts b/Accounts/src/Reducers/Register.ts index aa2204aaa4..5ac189fe61 100755 --- a/Accounts/src/Reducers/Register.ts +++ b/Accounts/src/Reducers/Register.ts @@ -1,7 +1,7 @@ import ApiBase from 'CommonUI/src/Reducers/ApiBase'; -export default class ChangePassword extends ApiBase{ +export default class ChangePassword extends ApiBase { constructor() { - super("Register"); + super('Register'); } -} \ No newline at end of file +} diff --git a/Accounts/src/Reducers/ResendVerifyEmail.ts b/Accounts/src/Reducers/ResendVerifyEmail.ts index 4ddfc09d89..820f0ddef8 100755 --- a/Accounts/src/Reducers/ResendVerifyEmail.ts +++ b/Accounts/src/Reducers/ResendVerifyEmail.ts @@ -1,7 +1,7 @@ import ApiBase from 'CommonUI/src/Reducers/ApiBase'; -export default class ResendVerifyEmail extends ApiBase{ +export default class ResendVerifyEmail extends ApiBase { constructor() { - super("ResendVerifyEmail"); + super('ResendVerifyEmail'); } -} \ No newline at end of file +} diff --git a/Accounts/src/Reducers/ResetPassword.ts b/Accounts/src/Reducers/ResetPassword.ts index 5c35c95f3c..a93597c365 100755 --- a/Accounts/src/Reducers/ResetPassword.ts +++ b/Accounts/src/Reducers/ResetPassword.ts @@ -2,6 +2,6 @@ import ApiBase from 'CommonUI/src/Reducers/ApiBase'; export default class ResetPassword extends ApiBase { constructor() { - super("ResetPassword"); + super('ResetPassword'); } -} \ No newline at end of file +} diff --git a/Accounts/src/Store.ts b/Accounts/src/Store.ts index 3192d115a9..a3c8eec9f9 100755 --- a/Accounts/src/Store.ts +++ b/Accounts/src/Store.ts @@ -59,7 +59,6 @@ const store: $TSFixMe = createStore( composedEnhancers ); - export type RootState = ReturnType; export default store; diff --git a/Common/Models/BaseModel.ts b/Common/Models/BaseModel.ts index db3ad06e7b..2c00427016 100644 --- a/Common/Models/BaseModel.ts +++ b/Common/Models/BaseModel.ts @@ -12,8 +12,6 @@ import { JSONObject } from '../Types/JSON'; import ObjectID from '../Types/ObjectID'; export default class BaseModel extends BaseEntity { - - @PrimaryGeneratedColumn('uuid') public _id!: string; @@ -29,7 +27,6 @@ export default class BaseModel extends BaseEntity { @VersionColumn() public version!: number; - private encryptedColumns: Columns = new Columns([]); private uniqueColumns: Columns = new Columns([]); private requiredColumns: Columns = new Columns([]); @@ -59,31 +56,30 @@ export default class BaseModel extends BaseEntity { private viewerDeleteableColumns: Columns = new Columns([]); private publicDeleteableColumns: Columns = new Columns([]); - private canAdminCreateRecord = false; - private canAdminDeleteRecord = false; - private canAdminUpdateRecord = false; - private canAdminReadRecord = false; + private canAdminCreateRecord = false; + private canAdminDeleteRecord = false; + private canAdminUpdateRecord = false; + private canAdminReadRecord = false; - private canPublicCreateRecord = false; - private canPublicDeleteRecord = false; - private canPublicUpdateRecord = false; - private canPublicReadRecord = false; + private canPublicCreateRecord = false; + private canPublicDeleteRecord = false; + private canPublicUpdateRecord = false; + private canPublicReadRecord = false; - private canOwnerCreateRecord = false; - private canOwnerDeleteRecord = false; - private canOwnerUpdateRecord = false; - private canOwnerReadRecord = false; + private canOwnerCreateRecord = false; + private canOwnerDeleteRecord = false; + private canOwnerUpdateRecord = false; + private canOwnerReadRecord = false; - private canMemberCreateRecord = false; - private canMemberDeleteRecord = false; - private canMemberUpdateRecord = false; - private canMemberReadRecord = false; - - private canViewerCreateRecord = false; - private canViewerDeleteRecord = false; - private canViewerUpdateRecord = false; - private canViewerReadRecord = false; + private canMemberCreateRecord = false; + private canMemberDeleteRecord = false; + private canMemberUpdateRecord = false; + private canMemberReadRecord = false; + private canViewerCreateRecord = false; + private canViewerDeleteRecord = false; + private canViewerUpdateRecord = false; + private canViewerReadRecord = false; private slugifyColumn!: string | null; private saveSlugToColumn!: string | null; @@ -341,8 +337,6 @@ export default class BaseModel extends BaseEntity { return this.viewerDeleteableColumns; } - - public setSlugifyColumn(columnName: string): void { this.slugifyColumn = columnName; } @@ -384,300 +378,335 @@ export default class BaseModel extends BaseEntity { private static _fromJSON(json: JSONObject): T { const baseModel = new BaseModel(); - for (let key of Object.keys(json)) { - + for (const key of Object.keys(json)) { (baseModel as any)[key] = json[key]; - } return baseModel as T; } - - public static fromJSON(json: JSONObject): T { return this._fromJSON(json); } - private static keepColumns(data: T, columnsToKeep: Columns): T { + private static keepColumns( + data: T, + columnsToKeep: Columns + ): T { const baseModel = new BaseModel(); - for (let key of Object.keys(data)) { - + for (const key of Object.keys(data)) { if (!columnsToKeep) { (baseModel as any)[key] = (data as any)[key]; } - if (columnsToKeep && columnsToKeep.columns.length > 0 && columnsToKeep.columns.includes(key)) { + if ( + columnsToKeep && + columnsToKeep.columns.length > 0 && + columnsToKeep.columns.includes(key) + ) { (baseModel as any)[key] = (data as any)[key]; } - } return baseModel as T; } - public static asPublicCreateable(data: JSONObject | T) { - + public static asPublicCreateable( + data: JSONObject | T + ): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canPublicCreateRecord) { - throw new BadRequestException("A user of role public cannot create this record.") + throw new BadRequestException( + 'A user of role public cannot create this record.' + ); } - return this.keepColumns(data, data.getPublicCreateableColumns()); + return this.keepColumns(data, data.getPublicCreateableColumns()); } - public static asPublicUpdateable(data: JSONObject | T) { - + public static asPublicUpdateable( + data: JSONObject | T + ): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canPublicUpdateRecord) { - throw new BadRequestException("A user of role public cannot update this record.") + throw new BadRequestException( + 'A user of role public cannot update this record.' + ); } - return this.keepColumns(data, data.getPublicUpdateableColumns()); + return this.keepColumns(data, data.getPublicUpdateableColumns()); } - public static asPublicReadable(data: JSONObject | T) { - + public static asPublicReadable(data: JSONObject | T): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canPublicReadRecord) { - throw new BadRequestException("A user of role public cannot read this record.") + throw new BadRequestException( + 'A user of role public cannot read this record.' + ); } - return this.keepColumns(data, data.getPublicReadableColumns()); + return this.keepColumns(data, data.getPublicReadableColumns()); } - public static asPublicDeleteable(data: JSONObject | T) { - + public static asPublicDeleteable( + data: JSONObject | T + ): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canPublicDeleteRecord) { - throw new BadRequestException("A user of role public cannot delete this record.") + throw new BadRequestException( + 'A user of role public cannot delete this record.' + ); } - return this.keepColumns(data, data.getPublicDeleteableColumns()); + return this.keepColumns(data, data.getPublicDeleteableColumns()); } - public static asOwnerCreateable(data: JSONObject | T) { - + public static asOwnerCreateable(data: JSONObject | T): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canOwnerCreateRecord) { - throw new BadRequestException("A user of role owner cannot create this record.") + throw new BadRequestException( + 'A user of role owner cannot create this record.' + ); } - return this.keepColumns(data, data.getOwnerCreateableColumns()); + return this.keepColumns(data, data.getOwnerCreateableColumns()); } - public static asOwnerUpdateable(data: JSONObject | T) { - + public static asOwnerUpdateable(data: JSONObject | T): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canOwnerUpdateRecord) { - throw new BadRequestException("A user of role owner cannot update this record.") + throw new BadRequestException( + 'A user of role owner cannot update this record.' + ); } - return this.keepColumns(data, data.getOwnerUpdateableColumns()); + return this.keepColumns(data, data.getOwnerUpdateableColumns()); } - public static asOwnerReadable(data: JSONObject | T) { - + public static asOwnerReadable(data: JSONObject | T): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canOwnerReadRecord) { - throw new BadRequestException("A user of role owner cannot delete this record.") + throw new BadRequestException( + 'A user of role owner cannot delete this record.' + ); } - return this.keepColumns(data, data.getOwnerReadableColumns()); + return this.keepColumns(data, data.getOwnerReadableColumns()); } - public static asOwnerDeleteable(data: JSONObject | T) { - + public static asOwnerDeleteable(data: JSONObject | T): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canOwnerDeleteRecord) { - throw new BadRequestException("A user of role owner cannot delete this record.") + throw new BadRequestException( + 'A user of role owner cannot delete this record.' + ); } - return this.keepColumns(data, data.getOwnerDeleteableColumns()); + return this.keepColumns(data, data.getOwnerDeleteableColumns()); } - - - public static asViewerCreateable(data: JSONObject | T) { - + public static asViewerCreateable( + data: JSONObject | T + ): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canViewerCreateRecord) { - throw new BadRequestException("A user of role viewer cannot create this record.") + throw new BadRequestException( + 'A user of role viewer cannot create this record.' + ); } - return this.keepColumns(data, data.getViewerCreateableColumns()); + return this.keepColumns(data, data.getViewerCreateableColumns()); } - public static asViewerUpdateable(data: JSONObject | T) { - + public static asViewerUpdateable( + data: JSONObject | T + ): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canViewerUpdateRecord) { - throw new BadRequestException("A user of role viewer cannot update this record.") + throw new BadRequestException( + 'A user of role viewer cannot update this record.' + ); } - return this.keepColumns(data, data.getViewerUpdateableColumns()); + return this.keepColumns(data, data.getViewerUpdateableColumns()); } - public static asViewerReadable(data: JSONObject | T) { - + public static asViewerReadable(data: JSONObject | T): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canViewerReadRecord) { - throw new BadRequestException("A user of role viewer cannot read this record.") + throw new BadRequestException( + 'A user of role viewer cannot read this record.' + ); } - return this.keepColumns(data, data.getViewerReadableColumns()); + return this.keepColumns(data, data.getViewerReadableColumns()); } - public static asViewerDeleteable(data: JSONObject | T) { - + public static asViewerDeleteable( + data: JSONObject | T + ): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canViewerDeleteRecord) { - throw new BadRequestException("A user of role viewer cannot delete this record.") + throw new BadRequestException( + 'A user of role viewer cannot delete this record.' + ); } - return this.keepColumns(data, data.getViewerDeleteableColumns()); + return this.keepColumns(data, data.getViewerDeleteableColumns()); } - - public static asMemberCreateable(data: JSONObject | T) { - + public static asMemberCreateable( + data: JSONObject | T + ): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canMemberCreateRecord) { - throw new BadRequestException("A user of role member cannot create this record.") + throw new BadRequestException( + 'A user of role member cannot create this record.' + ); } - return this.keepColumns(data, data.getMemberCreateableColumns()); + return this.keepColumns(data, data.getMemberCreateableColumns()); } - public static asMemberUpdateable(data: JSONObject | T) { - + public static asMemberUpdateable( + data: JSONObject | T + ): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canMemberUpdateRecord) { - throw new BadRequestException("A user of role member cannot update this record.") + throw new BadRequestException( + 'A user of role member cannot update this record.' + ); } - return this.keepColumns(data, data.getMemberUpdateableColumns()); + return this.keepColumns(data, data.getMemberUpdateableColumns()); } - public static asMemberReadable(data: JSONObject | T) { - + public static asMemberReadable(data: JSONObject | T): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canMemberReadRecord) { - throw new BadRequestException("A user of role member cannot read this record.") + throw new BadRequestException( + 'A user of role member cannot read this record.' + ); } - return this.keepColumns(data, data.getMemberReadableColumns()); + return this.keepColumns(data, data.getMemberReadableColumns()); } - public static asMemberDeleteable(data: JSONObject | T) { - + public static asMemberDeleteable( + data: JSONObject | T + ): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canMemberDeleteRecord) { - throw new BadRequestException("A user of role member cannot delete this record.") + throw new BadRequestException( + 'A user of role member cannot delete this record.' + ); } - return this.keepColumns(data, data.getMemberDeleteableColumns()); + return this.keepColumns(data, data.getMemberDeleteableColumns()); } - - public static asAdminCreateable(data: JSONObject | T) { - + public static asAdminCreateable(data: JSONObject | T): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canAdminCreateRecord) { - throw new BadRequestException("A user of role admin cannot create this record.") + throw new BadRequestException( + 'A user of role admin cannot create this record.' + ); } - return this.keepColumns(data, data.getAdminCreateableColumns()); + return this.keepColumns(data, data.getAdminCreateableColumns()); } - public static asAdminUpdateable(data: JSONObject | T) { - + public static asAdminUpdateable(data: JSONObject | T): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canAdminUpdateRecord) { - throw new BadRequestException("A user of role admin cannot update this record.") + throw new BadRequestException( + 'A user of role admin cannot update this record.' + ); } - return this.keepColumns(data, data.getAdminUpdateableColumns()); + return this.keepColumns(data, data.getAdminUpdateableColumns()); } - public static asAdminReadable(data: JSONObject | T) { - + public static asAdminReadable(data: JSONObject | T): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canAdminReadRecord) { - throw new BadRequestException("A user of role admin cannot read this record.") + throw new BadRequestException( + 'A user of role admin cannot read this record.' + ); } - return this.keepColumns(data, data.getAdminReadableColumns()); + return this.keepColumns(data, data.getAdminReadableColumns()); } - public static asAdminDeleteable(data: JSONObject | T) { - + public static asAdminDeleteable(data: JSONObject | T): T { if (!(data instanceof BaseModel)) { data = this._fromJSON(data); } if (!data.canAdminDeleteRecord) { - throw new BadRequestException("A user of role admin cannot delete this record.") + throw new BadRequestException( + 'A user of role admin cannot delete this record.' + ); } - return this.keepColumns(data, data.getAdminDeleteableColumns()); + return this.keepColumns(data, data.getAdminDeleteableColumns()); } } diff --git a/Common/Types/Date.ts b/Common/Types/Date.ts index ad4e0aa524..23aefb7729 100644 --- a/Common/Types/Date.ts +++ b/Common/Types/Date.ts @@ -42,7 +42,6 @@ export default class OneUptimeDate { .toDate(); } - public static getOneMinAfter(): Date { return this.getSomeMinutesAfter(new PositiveNumber(1)); } @@ -53,29 +52,28 @@ export default class OneUptimeDate { public static getSomeMinutesAfter(minutes: PositiveNumber): Date { return this.getCurrentMomentDate() - .add( minutes.toNumber(), 'minutes') + .add(minutes.toNumber(), 'minutes') .toDate(); } public static getSomeHoursAfter(hours: PositiveNumber): Date { return this.getCurrentMomentDate() - .add( hours.toNumber(), 'hours') + .add(hours.toNumber(), 'hours') .toDate(); } public static getSomeDaysAfter(days: PositiveNumber): Date { return this.getCurrentMomentDate() - .add( days.toNumber(), 'days') + .add(days.toNumber(), 'days') .toDate(); } public static getSomeSecondsAfter(seconds: PositiveNumber): Date { return this.getCurrentMomentDate() - .add( seconds.toNumber(), 'days') + .add(seconds.toNumber(), 'days') .toDate(); } - public static momentToDate(moment: moment.Moment): Date { return moment.toDate(); } diff --git a/Common/Types/Email/EmailSubjects.ts b/Common/Types/Email/EmailSubjects.ts index 113c58ff42..930962a3a0 100644 --- a/Common/Types/Email/EmailSubjects.ts +++ b/Common/Types/Email/EmailSubjects.ts @@ -1,23 +1,26 @@ -import Dictionary from "../Dictionary"; -import BadOperationException from "../Exception/BadOperationException"; -import EmailTemplateType from "./EmailTemplateType"; - -class EmailSubjects { +import Dictionary from '../Dictionary'; +import BadOperationException from '../Exception/BadOperationException'; +import EmailTemplateType from './EmailTemplateType'; +class EmailSubjects { private subjectMap: Dictionary = {}; - constructor() { - this.subjectMap[EmailTemplateType.SIGNUP_WELCOME_EMAIL] = "Welcome to OneUptime."; - this.subjectMap[EmailTemplateType.SIGNUP_VERIFICATION_EMAIL] = "Welcome to OneUptime. Please verify your email."; + public constructor() { + this.subjectMap[EmailTemplateType.SIGNUP_WELCOME_EMAIL] = + 'Welcome to OneUptime.'; + this.subjectMap[EmailTemplateType.SIGNUP_VERIFICATION_EMAIL] = + 'Welcome to OneUptime. Please verify your email.'; } - getSubjectByType(emailTemplateType: EmailTemplateType): string { + public getSubjectByType(emailTemplateType: EmailTemplateType): string { if (this.subjectMap[emailTemplateType]) { return this.subjectMap[emailTemplateType] as string; } - throw new BadOperationException(`Subject for ${emailTemplateType} not found.`); + throw new BadOperationException( + `Subject for ${emailTemplateType} not found.` + ); } } -export default new EmailSubjects(); \ No newline at end of file +export default new EmailSubjects(); diff --git a/Common/Types/EncryptionAlgorithm.ts b/Common/Types/EncryptionAlgorithm.ts index c52d8b5f93..5fe2e0796e 100644 --- a/Common/Types/EncryptionAlgorithm.ts +++ b/Common/Types/EncryptionAlgorithm.ts @@ -1,6 +1,5 @@ -enum EncryptionAlgorithm{ - SHA256 = "SHA-256" +enum EncryptionAlgorithm { + SHA256 = 'SHA-256', } - -export default EncryptionAlgorithm; \ No newline at end of file +export default EncryptionAlgorithm; diff --git a/Common/Types/Exception/ExceptionCode.ts b/Common/Types/Exception/ExceptionCode.ts index 635b6a4847..d3384e2db5 100644 --- a/Common/Types/Exception/ExceptionCode.ts +++ b/Common/Types/Exception/ExceptionCode.ts @@ -6,7 +6,6 @@ enum ExceptionCode { BadOperationException = 5, BadDataException = 400, BadRequestException = 400, - } export default ExceptionCode; diff --git a/Common/Types/HashedString.ts b/Common/Types/HashedString.ts index eec1dedc1a..da118c7f02 100644 --- a/Common/Types/HashedString.ts +++ b/Common/Types/HashedString.ts @@ -4,9 +4,9 @@ import DatabaseProperty from './Database/DatabaseProperty'; import BadOperationException from './Exception/BadOperationException'; import EncryptionAlgorithm from './EncryptionAlgorithm'; import ObjectID from './ObjectID'; +import { arrayBuffer } from 'stream/consumers'; export default class HashedString extends DatabaseProperty { - private isHashed: boolean = false; private _value: string = ''; @@ -41,45 +41,55 @@ export default class HashedString extends DatabaseProperty { return null; } - public isValueHashed(): boolean { + public isValueHashed(): boolean { return this.isHashed; } public async hashValue(encryptionSecret: ObjectID | null): Promise { - if (!this.value) { return ''; } if (this.isHashed) { - throw new BadOperationException("Value is alredy hashed"); + throw new BadOperationException('Value is alredy hashed'); } const valueToHash: string = (encryptionSecret || '') + this.value; this.isHashed = true; // encode as UTF-8 - const msgBuffer = new TextEncoder().encode(valueToHash); + const msgBuffer: Uint8Array = new TextEncoder().encode(valueToHash); // hash the message - const hashBuffer = await crypto.subtle.digest(EncryptionAlgorithm.SHA256, msgBuffer); - + const hashBuffer: ArrayBuffer = await crypto.subtle.digest( + EncryptionAlgorithm.SHA256, + msgBuffer + ); + // convert ArrayBuffer to Array - const hashArray = Array.from(new Uint8Array(hashBuffer)); + const hashArray: Uint8Array = Array.from(new Uint8Array(hashBuffer)); - // convert bytes to hex string - const hashHex: string = hashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); + // convert bytes to hex string + const hashHex: string = hashArray + .map((b) => { + return b.toString(16).padStart(2, '0'); + }) + .join(''); this.value = hashHex; return hashHex; - } - public static async hashValue(value: string, encryptionSecret: ObjectID | null): Promise { + public static async hashValue( + value: string, + encryptionSecret: ObjectID | null + ): Promise { const hashstring: HashedString = new HashedString(value, false); return await hashstring.hashValue(encryptionSecret); } - protected static override fromDatabase(_value: string): HashedString | null { + protected static override fromDatabase( + _value: string + ): HashedString | null { if (_value) { return new HashedString(_value, true); } diff --git a/Common/Types/UserRole.ts b/Common/Types/UserRole.ts index 3ca7b4a402..b581e40916 100644 --- a/Common/Types/UserRole.ts +++ b/Common/Types/UserRole.ts @@ -1,9 +1,8 @@ -import { JSONObject } from "./JSON"; -import ObjectID from "./ObjectID"; -import Role from "./Role"; +import { JSONObject } from './JSON'; +import ObjectID from './ObjectID'; +import Role from './Role'; export default class UserRole { - public projectId!: ObjectID; public userId!: ObjectID; public role!: Role; @@ -16,17 +15,17 @@ export default class UserRole { public toJSON(): JSONObject { return { - "userId": this.userId.toString(), - "projectId": this.projectId.toString(), - "role": this.role - } + userId: this.userId.toString(), + projectId: this.projectId.toString(), + role: this.role, + }; } - public static fromJSON(data: JSONObject): UserRole{ + public static fromJSON(data: JSONObject): UserRole { return new UserRole( - new ObjectID(data["projectId"] as string), - new ObjectID(data["userId"] as string), - data["role"] as Role - ) + new ObjectID(data['projectId'] as string), + new ObjectID(data['userId'] as string), + data['role'] as Role + ); } -} \ No newline at end of file +} diff --git a/CommonServer/Config.ts b/CommonServer/Config.ts index bc353bc2c9..cb1095a9c8 100644 --- a/CommonServer/Config.ts +++ b/CommonServer/Config.ts @@ -3,9 +3,9 @@ import ObjectID from 'Common/Types/ObjectID'; import Port from 'Common/Types/Port'; import Hostname from 'Common/Types/API/Hostname'; -export const DisableSignup: boolean = !!process.env['DISABLE_SIGNUP']; +export const DisableSignup: boolean = Boolean(process.env['DISABLE_SIGNUP']); -export const IsSaaSService: boolean = !!process.env['IS_SAAS_SERVICE']; +export const IsSaaSService: boolean = Boolean(process.env['IS_SAAS_SERVICE']); export const DatabaseHost: Hostname = new Hostname( process.env['DATABASE_HOST'] || '' @@ -21,7 +21,9 @@ export const DatabasePassword: string = process.env['DATABASE_PASSWORD'] || ''; export const DatabaseName: string = process.env['DATABASE_NAME'] || 'oneuptimedb'; -export const EncryptionSecret: ObjectID = new ObjectID(process.env['ENCRYPTIOJN_SECRET'] || ''); +export const EncryptionSecret: ObjectID = new ObjectID( + process.env['ENCRYPTIOJN_SECRET'] || '' +); export const AirtableApiKey: string = process.env['AIRTABLE_API_KEY'] || ''; diff --git a/CommonServer/Middleware/ProjectAuthorization.ts b/CommonServer/Middleware/ProjectAuthorization.ts index 297812706e..ec31a9aa6d 100644 --- a/CommonServer/Middleware/ProjectAuthorization.ts +++ b/CommonServer/Middleware/ProjectAuthorization.ts @@ -14,18 +14,13 @@ import PositiveNumber from 'Common/Types/PositiveNumber'; const ProjectService: ProjectServiceType = Services.ProjectService; export default class ProjectMiddleware { - public static getProjectId(req: ExpressRequest): ObjectID | null { - let projectId: ObjectID | null = null; if (req.params && req.params['projectId']) { projectId = new ObjectID(req.params['projectId']); } else if (req.query && req.query['projectId']) { projectId = new ObjectID(req.query['projectId'] as string); - } else if ( - req.headers && - req.headers['projectid'] - ) { + } else if (req.headers && req.headers['projectid']) { // Header keys are automatically transformed to lowercase projectId = new ObjectID(req.headers['projectid'] as string); } else if (req.body && req.body.projectId) { @@ -40,11 +35,8 @@ export default class ProjectMiddleware { if (req.query && req.query['apiKey']) { apiKey = new ObjectID(req.query['apiKey'] as string); - } else if ( - req.headers && - req.headers['apikey'] - ) { - apiKey = new ObjectID(req.headers['apikey'] as string) + } else if (req.headers && req.headers['apikey']) { + apiKey = new ObjectID(req.headers['apikey'] as string); } else if (req.body && req.body.apiKey) { apiKey = req.body.apiKey; } @@ -53,35 +45,34 @@ export default class ProjectMiddleware { } public static hasApiKey(req: ExpressRequest): boolean { - return !!this.getApiKey(req); + return Boolean(this.getApiKey(req)); } public static hasProjectID(req: ExpressRequest): boolean { - return !!this.getProjectId(req); - } + return Boolean(this.getProjectId(req)); + } public static async isValidProjectIdAndApiKeyMiddleware( req: ExpressRequest, _res: ExpressResponse, next: NextFunction ): Promise { - - let projectId: ObjectID | null = this.getProjectId(req); - let apiKey: ObjectID | null = this.getApiKey(req); + const projectId: ObjectID | null = this.getProjectId(req); + const apiKey: ObjectID | null = this.getApiKey(req); if (!projectId) { - throw new BadDataException("ProjectID not found in the request"); + throw new BadDataException('ProjectID not found in the request'); } if (!apiKey) { - throw new BadDataException("ApiKey not found in the request"); + throw new BadDataException('ApiKey not found in the request'); } const projectCount: PositiveNumber = await ProjectService.countBy({ query: { _id: projectId.toString(), apiKey: apiKey, - } + }, }); if (projectCount.toNumber() > 0) { @@ -89,8 +80,6 @@ export default class ProjectMiddleware { return next(); } - throw new BadDataException("Invalid Project ID or API Key"); - + throw new BadDataException('Invalid Project ID or API Key'); } - -} \ No newline at end of file +} diff --git a/CommonServer/Middleware/UserAuthorization.ts b/CommonServer/Middleware/UserAuthorization.ts index f3b989d518..ffab0bec7c 100644 --- a/CommonServer/Middleware/UserAuthorization.ts +++ b/CommonServer/Middleware/UserAuthorization.ts @@ -15,7 +15,6 @@ import JSONWebToken from '../Utils/JsonWebToken'; const UserService: UserServiceType = Service.UserService; export default class UserMiddleware { - /* * Description: Checking if user is authorized to access the page and decode jwt to get user data. * Params: @@ -24,7 +23,6 @@ export default class UserMiddleware { */ public static getAccessToken(req: ExpressRequest): string | null { - let accessToken: string | null = null; if (req.headers['authorization']) { @@ -35,7 +33,7 @@ export default class UserMiddleware { accessToken = req.query['accessToken'] as string; } - if (accessToken?.includes(" ")) { + if (accessToken?.includes(' ')) { accessToken = accessToken.split(' ')[1] || ''; } @@ -51,20 +49,23 @@ export default class UserMiddleware { if (projectId) { if (ProjectMiddleware.hasApiKey(req)) { - return await ProjectMiddleware.isValidProjectIdAndApiKeyMiddleware(req, res, next); + return await ProjectMiddleware.isValidProjectIdAndApiKeyMiddleware( + req, + res, + next + ); } } const accessToken: string | null = this.getAccessToken(req); if (!accessToken) { - throw new BadDataException("AccessToken not found in request"); + throw new BadDataException('AccessToken not found in request'); } - const oneuptimeRequest = (req as OneUptimeRequest); + const oneuptimeRequest: OneUptimeRequest = req as OneUptimeRequest; oneuptimeRequest.userAuthorization = JSONWebToken.decode(accessToken); - if (oneuptimeRequest.userAuthorization.isMasterAdmin) { oneuptimeRequest.authorizationType = AuthorizationType.MasterAdmin; } else { @@ -72,11 +73,12 @@ export default class UserMiddleware { } UserService.updateOneBy({ - query: { _id: oneuptimeRequest.userAuthorization.userId.toString() }, - data: { lastActive: Date.now() } + query: { + _id: oneuptimeRequest.userAuthorization.userId.toString(), + }, + data: { lastActive: Date.now() }, }); return next(); - } } diff --git a/CommonServer/Services/DatabaseService.ts b/CommonServer/Services/DatabaseService.ts index 93fffe67a0..dc098eb326 100644 --- a/CommonServer/Services/DatabaseService.ts +++ b/CommonServer/Services/DatabaseService.ts @@ -31,7 +31,7 @@ class DatabaseService { private database!: PostgresDatabase; public constructor( - type: { new(): TBaseModel }, + type: { new (): TBaseModel }, database: PostgresDatabase ) { this.entityName = type.name; @@ -101,13 +101,12 @@ class DatabaseService { } protected async hash(data: TBaseModel): Promise { - for (const key of data.getHashedColumns().columns) { - if (!((data as any)[key] as HashedString).isValueHashed) { - await ((data as any)[key] as HashedString).hashValue(EncryptionSecret); + await ((data as any)[key] as HashedString).hashValue( + EncryptionSecret + ); } - } return data; @@ -243,7 +242,7 @@ class DatabaseService { (data as any)[data.getSaveSlugToColumn() as string] = Slug.getSlug( (data as any)[ - data.getSlugifyColumn() as string + data.getSlugifyColumn() as string ] as string ); } @@ -454,15 +453,12 @@ class DatabaseService { return null; } - - public async findOneById( - id: ObjectID - ): Promise { + public async findOneById(id: ObjectID): Promise { return await this.findOneBy({ query: { - _id: id.toString() - } - }) + _id: id.toString(), + }, + }); } private async _updateBy({ @@ -507,21 +503,24 @@ class DatabaseService { return await this._updateBy({ query, data }); } - public async updateOneById(updateById: UpdateByID): Promise { + public async updateOneById( + updateById: UpdateByID + ): Promise { await this.updateOneBy({ query: { - _id: updateById.id.toString() + _id: updateById.id.toString(), }, - data: updateById.data + data: updateById.data, }); } - public async updateOneByIdAndFetch(updateById: UpdateByID): Promise { + public async updateOneByIdAndFetch( + updateById: UpdateByID + ): Promise { await this.updateOneById(updateById); return this.findOneById(updateById.id); } - public async searchBy({ skip, limit, diff --git a/CommonServer/Services/Index.ts b/CommonServer/Services/Index.ts index 5e7238bf56..3050c495a1 100644 --- a/CommonServer/Services/Index.ts +++ b/CommonServer/Services/Index.ts @@ -13,7 +13,7 @@ const postgresDatabase: PostgresDatabase = new PostgresDatabase(); await postgresDatabase.connect(postgresDatabase.getDatasourceOptions()); export default { - //Database Services + //Database Services ProbeService: new ProbeService(postgresDatabase), UserService: new UserService(postgresDatabase), GlobalConfigService: new GlobalConfigService(postgresDatabase), @@ -21,7 +21,9 @@ export default { EmailLogService: new EmailLogService(postgresDatabase), MonitorService: new MonitorService(postgresDatabase), ProjectService: new ProjectService(postgresDatabase), - EmailVerificationTokenService: new EmailVerificationTokenService(postgresDatabase), + EmailVerificationTokenService: new EmailVerificationTokenService( + postgresDatabase + ), // Other Services. MailService: new MailService(), diff --git a/CommonServer/Services/MailService.ts b/CommonServer/Services/MailService.ts index d2d6ba8bc6..572156c89b 100644 --- a/CommonServer/Services/MailService.ts +++ b/CommonServer/Services/MailService.ts @@ -1,42 +1,50 @@ -import HTTPResponse from "Common/Types/API/Response"; -import Route from "Common/Types/API/Route"; -import URL from "Common/Types/API/URL"; -import Dictionary from "Common/Types/Dictionary"; -import Email from "Common/Types/Email"; -import EmailTemplateType from "Common/Types/Email/EmailTemplateType"; -import { JSONObject } from "Common/Types/JSON"; -import ObjectID from "Common/Types/ObjectID"; -import API from "Common/Utils/API"; -import { ClusterKey, HttpProtocol, MailHostname } from "../Config"; +import HTTPResponse from 'Common/Types/API/Response'; +import Route from 'Common/Types/API/Route'; +import URL from 'Common/Types/API/URL'; +import Dictionary from 'Common/Types/Dictionary'; +import Email from 'Common/Types/Email'; +import EmailTemplateType from 'Common/Types/Email/EmailTemplateType'; +import { JSONObject } from 'Common/Types/JSON'; +import ObjectID from 'Common/Types/ObjectID'; +import API from 'Common/Utils/API'; +import { ClusterKey, HttpProtocol, MailHostname } from '../Config'; export default class MailService { - - public async sendMail(to: Email, subject: string, template: EmailTemplateType, vars: Dictionary, options?: { - projectId?: ObjectID - forceSendFromGlobalMailServer?: boolean - }): Promise { - + public async sendMail( + to: Email, + subject: string, + template: EmailTemplateType, + vars: Dictionary, + options?: { + projectId?: ObjectID; + forceSendFromGlobalMailServer?: boolean; + } + ): Promise { const body: JSONObject = { toEmail: to.toString(), subject, vars: vars, - } + }; if (options?.projectId) { - body["projectId"] = options.projectId; + body['projectId'] = options.projectId; } if (options?.forceSendFromGlobalMailServer) { - body["forceSendFromGlobalMailServer"] = options.forceSendFromGlobalMailServer; + body['forceSendFromGlobalMailServer'] = + options.forceSendFromGlobalMailServer; } return await API.post( - new URL(HttpProtocol, MailHostname, new Route('/email/' + template)), + new URL( + HttpProtocol, + MailHostname, + new Route('/email/' + template) + ), body, { - "clusterkey": ClusterKey.toString() + clusterkey: ClusterKey.toString(), } ); } - -} \ No newline at end of file +} diff --git a/CommonServer/Types/DB/UpdateByID.ts b/CommonServer/Types/DB/UpdateByID.ts index 21048630a6..e094115507 100644 --- a/CommonServer/Types/DB/UpdateByID.ts +++ b/CommonServer/Types/DB/UpdateByID.ts @@ -2,7 +2,7 @@ import BaseModel from 'Common/Models/BaseModel'; import ObjectID from 'Common/Types/ObjectID'; import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'; -export default interface UpdateBy{ +export default interface UpdateBy { id: ObjectID; data: QueryDeepPartialEntity; } diff --git a/CommonServer/Utils/Express.ts b/CommonServer/Utils/Express.ts index e0ff5a6b8c..0e8ec6061f 100644 --- a/CommonServer/Utils/Express.ts +++ b/CommonServer/Utils/Express.ts @@ -19,10 +19,10 @@ export type ExpressResponse = express.Response; export type ExpressApplication = express.Application; export type ExpressRouter = express.Router; -export enum AuthorizationType { - API = "API", - User = "User", - MasterAdmin = "MasterAdmin" +export enum AuthorizationType { + API = 'API', + User = 'User', + MasterAdmin = 'MasterAdmin', } export interface OneUptimeRequest extends express.Request { diff --git a/CommonServer/Utils/JsonWebToken.ts b/CommonServer/Utils/JsonWebToken.ts index ff9975f46f..28e7573b73 100644 --- a/CommonServer/Utils/JsonWebToken.ts +++ b/CommonServer/Utils/JsonWebToken.ts @@ -7,40 +7,48 @@ import jwt from 'jsonwebtoken'; import { EncryptionSecret } from '../Config'; export interface JSONWebTokenData { - userId: ObjectID, - email: Email, - roles: Array, - isMasterAdmin: boolean + userId: ObjectID; + email: Email; + roles: Array; + isMasterAdmin: boolean; } class JSONWebToken { - public static sign(data: JSONWebTokenData, expiresIn: Date): string { - return jwt.sign({ - userId: data.userId.toString(), - email: data.email.toString(), - roles: data.roles.map((role: UserRole): JSONObject => role.toJSON()), - isMasterAdmin: data.isMasterAdmin - }, EncryptionSecret.toString(), { - expiresIn: String(expiresIn), - }); + return jwt.sign( + { + userId: data.userId.toString(), + email: data.email.toString(), + roles: data.roles.map((role: UserRole): JSONObject => { + return role.toJSON(); + }), + isMasterAdmin: data.isMasterAdmin, + }, + EncryptionSecret.toString(), + { + expiresIn: String(expiresIn), + } + ); } public static decode(token: string): JSONWebTokenData { try { - - const decoded: JSONObject = JSON.parse(jwt.verify(token, EncryptionSecret.toString()) as string); + const decoded: JSONObject = JSON.parse( + jwt.verify(token, EncryptionSecret.toString()) as string + ); return { - userId: new ObjectID(decoded["userId"] as string), - email: new Email(decoded["email"] as string), - roles: (decoded["roles"] as JSONArray).map((obj: JSONObject): UserRole => { - return UserRole.fromJSON(obj); - }), - isMasterAdmin: !!decoded["isMasterAdmin"] - } + userId: new ObjectID(decoded['userId'] as string), + email: new Email(decoded['email'] as string), + roles: (decoded['roles'] as JSONArray).map( + (obj: JSONObject): UserRole => { + return UserRole.fromJSON(obj); + } + ), + isMasterAdmin: Boolean(decoded['isMasterAdmin']), + }; } catch (e) { - throw new BadDataException("AccessToken is invalid or expired"); + throw new BadDataException('AccessToken is invalid or expired'); } } } diff --git a/CommonServer/Utils/Response.ts b/CommonServer/Utils/Response.ts index 7f54b230c3..9900bf4eeb 100644 --- a/CommonServer/Utils/Response.ts +++ b/CommonServer/Utils/Response.ts @@ -21,25 +21,26 @@ export default class Response { ): void { const oneUptimeRequest: OneUptimeRequest = req as OneUptimeRequest; const oneUptimeResponse: OneUptimeResponse = res as OneUptimeResponse; - + const requestEndedAt: Date = new Date(); const method: string = oneUptimeRequest.method; const url: URL = URL.fromString(oneUptimeRequest.url); - + const duration_info: string = `OUTGOING RESPONSE ID: ${ oneUptimeRequest.id } -- POD NAME: ${ process.env['POD_NAME'] || 'NONE' } -- METHOD: ${method} -- URL: ${url.toString()} -- DURATION: ${( - requestEndedAt.getTime() - oneUptimeRequest.requestStartedAt.getTime() + requestEndedAt.getTime() - + oneUptimeRequest.requestStartedAt.getTime() ).toString()}ms -- STATUS: ${oneUptimeResponse.statusCode}`; - + const body_info: string = `OUTGOING RESPONSE ID: ${ oneUptimeRequest.id } -- RESPONSE BODY: ${ responsebody ? JSON.stringify(responsebody, null, 2) : 'EMPTY' }`; - + if (oneUptimeResponse.statusCode > 299) { logger.error(duration_info); logger.error(body_info); @@ -48,74 +49,80 @@ export default class Response { logger.info(body_info); } } - + public static sendEmptyResponse( req: ExpressRequest, res: ExpressResponse ): void { const oneUptimeRequest: OneUptimeRequest = req as OneUptimeRequest; const oneUptimeResponse: OneUptimeResponse = res as OneUptimeResponse; - - oneUptimeResponse.set('ExpressRequest-Id', oneUptimeRequest.id.toString()); + + oneUptimeResponse.set( + 'ExpressRequest-Id', + oneUptimeRequest.id.toString() + ); oneUptimeResponse.set('Pod-Id', process.env['POD_NAME']); - + oneUptimeResponse.status(200).send(); - + return this.logResponse(req, res, undefined); } - - public static async sendFileResponse ( + + public static async sendFileResponse( req: ExpressRequest | ExpressRequest, res: ExpressResponse, file: File ): Promise { /** Create read stream */ - + const oneUptimeResponse: OneUptimeResponse = res as OneUptimeResponse; - + /* * const gfs: GridFSBucket = new GridFSBucket(await Database.getDatabase(), { * bucketName: 'uploads', * }); */ - + /* * const readstream: GridFSBucketReadStream = gfs.openDownloadStreamByName( * file.name * ); */ - + /** Set the proper content type */ oneUptimeResponse.set('Content-Type', file.contentType); oneUptimeResponse.status(200); /** Return response */ // readstream.pipe(res); - + this.logResponse(req, res); - }; - - public static sendErrorResponse ( + } + + public static sendErrorResponse( req: ExpressRequest, res: ExpressResponse, error: Exception - ): void { + ): void { const oneUptimeRequest: OneUptimeRequest = req as OneUptimeRequest; const oneUptimeResponse: OneUptimeResponse = res as OneUptimeResponse; - + oneUptimeResponse.logBody = { message: error.message }; // To be used in 'auditLog' middleware to log reponse data; const status: number = error.code || 500; const message: string = error.message || 'Server Error'; - + logger.error(error); - - oneUptimeResponse.set('ExpressRequest-Id', oneUptimeRequest.id.toString()); + + oneUptimeResponse.set( + 'ExpressRequest-Id', + oneUptimeRequest.id.toString() + ); oneUptimeResponse.set('Pod-Id', process.env['POD_NAME']); - + oneUptimeResponse.status(status).send({ message }); return this.logResponse(req, res, { message }); - }; - - public static sendListResponse ( + } + + public static sendListResponse( req: ExpressRequest, res: ExpressResponse, list: JSONArray, @@ -123,43 +130,46 @@ export default class Response { ): void { const oneUptimeRequest: OneUptimeRequest = req as OneUptimeRequest; const oneUptimeResponse: OneUptimeResponse = res as OneUptimeResponse; - - oneUptimeResponse.set('ExpressRequest-Id', oneUptimeRequest.id.toString()); + + oneUptimeResponse.set( + 'ExpressRequest-Id', + oneUptimeRequest.id.toString() + ); oneUptimeResponse.set('Pod-Id', process.env['POD_NAME']); - + const listData: ListData = new ListData({ data: [], count: new PositiveNumber(0), skip: new PositiveNumber(0), limit: new PositiveNumber(0), }); - + if (!list) { list = []; } - + if (list) { listData.data = list; } - + if (count) { listData.count = count; } else if (list) { listData.count = new PositiveNumber(list.length); } - + if (oneUptimeRequest.query['skip']) { listData.skip = new PositiveNumber( parseInt(oneUptimeRequest.query['skip'].toString()) ); } - + if (oneUptimeRequest.query['limit']) { listData.limit = new PositiveNumber( parseInt(oneUptimeRequest.query['limit'].toString()) ); } - + if (oneUptimeRequest.query['output-type'] === 'csv') { const csv: string = JsonToCsv.ToCsv(listData.data); oneUptimeResponse.status(200).send(csv); @@ -169,29 +179,31 @@ export default class Response { oneUptimeResponse.status(200).send(listData); this.logResponse(req, res, listData.toJSON()); } - }; - - public static sendItemResponse ( + } + + public static sendItemResponse( req: ExpressRequest, res: ExpressResponse, item: JSONObject ): void { const oneUptimeRequest: OneUptimeRequest = req as OneUptimeRequest; const oneUptimeResponse: OneUptimeResponse = res as OneUptimeResponse; - - oneUptimeResponse.set('ExpressRequest-Id', oneUptimeRequest.id.toString()); + + oneUptimeResponse.set( + 'ExpressRequest-Id', + oneUptimeRequest.id.toString() + ); oneUptimeResponse.set('Pod-Id', process.env['POD_NAME']); - + if (oneUptimeRequest.query['output-type'] === 'csv') { const csv: string = JsonToCsv.ToCsv([item]); oneUptimeResponse.status(200).send(csv); this.logResponse(req, res); return; } - + oneUptimeResponse.logBody = item; oneUptimeResponse.status(200).send(item); this.logResponse(req, res, item); - }; - + } } diff --git a/CommonUI/src/Actions/ApiBaseAction.ts b/CommonUI/src/Actions/ApiBaseAction.ts index 14f6fb82b8..4b83d98348 100644 --- a/CommonUI/src/Actions/ApiBaseAction.ts +++ b/CommonUI/src/Actions/ApiBaseAction.ts @@ -11,14 +11,13 @@ import { Dispatch } from 'redux'; import HTTPErrorResponse from 'Common/Types/API/ErrorResponse'; export default class ActionBase { - private _name: string; private apiBaseConstants: ApiBaseConstants; public get name(): string { return this._name; } - constructor(name: string) { + public constructor(name: string) { this._name = name; this.apiBaseConstants = new ApiBaseConstants(name); } @@ -54,24 +53,26 @@ export default class ActionBase { public requestData(apiRequest: Promise): Function { return async (dispatch: Dispatch): Promise => { - - dispatch(this.request({ - requesting: true, - httpResponsePromise: apiRequest - })); + dispatch( + this.request({ + requesting: true, + httpResponsePromise: apiRequest, + }) + ); try { - const response: HTTPResponse = await apiRequest; - dispatch(this.success({ - response: response - })); + dispatch( + this.success({ + response: response, + }) + ); } catch (e) { - const errorResponse = e as HTTPErrorResponse; + const errorResponse: HTTPErrorResponse = e as HTTPErrorResponse; this.error({ - errorResponse: errorResponse - }) + errorResponse: errorResponse, + }); } }; } diff --git a/CommonUI/src/Constants/ApiBaseConstants.ts b/CommonUI/src/Constants/ApiBaseConstants.ts index c712bfd05d..aba6aea2ff 100644 --- a/CommonUI/src/Constants/ApiBaseConstants.ts +++ b/CommonUI/src/Constants/ApiBaseConstants.ts @@ -1,23 +1,22 @@ class ApiBaseConstant { - private _name: string; public get name(): string { return this._name; } - constructor(name: string) { + public constructor(name: string) { this._name = name; - this.REQUEST += name; - this.ERROR += name; + this.REQUEST += name; + this.ERROR += name; this.SUCCESS += name; this.RESET += name; } - - public REQUEST: string = "Request"; - public ERROR: string = "Error"; - public SUCCESS: string = "Success"; - public RESET: string = "Reset"; + + public REQUEST: string = 'Request'; + public ERROR: string = 'Error'; + public SUCCESS: string = 'Success'; + public RESET: string = 'Reset'; } export default ApiBaseConstant; diff --git a/CommonUI/src/Reducers/ApiBase.ts b/CommonUI/src/Reducers/ApiBase.ts index cba9e01012..aa8f59b4be 100644 --- a/CommonUI/src/Reducers/ApiBase.ts +++ b/CommonUI/src/Reducers/ApiBase.ts @@ -18,13 +18,12 @@ export interface InitialStateType { export default class ApiBaseReducer { private constants: ApiBaseConstants; private _name: string; - public get name(): string { return this._name; } - constructor(name: string) { + public constructor(name: string) { this._name = name; this.constants = new ApiBaseConstants(this.name); } @@ -65,4 +64,4 @@ export default class ApiBaseReducer { } }; } -} \ No newline at end of file +} diff --git a/Identity/API/User.ts b/Identity/API/User.ts index dfa322179e..f246dc0e81 100644 --- a/Identity/API/User.ts +++ b/Identity/API/User.ts @@ -1,4 +1,11 @@ -import { AccountsHostname, DashboardHostname, DisableSignup, HomeHostname, HttpProtocol, IsSaaSService } from 'CommonServer/Config'; +import { + AccountsHostname, + DashboardHostname, + DisableSignup, + HomeHostname, + HttpProtocol, + IsSaaSService, +} from 'CommonServer/Config'; import Express, { ExpressRequest, ExpressResponse, @@ -23,106 +30,124 @@ import OneUptimeDate from 'Common/Types/Date'; import PositiveNumber from 'Common/Types/PositiveNumber'; const UserService: UserServiceType = Service.UserService; -const EmailVerificationTokenService: EmailVerificationTokenServiceType = Service.EmailVerificationTokenService; +const EmailVerificationTokenService: EmailVerificationTokenServiceType = + Service.EmailVerificationTokenService; const MailService: MailServiceType = Service.MailService; const router: ExpressRouter = Express.getRouter(); -router.post('/signup', async (req: ExpressRequest, res: ExpressResponse): Promise => { +router.post( + '/signup', + async (req: ExpressRequest, res: ExpressResponse): Promise => { + if (DisableSignup) { + throw new BadRequestException('Sign up is disabled.'); + } + const data: JSONObject = req.body; + const user: User = User.fromJSON(data['user'] as JSONObject); - if ( - DisableSignup - ) { - throw new BadRequestException("Sign up is disabled."); - } + if (IsSaaSService) { + //ALERT: Delete data.role so user don't accidently sign up as master-admin from the API. + user.isMasterAdmin = false; + user.isEmailVerified = false; + } - const data: JSONObject = req.body; - const user: User = User.fromJSON(data["user"] as JSONObject); + let verificationToken: ObjectID | null = null; + let emailVerificationToken: EmailVerificationToken | null = null; + if (req.query['token']) { + verificationToken = new ObjectID(req.query['token'] as string); + emailVerificationToken = + await EmailVerificationTokenService.findOneBy({ + query: { + token: verificationToken, + }, + }); + } - if (IsSaaSService) { - //ALERT: Delete data.role so user don't accidently sign up as master-admin from the API. - user.isMasterAdmin = false; - user.isEmailVerified = false; - } - - let verificationToken: ObjectID | null = null; - let emailVerificationToken: EmailVerificationToken | null = null; - if (req.query['token']) { - verificationToken = new ObjectID(req.query['token'] as string); - emailVerificationToken = await EmailVerificationTokenService.findOneBy({ - query: { - token: verificationToken, - } - }) - } - - - const alreadySavedUser = await UserService.findOneBy({ - query: { email: user.email }, - select: { - _id: true, - password: true - }, - }); - - if (emailVerificationToken && user && user.id.toString() === emailVerificationToken.userId.toString()) { - user.isEmailVerified = true; - } - - if (alreadySavedUser && alreadySavedUser.password) { - throw new BadDataException(`User with email ${user.email} already exists.`); - } - - - let savedUser: User | null = null; - if (alreadySavedUser) { - savedUser = await UserService.updateOneByIdAndFetch({ - id: alreadySavedUser.id, data: user + const alreadySavedUser: User | null = await UserService.findOneBy({ + query: { email: user.email }, + select: { + _id: true, + password: true, + }, }); - } else { - savedUser = await UserService.create({ data: user }); + + if ( + emailVerificationToken && + user && + user.id.toString() === emailVerificationToken.userId.toString() + ) { + user.isEmailVerified = true; + } + + if (alreadySavedUser && alreadySavedUser.password) { + throw new BadDataException( + `User with email ${user.email} already exists.` + ); + } + + let savedUser: User | null = null; + if (alreadySavedUser) { + savedUser = await UserService.updateOneByIdAndFetch({ + id: alreadySavedUser.id, + data: user, + }); + } else { + savedUser = await UserService.create({ data: user }); + } + + if (alreadySavedUser) { + // Send Welcome Mail + MailService.sendMail( + user.email, + EmailSubjects.getSubjectByType( + EmailTemplateType.SIGNUP_WELCOME_EMAIL + ), + EmailTemplateType.SIGNUP_WELCOME_EMAIL, + { + name: user.name.toString(), + dashboardUrl: new URL( + HttpProtocol, + DashboardHostname + ).toString(), + homeUrl: new URL(HttpProtocol, HomeHostname).toString(), + } + ); + } else { + // Send EmailVerification Link because this is a new user. + MailService.sendMail( + user.email, + EmailSubjects.getSubjectByType( + EmailTemplateType.SIGNUP_WELCOME_EMAIL + ), + EmailTemplateType.SIGNUP_WELCOME_EMAIL, + { + name: user.name.toString(), + emailVerificationUrl: new URL( + HttpProtocol, + AccountsHostname + ).toString(), + homeUrl: new URL(HttpProtocol, HomeHostname).toString(), + } + ); + } + + if (savedUser) { + const token: string = JSONWebToken.sign( + { + userId: savedUser?.id, + email: savedUser?.email, + isMasterAdmin: savedUser?.isMasterAdmin, + roles: [], + }, + OneUptimeDate.getSomeDaysAfter(new PositiveNumber(30)) + ); + + return Response.sendItemResponse(req, res, { token: token }); + } + + throw new BadRequestException('Failed to create a user'); } +); - - if (alreadySavedUser) { - // Send Welcome Mail - MailService.sendMail( - user.email, - EmailSubjects.getSubjectByType(EmailTemplateType.SIGNUP_WELCOME_EMAIL), - EmailTemplateType.SIGNUP_WELCOME_EMAIL, - { - "name": user.name.toString(), - "dashboardUrl": new URL(HttpProtocol, DashboardHostname).toString(), - "homeUrl": new URL(HttpProtocol, HomeHostname).toString() - } - ) - } else { - // Send EmailVerification Link because this is a new user. - MailService.sendMail( - user.email, - EmailSubjects.getSubjectByType(EmailTemplateType.SIGNUP_WELCOME_EMAIL), - EmailTemplateType.SIGNUP_WELCOME_EMAIL, - { - "name": user.name.toString(), - "emailVerificationUrl": new URL(HttpProtocol, AccountsHostname).toString(), - "homeUrl": new URL(HttpProtocol, HomeHostname).toString() - } - ) - } - - if (savedUser) { - const token = JSONWebToken.sign({ - userId: savedUser?.id, - email: savedUser?.email, - isMasterAdmin: savedUser?.isMasterAdmin, - roles: [] - }, OneUptimeDate.getSomeDaysAfter(new PositiveNumber(30))); - - return Response.sendItemResponse(req, res, { token: token }); - } - - throw new BadRequestException("Failed to create a user"); -}); - -export default router; \ No newline at end of file +export default router; diff --git a/Mail/API/Mail.ts b/Mail/API/Mail.ts index 7bf1134a35..956c0f0c10 100644 --- a/Mail/API/Mail.ts +++ b/Mail/API/Mail.ts @@ -18,7 +18,6 @@ router.post( '/:template-name', ClusterKeyAuthorization.isAuthorizedServiceMiddleware, async (req: ExpressRequest, res: ExpressResponse) => { - const body: JSONObject = req.body; const mail: Mail = {