From 6c1489a87bd8c05118abafd52df2a467ee61633d Mon Sep 17 00:00:00 2001 From: Salman Date: Sat, 10 Feb 2024 03:26:56 +0530 Subject: [PATCH 01/38] Add admin invite only signup field --- .../migrations/20240205200732_invite-only.ts | 20 ++++ backend/src/db/schemas/super-admin.ts | 1 + backend/src/db/seeds/1-user.ts | 2 +- backend/src/ee/routes/v1/saml-router.ts | 2 +- backend/src/server/routes/v1/admin-router.ts | 3 +- .../super-admin/super-admin-service.ts | 2 +- frontend/src/hooks/api/admin/types.ts | 1 + frontend/src/pages/signupinvite.tsx | 10 +- .../admin/DashboardPage/DashboardPage.tsx | 99 ++++++++++++++----- 9 files changed, 108 insertions(+), 32 deletions(-) create mode 100644 backend/src/db/migrations/20240205200732_invite-only.ts diff --git a/backend/src/db/migrations/20240205200732_invite-only.ts b/backend/src/db/migrations/20240205200732_invite-only.ts new file mode 100644 index 000000000..dd4be591b --- /dev/null +++ b/backend/src/db/migrations/20240205200732_invite-only.ts @@ -0,0 +1,20 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + const isTablePresent = await knex.schema.hasTable(TableName.SuperAdmin); + if (isTablePresent) { + await knex.schema.alterTable(TableName.SuperAdmin, (t) => { + t.boolean("inviteOnlySignUp").defaultTo(false); + }); + } +} + +export async function down(knex: Knex): Promise { + if (await knex.schema.hasColumn(TableName.SuperAdmin, "inviteOnlySignUp")) { + await knex.schema.alterTable(TableName.SuperAdmin, (t) => { + t.dropColumn("inviteOnlySignUp"); + }); + } +} diff --git a/backend/src/db/schemas/super-admin.ts b/backend/src/db/schemas/super-admin.ts index 13bf45e7b..b43ada8d5 100644 --- a/backend/src/db/schemas/super-admin.ts +++ b/backend/src/db/schemas/super-admin.ts @@ -11,6 +11,7 @@ export const SuperAdminSchema = z.object({ id: z.string().uuid(), initialized: z.boolean().default(false).nullable().optional(), allowSignUp: z.boolean().default(true).nullable().optional(), + inviteOnlySignUp: z.boolean().default(false).nullable().optional(), createdAt: z.date(), updatedAt: z.date() }); diff --git a/backend/src/db/seeds/1-user.ts b/backend/src/db/seeds/1-user.ts index ca0042a98..0da9be9b1 100644 --- a/backend/src/db/seeds/1-user.ts +++ b/backend/src/db/seeds/1-user.ts @@ -9,7 +9,7 @@ export async function seed(knex: Knex): Promise { await knex(TableName.Users).del(); await knex(TableName.UserEncryptionKey).del(); await knex(TableName.SuperAdmin).del(); - await knex(TableName.SuperAdmin).insert([{ initialized: true, allowSignUp: true }]); + await knex(TableName.SuperAdmin).insert([{ initialized: true, allowSignUp: true, inviteOnlySignUp: false }]); // Inserts seed entries const [user] = await knex(TableName.Users) .insert([ diff --git a/backend/src/ee/routes/v1/saml-router.ts b/backend/src/ee/routes/v1/saml-router.ts index f81c21ffd..4c0e43cd6 100644 --- a/backend/src/ee/routes/v1/saml-router.ts +++ b/backend/src/ee/routes/v1/saml-router.ts @@ -105,7 +105,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => { email, firstName: profile.firstName as string, lastName: profile.lastName as string, - isSignupAllowed: Boolean(serverCfg.allowSignUp), + isSignupAllowed: Boolean(serverCfg.allowSignUp && serverCfg.inviteOnlySignUp), relayState: (req.body as { RelayState?: string }).RelayState, authProvider: (req as unknown as FastifyRequest).ssoConfig?.authProvider as string, orgId: (req as unknown as FastifyRequest).ssoConfig?.orgId as string diff --git a/backend/src/server/routes/v1/admin-router.ts b/backend/src/server/routes/v1/admin-router.ts index e23f68c3a..afe5c4c95 100644 --- a/backend/src/server/routes/v1/admin-router.ts +++ b/backend/src/server/routes/v1/admin-router.ts @@ -31,7 +31,8 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => { method: "PATCH", schema: { body: z.object({ - allowSignUp: z.boolean().optional() + allowSignUp: z.boolean().optional(), + inviteOnlySignUp: z.boolean().optional() }), response: { 200: z.object({ diff --git a/backend/src/services/super-admin/super-admin-service.ts b/backend/src/services/super-admin/super-admin-service.ts index 1144bd414..b15d95e56 100644 --- a/backend/src/services/super-admin/super-admin-service.ts +++ b/backend/src/services/super-admin/super-admin-service.ts @@ -33,7 +33,7 @@ export const superAdminServiceFactory = ({ const serverCfg = await serverCfgDAL.findOne({}); if (serverCfg) return; - const newCfg = await serverCfgDAL.create({ initialized: false, allowSignUp: true }); + const newCfg = await serverCfgDAL.create({ initialized: false, allowSignUp: true, inviteOnlySignUp: false }); return newCfg; }; diff --git a/frontend/src/hooks/api/admin/types.ts b/frontend/src/hooks/api/admin/types.ts index da6b5ce3c..593191d1f 100644 --- a/frontend/src/hooks/api/admin/types.ts +++ b/frontend/src/hooks/api/admin/types.ts @@ -1,6 +1,7 @@ export type TServerConfig = { initialized: boolean; allowSignUp: boolean; + inviteOnlySignUp: boolean; isMigrationModeOn?: boolean; }; diff --git a/frontend/src/pages/signupinvite.tsx b/frontend/src/pages/signupinvite.tsx index 5eaa48e63..5ede3126c 100644 --- a/frontend/src/pages/signupinvite.tsx +++ b/frontend/src/pages/signupinvite.tsx @@ -2,7 +2,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import crypto from "crypto"; -import { useState } from "react"; +import { useEffect,useState } from "react"; import Head from "next/head"; import Image from "next/image"; import Link from "next/link"; @@ -22,6 +22,7 @@ import { deriveArgonKey } from "@app/components/utilities/cryptography/crypto"; import issueBackupKey from "@app/components/utilities/cryptography/issueBackupKey"; import { saveTokenToLocalStorage } from "@app/components/utilities/saveTokenToLocalStorage"; import SecurityClient from "@app/components/utilities/SecurityClient"; +import { useServerConfig } from "@app/context"; import { completeAccountSignupInvite, verifySignupInvite } from "@app/hooks/api/auth/queries"; import { fetchOrganizations } from "@app/hooks/api/organization/queries"; @@ -56,6 +57,13 @@ export default function SignupInvite() { const token = parsedUrl.token as string; const organizationId = parsedUrl.organization_id as string; const email = (parsedUrl.to as string)?.replace(" ", "+").trim(); + const { config } = useServerConfig(); + + useEffect(() => { + if (!config.allowSignUp) { + router.push("/login"); + } + }, [config.allowSignUp]); // Verifies if the information that the users entered (name, workspace) is there, and if the password matched the criteria. const signupErrorCheck = async () => { diff --git a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx index 508dcda1e..240a9d5de 100644 --- a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx +++ b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx @@ -1,7 +1,16 @@ -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { useRouter } from "next/router"; -import { ContentLoader, Switch, Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; +import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; +import { + ContentLoader, + Select, + SelectItem, + Tab, + TabList, + TabPanel, + Tabs +} from "@app/components/v2"; import { useOrganization, useServerConfig, useUser } from "@app/context"; import { useUpdateServerConfig } from "@app/hooks/api"; @@ -9,13 +18,18 @@ enum TabSections { Settings = "settings" } +type SignUpMode = "disabled" | "invite-only" | "anyone"; + export const AdminDashboardPage = () => { const router = useRouter(); const data = useServerConfig(); + const [signUpMode, setSignUpMode] = useState("invite-only"); + const { config } = data; const { user, isLoading: isUserLoading } = useUser(); const { orgs } = useOrganization(); const { mutate: updateServerConfig } = useUpdateServerConfig(); + const { createNotification } = useNotificationContext(); const isNotAllowed = !user?.superAdmin; @@ -28,37 +42,68 @@ export const AdminDashboardPage = () => { } }, [isNotAllowed, isUserLoading]); + useEffect(() => { + if (!config.allowSignUp) { + setSignUpMode("disabled"); + return; + } + if (config.inviteOnlySignUp) { + setSignUpMode("invite-only"); + return; + } + setSignUpMode("anyone"); + }, [config]); + + function handleSignUpModeChange(newSignUpMode: SignUpMode) { + config.allowSignUp = newSignUpMode !== "disabled"; + config.inviteOnlySignUp = newSignUpMode === "invite-only"; + + createNotification({ + text: "Successfully changed sign up mode.", + type: "success" + }); + + updateServerConfig(config); + setSignUpMode(newSignUpMode); + } + return ( -
-
+
+

Admin Dashboard

Manage your Infisical instance.

- {isUserLoading || isNotAllowed ? ( - - ) : ( -
- - -
- General -
-
- -
- updateServerConfig({ allowSignUp: isChecked })} - /> -
Enable signup or invite
-
-
-
-
- )}
+ {isUserLoading || isNotAllowed ? ( + + ) : ( +
+ + +
+ General +
+
+ +
+
Allow user to Sign Up
+ +
+
+
+
+ )}
); }; From 5cf1ec24003438d575389817685fedf6bb7d5e7c Mon Sep 17 00:00:00 2001 From: Salman Date: Sat, 10 Feb 2024 10:44:39 +0530 Subject: [PATCH 02/38] Add restrict signup based on domain --- .../migrations/20240205200732_invite-only.ts | 7 ++ backend/src/db/schemas/super-admin.ts | 1 + backend/src/server/routes/v1/admin-router.ts | 3 +- backend/src/server/routes/v1/sso-router.ts | 8 +- backend/src/server/routes/v3/signup-router.ts | 12 ++- .../src/services/auth/auth-login-service.ts | 25 +++--- backend/src/services/auth/auth-login-type.ts | 3 + frontend/src/hooks/api/admin/types.ts | 1 + .../admin/DashboardPage/DashboardPage.tsx | 88 ++++++++++++++----- 9 files changed, 109 insertions(+), 39 deletions(-) diff --git a/backend/src/db/migrations/20240205200732_invite-only.ts b/backend/src/db/migrations/20240205200732_invite-only.ts index dd4be591b..d242623c8 100644 --- a/backend/src/db/migrations/20240205200732_invite-only.ts +++ b/backend/src/db/migrations/20240205200732_invite-only.ts @@ -7,6 +7,7 @@ export async function up(knex: Knex): Promise { if (isTablePresent) { await knex.schema.alterTable(TableName.SuperAdmin, (t) => { t.boolean("inviteOnlySignUp").defaultTo(false); + t.string("allowSpecificDomainSignUp"); }); } } @@ -17,4 +18,10 @@ export async function down(knex: Knex): Promise { t.dropColumn("inviteOnlySignUp"); }); } + + if (await knex.schema.hasColumn(TableName.SuperAdmin, "allowSpecificDomainSignUp")) { + await knex.schema.alterTable(TableName.SuperAdmin, (t) => { + t.dropColumn("allowSpecificDomainSignUp"); + }); + } } diff --git a/backend/src/db/schemas/super-admin.ts b/backend/src/db/schemas/super-admin.ts index b43ada8d5..fb373e19b 100644 --- a/backend/src/db/schemas/super-admin.ts +++ b/backend/src/db/schemas/super-admin.ts @@ -12,6 +12,7 @@ export const SuperAdminSchema = z.object({ initialized: z.boolean().default(false).nullable().optional(), allowSignUp: z.boolean().default(true).nullable().optional(), inviteOnlySignUp: z.boolean().default(false).nullable().optional(), + allowSpecificDomainSignUp: z.string().nullable().optional(), createdAt: z.date(), updatedAt: z.date() }); diff --git a/backend/src/server/routes/v1/admin-router.ts b/backend/src/server/routes/v1/admin-router.ts index afe5c4c95..ddd95522f 100644 --- a/backend/src/server/routes/v1/admin-router.ts +++ b/backend/src/server/routes/v1/admin-router.ts @@ -32,7 +32,8 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => { schema: { body: z.object({ allowSignUp: z.boolean().optional(), - inviteOnlySignUp: z.boolean().optional() + inviteOnlySignUp: z.boolean().optional(), + allowSpecificDomainSignUp: z.string().optional() }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/sso-router.ts b/backend/src/server/routes/v1/sso-router.ts index bfcf2f6ae..da0b12ca5 100644 --- a/backend/src/server/routes/v1/sso-router.ts +++ b/backend/src/server/routes/v1/sso-router.ts @@ -55,7 +55,7 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { lastName: profile?.name?.familyName || "", authMethod: AuthMethod.GOOGLE, callbackPort: req.query.state as string, - isSignupAllowed: Boolean(serverCfg.allowSignUp) + serverCfg }); cb(null, { isUserCompleted, providerAuthToken }); } catch (error) { @@ -91,7 +91,8 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { lastName: "", authMethod: AuthMethod.GITHUB, callbackPort: req.query.state as string, - isSignupAllowed: Boolean(serverCfg.allowSignUp) + serverCfg + // isSignupAllowed: Boolean(serverCfg.allowSignUp) }); return cb(null, { isUserCompleted, providerAuthToken }); } catch (error) { @@ -127,7 +128,8 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { lastName: "", authMethod: AuthMethod.GITLAB, callbackPort: req.query.state as string, - isSignupAllowed: Boolean(serverCfg.allowSignUp) + serverCfg + // isSignupAllowed: Boolean(serverCfg.allowSignUp) }); return cb(null, { isUserCompleted, providerAuthToken }); diff --git a/backend/src/server/routes/v3/signup-router.ts b/backend/src/server/routes/v3/signup-router.ts index 2a2f50f43..11d79d2b5 100644 --- a/backend/src/server/routes/v3/signup-router.ts +++ b/backend/src/server/routes/v3/signup-router.ts @@ -23,8 +23,16 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { } }, handler: async (req) => { - await server.services.signup.beginEmailSignupProcess(req.body.email); - return { message: `Sent an email verification code to ${req.body.email}` }; + const { email } = req.body; + const config = await server.services.superAdmin.initServerCfg(); + + if (config?.allowSpecificDomainSignUp) { + const domain = email.split("@")[1]; + + if (domain !== config.allowSpecificDomainSignUp) throw new Error(`Unsupported email domain (${domain}).`); + } + await server.services.signup.beginEmailSignupProcess(email); + return { message: `Sent an email verification code to ${email}` }; } }); diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index 6e4d60bba..ccfe619f4 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -261,20 +261,25 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }: /* * OAuth2 login for google,github, and other oauth2 provider * */ - const oauth2Login = async ({ - email, - firstName, - lastName, - authMethod, - callbackPort, - isSignupAllowed - }: TOauthLoginDTO) => { + const oauth2Login = async ({ email, firstName, lastName, authMethod, callbackPort, serverCfg }: TOauthLoginDTO) => { let user = await userDAL.findUserByEmail(email); const appCfg = getConfig(); - const isOauthSignUpDisabled = !isSignupAllowed && !user; - if (isOauthSignUpDisabled) throw new BadRequestError({ message: "User signup disabled", name: "Oauth 2 login" }); if (!user) { + // Create a new user based on oAuth + if (!serverCfg?.allowSignUp) + throw new BadRequestError({ message: "User signup disabled", name: "Oauth 2 login" }); + + if (serverCfg?.allowSpecificDomainSignUp) { + const domain = email.split("@")[1]; + + if (domain !== serverCfg.allowSpecificDomainSignUp) + throw new BadRequestError({ + message: `User email domain (${domain}) is not supported`, + name: "Oauth 2 login" + }); + } + user = await userDAL.create({ email, firstName, lastName, authMethods: [authMethod] }); } const isLinkingRequired = !user?.authMethods?.includes(authMethod); diff --git a/backend/src/services/auth/auth-login-type.ts b/backend/src/services/auth/auth-login-type.ts index 67f640bc9..54b27425b 100644 --- a/backend/src/services/auth/auth-login-type.ts +++ b/backend/src/services/auth/auth-login-type.ts @@ -1,3 +1,5 @@ +import { TSuperAdmin } from "@app/db/schemas/super-admin"; + import { AuthMethod } from "./auth-type"; export type TLoginGenServerPublicKeyDTO = { @@ -29,4 +31,5 @@ export type TOauthLoginDTO = { authMethod: AuthMethod; callbackPort?: string; isSignupAllowed?: boolean; + serverCfg?: TSuperAdmin; }; diff --git a/frontend/src/hooks/api/admin/types.ts b/frontend/src/hooks/api/admin/types.ts index 593191d1f..145f22072 100644 --- a/frontend/src/hooks/api/admin/types.ts +++ b/frontend/src/hooks/api/admin/types.ts @@ -2,6 +2,7 @@ export type TServerConfig = { initialized: boolean; allowSignUp: boolean; inviteOnlySignUp: boolean; + allowSpecificDomainSignUp?: string; isMigrationModeOn?: boolean; }; diff --git a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx index 240a9d5de..b0d07b7dc 100644 --- a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx +++ b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx @@ -1,9 +1,14 @@ -import { useEffect, useState } from "react"; +import { FormEvent, useEffect, useState } from "react"; import { useRouter } from "next/router"; +import { faAt } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { + Button, ContentLoader, + FormControl, + Input, Select, SelectItem, Tab, @@ -24,11 +29,13 @@ export const AdminDashboardPage = () => { const router = useRouter(); const data = useServerConfig(); const [signUpMode, setSignUpMode] = useState("invite-only"); + const [allowSpecificDomain, setAllowSpecificDomain] = useState(); const { config } = data; const { user, isLoading: isUserLoading } = useUser(); const { orgs } = useOrganization(); const { mutate: updateServerConfig } = useUpdateServerConfig(); + const { createNotification } = useNotificationContext(); const isNotAllowed = !user?.superAdmin; @@ -49,22 +56,28 @@ export const AdminDashboardPage = () => { } if (config.inviteOnlySignUp) { setSignUpMode("invite-only"); - return; + } else { + setSignUpMode("anyone"); + } + + if (config.allowSpecificDomainSignUp) { + setAllowSpecificDomain(config.allowSpecificDomainSignUp); } - setSignUpMode("anyone"); }, [config]); - function handleSignUpModeChange(newSignUpMode: SignUpMode) { - config.allowSignUp = newSignUpMode !== "disabled"; - config.inviteOnlySignUp = newSignUpMode === "invite-only"; + async function handleSubmit(e: FormEvent) { + e.preventDefault(); + + config.allowSignUp = signUpMode !== "disabled"; + config.inviteOnlySignUp = signUpMode === "invite-only"; + config.allowSpecificDomainSignUp = signUpMode === "anyone" ? allowSpecificDomain : ""; + + await updateServerConfig(config); createNotification({ text: "Successfully changed sign up mode.", type: "success" }); - - updateServerConfig(config); - setSignUpMode(newSignUpMode); } return ( @@ -86,20 +99,49 @@ export const AdminDashboardPage = () => {
-
-
Allow user to Sign Up
- -
+
+
+
+ Allow user to Sign Up +
+ +
+ + {signUpMode === "anyone" && ( +
+
+ Allow email with only specific domain +
+ +
+ } + value={allowSpecificDomain} + onChange={(ev) => setAllowSpecificDomain(ev.target.value)} + /> +
+
+
+ )} + + +
From da377f6fdad2b85392cf5d6f14f1f80574d15200 Mon Sep 17 00:00:00 2001 From: Salman Date: Sat, 10 Feb 2024 23:00:16 +0530 Subject: [PATCH 03/38] Update error handling and refactor --- backend/src/server/routes/v1/sso-router.ts | 15 +++------------ backend/src/server/routes/v3/signup-router.ts | 6 +++++- backend/src/services/auth/auth-login-service.ts | 7 +++++-- backend/src/services/auth/auth-login-type.ts | 4 ---- 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/backend/src/server/routes/v1/sso-router.ts b/backend/src/server/routes/v1/sso-router.ts index da0b12ca5..60bbec7db 100644 --- a/backend/src/server/routes/v1/sso-router.ts +++ b/backend/src/server/routes/v1/sso-router.ts @@ -18,7 +18,6 @@ import { BadRequestError } from "@app/lib/errors"; import { logger } from "@app/lib/logger"; import { fetchGithubEmails } from "@app/lib/requests/github"; import { AuthMethod } from "@app/services/auth/auth-type"; -import { getServerCfg } from "@app/services/super-admin/super-admin-service"; export const registerSsoRouter = async (server: FastifyZodProvider) => { const appCfg = getConfig(); @@ -42,7 +41,6 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { async (req, _accessToken, _refreshToken, profile, cb) => { try { const email = profile?.emails?.[0]?.value; - const serverCfg = await getServerCfg(); if (!email) throw new BadRequestError({ message: "Email not found", @@ -54,8 +52,7 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { firstName: profile?.name?.givenName || "", lastName: profile?.name?.familyName || "", authMethod: AuthMethod.GOOGLE, - callbackPort: req.query.state as string, - serverCfg + callbackPort: req.query.state as string }); cb(null, { isUserCompleted, providerAuthToken }); } catch (error) { @@ -84,15 +81,12 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { try { const ghEmails = await fetchGithubEmails(accessToken); const { email } = ghEmails.filter((gitHubEmail) => gitHubEmail.primary)[0]; - const serverCfg = await getServerCfg(); const { isUserCompleted, providerAuthToken } = await server.services.login.oauth2Login({ email, firstName: profile.displayName, lastName: "", authMethod: AuthMethod.GITHUB, - callbackPort: req.query.state as string, - serverCfg - // isSignupAllowed: Boolean(serverCfg.allowSignUp) + callbackPort: req.query.state as string }); return cb(null, { isUserCompleted, providerAuthToken }); } catch (error) { @@ -121,15 +115,12 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { async (req: any, _accessToken: string, _refreshToken: string, profile: any, cb: any) => { try { const email = profile.emails[0].value; - const serverCfg = await getServerCfg(); const { isUserCompleted, providerAuthToken } = await server.services.login.oauth2Login({ email, firstName: profile.displayName, lastName: "", authMethod: AuthMethod.GITLAB, - callbackPort: req.query.state as string, - serverCfg - // isSignupAllowed: Boolean(serverCfg.allowSignUp) + callbackPort: req.query.state as string }); return cb(null, { isUserCompleted, providerAuthToken }); diff --git a/backend/src/server/routes/v3/signup-router.ts b/backend/src/server/routes/v3/signup-router.ts index 11d79d2b5..257a4c173 100644 --- a/backend/src/server/routes/v3/signup-router.ts +++ b/backend/src/server/routes/v3/signup-router.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import { UsersSchema } from "@app/db/schemas"; import { getConfig } from "@app/lib/config/env"; +import { BadRequestError } from "@app/lib/errors"; import { authRateLimit } from "@app/server/config/rateLimiter"; import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; @@ -29,7 +30,10 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { if (config?.allowSpecificDomainSignUp) { const domain = email.split("@")[1]; - if (domain !== config.allowSpecificDomainSignUp) throw new Error(`Unsupported email domain (${domain}).`); + if (domain !== config.allowSpecificDomainSignUp) + throw new BadRequestError({ + message: `User email domain (@${domain}) is not supported` + }); } await server.services.signup.beginEmailSignupProcess(email); return { message: `Sent an email verification code to ${email}` }; diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index ccfe619f4..569b3d374 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -4,6 +4,7 @@ import { TUsers, UserDeviceSchema } from "@app/db/schemas"; import { getConfig } from "@app/lib/config/env"; import { generateSrpServerKey, srpCheckClientProof } from "@app/lib/crypto"; import { BadRequestError } from "@app/lib/errors"; +import { getServerCfg } from "@app/services/super-admin/super-admin-service"; import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service"; import { TokenType } from "../auth-token/auth-token-types"; @@ -261,8 +262,10 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }: /* * OAuth2 login for google,github, and other oauth2 provider * */ - const oauth2Login = async ({ email, firstName, lastName, authMethod, callbackPort, serverCfg }: TOauthLoginDTO) => { + const oauth2Login = async ({ email, firstName, lastName, authMethod, callbackPort }: TOauthLoginDTO) => { let user = await userDAL.findUserByEmail(email); + const serverCfg = await getServerCfg(); + const appCfg = getConfig(); if (!user) { @@ -275,7 +278,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }: if (domain !== serverCfg.allowSpecificDomainSignUp) throw new BadRequestError({ - message: `User email domain (${domain}) is not supported`, + message: `User email domain (@${domain}) is not supported`, name: "Oauth 2 login" }); } diff --git a/backend/src/services/auth/auth-login-type.ts b/backend/src/services/auth/auth-login-type.ts index 54b27425b..86af5a5f9 100644 --- a/backend/src/services/auth/auth-login-type.ts +++ b/backend/src/services/auth/auth-login-type.ts @@ -1,5 +1,3 @@ -import { TSuperAdmin } from "@app/db/schemas/super-admin"; - import { AuthMethod } from "./auth-type"; export type TLoginGenServerPublicKeyDTO = { @@ -30,6 +28,4 @@ export type TOauthLoginDTO = { lastName?: string; authMethod: AuthMethod; callbackPort?: string; - isSignupAllowed?: boolean; - serverCfg?: TSuperAdmin; }; From 3f96f0a8fb7a20bcf81dfd5934ebf6196fafee22 Mon Sep 17 00:00:00 2001 From: Salman Date: Sun, 11 Feb 2024 00:40:17 +0530 Subject: [PATCH 04/38] Fix dropdown not working on page transition --- .../admin/DashboardPage/DashboardPage.tsx | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx index b0d07b7dc..181dc890a 100644 --- a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx +++ b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx @@ -1,4 +1,4 @@ -import { FormEvent, useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import { useRouter } from "next/router"; import { faAt } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -65,9 +65,7 @@ export const AdminDashboardPage = () => { } }, [config]); - async function handleSubmit(e: FormEvent) { - e.preventDefault(); - + const handleSubmit = async () => { config.allowSignUp = signUpMode !== "disabled"; config.inviteOnlySignUp = signUpMode === "invite-only"; config.allowSpecificDomainSignUp = signUpMode === "anyone" ? allowSpecificDomain : ""; @@ -99,16 +97,13 @@ export const AdminDashboardPage = () => { -
+
Allow user to Sign Up
} @@ -138,10 +133,10 @@ export const AdminDashboardPage = () => {
)} - - +
From 2ef8781378cc40e78a730d71d95fd8a6bb746d86 Mon Sep 17 00:00:00 2001 From: Salman Date: Sun, 11 Feb 2024 10:55:36 +0530 Subject: [PATCH 05/38] Update support multiple domain and error handling --- backend/src/ee/routes/v1/saml-router.ts | 2 +- backend/src/server/routes/v3/signup-router.ts | 12 ++++---- .../src/services/auth/auth-login-service.ts | 6 ++-- .../src/components/signup/EnterEmailStep.tsx | 17 +++++++++-- .../admin/DashboardPage/DashboardPage.tsx | 30 ++++++++++++------- 5 files changed, 45 insertions(+), 22 deletions(-) diff --git a/backend/src/ee/routes/v1/saml-router.ts b/backend/src/ee/routes/v1/saml-router.ts index 4c0e43cd6..f81c21ffd 100644 --- a/backend/src/ee/routes/v1/saml-router.ts +++ b/backend/src/ee/routes/v1/saml-router.ts @@ -105,7 +105,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => { email, firstName: profile.firstName as string, lastName: profile.lastName as string, - isSignupAllowed: Boolean(serverCfg.allowSignUp && serverCfg.inviteOnlySignUp), + isSignupAllowed: Boolean(serverCfg.allowSignUp), relayState: (req.body as { RelayState?: string }).RelayState, authProvider: (req as unknown as FastifyRequest).ssoConfig?.authProvider as string, orgId: (req as unknown as FastifyRequest).ssoConfig?.orgId as string diff --git a/backend/src/server/routes/v3/signup-router.ts b/backend/src/server/routes/v3/signup-router.ts index 257a4c173..e0ce21006 100644 --- a/backend/src/server/routes/v3/signup-router.ts +++ b/backend/src/server/routes/v3/signup-router.ts @@ -4,6 +4,7 @@ import { UsersSchema } from "@app/db/schemas"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError } from "@app/lib/errors"; import { authRateLimit } from "@app/server/config/rateLimiter"; +import { getServerCfg } from "@app/services/super-admin/super-admin-service"; import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; export const registerSignupRouter = async (server: FastifyZodProvider) => { @@ -25,15 +26,16 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { }, handler: async (req) => { const { email } = req.body; - const config = await server.services.superAdmin.initServerCfg(); + const serverCfg = await getServerCfg(); - if (config?.allowSpecificDomainSignUp) { + if (serverCfg?.allowSpecificDomainSignUp) { const domain = email.split("@")[1]; - - if (domain !== config.allowSpecificDomainSignUp) + const allowedDomains = serverCfg.allowSpecificDomainSignUp.split(",").map((e) => e.trim()); + if (!allowedDomains.includes(domain)) { throw new BadRequestError({ - message: `User email domain (@${domain}) is not supported` + message: `Email with a domain (@${domain}) is not supported` }); + } } await server.services.signup.beginEmailSignupProcess(email); return { message: `Sent an email verification code to ${email}` }; diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index 569b3d374..f43fe063c 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -275,10 +275,10 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }: if (serverCfg?.allowSpecificDomainSignUp) { const domain = email.split("@")[1]; - - if (domain !== serverCfg.allowSpecificDomainSignUp) + const allowedDomains = serverCfg.allowSpecificDomainSignUp.split(",").map((e) => e.trim()); + if (!allowedDomains.includes(domain)) throw new BadRequestError({ - message: `User email domain (@${domain}) is not supported`, + message: `Email with a domain (@${domain}) is not supported`, name: "Oauth 2 login" }); } diff --git a/frontend/src/components/signup/EnterEmailStep.tsx b/frontend/src/components/signup/EnterEmailStep.tsx index e317a4ea5..058c23106 100644 --- a/frontend/src/components/signup/EnterEmailStep.tsx +++ b/frontend/src/components/signup/EnterEmailStep.tsx @@ -1,7 +1,9 @@ import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import Link from "next/link"; +import axios from "axios"; +import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { useSendVerificationEmail } from "@app/hooks/api"; import { Button, Input } from "../v2"; @@ -25,6 +27,7 @@ export default function EnterEmailStep({ setEmail, incrementStep }: DownloadBackupPDFStepProps): JSX.Element { + const { createNotification } = useNotificationContext(); const { mutateAsync } = useSendVerificationEmail(); const [emailError, setEmailError] = useState(false); const { t } = useTranslation(); @@ -46,8 +49,18 @@ export default function EnterEmailStep({ // If everything is correct, go to the next step if (!emailCheckBool) { - await mutateAsync({ email }); - incrementStep(); + try { + await mutateAsync({ email }); + incrementStep(); + } catch(e) { + if (axios.isAxiosError(e)) { + const { message = "Something went wrong" } = e.response?.data as { message: string}; + createNotification({ + type: "error", + text: message + }) + } + } } }; diff --git a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx index 181dc890a..340c1662a 100644 --- a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx +++ b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx @@ -66,17 +66,25 @@ export const AdminDashboardPage = () => { }, [config]); const handleSubmit = async () => { - config.allowSignUp = signUpMode !== "disabled"; - config.inviteOnlySignUp = signUpMode === "invite-only"; - config.allowSpecificDomainSignUp = signUpMode === "anyone" ? allowSpecificDomain : ""; + try { + config.allowSignUp = signUpMode !== "disabled"; + config.inviteOnlySignUp = signUpMode === "invite-only"; + config.allowSpecificDomainSignUp = signUpMode === "anyone" ? allowSpecificDomain : ""; - await updateServerConfig(config); + await updateServerConfig(config); - createNotification({ - text: "Successfully changed sign up mode.", - type: "success" - }); - } + createNotification({ + text: "Successfully changed sign up setting.", + type: "success" + }); + } catch (e) { + console.error(e); + createNotification({ + type: "error", + text: "Failed to update sign up setting." + }); + } + }; return (
@@ -118,12 +126,12 @@ export const AdminDashboardPage = () => { {signUpMode === "anyone" && (
- Allow email with only specific domain + Allow email with only specific domain(s)
} value={allowSpecificDomain} onChange={(ev) => setAllowSpecificDomain(ev.target.value)} From 0fb87ab05fd4df9df5f35763cba8540493c49812 Mon Sep 17 00:00:00 2001 From: Salman Date: Mon, 12 Feb 2024 04:09:46 +0530 Subject: [PATCH 06/38] Update move to react hook form, rename allowedSignUpDomain --- .../migrations/20240205200732_invite-only.ts | 6 +- backend/src/db/schemas/super-admin.ts | 2 +- backend/src/server/routes/v1/admin-router.ts | 2 +- backend/src/server/routes/v3/signup-router.ts | 4 +- .../src/services/auth/auth-login-service.ts | 4 +- frontend/src/hooks/api/admin/types.ts | 2 +- frontend/src/pages/signupinvite.tsx | 2 +- .../components/InitialStep/InitialStep.tsx | 2 +- .../admin/DashboardPage/DashboardPage.tsx | 139 +++++++++++------- 9 files changed, 100 insertions(+), 63 deletions(-) diff --git a/backend/src/db/migrations/20240205200732_invite-only.ts b/backend/src/db/migrations/20240205200732_invite-only.ts index d242623c8..4bebab17f 100644 --- a/backend/src/db/migrations/20240205200732_invite-only.ts +++ b/backend/src/db/migrations/20240205200732_invite-only.ts @@ -7,7 +7,7 @@ export async function up(knex: Knex): Promise { if (isTablePresent) { await knex.schema.alterTable(TableName.SuperAdmin, (t) => { t.boolean("inviteOnlySignUp").defaultTo(false); - t.string("allowSpecificDomainSignUp"); + t.string("allowedSignUpDomain"); }); } } @@ -19,9 +19,9 @@ export async function down(knex: Knex): Promise { }); } - if (await knex.schema.hasColumn(TableName.SuperAdmin, "allowSpecificDomainSignUp")) { + if (await knex.schema.hasColumn(TableName.SuperAdmin, "allowedSignUpDomain")) { await knex.schema.alterTable(TableName.SuperAdmin, (t) => { - t.dropColumn("allowSpecificDomainSignUp"); + t.dropColumn("allowedSignUpDomain"); }); } } diff --git a/backend/src/db/schemas/super-admin.ts b/backend/src/db/schemas/super-admin.ts index fb373e19b..4b410d88b 100644 --- a/backend/src/db/schemas/super-admin.ts +++ b/backend/src/db/schemas/super-admin.ts @@ -12,7 +12,7 @@ export const SuperAdminSchema = z.object({ initialized: z.boolean().default(false).nullable().optional(), allowSignUp: z.boolean().default(true).nullable().optional(), inviteOnlySignUp: z.boolean().default(false).nullable().optional(), - allowSpecificDomainSignUp: z.string().nullable().optional(), + allowedSignUpDomain: z.string().nullable().optional(), createdAt: z.date(), updatedAt: z.date() }); diff --git a/backend/src/server/routes/v1/admin-router.ts b/backend/src/server/routes/v1/admin-router.ts index ddd95522f..221014ccc 100644 --- a/backend/src/server/routes/v1/admin-router.ts +++ b/backend/src/server/routes/v1/admin-router.ts @@ -33,7 +33,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => { body: z.object({ allowSignUp: z.boolean().optional(), inviteOnlySignUp: z.boolean().optional(), - allowSpecificDomainSignUp: z.string().optional() + allowedSignUpDomain: z.string().optional() }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v3/signup-router.ts b/backend/src/server/routes/v3/signup-router.ts index e0ce21006..45434412e 100644 --- a/backend/src/server/routes/v3/signup-router.ts +++ b/backend/src/server/routes/v3/signup-router.ts @@ -28,9 +28,9 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { const { email } = req.body; const serverCfg = await getServerCfg(); - if (serverCfg?.allowSpecificDomainSignUp) { + if (serverCfg?.allowedSignUpDomain) { const domain = email.split("@")[1]; - const allowedDomains = serverCfg.allowSpecificDomainSignUp.split(",").map((e) => e.trim()); + const allowedDomains = serverCfg.allowedSignUpDomain.split(",").map((e) => e.trim()); if (!allowedDomains.includes(domain)) { throw new BadRequestError({ message: `Email with a domain (@${domain}) is not supported` diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index f43fe063c..e78b4080e 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -273,9 +273,9 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }: if (!serverCfg?.allowSignUp) throw new BadRequestError({ message: "User signup disabled", name: "Oauth 2 login" }); - if (serverCfg?.allowSpecificDomainSignUp) { + if (serverCfg?.allowedSignUpDomain) { const domain = email.split("@")[1]; - const allowedDomains = serverCfg.allowSpecificDomainSignUp.split(",").map((e) => e.trim()); + const allowedDomains = serverCfg.allowedSignUpDomain.split(",").map((e) => e.trim()); if (!allowedDomains.includes(domain)) throw new BadRequestError({ message: `Email with a domain (@${domain}) is not supported`, diff --git a/frontend/src/hooks/api/admin/types.ts b/frontend/src/hooks/api/admin/types.ts index 145f22072..e28e7f972 100644 --- a/frontend/src/hooks/api/admin/types.ts +++ b/frontend/src/hooks/api/admin/types.ts @@ -2,7 +2,7 @@ export type TServerConfig = { initialized: boolean; allowSignUp: boolean; inviteOnlySignUp: boolean; - allowSpecificDomainSignUp?: string; + allowedSignUpDomain?: string; isMigrationModeOn?: boolean; }; diff --git a/frontend/src/pages/signupinvite.tsx b/frontend/src/pages/signupinvite.tsx index 5ede3126c..a3b643e29 100644 --- a/frontend/src/pages/signupinvite.tsx +++ b/frontend/src/pages/signupinvite.tsx @@ -2,7 +2,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import crypto from "crypto"; -import { useEffect,useState } from "react"; +import { useEffect, useState } from "react"; import Head from "next/head"; import Image from "next/image"; import Link from "next/link"; diff --git a/frontend/src/views/Login/components/InitialStep/InitialStep.tsx b/frontend/src/views/Login/components/InitialStep/InitialStep.tsx index bbef55751..16541c9a0 100644 --- a/frontend/src/views/Login/components/InitialStep/InitialStep.tsx +++ b/frontend/src/views/Login/components/InitialStep/InitialStep.tsx @@ -226,7 +226,7 @@ export const InitialStep = ({ setStep, email, setEmail, password, setPassword }:
{!isLoading && loginError && } - {config.allowSignUp ? ( + {config.allowSignUp && !config.inviteOnlySignUp ? (
diff --git a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx index 340c1662a..912a60c18 100644 --- a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx +++ b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx @@ -1,7 +1,10 @@ -import { useEffect, useState } from "react"; +import { useEffect } from "react"; +import { Controller, useForm } from "react-hook-form"; import { useRouter } from "next/router"; import { faAt } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { yupResolver } from "@hookform/resolvers/yup"; +import * as yup from "yup"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { @@ -23,15 +26,37 @@ enum TabSections { Settings = "settings" } -type SignUpMode = "disabled" | "invite-only" | "anyone"; +const formSchema = yup.object({ + signUpMode: yup + .string() + .oneOf(["disabled", "invite-only", "anyone"]) + .required(), + allowedSignUpDomain: yup.string().optional() +}); + +type TDashboardForm = yup.InferType; export const AdminDashboardPage = () => { const router = useRouter(); const data = useServerConfig(); - const [signUpMode, setSignUpMode] = useState("invite-only"); - const [allowSpecificDomain, setAllowSpecificDomain] = useState(); - const { config } = data; + + const signUpStatus = config.allowSignUp + ? config.inviteOnlySignUp && "invite-only" + : "disabled"; + + const signUpType = signUpStatus || "anyone"; + + const { control, handleSubmit, watch } = useForm({ + resolver: yupResolver(formSchema), + defaultValues: { + signUpMode: signUpType, + allowedSignUpDomain: config.allowedSignUpDomain + } + }); + + const signupMode = watch("signUpMode"); + const { user, isLoading: isUserLoading } = useUser(); const { orgs } = useOrganization(); const { mutate: updateServerConfig } = useUpdateServerConfig(); @@ -49,29 +74,15 @@ export const AdminDashboardPage = () => { } }, [isNotAllowed, isUserLoading]); - useEffect(() => { - if (!config.allowSignUp) { - setSignUpMode("disabled"); - return; - } - if (config.inviteOnlySignUp) { - setSignUpMode("invite-only"); - } else { - setSignUpMode("anyone"); - } - - if (config.allowSpecificDomainSignUp) { - setAllowSpecificDomain(config.allowSpecificDomainSignUp); - } - }, [config]); - - const handleSubmit = async () => { + const onFormSubmit = async (formData: TDashboardForm) => { try { - config.allowSignUp = signUpMode !== "disabled"; - config.inviteOnlySignUp = signUpMode === "invite-only"; - config.allowSpecificDomainSignUp = signUpMode === "anyone" ? allowSpecificDomain : ""; + const { signUpMode, allowedSignUpDomain } = formData; - await updateServerConfig(config); + await updateServerConfig({ + allowSignUp: signUpMode !== "disabled", + inviteOnlySignUp: signUpMode === "invite-only", + allowedSignUpDomain: signUpMode === "anyone" ? allowedSignUpDomain : "" + }); createNotification({ text: "Successfully changed sign up setting.", @@ -86,6 +97,8 @@ export const AdminDashboardPage = () => { } }; + + return (
@@ -105,46 +118,70 @@ export const AdminDashboardPage = () => {
-
+
Allow user to Sign Up
- + ( + + + + )} + />
- {signUpMode === "anyone" && ( + {signupMode === "anyone" && (
Allow email with only specific domain(s)
- -
- } - value={allowSpecificDomain} - onChange={(ev) => setAllowSpecificDomain(ev.target.value)} - /> -
-
+ ( + + } + /> + + )} + />
)} - -
+
From 0ff3ddb0c86be4c8df2f4cf8c402bb5ab5fb4d37 Mon Sep 17 00:00:00 2001 From: Salman Date: Wed, 14 Feb 2024 07:52:46 +0530 Subject: [PATCH 07/38] Update generate schema run --- backend/src/db/schemas/super-admin.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/db/schemas/super-admin.ts b/backend/src/db/schemas/super-admin.ts index 4b410d88b..707ec60e9 100644 --- a/backend/src/db/schemas/super-admin.ts +++ b/backend/src/db/schemas/super-admin.ts @@ -11,10 +11,10 @@ export const SuperAdminSchema = z.object({ id: z.string().uuid(), initialized: z.boolean().default(false).nullable().optional(), allowSignUp: z.boolean().default(true).nullable().optional(), - inviteOnlySignUp: z.boolean().default(false).nullable().optional(), - allowedSignUpDomain: z.string().nullable().optional(), createdAt: z.date(), - updatedAt: z.date() + updatedAt: z.date(), + inviteOnlySignUp: z.boolean().default(false).nullable().optional(), + allowedSignUpDomain: z.string().nullable().optional() }); export type TSuperAdmin = z.infer; From ee69bccb6eee58a1775c8e22f89738bdcd9637db Mon Sep 17 00:00:00 2001 From: Salman Date: Wed, 14 Feb 2024 14:18:44 +0530 Subject: [PATCH 08/38] Update disabled sign up routes --- backend/src/server/routes/v3/signup-router.ts | 27 +++++++++++++++++++ .../src/services/auth/auth-login-service.ts | 3 +-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/backend/src/server/routes/v3/signup-router.ts b/backend/src/server/routes/v3/signup-router.ts index 45434412e..522af7e9f 100644 --- a/backend/src/server/routes/v3/signup-router.ts +++ b/backend/src/server/routes/v3/signup-router.ts @@ -26,7 +26,13 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { }, handler: async (req) => { const { email } = req.body; + const serverCfg = await getServerCfg(); + if (!serverCfg.allowSignUp) { + throw new BadRequestError({ + message: "Sign up is disabled!" + }); + } if (serverCfg?.allowedSignUpDomain) { const domain = email.split("@")[1]; @@ -62,6 +68,13 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { } }, handler: async (req) => { + const serverCfg = await getServerCfg(); + if (!serverCfg.allowSignUp) { + throw new BadRequestError({ + message: "Sign up is disabled!" + }); + } + const { token, user } = await server.services.signup.verifyEmailSignup(req.body.email, req.body.code); return { message: "Successfuly verified email", token, user }; } @@ -104,6 +117,13 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { if (!userAgent) throw new Error("user agent header is required"); const appCfg = getConfig(); + const serverCfg = await getServerCfg(); + if (!serverCfg.allowSignUp) { + throw new BadRequestError({ + message: "Sign up is disabled!" + }); + } + const { user, accessToken, refreshToken } = await server.services.signup.completeEmailAccountSignup({ ...req.body, ip: req.realIp, @@ -167,6 +187,13 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { if (!userAgent) throw new Error("user agent header is required"); const appCfg = getConfig(); + const serverCfg = await getServerCfg(); + if (!serverCfg.allowSignUp) { + throw new BadRequestError({ + message: "Sign up is disabled!" + }); + } + const { user, accessToken, refreshToken } = await server.services.signup.completeAccountInvite({ ...req.body, ip: req.realIp, diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index e78b4080e..04304980a 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -270,8 +270,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }: if (!user) { // Create a new user based on oAuth - if (!serverCfg?.allowSignUp) - throw new BadRequestError({ message: "User signup disabled", name: "Oauth 2 login" }); + if (!serverCfg?.allowSignUp) throw new BadRequestError({ message: "Sign Up disabled", name: "Oauth 2 login" }); if (serverCfg?.allowedSignUpDomain) { const domain = email.split("@")[1]; From 97d2a15d3ecc32eca9197464a07c95041dae602c Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Fri, 16 Feb 2024 13:41:18 +0530 Subject: [PATCH 09/38] feat: updated admin dashboard to use zod and ts enum --- .../admin/DashboardPage/DashboardPage.tsx | 79 +++++++++++-------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx index 912a60c18..afaa53d87 100644 --- a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx +++ b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx @@ -3,8 +3,8 @@ import { Controller, useForm } from "react-hook-form"; import { useRouter } from "next/router"; import { faAt } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { yupResolver } from "@hookform/resolvers/yup"; -import * as yup from "yup"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { @@ -26,31 +26,42 @@ enum TabSections { Settings = "settings" } -const formSchema = yup.object({ - signUpMode: yup - .string() - .oneOf(["disabled", "invite-only", "anyone"]) - .required(), - allowedSignUpDomain: yup.string().optional() +enum SignUpModes { + Disabled = "disabled", + InviteOnly = "invite-only", + Anyone = "anyone" +} + +const getSignUpMode = (isSignUpEnabled: boolean, isInviteOnly: boolean) => { + if (isSignUpEnabled) { + if (isInviteOnly) return SignUpModes.InviteOnly; + return SignUpModes.Anyone; + } + return SignUpModes.Disabled; +}; + +const formSchema = z.object({ + signUpMode: z.nativeEnum(SignUpModes), + allowedSignUpDomain: z.string().optional() }); -type TDashboardForm = yup.InferType; - +type TDashboardForm = z.infer; export const AdminDashboardPage = () => { const router = useRouter(); const data = useServerConfig(); const { config } = data; - const signUpStatus = config.allowSignUp - ? config.inviteOnlySignUp && "invite-only" - : "disabled"; - - const signUpType = signUpStatus || "anyone"; - - const { control, handleSubmit, watch } = useForm({ - resolver: yupResolver(formSchema), - defaultValues: { - signUpMode: signUpType, + const { + control, + handleSubmit, + watch, + getValues, + formState: { isSubmitting, isDirty } + } = useForm({ + resolver: zodResolver(formSchema), + values: { + // eslint-disable-next-line + signUpMode: getSignUpMode(config.allowSignUp, config.inviteOnlySignUp), allowedSignUpDomain: config.allowedSignUpDomain } }); @@ -59,12 +70,13 @@ export const AdminDashboardPage = () => { const { user, isLoading: isUserLoading } = useUser(); const { orgs } = useOrganization(); - const { mutate: updateServerConfig } = useUpdateServerConfig(); + const { mutateAsync: updateServerConfig } = useUpdateServerConfig(); const { createNotification } = useNotificationContext(); const isNotAllowed = !user?.superAdmin; + // TODO(akhilmhdh): on nextjs 14 roadmap this will be properly addressed with context split useEffect(() => { if (isNotAllowed && !isUserLoading) { if (orgs?.length) { @@ -77,13 +89,11 @@ export const AdminDashboardPage = () => { const onFormSubmit = async (formData: TDashboardForm) => { try { const { signUpMode, allowedSignUpDomain } = formData; - await updateServerConfig({ - allowSignUp: signUpMode !== "disabled", - inviteOnlySignUp: signUpMode === "invite-only", - allowedSignUpDomain: signUpMode === "anyone" ? allowedSignUpDomain : "" + allowSignUp: signUpMode !== SignUpModes.Disabled, + inviteOnlySignUp: signUpMode === SignUpModes.InviteOnly, + allowedSignUpDomain: signUpMode === SignUpModes.Anyone ? allowedSignUpDomain : "" }); - createNotification({ text: "Successfully changed sign up setting.", type: "success" @@ -97,8 +107,7 @@ export const AdminDashboardPage = () => { } }; - - + console.log(isDirty,getValues()); return (
@@ -142,15 +151,14 @@ export const AdminDashboardPage = () => { onValueChange={(e) => onChange(e)} {...field} > - Disabled - Invite Only - Anyone + Disabled + Invite Only + Anyone )} />
- {signupMode === "anyone" && (
@@ -177,8 +185,11 @@ export const AdminDashboardPage = () => { />
)} - - From 64fbe4161cb2529be250e3413d72249edd9bcbc5 Mon Sep 17 00:00:00 2001 From: "Salman K.A.A" <40920317+Salman2301@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:27:04 +0530 Subject: [PATCH 10/38] docs(sdk): fix typo PORT --- docs/documentation/guides/node.mdx | 2 +- docs/sdks/languages/node.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/documentation/guides/node.mdx b/docs/documentation/guides/node.mdx index 1e00aed99..8b78cde5e 100644 --- a/docs/documentation/guides/node.mdx +++ b/docs/documentation/guides/node.mdx @@ -75,7 +75,7 @@ app.get("/", async (req, res) => { app.listen(PORT, async () => { // initialize client - console.log(`App listening on port ${port}`); + console.log(`App listening on port ${PORT}`); }); ``` diff --git a/docs/sdks/languages/node.mdx b/docs/sdks/languages/node.mdx index faabd794c..7712caaf1 100644 --- a/docs/sdks/languages/node.mdx +++ b/docs/sdks/languages/node.mdx @@ -42,7 +42,7 @@ app.get("/", async (req, res) => { app.listen(PORT, async () => { // initialize client - console.log(`App listening on port ${port}`); + console.log(`App listening on port ${PORT}`); }); ``` From fed022ed09c93e5208b2ac22168c26042bff7642 Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Thu, 22 Feb 2024 13:09:51 +0530 Subject: [PATCH 11/38] feat: removed unused inviteSignup flag --- ...=> 20240222073748_admin-signup-control.ts} | 7 ------- backend/src/db/schemas/super-admin.ts | 1 - backend/src/db/seeds/1-user.ts | 2 +- backend/src/server/routes/v1/admin-router.ts | 3 +-- backend/src/server/routes/v3/signup-router.ts | 7 ------- .../super-admin/super-admin-service.ts | 2 +- frontend/src/hooks/api/admin/types.ts | 3 +-- frontend/src/hooks/api/serverDetails/types.ts | 3 +-- .../components/InitialStep/InitialStep.tsx | 2 +- .../admin/DashboardPage/DashboardPage.tsx | 20 ++++--------------- 10 files changed, 10 insertions(+), 40 deletions(-) rename backend/src/db/migrations/{20240205200732_invite-only.ts => 20240222073748_admin-signup-control.ts} (70%) diff --git a/backend/src/db/migrations/20240205200732_invite-only.ts b/backend/src/db/migrations/20240222073748_admin-signup-control.ts similarity index 70% rename from backend/src/db/migrations/20240205200732_invite-only.ts rename to backend/src/db/migrations/20240222073748_admin-signup-control.ts index 4bebab17f..c52f753c0 100644 --- a/backend/src/db/migrations/20240205200732_invite-only.ts +++ b/backend/src/db/migrations/20240222073748_admin-signup-control.ts @@ -6,19 +6,12 @@ export async function up(knex: Knex): Promise { const isTablePresent = await knex.schema.hasTable(TableName.SuperAdmin); if (isTablePresent) { await knex.schema.alterTable(TableName.SuperAdmin, (t) => { - t.boolean("inviteOnlySignUp").defaultTo(false); t.string("allowedSignUpDomain"); }); } } export async function down(knex: Knex): Promise { - if (await knex.schema.hasColumn(TableName.SuperAdmin, "inviteOnlySignUp")) { - await knex.schema.alterTable(TableName.SuperAdmin, (t) => { - t.dropColumn("inviteOnlySignUp"); - }); - } - if (await knex.schema.hasColumn(TableName.SuperAdmin, "allowedSignUpDomain")) { await knex.schema.alterTable(TableName.SuperAdmin, (t) => { t.dropColumn("allowedSignUpDomain"); diff --git a/backend/src/db/schemas/super-admin.ts b/backend/src/db/schemas/super-admin.ts index 707ec60e9..b4631195b 100644 --- a/backend/src/db/schemas/super-admin.ts +++ b/backend/src/db/schemas/super-admin.ts @@ -13,7 +13,6 @@ export const SuperAdminSchema = z.object({ allowSignUp: z.boolean().default(true).nullable().optional(), createdAt: z.date(), updatedAt: z.date(), - inviteOnlySignUp: z.boolean().default(false).nullable().optional(), allowedSignUpDomain: z.string().nullable().optional() }); diff --git a/backend/src/db/seeds/1-user.ts b/backend/src/db/seeds/1-user.ts index 0da9be9b1..ca0042a98 100644 --- a/backend/src/db/seeds/1-user.ts +++ b/backend/src/db/seeds/1-user.ts @@ -9,7 +9,7 @@ export async function seed(knex: Knex): Promise { await knex(TableName.Users).del(); await knex(TableName.UserEncryptionKey).del(); await knex(TableName.SuperAdmin).del(); - await knex(TableName.SuperAdmin).insert([{ initialized: true, allowSignUp: true, inviteOnlySignUp: false }]); + await knex(TableName.SuperAdmin).insert([{ initialized: true, allowSignUp: true }]); // Inserts seed entries const [user] = await knex(TableName.Users) .insert([ diff --git a/backend/src/server/routes/v1/admin-router.ts b/backend/src/server/routes/v1/admin-router.ts index 9552c10eb..2f26893d8 100644 --- a/backend/src/server/routes/v1/admin-router.ts +++ b/backend/src/server/routes/v1/admin-router.ts @@ -32,8 +32,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => { schema: { body: z.object({ allowSignUp: z.boolean().optional(), - inviteOnlySignUp: z.boolean().optional(), - allowedSignUpDomain: z.string().optional() + allowedSignUpDomain: z.string().optional().nullable() }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v3/signup-router.ts b/backend/src/server/routes/v3/signup-router.ts index ad3b3bc8f..b04b88d2f 100644 --- a/backend/src/server/routes/v3/signup-router.ts +++ b/backend/src/server/routes/v3/signup-router.ts @@ -187,13 +187,6 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { if (!userAgent) throw new Error("user agent header is required"); const appCfg = getConfig(); - const serverCfg = await getServerCfg(); - if (!serverCfg.allowSignUp) { - throw new BadRequestError({ - message: "Sign up is disabled!" - }); - } - const { user, accessToken, refreshToken } = await server.services.signup.completeAccountInvite({ ...req.body, ip: req.realIp, diff --git a/backend/src/services/super-admin/super-admin-service.ts b/backend/src/services/super-admin/super-admin-service.ts index b15d95e56..1144bd414 100644 --- a/backend/src/services/super-admin/super-admin-service.ts +++ b/backend/src/services/super-admin/super-admin-service.ts @@ -33,7 +33,7 @@ export const superAdminServiceFactory = ({ const serverCfg = await serverCfgDAL.findOne({}); if (serverCfg) return; - const newCfg = await serverCfgDAL.create({ initialized: false, allowSignUp: true, inviteOnlySignUp: false }); + const newCfg = await serverCfgDAL.create({ initialized: false, allowSignUp: true }); return newCfg; }; diff --git a/frontend/src/hooks/api/admin/types.ts b/frontend/src/hooks/api/admin/types.ts index e28e7f972..c7022a1d7 100644 --- a/frontend/src/hooks/api/admin/types.ts +++ b/frontend/src/hooks/api/admin/types.ts @@ -1,8 +1,7 @@ export type TServerConfig = { initialized: boolean; allowSignUp: boolean; - inviteOnlySignUp: boolean; - allowedSignUpDomain?: string; + allowedSignUpDomain?: string | null; isMigrationModeOn?: boolean; }; diff --git a/frontend/src/hooks/api/serverDetails/types.ts b/frontend/src/hooks/api/serverDetails/types.ts index 32cc92ae1..af7bc5b28 100644 --- a/frontend/src/hooks/api/serverDetails/types.ts +++ b/frontend/src/hooks/api/serverDetails/types.ts @@ -2,7 +2,6 @@ export type ServerStatus = { date: string; message: string; emailConfigured: boolean; - inviteOnlySignup: boolean; secretScanningConfigured: boolean redisConfigured: boolean -}; \ No newline at end of file +}; diff --git a/frontend/src/views/Login/components/InitialStep/InitialStep.tsx b/frontend/src/views/Login/components/InitialStep/InitialStep.tsx index 16541c9a0..bbef55751 100644 --- a/frontend/src/views/Login/components/InitialStep/InitialStep.tsx +++ b/frontend/src/views/Login/components/InitialStep/InitialStep.tsx @@ -226,7 +226,7 @@ export const InitialStep = ({ setStep, email, setEmail, password, setPassword }:
{!isLoading && loginError && } - {config.allowSignUp && !config.inviteOnlySignUp ? ( + {config.allowSignUp ? (
diff --git a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx index afaa53d87..2c7e3662a 100644 --- a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx +++ b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx @@ -28,21 +28,12 @@ enum TabSections { enum SignUpModes { Disabled = "disabled", - InviteOnly = "invite-only", Anyone = "anyone" } -const getSignUpMode = (isSignUpEnabled: boolean, isInviteOnly: boolean) => { - if (isSignUpEnabled) { - if (isInviteOnly) return SignUpModes.InviteOnly; - return SignUpModes.Anyone; - } - return SignUpModes.Disabled; -}; - const formSchema = z.object({ signUpMode: z.nativeEnum(SignUpModes), - allowedSignUpDomain: z.string().optional() + allowedSignUpDomain: z.string().optional().nullable() }); type TDashboardForm = z.infer; @@ -55,13 +46,12 @@ export const AdminDashboardPage = () => { control, handleSubmit, watch, - getValues, formState: { isSubmitting, isDirty } } = useForm({ resolver: zodResolver(formSchema), values: { // eslint-disable-next-line - signUpMode: getSignUpMode(config.allowSignUp, config.inviteOnlySignUp), + signUpMode: config.allowSignUp ? SignUpModes.Anyone : SignUpModes.Disabled, allowedSignUpDomain: config.allowedSignUpDomain } }); @@ -91,8 +81,7 @@ export const AdminDashboardPage = () => { const { signUpMode, allowedSignUpDomain } = formData; await updateServerConfig({ allowSignUp: signUpMode !== SignUpModes.Disabled, - inviteOnlySignUp: signUpMode === SignUpModes.InviteOnly, - allowedSignUpDomain: signUpMode === SignUpModes.Anyone ? allowedSignUpDomain : "" + allowedSignUpDomain: signUpMode === SignUpModes.Anyone ? allowedSignUpDomain : null }); createNotification({ text: "Successfully changed sign up setting.", @@ -107,7 +96,6 @@ export const AdminDashboardPage = () => { } }; - console.log(isDirty,getValues()); return (
@@ -152,7 +140,6 @@ export const AdminDashboardPage = () => { {...field} > Disabled - Invite Only Anyone @@ -177,6 +164,7 @@ export const AdminDashboardPage = () => { > } /> From 26482c6b0a6bdbfde95ba32ffb947f643edcf846 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Thu, 22 Feb 2024 07:46:48 +0000 Subject: [PATCH 12/38] fix: upgrade mysql2 from 3.6.5 to 3.9.1 Snyk has created this PR to upgrade mysql2 from 3.6.5 to 3.9.1. See this package in npm: https://www.npmjs.com/package/mysql2 See this project in Snyk: https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr --- backend/package-lock.json | 8 ++++---- backend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index fc6553745..35faf9534 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -45,7 +45,7 @@ "knex": "^3.0.1", "libsodium-wrappers": "^0.7.13", "lodash.isequal": "^4.5.0", - "mysql2": "^3.6.5", + "mysql2": "^3.9.1", "nanoid": "^5.0.4", "node-cache": "^5.1.2", "nodemailer": "^6.9.9", @@ -9112,9 +9112,9 @@ } }, "node_modules/mysql2": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.5.tgz", - "integrity": "sha512-pS/KqIb0xlXmtmqEuTvBXTmLoQ5LmAz5NW/r8UyQ1ldvnprNEj3P9GbmuQQ2J0A4LO+ynotGi6TbscPa8OUb+w==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz", + "integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==", "dependencies": { "denque": "^2.1.0", "generate-function": "^2.3.1", diff --git a/backend/package.json b/backend/package.json index 4921d7f30..cc816d5e9 100644 --- a/backend/package.json +++ b/backend/package.json @@ -106,7 +106,7 @@ "knex": "^3.0.1", "libsodium-wrappers": "^0.7.13", "lodash.isequal": "^4.5.0", - "mysql2": "^3.6.5", + "mysql2": "^3.9.1", "nanoid": "^5.0.4", "node-cache": "^5.1.2", "nodemailer": "^6.9.9", From 49f7780e52973b0e4a4a608628003791c597c300 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Thu, 22 Feb 2024 07:46:52 +0000 Subject: [PATCH 13/38] fix: upgrade bullmq from 5.1.1 to 5.1.6 Snyk has created this PR to upgrade bullmq from 5.1.1 to 5.1.6. See this package in npm: https://www.npmjs.com/package/bullmq See this project in Snyk: https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr --- backend/package-lock.json | 10 +++++----- backend/package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index fc6553745..e7f8c7feb 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -33,7 +33,7 @@ "axios": "^1.6.4", "axios-retry": "^4.0.0", "bcrypt": "^5.1.1", - "bullmq": "^5.1.1", + "bullmq": "^5.1.6", "dotenv": "^16.3.1", "fastify": "^4.24.3", "fastify-plugin": "^4.5.1", @@ -5472,15 +5472,15 @@ } }, "node_modules/bullmq": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.1.1.tgz", - "integrity": "sha512-j3zbNEQWsyHjpqGWiem2XBfmxAjYcArbwsmGlkM1E9MAVcrqB5hQUsXmyy9gEBAdL+PVotMICr7xTquR4Y2sKQ==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.1.6.tgz", + "integrity": "sha512-VkLfig+xm4U3hc4QChzuuAy0NGQ9dfPB8o54hmcZHCX9ofp0Zn6bEY+W3Ytkk76eYwPAgXfywDBlAb2Unjl1Rg==", "dependencies": { "cron-parser": "^4.6.0", "glob": "^8.0.3", "ioredis": "^5.3.2", "lodash": "^4.17.21", - "msgpackr": "^1.6.2", + "msgpackr": "^1.10.1", "node-abort-controller": "^3.1.1", "semver": "^7.5.4", "tslib": "^2.0.0", diff --git a/backend/package.json b/backend/package.json index 4921d7f30..74e627616 100644 --- a/backend/package.json +++ b/backend/package.json @@ -94,7 +94,7 @@ "axios": "^1.6.4", "axios-retry": "^4.0.0", "bcrypt": "^5.1.1", - "bullmq": "^5.1.1", + "bullmq": "^5.1.6", "dotenv": "^16.3.1", "fastify": "^4.24.3", "fastify-plugin": "^4.5.1", From adc10cf67535ad56b2dd10611262e597aa98999a Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Thu, 22 Feb 2024 07:46:55 +0000 Subject: [PATCH 14/38] fix: upgrade zod-to-json-schema from 3.22.0 to 3.22.4 Snyk has created this PR to upgrade zod-to-json-schema from 3.22.0 to 3.22.4. See this package in npm: https://www.npmjs.com/package/zod-to-json-schema See this project in Snyk: https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr --- backend/package-lock.json | 8 ++++---- backend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index fc6553745..876951b2b 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -63,7 +63,7 @@ "tweetnacl-util": "^0.15.1", "uuid": "^9.0.1", "zod": "^3.22.4", - "zod-to-json-schema": "^3.22.0" + "zod-to-json-schema": "^3.22.4" }, "devDependencies": { "@types/bcrypt": "^5.0.2", @@ -13812,9 +13812,9 @@ } }, "node_modules/zod-to-json-schema": { - "version": "3.22.0", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.22.0.tgz", - "integrity": "sha512-XQr8EwxPMzJGhoR+d/nRFWdi15VaZ+R5Uhssm+Xx5yS30xCpuutfKRm4rerE0SK9j2dWB5Z3FvDD0w8WMVGzkA==", + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.22.4.tgz", + "integrity": "sha512-2Ed5dJ+n/O3cU383xSY28cuVi0BCQhF8nYqWU5paEpl7fVdqdAmiLdqLyfblbNdfOFwFfi/mqU4O1pwc60iBhQ==", "peerDependencies": { "zod": "^3.22.4" } diff --git a/backend/package.json b/backend/package.json index 4921d7f30..9856db7ee 100644 --- a/backend/package.json +++ b/backend/package.json @@ -124,6 +124,6 @@ "tweetnacl-util": "^0.15.1", "uuid": "^9.0.1", "zod": "^3.22.4", - "zod-to-json-schema": "^3.22.0" + "zod-to-json-schema": "^3.22.4" } } From a10129e7504d023fde0e5cf2ec5699dfd7ab616d Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Thu, 22 Feb 2024 07:46:59 +0000 Subject: [PATCH 15/38] fix: upgrade @fastify/swagger from 8.12.0 to 8.14.0 Snyk has created this PR to upgrade @fastify/swagger from 8.12.0 to 8.14.0. See this package in npm: https://www.npmjs.com/package/@fastify/swagger See this project in Snyk: https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr --- backend/package-lock.json | 8 ++++---- backend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index fc6553745..0ea76f3e1 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -19,7 +19,7 @@ "@fastify/passport": "^2.4.0", "@fastify/rate-limit": "^9.0.0", "@fastify/session": "^10.7.0", - "@fastify/swagger": "^8.12.0", + "@fastify/swagger": "^8.14.0", "@fastify/swagger-ui": "^2.1.0", "@node-saml/passport-saml": "^4.0.4", "@octokit/rest": "^20.0.2", @@ -1790,9 +1790,9 @@ } }, "node_modules/@fastify/swagger": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/@fastify/swagger/-/swagger-8.12.0.tgz", - "integrity": "sha512-IMRc0xYuzRvtFDMuaWHyVbvM7CuAi0g3o2jaVgLDvETXPrXWAMWsHYR5niIdWBDPgGUq+soHkag1DKXyhPDB0w==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@fastify/swagger/-/swagger-8.14.0.tgz", + "integrity": "sha512-sGiznEb3rl6pKGGUZ+JmfI7ct5cwbTQGo+IjewaTvtzfrshnryu4dZwEsjw0YHABpBA+kCz3kpRaHB7qpa67jg==", "dependencies": { "fastify-plugin": "^4.0.0", "json-schema-resolver": "^2.0.0", diff --git a/backend/package.json b/backend/package.json index 4921d7f30..5cf11d95a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -80,7 +80,7 @@ "@fastify/passport": "^2.4.0", "@fastify/rate-limit": "^9.0.0", "@fastify/session": "^10.7.0", - "@fastify/swagger": "^8.12.0", + "@fastify/swagger": "^8.14.0", "@fastify/swagger-ui": "^2.1.0", "@node-saml/passport-saml": "^4.0.4", "@octokit/rest": "^20.0.2", From 57be73c17eaf6033374ee191a474f529ec542469 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Thu, 22 Feb 2024 07:47:03 +0000 Subject: [PATCH 16/38] fix: upgrade fastify from 4.24.3 to 4.26.0 Snyk has created this PR to upgrade fastify from 4.24.3 to 4.26.0. See this package in npm: https://www.npmjs.com/package/fastify See this project in Snyk: https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr --- backend/package-lock.json | 35 +++++++++++++++++++++++++---------- backend/package.json | 2 +- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index fc6553745..6e7862c33 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -35,7 +35,7 @@ "bcrypt": "^5.1.1", "bullmq": "^5.1.1", "dotenv": "^16.3.1", - "fastify": "^4.24.3", + "fastify": "^4.26.0", "fastify-plugin": "^4.5.1", "handlebars": "^4.7.8", "ioredis": "^5.3.2", @@ -6972,9 +6972,19 @@ } }, "node_modules/fastify": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.24.3.tgz", - "integrity": "sha512-6HHJ+R2x2LS3y1PqxnwEIjOTZxFl+8h4kSC/TuDPXtA+v2JnV9yEtOsNSKK1RMD7sIR2y1ZsA4BEFaid/cK5pg==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.26.0.tgz", + "integrity": "sha512-Fq/7ziWKc6pYLYLIlCRaqJqEVTIZ5tZYfcW/mDK2AQ9v/sqjGFpj0On0/7hU50kbPVjLO4de+larPA1WwPZSfw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], "dependencies": { "@fastify/ajv-compiler": "^3.5.0", "@fastify/error": "^3.4.0", @@ -6983,10 +6993,10 @@ "avvio": "^8.2.1", "fast-content-type-parse": "^1.1.0", "fast-json-stringify": "^5.8.0", - "find-my-way": "^7.7.0", + "find-my-way": "^8.0.0", "light-my-request": "^5.11.0", - "pino": "^8.16.0", - "process-warning": "^2.2.0", + "pino": "^8.17.0", + "process-warning": "^3.0.0", "proxy-addr": "^2.0.7", "rfdc": "^1.3.0", "secure-json-parse": "^2.7.0", @@ -6999,6 +7009,11 @@ "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz", "integrity": "sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==" }, + "node_modules/fastify/node_modules/process-warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==" + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -7062,9 +7077,9 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/find-my-way": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-7.7.0.tgz", - "integrity": "sha512-+SrHpvQ52Q6W9f3wJoJBbAQULJuNEEQwBvlvYwACDhBTLOTMiQ0HYWh4+vC3OivGP2ENcTI1oKlFA2OepJNjhQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.1.0.tgz", + "integrity": "sha512-41QwjCGcVTODUmLLqTMeoHeiozbMXYMAE1CKFiDyi9zVZ2Vjh0yz3MF0WQZoIb+cmzP/XlbFjlF2NtJmvZHznA==", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-querystring": "^1.0.0", diff --git a/backend/package.json b/backend/package.json index 4921d7f30..715be7e86 100644 --- a/backend/package.json +++ b/backend/package.json @@ -96,7 +96,7 @@ "bcrypt": "^5.1.1", "bullmq": "^5.1.1", "dotenv": "^16.3.1", - "fastify": "^4.24.3", + "fastify": "^4.26.0", "fastify-plugin": "^4.5.1", "handlebars": "^4.7.8", "ioredis": "^5.3.2", From be49de5f345c952130b00c4a62b3fcd1aa67c5b7 Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Thu, 22 Feb 2024 17:09:33 +0530 Subject: [PATCH 17/38] fix(telemetry): added back email for telemetry when using service token --- backend/src/ee/routes/v1/scim-router.ts | 2 +- .../services/permission/permission-service.ts | 2 ++ .../server/plugins/auth/inject-identity.ts | 2 +- backend/src/server/routes/v3/secret-router.ts | 2 +- .../service-token/service-token-dal.ts | 28 +++++++++++++++++-- .../service-token/service-token-service.ts | 2 +- 6 files changed, 31 insertions(+), 7 deletions(-) diff --git a/backend/src/ee/routes/v1/scim-router.ts b/backend/src/ee/routes/v1/scim-router.ts index 095815212..80eed5231 100644 --- a/backend/src/ee/routes/v1/scim-router.ts +++ b/backend/src/ee/routes/v1/scim-router.ts @@ -5,7 +5,7 @@ import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; export const registerScimRouter = async (server: FastifyZodProvider) => { - server.addContentTypeParser("application/scim+json", { parseAs: "string" }, function (req, body, done) { + server.addContentTypeParser("application/scim+json", { parseAs: "string" }, (_, body, done) => { try { const strBody = body instanceof Buffer ? body.toString() : body; diff --git a/backend/src/ee/services/permission/permission-service.ts b/backend/src/ee/services/permission/permission-service.ts index 4735312e4..67db2473c 100644 --- a/backend/src/ee/services/permission/permission-service.ts +++ b/backend/src/ee/services/permission/permission-service.ts @@ -177,6 +177,8 @@ export const permissionServiceFactory = ({ const getServiceTokenProjectPermission = async (serviceTokenId: string, projectId: string) => { const serviceToken = await serviceTokenDAL.findById(serviceTokenId); + if (!serviceToken) throw new BadRequestError({ message: "Service token not found" }); + if (serviceToken.projectId !== projectId) throw new UnauthorizedError({ message: "Failed to find service authorization for given project" diff --git a/backend/src/server/plugins/auth/inject-identity.ts b/backend/src/server/plugins/auth/inject-identity.ts index cf8d9dea3..3a0a0ab39 100644 --- a/backend/src/server/plugins/auth/inject-identity.ts +++ b/backend/src/server/plugins/auth/inject-identity.ts @@ -27,7 +27,7 @@ export type TAuthMode = } | { authMode: AuthMode.SERVICE_TOKEN; - serviceToken: TServiceTokens; + serviceToken: TServiceTokens & { createdByEmail: string }; actor: ActorType.SERVICE; serviceTokenId: string; } diff --git a/backend/src/server/routes/v3/secret-router.ts b/backend/src/server/routes/v3/secret-router.ts index 1aac86205..1ba5b4e08 100644 --- a/backend/src/server/routes/v3/secret-router.ts +++ b/backend/src/server/routes/v3/secret-router.ts @@ -28,7 +28,7 @@ const getDistinctId = (req: FastifyRequest) => { return `identity-${req.auth.identityId}`; } if (req.auth.actor === ActorType.SERVICE) { - return `service-token-${req.auth.serviceToken.id}`; + return req.auth.serviceToken.createdByEmail || `service-token-${req.auth.serviceTokenId}`; // when user gets removed from system } return "unknown-auth-data"; }; diff --git a/backend/src/services/service-token/service-token-dal.ts b/backend/src/services/service-token/service-token-dal.ts index b94c7ee35..5d3fcc5c8 100644 --- a/backend/src/services/service-token/service-token-dal.ts +++ b/backend/src/services/service-token/service-token-dal.ts @@ -1,10 +1,32 @@ +import { Knex } from "knex"; + import { TDbClient } from "@app/db"; -import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { TableName, TUsers } from "@app/db/schemas"; +import { DatabaseError } from "@app/lib/errors"; +import { ormify, selectAllTableCols } from "@app/lib/knex"; export type TServiceTokenDALFactory = ReturnType; export const serviceTokenDALFactory = (db: TDbClient) => { const stOrm = ormify(db, TableName.ServiceToken); - return stOrm; + + const findById = async (id: string, tx?: Knex) => { + try { + const doc = await (tx || db)(TableName.ServiceToken) + .leftJoin( + TableName.Users, + `${TableName.Users}.id`, + db.raw(`${TableName.ServiceToken}."createdBy"::uuid`) + ) + .where(`${TableName.ServiceToken}.id`, id) + .select(selectAllTableCols(TableName.ServiceToken)) + .select(db.ref("email").withSchema(TableName.Users).as("createdByEmail")) + .first(); + return doc; + } catch (err) { + throw new DatabaseError({ error: err, name: "FindById" }); + } + }; + + return { ...stOrm, findById }; }; diff --git a/backend/src/services/service-token/service-token-service.ts b/backend/src/services/service-token/service-token-service.ts index 76d33bd6b..cce0d3780 100644 --- a/backend/src/services/service-token/service-token-service.ts +++ b/backend/src/services/service-token/service-token-service.ts @@ -142,7 +142,7 @@ export const serviceTokenServiceFactory = ({ const updatedToken = await serviceTokenDAL.updateById(serviceToken.id, { lastUsed: new Date() }); - return updatedToken; + return { ...serviceToken, lastUsed: updatedToken.lastUsed }; }; return { From f1f2d62993b9d888868db46e74d13d15eda6920b Mon Sep 17 00:00:00 2001 From: Nithish Date: Thu, 22 Feb 2024 22:32:58 +0530 Subject: [PATCH 18/38] fix: access member returns empty results when search using upper case letters. --- .../components/OrgMembersSection/OrgMembersTable.tsx | 8 ++++---- .../components/MemberListTab/MemberListTab.tsx | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/src/views/Org/MembersPage/components/OrgMembersTab/components/OrgMembersSection/OrgMembersTable.tsx b/frontend/src/views/Org/MembersPage/components/OrgMembersTab/components/OrgMembersSection/OrgMembersTable.tsx index 5469bbf05..b3a3bd73e 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgMembersTab/components/OrgMembersSection/OrgMembersTable.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgMembersTab/components/OrgMembersSection/OrgMembersTable.tsx @@ -141,10 +141,10 @@ export const OrgMembersTable = ({ handlePopUpOpen, setCompleteInviteLink }: Prop () => members?.filter( ({ user: u, inviteEmail }) => - u?.firstName?.toLowerCase().includes(searchMemberFilter) || - u?.lastName?.toLowerCase().includes(searchMemberFilter) || - u?.email?.toLowerCase().includes(searchMemberFilter) || - inviteEmail?.includes(searchMemberFilter) + u?.firstName?.toLowerCase().includes(searchMemberFilter.toLowerCase()) || + u?.lastName?.toLowerCase().includes(searchMemberFilter.toLowerCase()) || + u?.email?.toLowerCase().includes(searchMemberFilter.toLowerCase()) || + inviteEmail?.includes(searchMemberFilter.toLowerCase()) ), [members, searchMemberFilter] ); diff --git a/frontend/src/views/Project/MembersPage/components/MemberListTab/MemberListTab.tsx b/frontend/src/views/Project/MembersPage/components/MemberListTab/MemberListTab.tsx index 76f97741d..6211449fd 100644 --- a/frontend/src/views/Project/MembersPage/components/MemberListTab/MemberListTab.tsx +++ b/frontend/src/views/Project/MembersPage/components/MemberListTab/MemberListTab.tsx @@ -200,10 +200,10 @@ export const MemberListTab = () => { () => members?.filter( ({ user: u, inviteEmail }) => - u?.firstName?.toLowerCase().includes(searchMemberFilter) || - u?.lastName?.toLowerCase().includes(searchMemberFilter) || - u?.email?.toLowerCase().includes(searchMemberFilter) || - inviteEmail?.includes(searchMemberFilter) + u?.firstName?.toLowerCase().includes(searchMemberFilter.toLowerCase()) || + u?.lastName?.toLowerCase().includes(searchMemberFilter.toLowerCase()) || + u?.email?.toLowerCase().includes(searchMemberFilter.toLowerCase()) || + inviteEmail?.includes(searchMemberFilter.toLowerCase()) ), [members, searchMemberFilter] ); From 0b258e39189528e341894c66e5f754a8820efbdf Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Thu, 22 Feb 2024 15:06:00 -0500 Subject: [PATCH 19/38] make clear service token with null creator --- backend/src/server/routes/v3/secret-router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/server/routes/v3/secret-router.ts b/backend/src/server/routes/v3/secret-router.ts index 1ba5b4e08..6bbb437ad 100644 --- a/backend/src/server/routes/v3/secret-router.ts +++ b/backend/src/server/routes/v3/secret-router.ts @@ -28,7 +28,7 @@ const getDistinctId = (req: FastifyRequest) => { return `identity-${req.auth.identityId}`; } if (req.auth.actor === ActorType.SERVICE) { - return req.auth.serviceToken.createdByEmail || `service-token-${req.auth.serviceTokenId}`; // when user gets removed from system + return req.auth.serviceToken.createdByEmail || `service-token-null-creator-${req.auth.serviceTokenId}`; // when user gets removed from system } return "unknown-auth-data"; }; From a831a7d848eca3a57c76788bc26c223bc314f196 Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Thu, 22 Feb 2024 15:35:09 -0500 Subject: [PATCH 20/38] small typos and update migration timestamp --- ...up-control.ts => 20240222201806_admin-signup-control.ts} | 0 backend/src/server/routes/v3/signup-router.ts | 6 +++--- backend/src/services/auth/auth-login-service.ts | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) rename backend/src/db/migrations/{20240222073748_admin-signup-control.ts => 20240222201806_admin-signup-control.ts} (100%) diff --git a/backend/src/db/migrations/20240222073748_admin-signup-control.ts b/backend/src/db/migrations/20240222201806_admin-signup-control.ts similarity index 100% rename from backend/src/db/migrations/20240222073748_admin-signup-control.ts rename to backend/src/db/migrations/20240222201806_admin-signup-control.ts diff --git a/backend/src/server/routes/v3/signup-router.ts b/backend/src/server/routes/v3/signup-router.ts index d1ec800f9..24387d2f5 100644 --- a/backend/src/server/routes/v3/signup-router.ts +++ b/backend/src/server/routes/v3/signup-router.ts @@ -30,7 +30,7 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { const serverCfg = await getServerCfg(); if (!serverCfg.allowSignUp) { throw new BadRequestError({ - message: "Sign up is disabled!" + message: "Sign up is disabled" }); } @@ -71,7 +71,7 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { const serverCfg = await getServerCfg(); if (!serverCfg.allowSignUp) { throw new BadRequestError({ - message: "Sign up is disabled!" + message: "Sign up is disabled" }); } @@ -120,7 +120,7 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { const serverCfg = await getServerCfg(); if (!serverCfg.allowSignUp) { throw new BadRequestError({ - message: "Sign up is disabled!" + message: "Sign up is disabled" }); } diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index ee2cc5995..11ce57735 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -270,7 +270,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }: if (!user) { // Create a new user based on oAuth - if (!serverCfg?.allowSignUp) throw new BadRequestError({ message: "Sign Up disabled", name: "Oauth 2 login" }); + if (!serverCfg?.allowSignUp) throw new BadRequestError({ message: "Sign up disabled", name: "Oauth 2 login" }); if (serverCfg?.allowedSignUpDomain) { const domain = email.split("@")[1]; @@ -281,9 +281,8 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }: name: "Oauth 2 login" }); } - + user = await userDAL.create({ email, firstName, lastName, authMethods: [authMethod], isGhost: false }); - } const isLinkingRequired = !user?.authMethods?.includes(authMethod); const isUserCompleted = user.isAccepted; From ff4b94385402b8c22722b2aa99f68b5af585db0b Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Thu, 22 Feb 2024 16:04:12 -0500 Subject: [PATCH 21/38] fix admin signup phrasing --- frontend/src/views/admin/DashboardPage/DashboardPage.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx index 2c7e3662a..8231d2924 100644 --- a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx +++ b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx @@ -121,7 +121,7 @@ export const AdminDashboardPage = () => { >
- Allow user to Sign Up + Allow user sign up
{ {signupMode === "anyone" && (
- Allow email with only specific domain(s) + Restrict sign up by email domain(s)
{ name="allowedSignUpDomain" render={({ field, fieldState: { error } }) => ( { } /> From 387094aa276eba691c28fb57a9b92c063817fe0e Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Thu, 22 Feb 2024 23:06:24 +0100 Subject: [PATCH 22/38] Allow deleting project members even on V1 projects --- .../project-membership/project-membership-service.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/backend/src/services/project-membership/project-membership-service.ts b/backend/src/services/project-membership/project-membership-service.ts index e96247c97..5f03e9a6e 100644 --- a/backend/src/services/project-membership/project-membership-service.ts +++ b/backend/src/services/project-membership/project-membership-service.ts @@ -419,9 +419,10 @@ export const projectMembershipServiceFactory = ({ }); } - if (project.version === ProjectVersion.V1) { - throw new BadRequestError({ message: "Please upgrade your project on your dashboard" }); - } + // This endpoint should be usable by normal and upgraded projects. + // if (project.version === ProjectVersion.V1) { + // throw new BadRequestError({ message: "Please upgrade your project on your dashboard" }); + // } const projectMembers = await projectMembershipDAL.findMembershipsByEmail(projectId, emails); From acf8a54abb8e74ff6b027f9e384d5bedfd8fc91f Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Thu, 22 Feb 2024 23:06:55 +0100 Subject: [PATCH 23/38] Fix service tokens not working after upgrade --- backend/src/services/project/project-fns.ts | 5 +++-- backend/src/services/project/project-queue.ts | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/backend/src/services/project/project-fns.ts b/backend/src/services/project/project-fns.ts index 0f1f5a08d..3ac75248d 100644 --- a/backend/src/services/project/project-fns.ts +++ b/backend/src/services/project/project-fns.ts @@ -33,11 +33,12 @@ export const assignWorkspaceKeysToMembers = ({ members, decryptKey, userPrivateK type TCreateProjectKeyDTO = { publicKey: string; privateKey: string; + plainProjectKey?: string; }; -export const createProjectKey = ({ publicKey, privateKey }: TCreateProjectKeyDTO) => { +export const createProjectKey = ({ publicKey, privateKey, plainProjectKey }: TCreateProjectKeyDTO) => { // 3. Create a random key that we'll use as the project key. - const randomBytes = crypto.randomBytes(16).toString("hex"); + const randomBytes = plainProjectKey || crypto.randomBytes(16).toString("hex"); // 4. Encrypt the project key with the users key pair. const { ciphertext: encryptedProjectKey, nonce: encryptedProjectKeyIv } = encryptAsymmetric( diff --git a/backend/src/services/project/project-queue.ts b/backend/src/services/project/project-queue.ts index 616aa1aef..efc795cae 100644 --- a/backend/src/services/project/project-queue.ts +++ b/backend/src/services/project/project-queue.ts @@ -122,6 +122,13 @@ export const projectQueueFactory = ({ tag: data.encryptedPrivateKey.encryptedKeyTag }); + const decryptedPlainProjectKey = decryptAsymmetric({ + ciphertext: oldProjectKey.encryptedKey, + nonce: oldProjectKey.nonce, + publicKey: oldProjectKey.sender.publicKey, + privateKey: userPrivateKey + }); + const projectEnvs = await projectEnvDAL.find({ projectId: project.id }); @@ -199,6 +206,7 @@ export const projectQueueFactory = ({ // Create a project key const { key: newEncryptedProjectKey, iv: newEncryptedProjectKeyIv } = createProjectKey({ + plainProjectKey: decryptedPlainProjectKey, publicKey: ghostUser.keys.publicKey, privateKey: ghostUser.keys.plainPrivateKey }); From 5c988c2cd55ac9fd08369eddd26bb571232d9563 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Thu, 22 Feb 2024 23:07:07 +0100 Subject: [PATCH 24/38] Docs --- docs/api-reference/endpoints/workspaces/create-workspace.mdx | 2 +- docs/api-reference/endpoints/workspaces/delete-workspace.mdx | 2 +- docs/api-reference/endpoints/workspaces/get-workspace.mdx | 2 +- docs/api-reference/endpoints/workspaces/update-workspace.mdx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/api-reference/endpoints/workspaces/create-workspace.mdx b/docs/api-reference/endpoints/workspaces/create-workspace.mdx index ec3d09b81..a8a7d0430 100644 --- a/docs/api-reference/endpoints/workspaces/create-workspace.mdx +++ b/docs/api-reference/endpoints/workspaces/create-workspace.mdx @@ -1,4 +1,4 @@ --- -title: "Create Workspace" +title: "Create Project" openapi: "POST /api/v2/workspace" --- \ No newline at end of file diff --git a/docs/api-reference/endpoints/workspaces/delete-workspace.mdx b/docs/api-reference/endpoints/workspaces/delete-workspace.mdx index ca6cb8914..6b5675c4b 100644 --- a/docs/api-reference/endpoints/workspaces/delete-workspace.mdx +++ b/docs/api-reference/endpoints/workspaces/delete-workspace.mdx @@ -1,5 +1,5 @@ --- -title: "Delete Workspace" +title: "Delete Project" openapi: "DELETE /api/v1/workspace/{workspaceId}" --- diff --git a/docs/api-reference/endpoints/workspaces/get-workspace.mdx b/docs/api-reference/endpoints/workspaces/get-workspace.mdx index 2d27d9455..edd0a0276 100644 --- a/docs/api-reference/endpoints/workspaces/get-workspace.mdx +++ b/docs/api-reference/endpoints/workspaces/get-workspace.mdx @@ -1,4 +1,4 @@ --- -title: "Get Workspace" +title: "Get Project" openapi: "GET /api/v1/workspace/{workspaceId}" --- \ No newline at end of file diff --git a/docs/api-reference/endpoints/workspaces/update-workspace.mdx b/docs/api-reference/endpoints/workspaces/update-workspace.mdx index 81a6ec8ea..699e3e3af 100644 --- a/docs/api-reference/endpoints/workspaces/update-workspace.mdx +++ b/docs/api-reference/endpoints/workspaces/update-workspace.mdx @@ -1,4 +1,4 @@ --- -title: "Update Workspace" +title: "Update Project" openapi: "PATCH /api/v1/workspace/{workspaceId}" --- \ No newline at end of file From 28adb8f0ac1db9c5c7ed933c7faf38a735e73a0c Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Thu, 22 Feb 2024 23:12:41 +0100 Subject: [PATCH 25/38] Re-add upgrade popup --- .../SecretOverviewPage/SecretOverviewPage.tsx | 114 +++++++++--------- 1 file changed, 60 insertions(+), 54 deletions(-) diff --git a/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx b/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx index 66e026fca..3c6b38e0a 100644 --- a/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx +++ b/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx @@ -29,7 +29,7 @@ import { Tooltip, Tr } from "@app/components/v2"; -// import { UpgradeProjectAlert } from "@app/components/v2/UpgradeProjectAlert"; +import { UpgradeProjectAlert } from "@app/components/v2/UpgradeProjectAlert"; import { useOrganization, useWorkspace } from "@app/context"; import { useCreateFolder, @@ -40,8 +40,8 @@ import { useGetUserWsKey, useUpdateSecretV3 } from "@app/hooks/api"; +import { ProjectVersion } from "@app/hooks/api/workspace/types"; -// import { ProjectVersion } from "@app/hooks/api/workspace/types"; import { FolderBreadCrumbs } from "./components/FolderBreadCrumbs"; import { ProjectIndexSecretsSection } from "./components/ProjectIndexSecretsSection"; import { SecretOverviewFolderRow } from "./components/SecretOverviewFolderRow"; @@ -274,62 +274,68 @@ export const SecretOverviewPage = () => {
-
-

Secrets Overview

-

- Inject your secrets using - - Infisical CLI - - , - - Infisical API - - , - - Infisical SDKs - - , and - - more - - . -

-
+
+
+

Secrets Overview

+

+ Inject your secrets using + + Infisical CLI + + , + + Infisical API + + , + + Infisical SDKs + + , and + + more + + . +

+
+ {currentWorkspace?.version === ProjectVersion.V1 && ( + + )} -
- -
- setSearchFilter(e.target.value)} - leftIcon={} - /> +
+ +
+ setSearchFilter(e.target.value)} + leftIcon={} + /> +
+
From 66a631ff4691315c3368809be47d055875d6112e Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Thu, 22 Feb 2024 23:16:21 +0100 Subject: [PATCH 26/38] Update SecretOverviewPage.tsx --- frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx b/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx index 3c6b38e0a..b3e0efb8a 100644 --- a/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx +++ b/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx @@ -335,7 +335,6 @@ export const SecretOverviewPage = () => { -
From 028541a18aeb9363365c77b48397e2ae2143d9ff Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Thu, 22 Feb 2024 23:18:32 +0100 Subject: [PATCH 27/38] Update project-membership-service.ts --- .../project-membership/project-membership-service.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/backend/src/services/project-membership/project-membership-service.ts b/backend/src/services/project-membership/project-membership-service.ts index 5f03e9a6e..cf538e2c5 100644 --- a/backend/src/services/project-membership/project-membership-service.ts +++ b/backend/src/services/project-membership/project-membership-service.ts @@ -419,11 +419,6 @@ export const projectMembershipServiceFactory = ({ }); } - // This endpoint should be usable by normal and upgraded projects. - // if (project.version === ProjectVersion.V1) { - // throw new BadRequestError({ message: "Please upgrade your project on your dashboard" }); - // } - const projectMembers = await projectMembershipDAL.findMembershipsByEmail(projectId, emails); if (projectMembers.length !== emails.length) { From 3063bb998271de3480c4c0cb99480ac5957df980 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Fri, 23 Feb 2024 01:12:02 +0100 Subject: [PATCH 28/38] Update UpgradeProjectAlert.tsx --- .../UpgradeProjectAlert.tsx | 50 ++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx b/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx index db5eb1179..28ce117be 100644 --- a/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx +++ b/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx @@ -2,6 +2,7 @@ import { useCallback, useState } from "react"; import { useRouter } from "next/router"; import { faWarning } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { twMerge } from "tailwind-merge"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { useProjectPermission } from "@app/context"; @@ -10,12 +11,14 @@ import { Workspace } from "@app/hooks/api/types"; import { ProjectVersion } from "@app/hooks/api/workspace/types"; import { Button } from "../Button"; +import { Tooltip } from "../Tooltip"; export type UpgradeProjectAlertProps = { project: Workspace; }; export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX.Element | null => { + console.log("yes"); const { createNotification } = useNotificationContext(); const router = useRouter(); const { membership } = useProjectPermission(); @@ -23,6 +26,8 @@ export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX. const [currentStatus, setCurrentStatus] = useState(null); const [isUpgrading, setIsUpgrading] = useState(false); + console.log("yes 2"); + const { data: projectStatus, isLoading: statusIsLoading, @@ -50,6 +55,8 @@ export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX. } }); + console.log("yes 3"); + const onUpgradeProject = useCallback(async () => { if (upgradeProject.isLoading) { return; @@ -75,6 +82,8 @@ export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX. setTimeout(() => setIsUpgrading(false), 5_000); }, []); + console.log("yes 4"); + const isLoading = isUpgrading || ((upgradeProject.isLoading || @@ -82,21 +91,48 @@ export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX. (currentStatus === null && statusIsLoading)) && projectStatus?.status !== "FAILED"); - if (project.version !== ProjectVersion.V1) return null; - if (membership.role !== "admin") return null; + console.log("yes 5"); + if (project.version !== ProjectVersion.V1) return null; + + console.log("yes 6"); return ( -
+
Upgrade your project - Upgrade your project version to continue receiving the latest improvements and patches. + {membership.role === "admin" ? ( +

+ Upgrade your project version to continue receiving the latest improvements and patches. +

+ ) : ( +

+ Please ask a project admin to upgrade the project. +
+ Upgrading the project version is required to continue receiving the latest improvements + and patches. +

+ )} {currentStatus &&

Status: {currentStatus}

}
- + + +
); From ceb7fafc063fdadf00e4fbd9fddbc4527219c56b Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Fri, 23 Feb 2024 01:12:22 +0100 Subject: [PATCH 29/38] Update UpgradeProjectAlert.tsx --- .../v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx b/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx index 28ce117be..121f77067 100644 --- a/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx +++ b/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx @@ -18,7 +18,6 @@ export type UpgradeProjectAlertProps = { }; export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX.Element | null => { - console.log("yes"); const { createNotification } = useNotificationContext(); const router = useRouter(); const { membership } = useProjectPermission(); @@ -26,8 +25,6 @@ export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX. const [currentStatus, setCurrentStatus] = useState(null); const [isUpgrading, setIsUpgrading] = useState(false); - console.log("yes 2"); - const { data: projectStatus, isLoading: statusIsLoading, @@ -55,8 +52,6 @@ export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX. } }); - console.log("yes 3"); - const onUpgradeProject = useCallback(async () => { if (upgradeProject.isLoading) { return; @@ -82,8 +77,6 @@ export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX. setTimeout(() => setIsUpgrading(false), 5_000); }, []); - console.log("yes 4"); - const isLoading = isUpgrading || ((upgradeProject.isLoading || @@ -91,11 +84,8 @@ export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX. (currentStatus === null && statusIsLoading)) && projectStatus?.status !== "FAILED"); - console.log("yes 5"); - if (project.version !== ProjectVersion.V1) return null; - console.log("yes 6"); return (
Date: Fri, 23 Feb 2024 01:13:26 +0100 Subject: [PATCH 30/38] Update UpgradeOverlay.tsx --- frontend/src/components/v2/UpgradeOverlay/UpgradeOverlay.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/src/components/v2/UpgradeOverlay/UpgradeOverlay.tsx b/frontend/src/components/v2/UpgradeOverlay/UpgradeOverlay.tsx index 7dd1f5afa..f6d8d71c7 100644 --- a/frontend/src/components/v2/UpgradeOverlay/UpgradeOverlay.tsx +++ b/frontend/src/components/v2/UpgradeOverlay/UpgradeOverlay.tsx @@ -33,9 +33,7 @@ export const UpgradeOverlay = () => { return null; } - // for non admin this would throw an error - // so no need to render - return !isUpgradeStatusLoading && isUpgrading ? ( // isUpgrading + return !isUpgradeStatusLoading && isUpgrading ? (
From 76daa20d69363ba49f10c280bb1e4401a115087b Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Thu, 22 Feb 2024 20:12:17 +0530 Subject: [PATCH 31/38] feat(telemetry): added telemetry events for creation of integration,project,machine identity and user invitation to org --- backend/src/server/lib/telemtry.ts | 17 ++++++ backend/src/server/routes/index.ts | 4 ++ .../src/server/routes/v1/identity-router.ts | 13 +++++ .../server/routes/v1/integration-router.ts | 46 ++++++++++------ .../src/server/routes/v1/invite-org-router.ts | 11 ++++ .../src/server/routes/v2/project-router.ts | 12 +++++ .../services/telemetry/telemetry-service.ts | 9 +++- .../src/services/telemetry/telemetry-types.ts | 54 ++++++++++++++++++- 8 files changed, 148 insertions(+), 18 deletions(-) create mode 100644 backend/src/server/lib/telemtry.ts diff --git a/backend/src/server/lib/telemtry.ts b/backend/src/server/lib/telemtry.ts new file mode 100644 index 000000000..6794d7bb3 --- /dev/null +++ b/backend/src/server/lib/telemtry.ts @@ -0,0 +1,17 @@ +import { FastifyRequest } from "fastify"; + +import { ActorType } from "@app/services/auth/auth-type"; + +// this is a unique id for sending posthog event +export const getTelemetryDistinctId = (req: FastifyRequest) => { + if (req.auth.actor === ActorType.USER) { + return req.auth.user.email; + } + if (req.auth.actor === ActorType.IDENTITY) { + return `identity-${req.auth.identityId}`; + } + if (req.auth.actor === ActorType.SERVICE) { + return `service-token-${req.auth.serviceToken.id}`; + } + return "unknown-auth-data"; +}; diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index 9444aff16..7366c7041 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -585,4 +585,8 @@ export const registerRoutes = async ( ); await server.register(registerV2Routes, { prefix: "/api/v2" }); await server.register(registerV3Routes, { prefix: "/api/v3" }); + + server.addHook("onClose", async () => { + await telemetryService.flushAll(); + }); }; diff --git a/backend/src/server/routes/v1/identity-router.ts b/backend/src/server/routes/v1/identity-router.ts index 7441d58cb..adf5bca30 100644 --- a/backend/src/server/routes/v1/identity-router.ts +++ b/backend/src/server/routes/v1/identity-router.ts @@ -2,8 +2,10 @@ import { z } from "zod"; import { IdentitiesSchema, OrgMembershipRole } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { getTelemetryDistinctId } from "@app/server/lib/telemtry"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; +import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; export const registerIdentityRouter = async (server: FastifyZodProvider) => { server.route({ @@ -49,6 +51,17 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => { } }); + server.services.telemetry.sendPostHogEvents({ + event: PostHogEventTypes.MachineIdentityCreated, + distinctId: getTelemetryDistinctId(req), + properties: { + orgId: req.body.organizationId, + name: identity.name, + identityId: identity.id, + ...req.auditLogInfo + } + }); + return { identity }; } }); diff --git a/backend/src/server/routes/v1/integration-router.ts b/backend/src/server/routes/v1/integration-router.ts index ab0ba36eb..23d4f41eb 100644 --- a/backend/src/server/routes/v1/integration-router.ts +++ b/backend/src/server/routes/v1/integration-router.ts @@ -3,8 +3,10 @@ import { z } from "zod"; import { IntegrationsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { removeTrailingSlash, shake } from "@app/lib/fn"; +import { getTelemetryDistinctId } from "@app/server/lib/telemtry"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; +import { PostHogEventTypes, TIntegrationCreatedEvent } from "@app/services/telemetry/telemetry-types"; export const registerIntegrationRouter = async (server: FastifyZodProvider) => { server.route({ @@ -53,28 +55,40 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => { actorOrgId: req.permission.orgId, ...req.body }); + + const createIntegrationEventProperty = shake({ + integrationId: integration.id.toString(), + integration: integration.integration, + environment: req.body.sourceEnvironment, + secretPath: req.body.secretPath, + url: integration.url, + app: integration.app, + appId: integration.appId, + targetEnvironment: integration.targetEnvironment, + targetEnvironmentId: integration.targetEnvironmentId, + targetService: integration.targetService, + targetServiceId: integration.targetServiceId, + path: integration.path, + region: integration.region + }) as TIntegrationCreatedEvent["properties"]; + await server.services.auditLog.createAuditLog({ ...req.auditLogInfo, projectId: integrationAuth.projectId, event: { type: EventType.CREATE_INTEGRATION, // eslint-disable-next-line - metadata: shake({ - integrationId: integration.id.toString(), - integration: integration.integration, - environment: req.body.sourceEnvironment, - secretPath: req.body.secretPath, - url: integration.url, - app: integration.app, - appId: integration.appId, - targetEnvironment: integration.targetEnvironment, - targetEnvironmentId: integration.targetEnvironmentId, - targetService: integration.targetService, - targetServiceId: integration.targetServiceId, - path: integration.path, - region: integration.region - // eslint-disable-next-line - }) as any + metadata: createIntegrationEventProperty + } + }); + + server.services.telemetry.sendPostHogEvents({ + event: PostHogEventTypes.IntegrationCreated, + distinctId: getTelemetryDistinctId(req), + properties: { + ...createIntegrationEventProperty, + projectId: integrationAuth.projectId, + ...req.auditLogInfo } }); return { integration }; diff --git a/backend/src/server/routes/v1/invite-org-router.ts b/backend/src/server/routes/v1/invite-org-router.ts index 0d1fe5070..0184c0ea3 100644 --- a/backend/src/server/routes/v1/invite-org-router.ts +++ b/backend/src/server/routes/v1/invite-org-router.ts @@ -1,8 +1,10 @@ import { z } from "zod"; import { UsersSchema } from "@app/db/schemas"; +import { getTelemetryDistinctId } from "@app/server/lib/telemtry"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { ActorType, AuthMode } from "@app/services/auth/auth-type"; +import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; export const registerInviteOrgRouter = async (server: FastifyZodProvider) => { server.route({ @@ -30,6 +32,15 @@ export const registerInviteOrgRouter = async (server: FastifyZodProvider) => { actorOrgId: req.permission.orgId }); + server.services.telemetry.sendPostHogEvents({ + event: PostHogEventTypes.UserOrgInvitation, + distinctId: getTelemetryDistinctId(req), + properties: { + inviteeEmail: req.body.inviteeEmail, + ...req.auditLogInfo + } + }); + return { completeInviteLink, message: `Send an invite link to ${req.body.inviteeEmail}` diff --git a/backend/src/server/routes/v2/project-router.ts b/backend/src/server/routes/v2/project-router.ts index 7cbcff37c..a8ed57a52 100644 --- a/backend/src/server/routes/v2/project-router.ts +++ b/backend/src/server/routes/v2/project-router.ts @@ -4,8 +4,10 @@ import { z } from "zod"; import { ProjectKeysSchema, ProjectsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { authRateLimit } from "@app/server/config/rateLimiter"; +import { getTelemetryDistinctId } from "@app/server/lib/telemtry"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; +import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; const projectWithEnv = ProjectsSchema.merge( z.object({ @@ -152,6 +154,16 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { slug: req.body.slug }); + server.services.telemetry.sendPostHogEvents({ + event: PostHogEventTypes.ProjectCreated, + distinctId: getTelemetryDistinctId(req), + properties: { + orgId: req.body.organizationId, + name: project.name, + ...req.auditLogInfo + } + }); + return { project }; } }); diff --git a/backend/src/services/telemetry/telemetry-service.ts b/backend/src/services/telemetry/telemetry-service.ts index c386abd95..a1a4b78f7 100644 --- a/backend/src/services/telemetry/telemetry-service.ts +++ b/backend/src/services/telemetry/telemetry-service.ts @@ -61,8 +61,15 @@ To opt into telemetry, you can set "TELEMETRY_ENABLED=true" within the environme } }; + const flushAll = async () => { + if (postHog) { + await postHog.shutdownAsync(); + } + }; + return { sendLoopsEvent, - sendPostHogEvents + sendPostHogEvents, + flushAll }; }; diff --git a/backend/src/services/telemetry/telemetry-types.ts b/backend/src/services/telemetry/telemetry-types.ts index d97c3c7ac..ada71e6ef 100644 --- a/backend/src/services/telemetry/telemetry-types.ts +++ b/backend/src/services/telemetry/telemetry-types.ts @@ -8,7 +8,11 @@ export enum PostHogEventTypes { UserSignedUp = "User Signed Up", SecretRotated = "secrets rotated", SecretScannerFull = "historical cloud secret scan", - SecretScannerPush = "cloud secret scan" + SecretScannerPush = "cloud secret scan", + ProjectCreated = "project created", + IntegrationCreated = "integration created", + MachineIdentityCreated = "machine identity created", + UserOrgInvitation = "user org invitation" } export type TSecretModifiedEvent = { @@ -53,9 +57,57 @@ export type TSecretScannerEvent = { }; }; +export type TProjectCreateEvent = { + event: PostHogEventTypes.ProjectCreated; + properties: { + name: string; + orgId: string; + }; +}; + +export type TMachineIdentityCreatedEvent = { + event: PostHogEventTypes.MachineIdentityCreated; + properties: { + name: string; + orgId: string; + identityId: string; + }; +}; + +export type TIntegrationCreatedEvent = { + event: PostHogEventTypes.IntegrationCreated; + properties: { + projectId: string; + integrationId: string; + integration: string; // TODO: fix type + environment: string; + secretPath: string; + url?: string; + app?: string; + appId?: string; + targetEnvironment?: string; + targetEnvironmentId?: string; + targetService?: string; + targetServiceId?: string; + path?: string; + region?: string; + }; +}; + +export type TUserOrgInvitedEvent = { + event: PostHogEventTypes.UserOrgInvitation; + properties: { + inviteeEmail: string; + }; +}; + export type TPostHogEvent = { distinctId: string } & ( | TSecretModifiedEvent | TAdminInitEvent | TUserSignedUpEvent | TSecretScannerEvent + | TUserOrgInvitedEvent + | TMachineIdentityCreatedEvent + | TIntegrationCreatedEvent + | TProjectCreateEvent ); From 92acb4d9435924181477b2884bdf922671079b58 Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Fri, 23 Feb 2024 00:07:51 +0530 Subject: [PATCH 32/38] feat(telemetry): fixed typo in filename lib/telemetry and capitalized new posthog event names --- backend/src/server/lib/{telemtry.ts => telemetry.ts} | 0 backend/src/server/routes/v1/identity-router.ts | 2 +- backend/src/server/routes/v1/integration-router.ts | 2 +- backend/src/server/routes/v1/invite-org-router.ts | 2 +- backend/src/server/routes/v2/project-router.ts | 2 +- backend/src/services/telemetry/telemetry-types.ts | 8 ++++---- 6 files changed, 8 insertions(+), 8 deletions(-) rename backend/src/server/lib/{telemtry.ts => telemetry.ts} (100%) diff --git a/backend/src/server/lib/telemtry.ts b/backend/src/server/lib/telemetry.ts similarity index 100% rename from backend/src/server/lib/telemtry.ts rename to backend/src/server/lib/telemetry.ts diff --git a/backend/src/server/routes/v1/identity-router.ts b/backend/src/server/routes/v1/identity-router.ts index adf5bca30..a03cde62f 100644 --- a/backend/src/server/routes/v1/identity-router.ts +++ b/backend/src/server/routes/v1/identity-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentitiesSchema, OrgMembershipRole } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { getTelemetryDistinctId } from "@app/server/lib/telemtry"; +import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; diff --git a/backend/src/server/routes/v1/integration-router.ts b/backend/src/server/routes/v1/integration-router.ts index 23d4f41eb..1ccf75e94 100644 --- a/backend/src/server/routes/v1/integration-router.ts +++ b/backend/src/server/routes/v1/integration-router.ts @@ -3,7 +3,7 @@ import { z } from "zod"; import { IntegrationsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { removeTrailingSlash, shake } from "@app/lib/fn"; -import { getTelemetryDistinctId } from "@app/server/lib/telemtry"; +import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; import { PostHogEventTypes, TIntegrationCreatedEvent } from "@app/services/telemetry/telemetry-types"; diff --git a/backend/src/server/routes/v1/invite-org-router.ts b/backend/src/server/routes/v1/invite-org-router.ts index 0184c0ea3..dd2fd8157 100644 --- a/backend/src/server/routes/v1/invite-org-router.ts +++ b/backend/src/server/routes/v1/invite-org-router.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { UsersSchema } from "@app/db/schemas"; -import { getTelemetryDistinctId } from "@app/server/lib/telemtry"; +import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { ActorType, AuthMode } from "@app/services/auth/auth-type"; import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; diff --git a/backend/src/server/routes/v2/project-router.ts b/backend/src/server/routes/v2/project-router.ts index a8ed57a52..62f4c7cf5 100644 --- a/backend/src/server/routes/v2/project-router.ts +++ b/backend/src/server/routes/v2/project-router.ts @@ -4,7 +4,7 @@ import { z } from "zod"; import { ProjectKeysSchema, ProjectsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { authRateLimit } from "@app/server/config/rateLimiter"; -import { getTelemetryDistinctId } from "@app/server/lib/telemtry"; +import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; diff --git a/backend/src/services/telemetry/telemetry-types.ts b/backend/src/services/telemetry/telemetry-types.ts index ada71e6ef..0f92da4da 100644 --- a/backend/src/services/telemetry/telemetry-types.ts +++ b/backend/src/services/telemetry/telemetry-types.ts @@ -9,10 +9,10 @@ export enum PostHogEventTypes { SecretRotated = "secrets rotated", SecretScannerFull = "historical cloud secret scan", SecretScannerPush = "cloud secret scan", - ProjectCreated = "project created", - IntegrationCreated = "integration created", - MachineIdentityCreated = "machine identity created", - UserOrgInvitation = "user org invitation" + ProjectCreated = "Project Created", + IntegrationCreated = "Integration Created", + MachineIdentityCreated = "Machine Identity Created", + UserOrgInvitation = "User Org Invitation" } export type TSecretModifiedEvent = { From e91499b30101200271be28c5e980b9bfea4bbb2b Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Fri, 23 Feb 2024 13:22:53 +0530 Subject: [PATCH 33/38] feat(telemetry): updated telemetry distinct id to use service token from secrets one --- backend/src/server/lib/telemetry.ts | 2 +- backend/src/server/routes/v3/secret-router.ts | 41 +++++++------------ 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/backend/src/server/lib/telemetry.ts b/backend/src/server/lib/telemetry.ts index 6794d7bb3..5169b0e97 100644 --- a/backend/src/server/lib/telemetry.ts +++ b/backend/src/server/lib/telemetry.ts @@ -11,7 +11,7 @@ export const getTelemetryDistinctId = (req: FastifyRequest) => { return `identity-${req.auth.identityId}`; } if (req.auth.actor === ActorType.SERVICE) { - return `service-token-${req.auth.serviceToken.id}`; + return req.auth.serviceToken.createdByEmail || `service-token-null-creator-${req.auth.serviceTokenId}`; // when user gets removed from system } return "unknown-auth-data"; }; diff --git a/backend/src/server/routes/v3/secret-router.ts b/backend/src/server/routes/v3/secret-router.ts index 6bbb437ad..cfe4a87d7 100644 --- a/backend/src/server/routes/v3/secret-router.ts +++ b/backend/src/server/routes/v3/secret-router.ts @@ -1,4 +1,3 @@ -import { FastifyRequest } from "fastify"; import picomatch from "picomatch"; import { z } from "zod"; @@ -13,6 +12,7 @@ import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { CommitType } from "@app/ee/services/secret-approval-request/secret-approval-request-types"; import { BadRequestError } from "@app/lib/errors"; import { removeTrailingSlash } from "@app/lib/fn"; +import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; import { getUserAgentType } from "@app/server/plugins/audit-log"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { ActorType, AuthMode } from "@app/services/auth/auth-type"; @@ -20,19 +20,6 @@ import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; import { secretRawSchema } from "../sanitizedSchemas"; -const getDistinctId = (req: FastifyRequest) => { - if (req.auth.actor === ActorType.USER) { - return req.auth.user.email; - } - if (req.auth.actor === ActorType.IDENTITY) { - return `identity-${req.auth.identityId}`; - } - if (req.auth.actor === ActorType.SERVICE) { - return req.auth.serviceToken.createdByEmail || `service-token-null-creator-${req.auth.serviceTokenId}`; // when user gets removed from system - } - return "unknown-auth-data"; -}; - export const registerSecretRouter = async (server: FastifyZodProvider) => { server.route({ url: "/raw", @@ -110,7 +97,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretPulled, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: secrets.length, workspaceId, @@ -200,7 +187,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretPulled, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: 1, workspaceId, @@ -276,7 +263,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretCreated, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: 1, workspaceId: req.body.workspaceId, @@ -351,7 +338,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretUpdated, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: 1, workspaceId: req.body.workspaceId, @@ -421,7 +408,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretDeleted, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: 1, workspaceId: req.body.workspaceId, @@ -527,7 +514,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { if (shouldCapture) { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretPulled, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: shouldRecordK8Event ? approximateNumberTotalSecrets : secrets.length, workspaceId: req.query.workspaceId, @@ -604,7 +591,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretPulled, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: 1, workspaceId: req.query.workspaceId, @@ -767,7 +754,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretCreated, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: 1, workspaceId: req.body.workspaceId, @@ -949,7 +936,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretUpdated, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: 1, workspaceId: req.body.workspaceId, @@ -1067,7 +1054,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretDeleted, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: 1, workspaceId: req.body.workspaceId, @@ -1187,7 +1174,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretCreated, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: secrets.length, workspaceId: req.body.workspaceId, @@ -1307,7 +1294,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretUpdated, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: secrets.length, workspaceId: req.body.workspaceId, @@ -1415,7 +1402,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.SecretDeleted, - distinctId: getDistinctId(req), + distinctId: getTelemetryDistinctId(req), properties: { numberOfSecrets: secrets.length, workspaceId: req.body.workspaceId, From 70822d0d98e26105c2083fea33fe4f6511fe375c Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Fri, 23 Feb 2024 11:28:36 +0000 Subject: [PATCH 34/38] fix: frontend/package.json & frontend/package-lock.json to reduce vulnerabilities The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-SANITIZEHTML-6256334 --- frontend/package-lock.json | 10 +++++----- frontend/package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 0e9e32a59..0ab91f92f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,5 +1,5 @@ { - "name": "npm-proj-1708142380787-0.9952765718063858vJAsWg", + "name": "npm-proj-1708687711895-0.8280111363176879xoEiUg", "lockfileVersion": 3, "requires": true, "packages": { @@ -82,7 +82,7 @@ "react-markdown": "^8.0.3", "react-redux": "^8.0.2", "react-table": "^7.8.0", - "sanitize-html": "^2.11.0", + "sanitize-html": "^2.12.1", "set-cookie-parser": "^2.5.1", "sharp": "^0.33.2", "styled-components": "^5.3.7", @@ -21111,9 +21111,9 @@ "dev": true }, "node_modules/sanitize-html": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.11.0.tgz", - "integrity": "sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.12.1.tgz", + "integrity": "sha512-Plh+JAn0UVDpBRP/xEjsk+xDCoOvMBwQUf/K+/cBAVuTbtX8bj2VB7S1sL1dssVpykqp0/KPSesHrqXtokVBpA==", "dependencies": { "deepmerge": "^4.2.2", "escape-string-regexp": "^4.0.0", diff --git a/frontend/package.json b/frontend/package.json index 3407af2d5..d28ca4bf6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -90,7 +90,7 @@ "react-markdown": "^8.0.3", "react-redux": "^8.0.2", "react-table": "^7.8.0", - "sanitize-html": "^2.11.0", + "sanitize-html": "^2.12.1", "set-cookie-parser": "^2.5.1", "sharp": "^0.33.2", "styled-components": "^5.3.7", From 200d4a5af6e7128d2facedd8b0dce2a234b6a7a2 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Fri, 23 Feb 2024 17:54:00 +0000 Subject: [PATCH 35/38] fix: upgrade @aws-sdk/client-secrets-manager from 3.502.0 to 3.504.0 Snyk has created this PR to upgrade @aws-sdk/client-secrets-manager from 3.502.0 to 3.504.0. See this package in npm: https://www.npmjs.com/package/@aws-sdk/client-secrets-manager See this project in Snyk: https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr --- backend/package-lock.json | 100 +++++++++++++++++++++++--------------- backend/package.json | 2 +- 2 files changed, 61 insertions(+), 41 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index fc535212a..ef4f6a48c 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@aws-sdk/client-secrets-manager": "^3.502.0", + "@aws-sdk/client-secrets-manager": "^3.504.0", "@casl/ability": "^6.5.0", "@fastify/cookie": "^9.2.0", "@fastify/cors": "^8.4.1", @@ -661,15 +661,15 @@ } }, "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.502.0.tgz", - "integrity": "sha512-ICU084A/EbYMqca6NVFqeMtHh+KCdn0H7UjARUy5ur1yOlXXvxqAJGtKZDYFjuEO08F30zbv7+4HCOy6yjOJ0Q==", + "version": "3.504.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.504.0.tgz", + "integrity": "sha512-JPwsYfQMjs5t74JmA4r1AjpiOG/LEw74d4a8vEdSy3pe2lhl/sSsxSdQtbI30wlJJramngtLNZjxn2+BGDphbg==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.502.0", + "@aws-sdk/client-sts": "3.504.0", "@aws-sdk/core": "3.496.0", - "@aws-sdk/credential-provider-node": "3.502.0", + "@aws-sdk/credential-provider-node": "3.504.0", "@aws-sdk/middleware-host-header": "3.502.0", "@aws-sdk/middleware-logger": "3.502.0", "@aws-sdk/middleware-recursion-detection": "3.502.0", @@ -767,13 +767,13 @@ } }, "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.502.0.tgz", - "integrity": "sha512-Yc9tZqTOMWtdgpkrdjKShgWb9oKNsFQrItfoiN1xWDllaFFRPi2KTiZiR0AbSTrNasJy13d210DOxrIdte+kWQ==", + "version": "3.504.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.504.0.tgz", + "integrity": "sha512-ODA33/nm2srhV08EW0KZAP577UgV0qjyr7Xp2yEo8MXWL4ZqQZprk1c+QKBhjr4Djesrm0VPmSD/np0mtYP68A==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.502.0", + "@aws-sdk/client-sts": "3.504.0", "@aws-sdk/core": "3.496.0", "@aws-sdk/middleware-host-header": "3.502.0", "@aws-sdk/middleware-logger": "3.502.0", @@ -815,13 +815,13 @@ "node": ">=14.0.0" }, "peerDependencies": { - "@aws-sdk/credential-provider-node": "*" + "@aws-sdk/credential-provider-node": "^3.504.0" } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.502.0.tgz", - "integrity": "sha512-0q08gsvn6nuRqjK+i/e30PT/t7vvYwmGJS0PhJikZWv5yRDNSUxSYG0uDwKSbLDzmc2UX5+mLeyjPHlL4hbGlA==", + "version": "3.504.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.504.0.tgz", + "integrity": "sha512-IESs8FkL7B/uY+ml4wgoRkrr6xYo4PizcNw6JX17eveq1gRBCPKeGMjE6HTDOcIYZZ8rqz/UeuH3JD4UhrMOnA==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", @@ -867,7 +867,7 @@ "node": ">=14.0.0" }, "peerDependencies": { - "@aws-sdk/credential-provider-node": "*" + "@aws-sdk/credential-provider-node": "^3.504.0" } }, "node_modules/@aws-sdk/core": { @@ -900,16 +900,35 @@ "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.502.0.tgz", - "integrity": "sha512-1wB/escbspUY6uRDEMp9AMMyypUSyuQ0AMO1yQNtXviV8cPf+CuRbqP/UVnimHO1RuX0n5BmjDVVjUIEU6kuGA==", + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.503.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.503.1.tgz", + "integrity": "sha512-rTdlFFGoPPFMF2YjtlfRuSgKI+XsF49u7d98255hySwhsbwd3Xp+utTTPquxP+CwDxMHbDlI7NxDzFiFdsoZug==", "dependencies": { - "@aws-sdk/client-sts": "3.502.0", + "@aws-sdk/types": "3.502.0", + "@smithy/fetch-http-handler": "^2.4.1", + "@smithy/node-http-handler": "^2.3.1", + "@smithy/property-provider": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/util-stream": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.504.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.504.0.tgz", + "integrity": "sha512-ODICLXfr8xTUd3wweprH32Ge41yuBa+u3j0JUcLdTUO1N9ldczSMdo8zOPlP0z4doqD3xbnqMkjNQWgN/Q+5oQ==", + "dependencies": { + "@aws-sdk/client-sts": "3.504.0", "@aws-sdk/credential-provider-env": "3.502.0", "@aws-sdk/credential-provider-process": "3.502.0", - "@aws-sdk/credential-provider-sso": "3.502.0", - "@aws-sdk/credential-provider-web-identity": "3.502.0", + "@aws-sdk/credential-provider-sso": "3.504.0", + "@aws-sdk/credential-provider-web-identity": "3.504.0", "@aws-sdk/types": "3.502.0", "@smithy/credential-provider-imds": "^2.2.1", "@smithy/property-provider": "^2.1.1", @@ -922,15 +941,16 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.502.0.tgz", - "integrity": "sha512-qg71UpYeFrjhu5hD+vdRqZ+EYFB11BeszsbfEJGaHhOMHmmTHNBaDAexW+bUnJSXcJL0a8vniCvca+rElbcAHQ==", + "version": "3.504.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.504.0.tgz", + "integrity": "sha512-6+V5hIh+tILmUjf2ZQWQINR3atxQVgH/bFrGdSR/sHSp/tEgw3m0xWL3IRslWU1e4/GtXrfg1iYnMknXy68Ikw==", "dependencies": { "@aws-sdk/credential-provider-env": "3.502.0", - "@aws-sdk/credential-provider-ini": "3.502.0", + "@aws-sdk/credential-provider-http": "3.503.1", + "@aws-sdk/credential-provider-ini": "3.504.0", "@aws-sdk/credential-provider-process": "3.502.0", - "@aws-sdk/credential-provider-sso": "3.502.0", - "@aws-sdk/credential-provider-web-identity": "3.502.0", + "@aws-sdk/credential-provider-sso": "3.504.0", + "@aws-sdk/credential-provider-web-identity": "3.504.0", "@aws-sdk/types": "3.502.0", "@smithy/credential-provider-imds": "^2.2.1", "@smithy/property-provider": "^2.1.1", @@ -958,12 +978,12 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.502.0.tgz", - "integrity": "sha512-/2Nyvo+cWQpH283lmZBimTJ9JDhES9FzQUkhUXZgxQo3Ez4sguLVi2V9xoFFyG0cMff5fuNivdKHfj4FeMGjZw==", + "version": "3.504.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.504.0.tgz", + "integrity": "sha512-4MgH2or2SjPzaxM08DCW+BjaX4DSsEGJlicHKmz6fh+w9JmLh750oXcTnbvgUeVz075jcs6qTKjvUcsdGM/t8Q==", "dependencies": { "@aws-sdk/client-sso": "3.502.0", - "@aws-sdk/token-providers": "3.502.0", + "@aws-sdk/token-providers": "3.504.0", "@aws-sdk/types": "3.502.0", "@smithy/property-provider": "^2.1.1", "@smithy/shared-ini-file-loader": "^2.3.1", @@ -975,11 +995,11 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.502.0.tgz", - "integrity": "sha512-veBAjDqjMMgA2Qxxf9ywDfHYLeJpaeHWLWCQ9XCHwJJ6ZIGWmAZPTq3he/UMr5JIQXooIccqqyqXMDIXPenXpA==", + "version": "3.504.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.504.0.tgz", + "integrity": "sha512-L1ljCvGpIEFdJk087ijf2ohg7HBclOeB1UgBxUBBzf4iPRZTQzd2chGaKj0hm2VVaXz7nglswJeURH5PFcS5oA==", "dependencies": { - "@aws-sdk/client-sts": "3.502.0", + "@aws-sdk/client-sts": "3.504.0", "@aws-sdk/types": "3.502.0", "@smithy/property-provider": "^2.1.1", "@smithy/types": "^2.9.1", @@ -1079,11 +1099,11 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.502.0.tgz", - "integrity": "sha512-RQgMgIXYlSf0xGl6EUeD+pqIPBlb7e29dbqHOBFc66hJVYUC2ULZX7Y+jLvcGIEaMiIaTPyvntZRFip+U+9hag==", + "version": "3.504.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.504.0.tgz", + "integrity": "sha512-YIJWWsZi2ClUiILS1uh5L6VjmCUSTI6KKMuL9DkGjYqJ0aI6M8bd8fT9Wm7QmXCyjcArTgr/Atkhia4T7oKvzQ==", "dependencies": { - "@aws-sdk/client-sso-oidc": "3.502.0", + "@aws-sdk/client-sso-oidc": "3.504.0", "@aws-sdk/types": "3.502.0", "@smithy/property-provider": "^2.1.1", "@smithy/shared-ini-file-loader": "^2.3.1", diff --git a/backend/package.json b/backend/package.json index 0b79939f0..054f83961 100644 --- a/backend/package.json +++ b/backend/package.json @@ -70,7 +70,7 @@ "vitest": "^1.2.2" }, "dependencies": { - "@aws-sdk/client-secrets-manager": "^3.502.0", + "@aws-sdk/client-secrets-manager": "^3.504.0", "@casl/ability": "^6.5.0", "@fastify/cookie": "^9.2.0", "@fastify/cors": "^8.4.1", From a5a881c382f5c93356903e7e5a9a867f1b1d73b0 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Fri, 23 Feb 2024 17:54:04 +0000 Subject: [PATCH 36/38] fix: upgrade axios from 1.6.4 to 1.6.7 Snyk has created this PR to upgrade axios from 1.6.4 to 1.6.7. See this package in npm: https://www.npmjs.com/package/axios See this project in Snyk: https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr --- backend/package-lock.json | 8 ++++---- backend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index fc535212a..f525ce0a2 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -30,7 +30,7 @@ "ajv": "^8.12.0", "argon2": "^0.31.2", "aws-sdk": "^2.1545.0", - "axios": "^1.6.4", + "axios": "^1.6.7", "axios-retry": "^4.0.0", "bcrypt": "^5.1.1", "bullmq": "^5.1.6", @@ -5250,9 +5250,9 @@ } }, "node_modules/axios": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.4.tgz", - "integrity": "sha512-heJnIs6N4aa1eSthhN9M5ioILu8Wi8vmQW9iHQ9NUvfkJb0lEEDUiIdQNAuBtfUt3FxReaKdpQA5DbmMOqzF/A==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { "follow-redirects": "^1.15.4", "form-data": "^4.0.0", diff --git a/backend/package.json b/backend/package.json index 0b79939f0..41b355a83 100644 --- a/backend/package.json +++ b/backend/package.json @@ -91,7 +91,7 @@ "ajv": "^8.12.0", "argon2": "^0.31.2", "aws-sdk": "^2.1545.0", - "axios": "^1.6.4", + "axios": "^1.6.7", "axios-retry": "^4.0.0", "bcrypt": "^5.1.1", "bullmq": "^5.1.6", From e780ee657336d0c6b5c1d89cb6f54d104c19afb3 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Fri, 23 Feb 2024 17:54:08 +0000 Subject: [PATCH 37/38] fix: upgrade dotenv from 16.3.1 to 16.4.1 Snyk has created this PR to upgrade dotenv from 16.3.1 to 16.4.1. See this package in npm: https://www.npmjs.com/package/dotenv See this project in Snyk: https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr --- backend/package-lock.json | 8 ++++---- backend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index fc535212a..c1bcb7ffc 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -34,7 +34,7 @@ "axios-retry": "^4.0.0", "bcrypt": "^5.1.1", "bullmq": "^5.1.6", - "dotenv": "^16.3.1", + "dotenv": "^16.4.1", "fastify": "^4.26.0", "fastify-plugin": "^4.5.1", "handlebars": "^4.7.8", @@ -5995,9 +5995,9 @@ } }, "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "version": "16.4.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", + "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", "engines": { "node": ">=12" }, diff --git a/backend/package.json b/backend/package.json index 0b79939f0..19e5b83ae 100644 --- a/backend/package.json +++ b/backend/package.json @@ -95,7 +95,7 @@ "axios-retry": "^4.0.0", "bcrypt": "^5.1.1", "bullmq": "^5.1.6", - "dotenv": "^16.3.1", + "dotenv": "^16.4.1", "fastify": "^4.26.0", "fastify-plugin": "^4.5.1", "handlebars": "^4.7.8", From 320074ef6c2804603107d27317b783fa4c2c642f Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Fri, 23 Feb 2024 17:54:12 +0000 Subject: [PATCH 38/38] fix: upgrade @fastify/cors from 8.4.1 to 8.5.0 Snyk has created this PR to upgrade @fastify/cors from 8.4.1 to 8.5.0. See this package in npm: https://www.npmjs.com/package/@fastify/cors See this project in Snyk: https://app.snyk.io/org/maidul98/project/35057e82-ed7d-4e19-ba4d-719a42135cd6?utm_source=github&utm_medium=referral&page=upgrade-pr --- backend/package-lock.json | 16 ++++++++-------- backend/package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index fc535212a..6db980d02 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -12,7 +12,7 @@ "@aws-sdk/client-secrets-manager": "^3.502.0", "@casl/ability": "^6.5.0", "@fastify/cookie": "^9.2.0", - "@fastify/cors": "^8.4.1", + "@fastify/cors": "^8.5.0", "@fastify/etag": "^5.1.0", "@fastify/formbody": "^7.4.0", "@fastify/helmet": "^11.1.1", @@ -1676,12 +1676,12 @@ } }, "node_modules/@fastify/cors": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-8.4.1.tgz", - "integrity": "sha512-iYQJtrY3pFiDS5mo5zRaudzg2OcUdJ96PD6xfkKOOEilly5nnrFZx/W6Sce2T79xxlEn2qpU3t5+qS2phS369w==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-8.5.0.tgz", + "integrity": "sha512-/oZ1QSb02XjP0IK1U0IXktEsw/dUBTxJOW7IpIeO8c/tNalw/KjoNSJv1Sf6eqoBPO+TDGkifq6ynFK3v68HFQ==", "dependencies": { "fastify-plugin": "^4.0.0", - "mnemonist": "0.39.5" + "mnemonist": "0.39.6" } }, "node_modules/@fastify/deepmerge": { @@ -9064,9 +9064,9 @@ } }, "node_modules/mnemonist": { - "version": "0.39.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.5.tgz", - "integrity": "sha512-FPUtkhtJ0efmEFGpU14x7jGbTB+s18LrzRL2KgoWz9YvcY3cPomz8tih01GbHwnGk/OmkOKfqd/RAQoc8Lm7DQ==", + "version": "0.39.6", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.6.tgz", + "integrity": "sha512-A/0v5Z59y63US00cRSLiloEIw3t5G+MiKz4BhX21FI+YBJXBOGW0ohFxTxO08dsOYlzxo87T7vGfZKYp2bcAWA==", "dependencies": { "obliterator": "^2.0.1" } diff --git a/backend/package.json b/backend/package.json index 0b79939f0..6be4506ec 100644 --- a/backend/package.json +++ b/backend/package.json @@ -73,7 +73,7 @@ "@aws-sdk/client-secrets-manager": "^3.502.0", "@casl/ability": "^6.5.0", "@fastify/cookie": "^9.2.0", - "@fastify/cors": "^8.4.1", + "@fastify/cors": "^8.5.0", "@fastify/etag": "^5.1.0", "@fastify/formbody": "^7.4.0", "@fastify/helmet": "^11.1.1",