diff --git a/Accounts/Serve.ts b/Accounts/Serve.ts index 92cd13a384..bded796593 100755 --- a/Accounts/Serve.ts +++ b/Accounts/Serve.ts @@ -19,6 +19,7 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); export default app; diff --git a/Accounts/src/Utils/Login.ts b/Accounts/src/Utils/Login.ts index 3c94217fff..0ac0685e40 100644 --- a/Accounts/src/Utils/Login.ts +++ b/Accounts/src/Utils/Login.ts @@ -21,7 +21,7 @@ export default abstract class LoginUtil { UserUtil.setAccessToken(token); UserUtil.setEmail(user.email as Email); UserUtil.setUserId(user.id as ObjectID); - UserUtil.setName(user.name as Name); + UserUtil.setName(user.name || new Name('')); UserUtil.setIsMasterAdmin(user.isMasterAdmin as boolean); Analytics.userAuth(user.email!); diff --git a/AdminDashboard/Serve.ts b/AdminDashboard/Serve.ts index 26302b1384..4ce80126ce 100755 --- a/AdminDashboard/Serve.ts +++ b/AdminDashboard/Serve.ts @@ -18,6 +18,7 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); export default app; diff --git a/AdminDashboard/package-lock.json b/AdminDashboard/package-lock.json index 0569a4c31c..7cada1ceb1 100644 --- a/AdminDashboard/package-lock.json +++ b/AdminDashboard/package-lock.json @@ -66,7 +66,7 @@ "moment-timezone": "^0.5.40", "nanoid": "^3.3.2", "nanoid-dictionary": "^4.3.0", - "posthog-js": "^1.37.0", + "posthog-js": "^1.77.0", "process": "^0.11.10", "reflect-metadata": "^0.1.13", "slugify": "^1.6.5", @@ -74,7 +74,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@faker-js/faker": "^6.3.1", + "@faker-js/faker": "^8.0.2", "@types/jest": "^27.5.2", "@types/node": "^17.0.22", "jest": "^27.5.1", @@ -86,6 +86,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "@clickhouse/client": "^0.2.1", "@elastic/elasticsearch": "^8.1.0", "@opentelemetry/api": "^1.1.0", "@opentelemetry/auto-instrumentations-node": "^0.31.0", @@ -11913,9 +11914,9 @@ "peer": true }, "node_modules/json5": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", - "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "peer": true, "bin": { @@ -17137,9 +17138,9 @@ } }, "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "peer": true, "dependencies": { @@ -23463,7 +23464,7 @@ "Common": { "version": "file:../Common", "requires": { - "@faker-js/faker": "^6.3.1", + "@faker-js/faker": "^8.0.2", "@types/crypto-js": "^4.1.1", "@types/jest": "^27.5.2", "@types/nanoid-dictionary": "^4.2.0", @@ -23477,7 +23478,7 @@ "moment-timezone": "^0.5.40", "nanoid": "^3.3.2", "nanoid-dictionary": "^4.3.0", - "posthog-js": "^1.37.0", + "posthog-js": "^1.77.0", "process": "^0.11.10", "reflect-metadata": "^0.1.13", "slugify": "^1.6.5", @@ -23510,6 +23511,7 @@ "CommonServer": { "version": "file:../CommonServer", "requires": { + "@clickhouse/client": "^0.2.1", "@elastic/elasticsearch": "^8.1.0", "@faker-js/faker": "^6.3.1", "@opentelemetry/api": "^1.1.0", @@ -27674,9 +27676,9 @@ "peer": true }, "json5": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", - "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "peer": true }, @@ -31459,9 +31461,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "peer": true, "requires": { diff --git a/ApiReference/Index.ts b/ApiReference/Index.ts index 0007b6efff..ffb956c663 100755 --- a/ApiReference/Index.ts +++ b/ApiReference/Index.ts @@ -98,6 +98,7 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); export default app; diff --git a/Common/Types/PositiveNumber.ts b/Common/Types/PositiveNumber.ts index c880ce053c..44243c9967 100644 --- a/Common/Types/PositiveNumber.ts +++ b/Common/Types/PositiveNumber.ts @@ -12,7 +12,10 @@ export default class PositiveNumber { public constructor(positiveNumber: number | string) { if (typeof positiveNumber === Typeof.String) { - positiveNumber = Number.parseInt(positiveNumber.toString().trim(), 10); + positiveNumber = Number.parseInt( + positiveNumber.toString().trim(), + 10 + ); if (isNaN(positiveNumber)) { throw new BadDataException(`Invalid number: ${positiveNumber}`); } diff --git a/CommonServer/API/ProjectAPI.ts b/CommonServer/API/ProjectAPI.ts index 6fe2fb353c..6f1fc76655 100644 --- a/CommonServer/API/ProjectAPI.ts +++ b/CommonServer/API/ProjectAPI.ts @@ -12,10 +12,10 @@ import { } from '../Utils/Express'; import TeamMemberService from '../Services/TeamMemberService'; import { LIMIT_PER_PROJECT } from 'Common/Types/Database/LimitMax'; -import NotAuthorizedException from 'Common/Types/Exception/NotAuthorizedException'; import PositiveNumber from 'Common/Types/PositiveNumber'; import Response from '../Utils/Response'; import TeamMember from 'Model/Models/TeamMember'; +import NotAuthenticatedException from 'Common/Types/Exception/NotAuthenticatedException'; export default class ProjectAPI extends BaseAPI { public constructor() { @@ -35,7 +35,7 @@ export default class ProjectAPI extends BaseAPI { ) => { try { if (!(req as OneUptimeRequest).userAuthorization?.userId) { - throw new NotAuthorizedException( + throw new NotAuthenticatedException( 'User should be logged in to access this API' ); } diff --git a/CommonServer/Services/StatusPagePrivateUserService.ts b/CommonServer/Services/StatusPagePrivateUserService.ts index 0f5cf0a830..619f268396 100644 --- a/CommonServer/Services/StatusPagePrivateUserService.ts +++ b/CommonServer/Services/StatusPagePrivateUserService.ts @@ -14,12 +14,44 @@ import { FileRoute } from 'Common/ServiceRoute'; import DatabaseConfig from '../DatabaseConfig'; import Hostname from 'Common/Types/API/Hostname'; import Protocol from 'Common/Types/API/Protocol'; +import CreateBy from '../Types/Database/CreateBy'; export class Service extends DatabaseService { public constructor(postgresDatabase?: PostgresDatabase) { super(Model, postgresDatabase); } + protected override async onBeforeCreate( + createBy: CreateBy + ): Promise> { + // check if this user is already invited. + if (createBy.data.statusPageId && createBy.data.email) { + const statusPageUser: Model | null = await this.findOneBy({ + query: { + email: createBy.data.email, + statusPageId: createBy.data.statusPageId, + }, + props: { + isRoot: true, + }, + select: { + _id: true, + }, + }); + + if (statusPageUser) { + throw new BadDataException( + 'This user is already invited to this status page.' + ); + } + } + + return { + createBy: createBy, + carryForward: null, + }; + } + protected override async onCreateSuccess( _onCreate: OnCreate, createdItem: Model diff --git a/CommonServer/Services/StatusPageSubscriberService.ts b/CommonServer/Services/StatusPageSubscriberService.ts index 2f1bce56af..7309664039 100644 --- a/CommonServer/Services/StatusPageSubscriberService.ts +++ b/CommonServer/Services/StatusPageSubscriberService.ts @@ -6,7 +6,7 @@ import BadDataException from 'Common/Types/Exception/BadDataException'; import StatusPageService from './StatusPageService'; import MailService from './MailService'; import EmailTemplateType from 'Common/Types/Email/EmailTemplateType'; -import { LIMIT_PER_PROJECT } from 'Common/Types/Database/LimitMax'; +import LIMIT_MAX from 'Common/Types/Database/LimitMax'; import URL from 'Common/Types/API/URL'; import { FileRoute } from 'Common/ServiceRoute'; import DatabaseConfig from '../DatabaseConfig'; @@ -175,7 +175,7 @@ export class Service extends DatabaseService { subscriberWebhook: true, }, skip: 0, - limit: LIMIT_PER_PROJECT, + limit: LIMIT_MAX, props: props, }); } diff --git a/CommonServer/Services/TeamMemberService.ts b/CommonServer/Services/TeamMemberService.ts index 061800d3f4..0560f877ad 100644 --- a/CommonServer/Services/TeamMemberService.ts +++ b/CommonServer/Services/TeamMemberService.ts @@ -16,7 +16,7 @@ import QueryHelper from '../Types/Database/QueryHelper'; import LIMIT_MAX from 'Common/Types/Database/LimitMax'; import ProjectService from './ProjectService'; import { IsBillingEnabled } from '../EnvironmentConfig'; -import { DashboardRoute } from 'Common/ServiceRoute'; +import { AccountsRoute } from 'Common/ServiceRoute'; import DatabaseConfig from '../DatabaseConfig'; import BillingService from './BillingService'; import SubscriptionPlan from 'Common/Types/Billing/SubscriptionPlan'; @@ -78,7 +78,10 @@ export class TeamMemberService extends DatabaseService { isRoot: true, }); + let isNewUser: boolean = false; + if (!user) { + isNewUser = true; user = await UserService.createByEmail(email, { isRoot: true, }); @@ -106,11 +109,24 @@ export class TeamMemberService extends DatabaseService { toEmail: email, templateType: EmailTemplateType.InviteMember, vars: { - dashboardUrl: new URL( - httpProtocol, - host, - DashboardRoute + signInLink: URL.fromString( + new URL( + httpProtocol, + host, + AccountsRoute + ).toString() ).toString(), + registerLink: URL.fromString( + new URL( + httpProtocol, + host, + AccountsRoute + ).toString() + ) + .addRoute('/register') + .addQueryParam('email', email.toString()) + .toString(), + isNewUser: isNewUser.toString(), projectName: project.name!, homeUrl: new URL(httpProtocol, host).toString(), }, diff --git a/CommonUI/src/Components/Forms/ModelForm.tsx b/CommonUI/src/Components/Forms/ModelForm.tsx index 1a69e1a0ca..a84c9f4174 100644 --- a/CommonUI/src/Components/Forms/ModelForm.tsx +++ b/CommonUI/src/Components/Forms/ModelForm.tsx @@ -118,7 +118,7 @@ const ModelForm: ( ? (Object.keys(field.field)[0] as string) : null; - if (key && hasPermissionOnField(key)) { + if (key && (hasPermissionOnField(key) || field.forceShow)) { (select as Dictionary)[key] = true; } } diff --git a/Dashboard/Serve.ts b/Dashboard/Serve.ts index a5bf09f425..c3d3775023 100755 --- a/Dashboard/Serve.ts +++ b/Dashboard/Serve.ts @@ -18,6 +18,7 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); export default app; diff --git a/DashboardAPI/Index.ts b/DashboardAPI/Index.ts index a63bc96241..175ccd5baf 100755 --- a/DashboardAPI/Index.ts +++ b/DashboardAPI/Index.ts @@ -1024,4 +1024,5 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); diff --git a/File/Index.ts b/File/Index.ts index ae4af40d45..465b553241 100644 --- a/File/Index.ts +++ b/File/Index.ts @@ -47,4 +47,5 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); diff --git a/HelmChart/package-lock.json b/HelmChart/package-lock.json index 8a1509bb0b..c35481740a 100644 --- a/HelmChart/package-lock.json +++ b/HelmChart/package-lock.json @@ -42,7 +42,7 @@ "moment-timezone": "^0.5.40", "nanoid": "^3.3.2", "nanoid-dictionary": "^4.3.0", - "posthog-js": "^1.37.0", + "posthog-js": "^1.77.0", "process": "^0.11.10", "reflect-metadata": "^0.1.13", "slugify": "^1.6.5", @@ -50,7 +50,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@faker-js/faker": "^6.3.1", + "@faker-js/faker": "^8.0.2", "@types/jest": "^27.5.2", "@types/node": "^17.0.22", "jest": "^27.5.1", @@ -62,6 +62,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "@clickhouse/client": "^0.2.1", "@elastic/elasticsearch": "^8.1.0", "@opentelemetry/api": "^1.1.0", "@opentelemetry/auto-instrumentations-node": "^0.31.0", @@ -608,6 +609,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -873,6 +875,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -880,7 +883,8 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", @@ -1265,6 +1269,11 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -1404,9 +1413,9 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "engines": { "node": "*" } @@ -2047,6 +2056,11 @@ "url": "https://opencollective.com/mochajs" } }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "node_modules/mocha/node_modules/debug": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", @@ -2866,7 +2880,8 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true }, "node_modules/statuses": { "version": "2.0.1", @@ -3297,6 +3312,22 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -3802,6 +3833,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -4009,6 +4041,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "requires": { "color-name": "1.1.3" } @@ -4016,7 +4049,8 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "combined-stream": { "version": "1.0.8", @@ -4029,7 +4063,7 @@ "Common": { "version": "file:../Common", "requires": { - "@faker-js/faker": "^6.3.1", + "@faker-js/faker": "^8.0.2", "@types/crypto-js": "^4.1.1", "@types/jest": "^27.5.2", "@types/nanoid-dictionary": "^4.2.0", @@ -4043,7 +4077,7 @@ "moment-timezone": "^0.5.40", "nanoid": "^3.3.2", "nanoid-dictionary": "^4.3.0", - "posthog-js": "^1.37.0", + "posthog-js": "^1.77.0", "process": "^0.11.10", "reflect-metadata": "^0.1.13", "slugify": "^1.6.5", @@ -4055,6 +4089,7 @@ "CommonServer": { "version": "file:../CommonServer", "requires": { + "@clickhouse/client": "^0.2.1", "@elastic/elasticsearch": "^8.1.0", "@faker-js/faker": "^6.3.1", "@opentelemetry/api": "^1.1.0", @@ -4379,6 +4414,11 @@ "requires": { "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -4485,9 +4525,9 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==" }, "get-intrinsic": { "version": "1.1.3", @@ -4948,6 +4988,11 @@ "yargs-unparser": "2.0.0" }, "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "debug": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", @@ -5558,7 +5603,8 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true }, "statuses": { "version": "2.0.1", @@ -5853,6 +5899,19 @@ "requires": { "color-convert": "^2.0.1" } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" } } }, diff --git a/Identity/API/Authentication.ts b/Identity/API/Authentication.ts index 503ff248a2..e14cc51557 100644 --- a/Identity/API/Authentication.ts +++ b/Identity/API/Authentication.ts @@ -230,7 +230,7 @@ router.post( }, }); - if (alreadySavedUser) { + if (alreadySavedUser && alreadySavedUser.password) { const token: string = ObjectID.generate().toString(); await UserService.updateOneBy({ query: { @@ -274,7 +274,7 @@ router.post( req, res, new BadDataException( - `No user is registered with ${user.email?.toString()}` + `No user is registered with ${user.email?.toString()}. Please sign up for a new account.` ) ); } catch (err) { diff --git a/Identity/API/StatusPageAuthentication.ts b/Identity/API/StatusPageAuthentication.ts index 653750b1ed..3ab72e991e 100644 --- a/Identity/API/StatusPageAuthentication.ts +++ b/Identity/API/StatusPageAuthentication.ts @@ -38,6 +38,10 @@ router.post( try { const data: JSONObject = req.body['data']; + if (!data['email']) { + throw new BadDataException('Email is required.'); + } + const user: StatusPagePrivateUser = JSONFunctions.fromJSON( data as JSONObject, StatusPagePrivateUser @@ -164,7 +168,13 @@ router.post( next: NextFunction ): Promise => { try { - const data: JSONObject = req.body['data']; + const data: JSONObject = JSONFunctions.deserialize( + req.body['data'] + ); + + if (!data['statusPageId']) { + throw new BadDataException('Status Page ID is required.'); + } const user: StatusPagePrivateUser = JSONFunctions.fromJSON( data as JSONObject, @@ -176,6 +186,9 @@ router.post( const alreadySavedUser: StatusPagePrivateUser | null = await StatusPagePrivateUserService.findOneBy({ query: { + statusPageId: new ObjectID( + data['statusPageId'].toString() + ), resetPasswordToken: (user.resetPasswordToken as string) || '', }, @@ -207,7 +220,7 @@ router.post( const statusPage: StatusPage | null = await StatusPageService.findOneById({ - id: new ObjectID(data['statusPageId'] as string), + id: new ObjectID(data['statusPageId'].toString()), props: { isRoot: true, ignoreHooks: true, @@ -329,7 +342,11 @@ router.post( const alreadySavedUser: StatusPagePrivateUser | null = await StatusPagePrivateUserService.findOneBy({ - query: { email: user.email!, password: user.password! }, + query: { + email: user.email!, + password: user.password!, + statusPageId: user.statusPageId!, + }, select: { _id: true, password: true, diff --git a/Identity/Index.ts b/Identity/Index.ts index 77b8f2475e..e8da10926b 100644 --- a/Identity/Index.ts +++ b/Identity/Index.ts @@ -51,4 +51,5 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); diff --git a/Licensing/package-lock.json b/Licensing/package-lock.json index a2f051ce79..7ed5391d4c 100644 --- a/Licensing/package-lock.json +++ b/Licensing/package-lock.json @@ -46,7 +46,7 @@ "moment-timezone": "^0.5.40", "nanoid": "^3.3.2", "nanoid-dictionary": "^4.3.0", - "posthog-js": "^1.37.0", + "posthog-js": "^1.77.0", "process": "^0.11.10", "reflect-metadata": "^0.1.13", "slugify": "^1.6.5", @@ -54,7 +54,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@faker-js/faker": "^6.3.1", + "@faker-js/faker": "^8.0.2", "@types/jest": "^27.5.2", "@types/node": "^17.0.22", "jest": "^27.5.1", @@ -66,6 +66,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "@clickhouse/client": "^0.2.1", "@elastic/elasticsearch": "^8.1.0", "@opentelemetry/api": "^1.1.0", "@opentelemetry/auto-instrumentations-node": "^0.31.0", @@ -1489,9 +1490,9 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "engines": { "node": "*" } @@ -4408,7 +4409,7 @@ "Common": { "version": "file:../Common", "requires": { - "@faker-js/faker": "^6.3.1", + "@faker-js/faker": "^8.0.2", "@types/crypto-js": "^4.1.1", "@types/jest": "^27.5.2", "@types/nanoid-dictionary": "^4.2.0", @@ -4422,7 +4423,7 @@ "moment-timezone": "^0.5.40", "nanoid": "^3.3.2", "nanoid-dictionary": "^4.3.0", - "posthog-js": "^1.37.0", + "posthog-js": "^1.77.0", "process": "^0.11.10", "reflect-metadata": "^0.1.13", "slugify": "^1.6.5", @@ -4434,6 +4435,7 @@ "CommonServer": { "version": "file:../CommonServer", "requires": { + "@clickhouse/client": "^0.2.1", "@elastic/elasticsearch": "^8.1.0", "@faker-js/faker": "^6.3.1", "@opentelemetry/api": "^1.1.0", @@ -4895,9 +4897,9 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==" }, "get-intrinsic": { "version": "1.1.3", diff --git a/LinkShortener/Index.ts b/LinkShortener/Index.ts index 35789e2f0a..c0e38dd412 100644 --- a/LinkShortener/Index.ts +++ b/LinkShortener/Index.ts @@ -27,6 +27,7 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); export default app; diff --git a/Notification/Index.ts b/Notification/Index.ts index 0978f0fea5..31de57a692 100644 --- a/Notification/Index.ts +++ b/Notification/Index.ts @@ -46,4 +46,5 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); diff --git a/Notification/Templates/InviteMember.hbs b/Notification/Templates/InviteMember.hbs index c9ad0fbd12..c8abf930c3 100644 --- a/Notification/Templates/InviteMember.hbs +++ b/Notification/Templates/InviteMember.hbs @@ -4,12 +4,24 @@ {{> EmailTitle title=(concat "You have been invited to " projectName) }} -{{> InfoBlock info="Please click on the 'Go to dashboard' button below to see all your invitations and manage them."}} +{{#ifCond isNewUser "true"}} +{{> InfoBlock info="Please sign up to a new account to accept this invitation"}} -{{> ButtonBlock buttonUrl=dashboardUrl buttonText="Go to Dashboard"}} +{{> ButtonBlock buttonUrl=registerLink buttonText="Sign up to a new account"}} {{> InfoBlock info="You can also copy and paste this link:"}} -{{> InfoBlock info=dashboardUrl}} +{{> InfoBlock info=registerLink}} +{{/ifCond}} + +{{#ifCond isNewUser "false"}} +{{> InfoBlock info="Please sign in to your account to see all your invitations and manage them."}} + +{{> ButtonBlock buttonUrl=signInLink buttonText="Sign in to OneUptime"}} + +{{> InfoBlock info="You can also copy and paste this link:"}} +{{> InfoBlock info=signInLink}} +{{/ifCond}} + {{> InfoBlock info="If you have not signed up to OneUptime so far. You'll be redirected to the account sign up page to sign up first."}} diff --git a/Probe/Index.ts b/Probe/Index.ts index f43e624617..e2c86f8d26 100644 --- a/Probe/Index.ts +++ b/Probe/Index.ts @@ -54,4 +54,5 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); diff --git a/ProbeAPI/Index.ts b/ProbeAPI/Index.ts index 2b027f792c..64d2322792 100644 --- a/ProbeAPI/Index.ts +++ b/ProbeAPI/Index.ts @@ -45,4 +45,5 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); diff --git a/StatusPage/Serve.ts b/StatusPage/Serve.ts index 606948808b..c88062d030 100644 --- a/StatusPage/Serve.ts +++ b/StatusPage/Serve.ts @@ -23,6 +23,7 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); export default app; diff --git a/StatusPage/src/Pages/Accounts/ResetPassword.tsx b/StatusPage/src/Pages/Accounts/ResetPassword.tsx index 643a15364a..e80ce9da0b 100644 --- a/StatusPage/src/Pages/Accounts/ResetPassword.tsx +++ b/StatusPage/src/Pages/Accounts/ResetPassword.tsx @@ -110,6 +110,9 @@ const ResetPassword: FunctionComponent = ( ?.toString() .replace('/', '') .toString() || ''; + + item.statusPageId = + StatusPageUtil.getStatusPageId()!; return Promise.resolve(item); }} showAsColumns={1} diff --git a/TestServer/Index.ts b/TestServer/Index.ts index cca20009e2..54dbf6bdd5 100644 --- a/TestServer/Index.ts +++ b/TestServer/Index.ts @@ -24,4 +24,5 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); diff --git a/Workers/Index.ts b/Workers/Index.ts index 0ce2811dae..7cf4516825 100644 --- a/Workers/Index.ts +++ b/Workers/Index.ts @@ -126,4 +126,5 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); diff --git a/Workflow/Index.ts b/Workflow/Index.ts index f0a40a4187..a8e6972b47 100644 --- a/Workflow/Index.ts +++ b/Workflow/Index.ts @@ -78,6 +78,7 @@ const init: () => Promise = async (): Promise => { init().catch((err: Error) => { logger.error(err); + process.exit(1); }); export default app; diff --git a/docker-compose.base.yml b/docker-compose.base.yml index 81fbe9231f..4de9c04574 100644 --- a/docker-compose.base.yml +++ b/docker-compose.base.yml @@ -13,6 +13,45 @@ x-common-variables: &common-variables ANALYTICS_KEY: ${ANALYTICS_KEY} ANALYTICS_HOST: ${ANALYTICS_HOST} + SERVER_ACCOUNTS_HOSTNAME: accounts + SERVER_REALTIME_HOSTNAME: realtime + SERVER_DASHBOARD_API_HOSTNAME: dashboard-api + SERVER_WORKFLOW_HOSTNAME: workflow + SERVER_LINK_SHORTENER_HOSTNAME: link-shortener + SERVER_ALERT_HOSTNAME: alert + SERVER_PROBE_API_HOSTNAME: probe-api + SERVER_TEST_SERVER_HOSTNAME: test-server + SERVER_FILE_HOSTNAME: file + SERVER_HOME_HOSTNAME: home + SERVER_IDENTITY_HOSTNAME: identity + SERVER_NOTIFICATION_HOSTNAME: notification + SERVER_WORKERS_HOSTNAME: workers + SERVER_STATUS_PAGE_HOSTNAME: status-page + SERVER_DASHBOARD_HOSTNAME: dashboard + SERVER_ADMIN_DASHBOARD_HOSTNAME: admin-dashboard + SERVER_API_REFERENCE_HOSTNAME: api-reference + + + #Ports. Usually they don't need to change. + DASHBOARD_API_PORT: ${DASHBOARD_API_PORT} + API_REFERENCE_PORT: ${API_REFERENCE_PORT} + WORKFLOW_PORT: ${WORKFLOW_PORT} + LINK_SHORTENER_PORT: ${LINK_SHORTENER_PORT} + ALERT_PORT: ${ALERT_PORT} + PROBE_API_PORT: ${PROBE_API_PORT} + PROBE_PORT: ${PROBE_PORT} + TEST_SERVER_PORT: ${TEST_SERVER_PORT} + FILE_PORT: ${FILE_PORT} + HOME_PORT: ${HOME_PORT} + IDENTITY_PORT: ${IDENTITY_PORT} + NOTIFICATION_PORT: ${NOTIFICATION_PORT} + REALTIME_PORT: ${REALTIME_PORT} + WORKERS_PORT: ${WORKERS_PORT} + ACCOUNTS_PORT: ${ACCOUNTS_PORT} + STATUS_PAGE_PORT: ${STATUS_PAGE_PORT} + DASHBOARD_PORT: ${DASHBOARD_PORT} + ADMIN_DASHBOARD_PORT: ${ADMIN_DASHBOARD_PORT} + x-common-ui-variables: &common-ui-variables <<: *common-variables IS_SERVER: false @@ -57,46 +96,6 @@ x-common-server-variables: &common-server-variables DISABLE_AUTOMATIC_INCIDENT_CREATION: ${DISABLE_AUTOMATIC_INCIDENT_CREATION} - SERVER_ACCOUNTS_HOSTNAME: accounts - SERVER_REALTIME_HOSTNAME: realtime - SERVER_DASHBOARD_API_HOSTNAME: dashboard-api - SERVER_WORKFLOW_HOSTNAME: workflow - SERVER_LINK_SHORTENER_HOSTNAME: link-shortener - SERVER_ALERT_HOSTNAME: alert - SERVER_PROBE_API_HOSTNAME: probe-api - SERVER_TEST_SERVER_HOSTNAME: test-server - SERVER_FILE_HOSTNAME: file - SERVER_HOME_HOSTNAME: home - SERVER_IDENTITY_HOSTNAME: identity - SERVER_NOTIFICATION_HOSTNAME: notification - SERVER_WORKERS_HOSTNAME: workers - SERVER_STATUS_PAGE_HOSTNAME: status-page - SERVER_DASHBOARD_HOSTNAME: dashboard - SERVER_ADMIN_DASHBOARD_HOSTNAME: admin-dashboard - SERVER_API_REFERENCE_HOSTNAME: api-reference - - - #Ports. Usually they don't need to change. - DASHBOARD_API_PORT: ${DASHBOARD_API_PORT} - API_REFERENCE_PORT: ${API_REFERENCE_PORT} - WORKFLOW_PORT: ${WORKFLOW_PORT} - LINK_SHORTENER_PORT: ${LINK_SHORTENER_PORT} - ALERT_PORT: ${ALERT_PORT} - PROBE_API_PORT: ${PROBE_API_PORT} - PROBE_PORT: ${PROBE_PORT} - TEST_SERVER_PORT: ${TEST_SERVER_PORT} - FILE_PORT: ${FILE_PORT} - HOME_PORT: ${HOME_PORT} - IDENTITY_PORT: ${IDENTITY_PORT} - NOTIFICATION_PORT: ${NOTIFICATION_PORT} - REALTIME_PORT: ${REALTIME_PORT} - WORKERS_PORT: ${WORKERS_PORT} - ACCOUNTS_PORT: ${ACCOUNTS_PORT} - STATUS_PAGE_PORT: ${STATUS_PAGE_PORT} - DASHBOARD_PORT: ${DASHBOARD_PORT} - ADMIN_DASHBOARD_PORT: ${ADMIN_DASHBOARD_PORT} - - services: minio: