feat: addressed rabbit and reptile feedback

This commit is contained in:
=
2025-04-28 19:48:56 +05:30
parent 58940f31e3
commit d3d76467ac
7 changed files with 22 additions and 15 deletions
@@ -1,11 +1,12 @@
import { z } from "zod"; import { z } from "zod";
import { GithubOrgSyncConfigsSchema } from "@app/db/schemas"; import { GithubOrgSyncConfigsSchema } from "@app/db/schemas";
import { CharacterType, zodValidateCharacters } from "@app/lib/validator/validate-string";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
const SanitiziedGithubOrgSyncSchema = GithubOrgSyncConfigsSchema.pick({ const SanitizedGithubOrgSyncSchema = GithubOrgSyncConfigsSchema.pick({
isActive: true, isActive: true,
id: true, id: true,
createdAt: true, createdAt: true,
@@ -14,6 +15,7 @@ const SanitiziedGithubOrgSyncSchema = GithubOrgSyncConfigsSchema.pick({
githubOrgName: true githubOrgName: true
}); });
const githubOrgNameValidator = zodValidateCharacters([CharacterType.AlphaNumeric, CharacterType.Hyphen]);
export const registerGithubOrgSyncRouter = async (server: FastifyZodProvider) => { export const registerGithubOrgSyncRouter = async (server: FastifyZodProvider) => {
server.route({ server.route({
url: "/", url: "/",
@@ -24,13 +26,13 @@ export const registerGithubOrgSyncRouter = async (server: FastifyZodProvider) =>
onRequest: verifyAuth([AuthMode.JWT]), onRequest: verifyAuth([AuthMode.JWT]),
schema: { schema: {
body: z.object({ body: z.object({
githubOrgName: z.string().trim(), githubOrgName: githubOrgNameValidator(z.string().trim(), "GitHub Org Name"),
githubOrgAccessToken: z.string().trim().max(1000).optional(), githubOrgAccessToken: z.string().trim().max(1000).optional(),
isActive: z.boolean().default(false) isActive: z.boolean().default(false)
}), }),
response: { response: {
200: z.object({ 200: z.object({
githubOrgSyncConfig: SanitiziedGithubOrgSyncSchema githubOrgSyncConfig: SanitizedGithubOrgSyncSchema
}) })
} }
}, },
@@ -56,14 +58,14 @@ export const registerGithubOrgSyncRouter = async (server: FastifyZodProvider) =>
schema: { schema: {
body: z body: z
.object({ .object({
githubOrgName: z.string().trim(), githubOrgName: githubOrgNameValidator(z.string().trim(), "GitHub Org Name"),
githubOrgAccessToken: z.string().trim().max(1000), githubOrgAccessToken: z.string().trim().max(1000),
isActive: z.boolean().default(false) isActive: z.boolean().default(false)
}) })
.partial(), .partial(),
response: { response: {
200: z.object({ 200: z.object({
githubOrgSyncConfig: SanitiziedGithubOrgSyncSchema githubOrgSyncConfig: SanitizedGithubOrgSyncSchema
}) })
} }
}, },
@@ -89,7 +91,7 @@ export const registerGithubOrgSyncRouter = async (server: FastifyZodProvider) =>
schema: { schema: {
response: { response: {
200: z.object({ 200: z.object({
githubOrgSyncConfig: SanitiziedGithubOrgSyncSchema githubOrgSyncConfig: SanitizedGithubOrgSyncSchema
}) })
} }
}, },
@@ -112,7 +114,7 @@ export const registerGithubOrgSyncRouter = async (server: FastifyZodProvider) =>
schema: { schema: {
response: { response: {
200: z.object({ 200: z.object({
githubOrgSyncConfig: SanitiziedGithubOrgSyncSchema githubOrgSyncConfig: SanitizedGithubOrgSyncSchema
}) })
} }
}, },
@@ -79,7 +79,7 @@ export const githubOrgSyncServiceFactory = ({
const { data } = await octokit.rest.orgs.get({ const { data } = await octokit.rest.orgs.get({
org: githubOrgName org: githubOrgName
}); });
if (data.login.toLowerCase() !== githubOrgName) if (data.login.toLowerCase() !== githubOrgName.toLowerCase())
throw new BadRequestError({ message: "Invalid GitHub organisation" }); throw new BadRequestError({ message: "Invalid GitHub organisation" });
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
@@ -152,7 +152,7 @@ export const githubOrgSyncServiceFactory = ({
org: newData.githubOrgName org: newData.githubOrgName
}); });
if (data.login.toLowerCase() !== newData.githubOrgName) if (data.login.toLowerCase() !== newData.githubOrgName.toLowerCase())
throw new BadRequestError({ message: "Invalid GitHub organisation" }); throw new BadRequestError({ message: "Invalid GitHub organisation" });
} }
@@ -280,7 +280,7 @@ export const githubOrgSyncServiceFactory = ({
const { const {
organization: { teams } organization: { teams }
} = data; } = data;
const githubUserTeams = teams?.edges?.map((el) => el.node.name.toLowerCase()); const githubUserTeams = teams?.edges?.map((el) => el.node.name.toLowerCase()) || [];
const githubUserTeamSet = new Set(githubUserTeams); const githubUserTeamSet = new Set(githubUserTeams);
const githubUserTeamOnInfisical = await groupDAL.find({ orgId, $in: { name: githubUserTeams } }); const githubUserTeamOnInfisical = await groupDAL.find({ orgId, $in: { name: githubUserTeams } });
const githubUserTeamOnInfisicalGroupByName = groupBy(githubUserTeamOnInfisical, (i) => i.name); const githubUserTeamOnInfisicalGroupByName = groupBy(githubUserTeamOnInfisical, (i) => i.name);
@@ -19,7 +19,7 @@ To enable and configure GitHub Organization Synchronization, follow these steps:
![config-modal](../../images/platform/external-syncs/github-org-sync-config-modal.png) ![config-modal](../../images/platform/external-syncs/github-org-sync-config-modal.png)
</Step> </Step>
<Step title="Enable GitHub organization sync"> <Step title="Enable GitHub organization sync">
Toggle ON GitHub Organization sync to active sync. Toggle ON GitHub Organization sync to activate sync.
![toggle-on](../../images/platform/external-syncs/github-org-sync-active.png) ![toggle-on](../../images/platform/external-syncs/github-org-sync-active.png)
</Step> </Step>
<Step title="Approve the Infisical OAuth application on your organization"> <Step title="Approve the Infisical OAuth application on your organization">
@@ -33,7 +33,7 @@ To enable and configure GitHub Organization Synchronization, follow these steps:
<Info> <Info>
This action only needs to be done once and authorizes the Infisical OAuth app to read organization details, including team information. This action only needs to be done once and authorizes the Infisical OAuth app to read organization details, including team information.
The following users doesn't need to select organization in GitHub on login anymore. The following users don't need to select organization in GitHub on login anymore.
</Info> </Info>
</Step> </Step>
@@ -1,7 +1,7 @@
export type TGithubOrgSyncConfig = { export type TGithubOrgSyncConfig = {
id: string; id: string;
orgId: string; orgId: string;
githubAccessToken: string; githubOrgAccessToken?: string;
githubOrgName: string; githubOrgName: string;
createdAt: string; createdAt: string;
isActive?: boolean; isActive?: boolean;
@@ -110,6 +110,7 @@ export const formSchema = z.object({
"secret-scanning": generalPermissionSchema, "secret-scanning": generalPermissionSchema,
sso: generalPermissionSchema, sso: generalPermissionSchema,
scim: generalPermissionSchema, scim: generalPermissionSchema,
[OrgPermissionSubjects.GithubOrgSync]: generalPermissionSchema,
ldap: generalPermissionSchema, ldap: generalPermissionSchema,
billing: generalPermissionSchema, billing: generalPermissionSchema,
identity: identityPermissionSchema, identity: identityPermissionSchema,
@@ -63,6 +63,10 @@ const SIMPLE_PERMISSION_OPTIONS = [
title: "SCIM", title: "SCIM",
formName: "scim" formName: "scim"
}, },
{
title: "GitHub Organization Sync",
formName: OrgPermissionSubjects.GithubOrgSync
},
{ {
title: "External KMS", title: "External KMS",
formName: OrgPermissionSubjects.Kms formName: OrgPermissionSubjects.Kms
@@ -145,7 +145,7 @@ export const GithubOrgSyncConfigModal = ({
<Button <Button
variant="plain" variant="plain"
colorSchema="secondary" colorSchema="secondary"
onClick={() => handlePopUpToggle("deleteGithubOrgSyncConfig", false)} onClick={() => handlePopUpToggle("githubOrgSyncConfig", false)}
> >
Cancel Cancel
</Button> </Button>
@@ -163,7 +163,7 @@ export const GithubOrgSyncConfigModal = ({
<DeleteActionModal <DeleteActionModal
isOpen={popUp.deleteGithubOrgSyncConfig.isOpen} isOpen={popUp.deleteGithubOrgSyncConfig.isOpen}
title="Are you sure want to remove GitHub organization sync?" title="Are you sure want to remove GitHub organization sync?"
onChange={(isOpen) => handlePopUpToggle("githubOrgSyncConfig", isOpen)} onChange={(isOpen) => handlePopUpToggle("deleteGithubOrgSyncConfig", isOpen)}
deleteKey="confirm" deleteKey="confirm"
onDeleteApproved={onDelete} onDeleteApproved={onDelete}
/> />