mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat(microsoft-teams): better authentication flow and doc references
This commit is contained in:
@@ -47,7 +47,7 @@ export async function up(knex: Knex): Promise<void> {
|
||||
table.foreign("id").references("id").inTable(TableName.WorkflowIntegrations).onDelete("CASCADE"); // the ID itself is the workflow integration ID
|
||||
|
||||
table.string("internalTeamsAppId").nullable();
|
||||
table.string("tenantId").notNullable();
|
||||
table.string("tenantId").unique().notNullable();
|
||||
table.binary("encryptedAccessToken").nullable();
|
||||
table.binary("encryptedBotAccessToken").nullable();
|
||||
|
||||
|
||||
@@ -22,33 +22,63 @@ const sanitizedMicrosoftTeamsIntegrationSchema = WorkflowIntegrationsSchema.pick
|
||||
|
||||
export const registerMicrosoftTeamsRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
method: "POST",
|
||||
url: "/",
|
||||
method: "GET",
|
||||
url: "/client-id",
|
||||
config: {
|
||||
rateLimit: writeLimit
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
body: z.object({
|
||||
tenantId: z.string(),
|
||||
slug: slugSchema({ max: 64 })
|
||||
}),
|
||||
response: {
|
||||
200: sanitizedMicrosoftTeamsIntegrationSchema
|
||||
200: z.object({
|
||||
clientId: z.string()
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const microsoftTeamsIntegration = await server.services.microsoftTeams.createMicrosoftTeamsIntegration({
|
||||
const clientId = await server.services.microsoftTeams.getClientId({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
...req.body
|
||||
actorOrgId: req.permission.orgId
|
||||
});
|
||||
|
||||
return microsoftTeamsIntegration;
|
||||
return {
|
||||
clientId
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "POST",
|
||||
url: "/",
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
body: z.object({
|
||||
redirectUri: z.string(),
|
||||
tenantId: z.string(),
|
||||
slug: z.string(),
|
||||
description: z.string().optional()
|
||||
})
|
||||
},
|
||||
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
await server.services.microsoftTeams.completeMicrosoftTeamsIntegration({
|
||||
tenantId: req.body.tenantId,
|
||||
slug: req.body.slug,
|
||||
description: req.body.description,
|
||||
redirectUri: req.body.redirectUri,
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/",
|
||||
|
||||
@@ -15,6 +15,51 @@ import { TWorkflowIntegrationDALFactory } from "../workflow-integration/workflow
|
||||
import { WorkflowIntegrationStatus } from "../workflow-integration/workflow-integration-types";
|
||||
import { TMicrosoftTeamsIntegrationDALFactory } from "./microsoft-teams-integration-dal";
|
||||
|
||||
export const verifyTenantFromCode = async (
|
||||
tenantId: string,
|
||||
redirectUri: string,
|
||||
clientId: string,
|
||||
clientSecret: string
|
||||
) => {
|
||||
const tokenEndpoint = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
|
||||
|
||||
const params = new URLSearchParams({
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
scope: "https://graph.microsoft.com/.default",
|
||||
redirect_uri: redirectUri,
|
||||
grant_type: "client_credentials"
|
||||
});
|
||||
|
||||
const response = await axios
|
||||
.post<{ access_token: string }>(tokenEndpoint, params, {
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
if (axios.isAxiosError(err)) {
|
||||
logger.error(err.response?.data, "Error fetching Microsoft Teams access token");
|
||||
}
|
||||
throw err;
|
||||
});
|
||||
|
||||
const accessToken = response.data.access_token;
|
||||
const tokenParts = accessToken.split(".");
|
||||
const tokenPayload = JSON.parse(Buffer.from(tokenParts[1], "base64").toString()) as { tid: string };
|
||||
|
||||
// the 'tid' claim in the token contains the tenant ID
|
||||
const tenantIdFromToken = tokenPayload.tid;
|
||||
|
||||
if (tenantIdFromToken !== tenantId) {
|
||||
throw new BadRequestError({
|
||||
message: `Invalid tenant state ID. Expected ${tenantId}, got ${tenantIdFromToken}`
|
||||
});
|
||||
}
|
||||
|
||||
return tenantIdFromToken;
|
||||
};
|
||||
|
||||
export const getMicrosoftTeamsAccessToken = async (
|
||||
{
|
||||
orgId,
|
||||
@@ -219,9 +264,6 @@ export const isBotInstalledInTenant = async (
|
||||
tx
|
||||
).catch(() => null);
|
||||
|
||||
console.log("botAccessToken", botAccessToken);
|
||||
console.log("accessToken", accessToken);
|
||||
|
||||
if (!botAccessToken || !accessToken) {
|
||||
return {
|
||||
accessToken: null,
|
||||
@@ -256,12 +298,6 @@ export const isBotInstalledInTenant = async (
|
||||
|
||||
const botInstalledInTenant = appsResponse.data.value.find((a) => a.externalId === botId);
|
||||
|
||||
for (const app of appsResponse.data.value) {
|
||||
if (app.displayName.toLowerCase().includes("infisical")) {
|
||||
console.log(`${app.displayName} - ${app.externalId}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!botInstalledInTenant) {
|
||||
return {
|
||||
installed: false,
|
||||
|
||||
@@ -10,7 +10,7 @@ import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors";
|
||||
import { logger } from "@app/lib/logger";
|
||||
|
||||
import { TKmsServiceFactory } from "../kms/kms-service";
|
||||
@@ -18,12 +18,18 @@ import { KmsDataKey } from "../kms/kms-types";
|
||||
import { TSuperAdminDALFactory } from "../super-admin/super-admin-dal";
|
||||
import { TWorkflowIntegrationDALFactory } from "../workflow-integration/workflow-integration-dal";
|
||||
import { WorkflowIntegration, WorkflowIntegrationStatus } from "../workflow-integration/workflow-integration-types";
|
||||
import { getMicrosoftTeamsAccessToken, isBotInstalledInTenant, TeamsBot } from "./microsoft-teams-fns";
|
||||
import {
|
||||
getMicrosoftTeamsAccessToken,
|
||||
isBotInstalledInTenant,
|
||||
TeamsBot,
|
||||
verifyTenantFromCode
|
||||
} from "./microsoft-teams-fns";
|
||||
import { TMicrosoftTeamsIntegrationDALFactory } from "./microsoft-teams-integration-dal";
|
||||
import {
|
||||
TCheckInstallationStatusDTO,
|
||||
TCreateMicrosoftTeamsIntegrationDTO,
|
||||
TDeleteMicrosoftTeamsIntegrationDTO,
|
||||
TGetClientIdDTO,
|
||||
TGetMicrosoftTeamsIntegrationByIdDTO,
|
||||
TGetMicrosoftTeamsIntegrationByOrgDTO,
|
||||
TGetTeamsDTO,
|
||||
@@ -202,14 +208,15 @@ export const microsoftTeamsServiceFactory = ({
|
||||
}
|
||||
};
|
||||
|
||||
const createMicrosoftTeamsIntegration = async ({
|
||||
actorId,
|
||||
const completeMicrosoftTeamsIntegration = async ({
|
||||
actor,
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
tenantId,
|
||||
slug,
|
||||
description,
|
||||
tenantId
|
||||
redirectUri
|
||||
}: TCreateMicrosoftTeamsIntegrationDTO) => {
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
@@ -237,7 +244,14 @@ export const microsoftTeamsServiceFactory = ({
|
||||
});
|
||||
}
|
||||
|
||||
const integration = await workflowIntegrationDAL.transaction(async (tx) => {
|
||||
const decryptWithRoot = kmsService.decryptWithRootKey();
|
||||
const botAppId = decryptWithRoot(encryptedMicrosoftTeamsAppId);
|
||||
const botAppPassword = decryptWithRoot(encryptedMicrosoftTeamsClientSecret);
|
||||
const botId = decryptWithRoot(encryptedMicrosoftTeamsBotId);
|
||||
|
||||
await verifyTenantFromCode(tenantId, redirectUri, botAppId.toString(), botAppPassword.toString());
|
||||
|
||||
await workflowIntegrationDAL.transaction(async (tx) => {
|
||||
const workflowIntegration = await workflowIntegrationDAL.create(
|
||||
{
|
||||
description,
|
||||
@@ -249,19 +263,24 @@ export const microsoftTeamsServiceFactory = ({
|
||||
tx
|
||||
);
|
||||
|
||||
const microsoftTeamsIntegration = await microsoftTeamsIntegrationDAL.create(
|
||||
{
|
||||
// @ts-expect-error id is kept as fixed because it is always equal to the workflow integration ID
|
||||
id: workflowIntegration.id,
|
||||
tenantId
|
||||
},
|
||||
tx
|
||||
);
|
||||
|
||||
const decryptWithRoot = kmsService.decryptWithRootKey();
|
||||
const botAppId = decryptWithRoot(encryptedMicrosoftTeamsAppId);
|
||||
const botAppPassword = decryptWithRoot(encryptedMicrosoftTeamsClientSecret);
|
||||
const botId = decryptWithRoot(encryptedMicrosoftTeamsBotId);
|
||||
const microsoftTeamsIntegration = await microsoftTeamsIntegrationDAL
|
||||
.create(
|
||||
{
|
||||
// @ts-expect-error id is kept as fixed because it is always equal to the workflow integration ID
|
||||
id: workflowIntegration.id,
|
||||
tenantId
|
||||
},
|
||||
tx
|
||||
)
|
||||
.catch((err) => {
|
||||
if (err instanceof DatabaseError) {
|
||||
if ((err.error as Error)?.stack?.includes("duplicate key value violates unique constraint"))
|
||||
throw new BadRequestError({
|
||||
message: "Microsoft Teams integration with the same Tenant ID already exists."
|
||||
});
|
||||
}
|
||||
throw err;
|
||||
});
|
||||
|
||||
const teamsBotInfo = await isBotInstalledInTenant(
|
||||
{
|
||||
@@ -307,17 +326,37 @@ export const microsoftTeamsServiceFactory = ({
|
||||
tx
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...workflowIntegration,
|
||||
status: workflowIntegration.status as WorkflowIntegrationStatus,
|
||||
tenantId: microsoftTeamsIntegration.tenantId
|
||||
};
|
||||
});
|
||||
|
||||
return integration;
|
||||
};
|
||||
const getClientId = async ({ actorId, actor, actorOrgId, actorAuthMethod }: TGetClientIdDTO) => {
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Settings);
|
||||
|
||||
const serverCfg = await serverCfgDAL.findById(ADMIN_CONFIG_DB_UUID);
|
||||
if (!serverCfg) {
|
||||
throw new BadRequestError({
|
||||
message: "Failed to get server configuration."
|
||||
});
|
||||
}
|
||||
|
||||
if (!serverCfg.encryptedMicrosoftTeamsAppId) {
|
||||
throw new BadRequestError({
|
||||
message: "Microsoft Teams app ID is not set"
|
||||
});
|
||||
}
|
||||
|
||||
const decryptWithRoot = kmsService.decryptWithRootKey();
|
||||
const clientId = decryptWithRoot(serverCfg.encryptedMicrosoftTeamsAppId);
|
||||
|
||||
return clientId.toString();
|
||||
};
|
||||
const getMicrosoftTeamsIntegrationsByOrg = async ({
|
||||
actorId,
|
||||
actor,
|
||||
@@ -335,7 +374,8 @@ export const microsoftTeamsServiceFactory = ({
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Settings);
|
||||
|
||||
const microsoftTeamsIntegrations = await microsoftTeamsIntegrationDAL.findWithWorkflowIntegrationDetails({
|
||||
orgId: actorOrgId
|
||||
orgId: actorOrgId,
|
||||
status: WorkflowIntegrationStatus.INSTALLED
|
||||
});
|
||||
|
||||
return microsoftTeamsIntegrations.map((integration) => ({
|
||||
@@ -652,12 +692,13 @@ export const microsoftTeamsServiceFactory = ({
|
||||
getMicrosoftTeamsIntegrationById,
|
||||
updateMicrosoftTeamsIntegration,
|
||||
deleteMicrosoftTeamsIntegration,
|
||||
createMicrosoftTeamsIntegration,
|
||||
completeMicrosoftTeamsIntegration,
|
||||
initializeTeamsBot,
|
||||
getTeams,
|
||||
handleMessageEndpoint,
|
||||
start,
|
||||
sendNotification,
|
||||
checkInstallationStatus
|
||||
checkInstallationStatus,
|
||||
getClientId
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3,10 +3,13 @@ import { TNotification } from "@app/lib/workflow-integrations/types";
|
||||
|
||||
export type TGetMicrosoftTeamsIntegrationByOrgDTO = Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TGetClientIdDTO = Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TCreateMicrosoftTeamsIntegrationDTO = Omit<TOrgPermission, "orgId"> & {
|
||||
slug: string;
|
||||
description?: string;
|
||||
tenantId: string;
|
||||
slug: string;
|
||||
redirectUri: string;
|
||||
description?: string;
|
||||
};
|
||||
|
||||
export type TCheckInstallationStatusDTO = { workflowIntegrationId: string } & Omit<TOrgPermission, "orgId">;
|
||||
|
||||
@@ -67,7 +67,7 @@ import { validateSlackChannelsField } from "../slack/slack-auth-validators";
|
||||
import { TSlackIntegrationDALFactory } from "../slack/slack-integration-dal";
|
||||
import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service";
|
||||
import { TUserDALFactory } from "../user/user-dal";
|
||||
import { WorkflowIntegration } from "../workflow-integration/workflow-integration-types";
|
||||
import { WorkflowIntegration, WorkflowIntegrationStatus } from "../workflow-integration/workflow-integration-types";
|
||||
import { TProjectDALFactory } from "./project-dal";
|
||||
import { assignWorkspaceKeysToMembers, bootstrapSshProject, createProjectKey } from "./project-fns";
|
||||
import { TProjectQueueFactory } from "./project-queue";
|
||||
@@ -1539,6 +1539,12 @@ export const projectServiceFactory = ({
|
||||
});
|
||||
}
|
||||
|
||||
if (microsoftTeamsIntegration.status !== WorkflowIntegrationStatus.INSTALLED) {
|
||||
throw new BadRequestError({
|
||||
message: "Microsoft Teams integration is not properly installed in your tenant."
|
||||
});
|
||||
}
|
||||
|
||||
if (microsoftTeamsIntegration.orgId !== actorOrgId) {
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Selected Microsoft Teams integration is not in the same organization"
|
||||
|
||||
@@ -17,6 +17,12 @@ export const ROUTE_PATHS = Object.freeze({
|
||||
PasswordSetupPage: setRoute("/password-setup", "/_authenticate/password-setup")
|
||||
},
|
||||
Organization: {
|
||||
Settings: {
|
||||
OauthCallbackPage: setRoute(
|
||||
"/organization/settings/oauth/callback",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings/oauth/callback"
|
||||
)
|
||||
},
|
||||
SecretScanning: setRoute(
|
||||
"/organization/secret-scanning",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/secret-scanning"
|
||||
|
||||
@@ -23,7 +23,8 @@ export const workflowIntegrationKeys = {
|
||||
{ id },
|
||||
"microsoft-teams-workflow-integration-teams"
|
||||
],
|
||||
getSlackIntegrationChannels: (id?: string) => [{ id }, "slack-workflow-integration-channels"]
|
||||
getSlackIntegrationChannels: (id?: string) => [{ id }, "slack-workflow-integration-channels"],
|
||||
getMicrosoftTeamsClientId: () => ["microsoft-teams-client-id"]
|
||||
};
|
||||
|
||||
export const fetchSlackInstallUrl = async ({
|
||||
@@ -104,6 +105,14 @@ export const fetchMicrosoftTeamsIntegrationTeams = async (id?: string) => {
|
||||
return data;
|
||||
};
|
||||
|
||||
export const fetchMicrosoftTeamsClientId = async () => {
|
||||
const { data } = await apiRequest.get<{ clientId: string }>(
|
||||
"/api/v1/workflow-integrations/microsoft-teams/client-id"
|
||||
);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const useGetMicrosoftTeamsIntegrations = (orgId?: string) =>
|
||||
useQuery({
|
||||
queryKey: workflowIntegrationKeys.getMicrosoftTeamsIntegrations(orgId),
|
||||
@@ -145,3 +154,10 @@ export const useGetWorkflowIntegrations = (id?: string) =>
|
||||
queryFn: () => fetchWorkflowIntegrations(),
|
||||
enabled: Boolean(id)
|
||||
});
|
||||
|
||||
export const useGetMicrosoftTeamsClientId = () =>
|
||||
useQuery({
|
||||
queryKey: workflowIntegrationKeys.getMicrosoftTeamsClientId(),
|
||||
queryFn: () => fetchMicrosoftTeamsClientId(),
|
||||
enabled: true
|
||||
});
|
||||
|
||||
@@ -59,10 +59,11 @@ export type TUpdateMicrosoftTeamsIntegrationDTO = {
|
||||
};
|
||||
|
||||
export type TCreateMicrosoftTeamsIntegrationDTO = {
|
||||
orgId: string;
|
||||
tenantId: string;
|
||||
slug: string;
|
||||
description?: string;
|
||||
redirectUri: string;
|
||||
orgId: string;
|
||||
};
|
||||
|
||||
export type TDeleteSlackIntegrationDTO = {
|
||||
|
||||
@@ -80,11 +80,18 @@ export const MicrosoftTeamsIntegrationForm = ({ adminIntegrationsConfig }: Props
|
||||
</AccordionTrigger>
|
||||
<AccordionContent childrenClassName="px-0 py-0">
|
||||
<div className="flex w-full flex-col justify-start rounded-md rounded-t-none border border-t-0 border-mineshaft-500 bg-mineshaft-700 px-4 py-4">
|
||||
<div className="mb-4 max-w-lg text-sm text-mineshaft-300">
|
||||
Step 1: Create Microsoft Teams bot
|
||||
<div className="mb-2 max-w-lg text-sm text-mineshaft-300">
|
||||
Step 1: Create and configure Microsoft Teams bot and Azure Resources. Please refer
|
||||
to the documentation below for more information.
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
<Button colorSchema="secondary">Documentation</Button>
|
||||
<a
|
||||
href="https://infisical.com/docs/documentation/platform/workflow-integrations/microsoft-teams-integration"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button colorSchema="secondary">Documentation</Button>
|
||||
</a>
|
||||
</div>
|
||||
<div className="mb-4 max-w-lg text-sm text-mineshaft-300">
|
||||
Step 2: Configure your instance-wide settings to enable integration with Microsoft
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||
import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ContentLoader } from "@app/components/v2";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { useOrganization } from "@app/context";
|
||||
import { useCreateMicrosoftTeamsIntegration } from "@app/hooks/api";
|
||||
|
||||
const stateSchema = z.object({
|
||||
redirectUri: z.string(),
|
||||
tenantId: z.string(),
|
||||
slug: z.string(),
|
||||
description: z.string().optional(),
|
||||
csrfToken: z.string()
|
||||
});
|
||||
|
||||
export const OAuthCallbackPage = () => {
|
||||
const navigate = useNavigate();
|
||||
const { currentOrg } = useOrganization();
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
|
||||
const search = useSearch({
|
||||
from: ROUTE_PATHS.Organization.Settings.OauthCallbackPage.id
|
||||
});
|
||||
|
||||
const createMicrosoftTeamsWorkflowIntegration = useCreateMicrosoftTeamsIntegration();
|
||||
|
||||
const { state: rawState, tenant: stateTenant, admin_consent: adminConsent } = search;
|
||||
|
||||
const state = stateSchema.parse(rawState);
|
||||
|
||||
const clearState = () => {
|
||||
if (state.csrfToken !== localStorage.getItem("latestCSRFToken")) {
|
||||
throw new Error("Invalid CSRF token");
|
||||
}
|
||||
|
||||
localStorage.removeItem("latestCSRFToken");
|
||||
};
|
||||
|
||||
const handleMicrosoftTeams = useCallback(async () => {
|
||||
clearState();
|
||||
|
||||
if (Boolean(adminConsent.toLowerCase()) !== true) {
|
||||
throw new Error("Failed to grant admin consent");
|
||||
}
|
||||
|
||||
if (stateTenant !== state.tenantId) {
|
||||
throw new Error(`Invalid tenant ID. Expected ${stateTenant}, got ${state.tenantId}`);
|
||||
}
|
||||
|
||||
await createMicrosoftTeamsWorkflowIntegration.mutateAsync({
|
||||
orgId: currentOrg.id,
|
||||
tenantId: state.tenantId,
|
||||
slug: state.slug,
|
||||
description: state.description ?? "",
|
||||
redirectUri: state.redirectUri
|
||||
});
|
||||
}, []);
|
||||
|
||||
// Ensure that the localstorage is ready for use, to avoid the form data being malformed
|
||||
useEffect(() => {
|
||||
if (!isReady) {
|
||||
setIsReady(!!localStorage.length);
|
||||
}
|
||||
}, [localStorage.length]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isReady) return;
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
await handleMicrosoftTeams();
|
||||
|
||||
createNotification({
|
||||
text: "Successfully granted Microsoft Teams admin consent",
|
||||
type: "success"
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
createNotification({
|
||||
text: "Failed to grant Microsoft Teams admin consent",
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
|
||||
navigate({
|
||||
to: ROUTE_PATHS.Organization.SettingsPage.path
|
||||
});
|
||||
})();
|
||||
}, [isReady]);
|
||||
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<ContentLoader text="Please wait! Authentication in process." />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import { zodValidator } from "@tanstack/zod-adapter";
|
||||
import { z } from "zod";
|
||||
|
||||
import { OAuthCallbackPage } from "./OauthCallbackPage";
|
||||
|
||||
const SettingsOAuthCallbackPageQueryParamsSchema = z.object({
|
||||
state: z
|
||||
.object({
|
||||
tenantId: z.string(),
|
||||
slug: z.string(),
|
||||
description: z.string().optional(),
|
||||
redirectUri: z.string(),
|
||||
csrfToken: z.string()
|
||||
})
|
||||
.nullable()
|
||||
.catch(null),
|
||||
tenant: z.string().catch(""),
|
||||
admin_consent: z.string().catch("")
|
||||
});
|
||||
|
||||
export const Route = createFileRoute(
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings/oauth/callback"
|
||||
)({
|
||||
component: OAuthCallbackPage,
|
||||
validateSearch: zodValidator(SettingsOAuthCallbackPageQueryParamsSchema)
|
||||
});
|
||||
@@ -1,3 +1,5 @@
|
||||
import crypto from "crypto";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
@@ -7,7 +9,7 @@ import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormControl, Input } from "@app/components/v2";
|
||||
import { useOrganization } from "@app/context";
|
||||
import {
|
||||
useCreateMicrosoftTeamsIntegration,
|
||||
useGetMicrosoftTeamsClientId,
|
||||
useGetMicrosoftTeamsIntegrationById,
|
||||
useUpdateMicrosoftTeamsIntegration
|
||||
} from "@app/hooks/api";
|
||||
@@ -38,8 +40,8 @@ export const MicrosoftTeamsIntegrationForm = ({ id, onClose }: Props) => {
|
||||
|
||||
const { currentOrg } = useOrganization();
|
||||
const { data: microsoftTeamsIntegration } = useGetMicrosoftTeamsIntegrationById(id);
|
||||
const { mutateAsync: createMicrosoftTeamsIntegration } = useCreateMicrosoftTeamsIntegration();
|
||||
const { mutateAsync: updateMicrosoftTeamsIntegration } = useUpdateMicrosoftTeamsIntegration();
|
||||
const { data: microsoftTeamsClientId } = useGetMicrosoftTeamsClientId();
|
||||
|
||||
useEffect(() => {
|
||||
if (microsoftTeamsIntegration) {
|
||||
@@ -54,6 +56,14 @@ export const MicrosoftTeamsIntegrationForm = ({ id, onClose }: Props) => {
|
||||
description,
|
||||
tenantId
|
||||
}: TMicrosoftTeamsFormData) => {
|
||||
if (!microsoftTeamsClientId) {
|
||||
createNotification({
|
||||
text: "Microsoft Teams client ID is not set. Please contact your instance administrator.",
|
||||
type: "error"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (id && microsoftTeamsIntegration) {
|
||||
if (!currentOrg) {
|
||||
return;
|
||||
@@ -81,23 +91,37 @@ export const MicrosoftTeamsIntegrationForm = ({ id, onClose }: Props) => {
|
||||
|
||||
onClose();
|
||||
} else {
|
||||
await createMicrosoftTeamsIntegration({
|
||||
orgId: currentOrg.id,
|
||||
const csrfToken = crypto.randomBytes(32).toString("hex");
|
||||
localStorage.setItem("latestCSRFToken", csrfToken);
|
||||
|
||||
const state = {
|
||||
redirectUri: `${window.location.origin}/organization/settings/oauth/callback`,
|
||||
tenantId,
|
||||
slug,
|
||||
description
|
||||
});
|
||||
description,
|
||||
csrfToken
|
||||
};
|
||||
|
||||
onClose();
|
||||
createNotification({
|
||||
text: "Successfully created Microsoft Teams integration",
|
||||
type: "success"
|
||||
});
|
||||
const url = `https://login.microsoftonline.com/${tenantId}/adminconsent?client_id=${microsoftTeamsClientId.clientId}&redirect_uri=${state.redirectUri}&state=${encodeURIComponent(JSON.stringify(state))}`;
|
||||
window.location.href = url;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(handleMicrosoftTeamsFormSubmit)} autoComplete="off">
|
||||
<div className="mb-4 text-xs text-mineshaft-200">
|
||||
For seamless installations, ensure that the Infisical bot is already installed in your
|
||||
Microsoft Teams tenant. For more information, please refer to the{" "}
|
||||
<a
|
||||
className="text-primary-500"
|
||||
href="https://infisical.com/docs/documentation/platform/workflow-integrations/microsoft-teams-integration"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Microsoft Teams Workflow Integration Documentation
|
||||
</a>
|
||||
, which will guide you through the download and installation process.
|
||||
</div>
|
||||
<Controller
|
||||
control={control}
|
||||
name="slug"
|
||||
|
||||
@@ -11,7 +11,7 @@ const SettingsPageQueryParams = z.object({
|
||||
});
|
||||
|
||||
export const Route = createFileRoute(
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings"
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings/"
|
||||
)({
|
||||
component: SettingsPage,
|
||||
validateSearch: zodValidator(SettingsPageQueryParams),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Modal, ModalContent } from "@app/components/v2";
|
||||
import { WorkflowIntegrationPlatform } from "@app/hooks/api/workflowIntegrations/types";
|
||||
|
||||
import { SlackIntegrationForm } from "./SlackIntegrationForm";
|
||||
import { MicrosoftTeamsIntegrationForm } from "./MicrosoftTeamsIntegrationForm";
|
||||
import { SlackIntegrationForm } from "./SlackIntegrationForm";
|
||||
|
||||
type Props = {
|
||||
isOpen?: boolean;
|
||||
|
||||
@@ -42,7 +42,6 @@ import { Route as adminLayoutImport } from './pages/admin/layout'
|
||||
import { Route as authProviderSuccessPageRouteImport } from './pages/auth/ProviderSuccessPage/route'
|
||||
import { Route as authProviderErrorPageRouteImport } from './pages/auth/ProviderErrorPage/route'
|
||||
import { Route as userPersonalSettingsPageRouteImport } from './pages/user/PersonalSettingsPage/route'
|
||||
import { Route as organizationSettingsPageRouteImport } from './pages/organization/SettingsPage/route'
|
||||
import { Route as organizationSecretScanningPageRouteImport } from './pages/organization/SecretScanningPage/route'
|
||||
import { Route as organizationBillingPageRouteImport } from './pages/organization/BillingPage/route'
|
||||
import { Route as organizationAuditLogsPageRouteImport } from './pages/organization/AuditLogsPage/route'
|
||||
@@ -62,6 +61,7 @@ import { Route as organizationKmsOverviewPageRouteImport } from './pages/organiz
|
||||
import { Route as organizationIdentityDetailsByIDPageRouteImport } from './pages/organization/IdentityDetailsByIDPage/route'
|
||||
import { Route as organizationGroupDetailsByIDPageRouteImport } from './pages/organization/GroupDetailsByIDPage/route'
|
||||
import { Route as organizationCertManagerOverviewPageRouteImport } from './pages/organization/CertManagerOverviewPage/route'
|
||||
import { Route as organizationSettingsPageRouteImport } from './pages/organization/SettingsPage/route'
|
||||
import { Route as organizationSecretSharingPageRouteImport } from './pages/organization/SecretSharingPage/route'
|
||||
import { Route as organizationGatewaysGatewayListPageRouteImport } from './pages/organization/Gateways/GatewayListPage/route'
|
||||
import { Route as organizationAppConnectionsAppConnectionsPageRouteImport } from './pages/organization/AppConnections/AppConnectionsPage/route'
|
||||
@@ -87,6 +87,7 @@ import { Route as secretManagerSecretRotationPageRouteImport } from './pages/sec
|
||||
import { Route as secretManagerOverviewPageRouteImport } from './pages/secret-manager/OverviewPage/route'
|
||||
import { Route as secretManagerSecretApprovalsPageRouteImport } from './pages/secret-manager/SecretApprovalsPage/route'
|
||||
import { Route as secretManagerIPAllowlistPageRouteImport } from './pages/secret-manager/IPAllowlistPage/route'
|
||||
import { Route as organizationSettingsPageOauthCallbackPageRouteImport } from './pages/organization/SettingsPage/OauthCallbackPage/route'
|
||||
import { Route as kmsSettingsPageRouteImport } from './pages/kms/SettingsPage/route'
|
||||
import { Route as kmsOverviewPageRouteImport } from './pages/kms/OverviewPage/route'
|
||||
import { Route as kmsKmipPageRouteImport } from './pages/kms/KmipPage/route'
|
||||
@@ -217,6 +218,10 @@ const AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdImport =
|
||||
createFileRoute(
|
||||
'/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId',
|
||||
)()
|
||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsImport =
|
||||
createFileRoute(
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings',
|
||||
)()
|
||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingImport =
|
||||
createFileRoute(
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing',
|
||||
@@ -483,6 +488,14 @@ const AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRoute =
|
||||
getParentRoute: () => organizationLayoutRoute,
|
||||
} as any)
|
||||
|
||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute =
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsImport.update({
|
||||
id: '/settings',
|
||||
path: '/settings',
|
||||
getParentRoute: () =>
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute,
|
||||
} as any)
|
||||
|
||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute =
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingImport.update({
|
||||
id: '/secret-sharing',
|
||||
@@ -521,14 +534,6 @@ const AuthenticateInjectOrgDetailsOrgLayoutCertManagerProjectIdRoute =
|
||||
getParentRoute: () => organizationLayoutRoute,
|
||||
} as any)
|
||||
|
||||
const organizationSettingsPageRouteRoute =
|
||||
organizationSettingsPageRouteImport.update({
|
||||
id: '/settings',
|
||||
path: '/settings',
|
||||
getParentRoute: () =>
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute,
|
||||
} as any)
|
||||
|
||||
const organizationSecretScanningPageRouteRoute =
|
||||
organizationSecretScanningPageRouteImport.update({
|
||||
id: '/secret-scanning',
|
||||
@@ -670,6 +675,14 @@ const organizationCertManagerOverviewPageRouteRoute =
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute,
|
||||
} as any)
|
||||
|
||||
const organizationSettingsPageRouteRoute =
|
||||
organizationSettingsPageRouteImport.update({
|
||||
id: '/',
|
||||
path: '/',
|
||||
getParentRoute: () =>
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute,
|
||||
} as any)
|
||||
|
||||
const organizationSecretSharingPageRouteRoute =
|
||||
organizationSecretSharingPageRouteImport.update({
|
||||
id: '/',
|
||||
@@ -864,6 +877,14 @@ const secretManagerIPAllowlistPageRouteRoute =
|
||||
getParentRoute: () => secretManagerLayoutRoute,
|
||||
} as any)
|
||||
|
||||
const organizationSettingsPageOauthCallbackPageRouteRoute =
|
||||
organizationSettingsPageOauthCallbackPageRouteImport.update({
|
||||
id: '/oauth/callback',
|
||||
path: '/oauth/callback',
|
||||
getParentRoute: () =>
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute,
|
||||
} as any)
|
||||
|
||||
const kmsSettingsPageRouteRoute = kmsSettingsPageRouteImport.update({
|
||||
id: '/settings',
|
||||
path: '/settings',
|
||||
@@ -1952,13 +1973,6 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof organizationSecretScanningPageRouteImport
|
||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport
|
||||
}
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings': {
|
||||
id: '/_authenticate/_inject-org-details/_org-layout/organization/settings'
|
||||
path: '/settings'
|
||||
fullPath: '/organization/settings'
|
||||
preLoaderRoute: typeof organizationSettingsPageRouteImport
|
||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport
|
||||
}
|
||||
'/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId': {
|
||||
id: '/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId'
|
||||
path: '/cert-manager/$projectId'
|
||||
@@ -1994,6 +2008,13 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingImport
|
||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport
|
||||
}
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings': {
|
||||
id: '/_authenticate/_inject-org-details/_org-layout/organization/settings'
|
||||
path: '/settings'
|
||||
fullPath: '/organization/settings'
|
||||
preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsImport
|
||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport
|
||||
}
|
||||
'/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId': {
|
||||
id: '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId'
|
||||
path: '/secret-manager/$projectId'
|
||||
@@ -2029,6 +2050,13 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof organizationSecretSharingPageRouteImport
|
||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingImport
|
||||
}
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings/': {
|
||||
id: '/_authenticate/_inject-org-details/_org-layout/organization/settings/'
|
||||
path: '/'
|
||||
fullPath: '/organization/settings/'
|
||||
preLoaderRoute: typeof organizationSettingsPageRouteImport
|
||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsImport
|
||||
}
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview': {
|
||||
id: '/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview'
|
||||
path: '/cert-manager/overview'
|
||||
@@ -2169,6 +2197,13 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof kmsSettingsPageRouteImport
|
||||
parentRoute: typeof kmsLayoutImport
|
||||
}
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings/oauth/callback': {
|
||||
id: '/_authenticate/_inject-org-details/_org-layout/organization/settings/oauth/callback'
|
||||
path: '/oauth/callback'
|
||||
fullPath: '/organization/settings/oauth/callback'
|
||||
preLoaderRoute: typeof organizationSettingsPageOauthCallbackPageRouteImport
|
||||
parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsImport
|
||||
}
|
||||
'/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/allowlist': {
|
||||
id: '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/allowlist'
|
||||
path: '/allowlist'
|
||||
@@ -3090,16 +3125,33 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChi
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteChildren,
|
||||
)
|
||||
|
||||
interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteChildren {
|
||||
organizationSettingsPageRouteRoute: typeof organizationSettingsPageRouteRoute
|
||||
organizationSettingsPageOauthCallbackPageRouteRoute: typeof organizationSettingsPageOauthCallbackPageRouteRoute
|
||||
}
|
||||
|
||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteChildren =
|
||||
{
|
||||
organizationSettingsPageRouteRoute: organizationSettingsPageRouteRoute,
|
||||
organizationSettingsPageOauthCallbackPageRouteRoute:
|
||||
organizationSettingsPageOauthCallbackPageRouteRoute,
|
||||
}
|
||||
|
||||
const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren =
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute._addFileChildren(
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteChildren,
|
||||
)
|
||||
|
||||
interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteChildren {
|
||||
organizationAccessManagementPageRouteRoute: typeof organizationAccessManagementPageRouteRoute
|
||||
organizationAdminPageRouteRoute: typeof organizationAdminPageRouteRoute
|
||||
organizationAuditLogsPageRouteRoute: typeof organizationAuditLogsPageRouteRoute
|
||||
organizationBillingPageRouteRoute: typeof organizationBillingPageRouteRoute
|
||||
organizationSecretScanningPageRouteRoute: typeof organizationSecretScanningPageRouteRoute
|
||||
organizationSettingsPageRouteRoute: typeof organizationSettingsPageRouteRoute
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren
|
||||
organizationCertManagerOverviewPageRouteRoute: typeof organizationCertManagerOverviewPageRouteRoute
|
||||
organizationGroupDetailsByIDPageRouteRoute: typeof organizationGroupDetailsByIDPageRouteRoute
|
||||
organizationIdentityDetailsByIDPageRouteRoute: typeof organizationIdentityDetailsByIDPageRouteRoute
|
||||
@@ -3119,13 +3171,14 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteChildren: Authentica
|
||||
organizationBillingPageRouteRoute: organizationBillingPageRouteRoute,
|
||||
organizationSecretScanningPageRouteRoute:
|
||||
organizationSecretScanningPageRouteRoute,
|
||||
organizationSettingsPageRouteRoute: organizationSettingsPageRouteRoute,
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute:
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren,
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRoute:
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren,
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute:
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren,
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute:
|
||||
AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren,
|
||||
organizationCertManagerOverviewPageRouteRoute:
|
||||
organizationCertManagerOverviewPageRouteRoute,
|
||||
organizationGroupDetailsByIDPageRouteRoute:
|
||||
@@ -3809,17 +3862,18 @@ export interface FileRoutesByFullPath {
|
||||
'/organization/audit-logs': typeof organizationAuditLogsPageRouteRoute
|
||||
'/organization/billing': typeof organizationBillingPageRouteRoute
|
||||
'/organization/secret-scanning': typeof organizationSecretScanningPageRouteRoute
|
||||
'/organization/settings': typeof organizationSettingsPageRouteRoute
|
||||
'/cert-manager/$projectId': typeof certManagerLayoutRouteWithChildren
|
||||
'/kms/$projectId': typeof kmsLayoutRouteWithChildren
|
||||
'/organization/app-connections': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren
|
||||
'/organization/gateways': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren
|
||||
'/organization/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren
|
||||
'/organization/settings': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren
|
||||
'/secret-manager/$projectId': typeof secretManagerLayoutRouteWithChildren
|
||||
'/ssh/$projectId': typeof sshLayoutRouteWithChildren
|
||||
'/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute
|
||||
'/organization/gateways/': typeof organizationGatewaysGatewayListPageRouteRoute
|
||||
'/organization/secret-sharing/': typeof organizationSecretSharingPageRouteRoute
|
||||
'/organization/settings/': typeof organizationSettingsPageRouteRoute
|
||||
'/organization/cert-manager/overview': typeof organizationCertManagerOverviewPageRouteRoute
|
||||
'/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute
|
||||
'/organization/identities/$identityId': typeof organizationIdentityDetailsByIDPageRouteRoute
|
||||
@@ -3836,6 +3890,7 @@ export interface FileRoutesByFullPath {
|
||||
'/kms/$projectId/kmip': typeof kmsKmipPageRouteRoute
|
||||
'/kms/$projectId/overview': typeof kmsOverviewPageRouteRoute
|
||||
'/kms/$projectId/settings': typeof kmsSettingsPageRouteRoute
|
||||
'/organization/settings/oauth/callback': typeof organizationSettingsPageOauthCallbackPageRouteRoute
|
||||
'/secret-manager/$projectId/allowlist': typeof secretManagerIPAllowlistPageRouteRoute
|
||||
'/secret-manager/$projectId/approval': typeof secretManagerSecretApprovalsPageRouteRoute
|
||||
'/secret-manager/$projectId/overview': typeof secretManagerOverviewPageRouteRoute
|
||||
@@ -3989,7 +4044,6 @@ export interface FileRoutesByTo {
|
||||
'/organization/audit-logs': typeof organizationAuditLogsPageRouteRoute
|
||||
'/organization/billing': typeof organizationBillingPageRouteRoute
|
||||
'/organization/secret-scanning': typeof organizationSecretScanningPageRouteRoute
|
||||
'/organization/settings': typeof organizationSettingsPageRouteRoute
|
||||
'/cert-manager/$projectId': typeof certManagerLayoutRouteWithChildren
|
||||
'/kms/$projectId': typeof kmsLayoutRouteWithChildren
|
||||
'/secret-manager/$projectId': typeof secretManagerLayoutRouteWithChildren
|
||||
@@ -3997,6 +4051,7 @@ export interface FileRoutesByTo {
|
||||
'/organization/app-connections': typeof organizationAppConnectionsAppConnectionsPageRouteRoute
|
||||
'/organization/gateways': typeof organizationGatewaysGatewayListPageRouteRoute
|
||||
'/organization/secret-sharing': typeof organizationSecretSharingPageRouteRoute
|
||||
'/organization/settings': typeof organizationSettingsPageRouteRoute
|
||||
'/organization/cert-manager/overview': typeof organizationCertManagerOverviewPageRouteRoute
|
||||
'/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute
|
||||
'/organization/identities/$identityId': typeof organizationIdentityDetailsByIDPageRouteRoute
|
||||
@@ -4013,6 +4068,7 @@ export interface FileRoutesByTo {
|
||||
'/kms/$projectId/kmip': typeof kmsKmipPageRouteRoute
|
||||
'/kms/$projectId/overview': typeof kmsOverviewPageRouteRoute
|
||||
'/kms/$projectId/settings': typeof kmsSettingsPageRouteRoute
|
||||
'/organization/settings/oauth/callback': typeof organizationSettingsPageOauthCallbackPageRouteRoute
|
||||
'/secret-manager/$projectId/allowlist': typeof secretManagerIPAllowlistPageRouteRoute
|
||||
'/secret-manager/$projectId/approval': typeof secretManagerSecretApprovalsPageRouteRoute
|
||||
'/secret-manager/$projectId/overview': typeof secretManagerOverviewPageRouteRoute
|
||||
@@ -4175,17 +4231,18 @@ export interface FileRoutesById {
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/audit-logs': typeof organizationAuditLogsPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/billing': typeof organizationBillingPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/secret-scanning': typeof organizationSecretScanningPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings': typeof organizationSettingsPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutCertManagerProjectIdRouteWithChildren
|
||||
'/_authenticate/_inject-org-details/_org-layout/kms/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutKmsProjectIdRouteWithChildren
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/app-connections': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/gateways': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren
|
||||
'/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren
|
||||
'/_authenticate/_inject-org-details/_org-layout/ssh/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSshProjectIdRouteWithChildren
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/gateways/': typeof organizationGatewaysGatewayListPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/': typeof organizationSecretSharingPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings/': typeof organizationSettingsPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview': typeof organizationCertManagerOverviewPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/identities/$identityId': typeof organizationIdentityDetailsByIDPageRouteRoute
|
||||
@@ -4206,6 +4263,7 @@ export interface FileRoutesById {
|
||||
'/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout/kmip': typeof kmsKmipPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout/overview': typeof kmsOverviewPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout/settings': typeof kmsSettingsPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings/oauth/callback': typeof organizationSettingsPageOauthCallbackPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/allowlist': typeof secretManagerIPAllowlistPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/approval': typeof secretManagerSecretApprovalsPageRouteRoute
|
||||
'/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/overview': typeof secretManagerOverviewPageRouteRoute
|
||||
@@ -4365,17 +4423,18 @@ export interface FileRouteTypes {
|
||||
| '/organization/audit-logs'
|
||||
| '/organization/billing'
|
||||
| '/organization/secret-scanning'
|
||||
| '/organization/settings'
|
||||
| '/cert-manager/$projectId'
|
||||
| '/kms/$projectId'
|
||||
| '/organization/app-connections'
|
||||
| '/organization/gateways'
|
||||
| '/organization/secret-sharing'
|
||||
| '/organization/settings'
|
||||
| '/secret-manager/$projectId'
|
||||
| '/ssh/$projectId'
|
||||
| '/organization/app-connections/'
|
||||
| '/organization/gateways/'
|
||||
| '/organization/secret-sharing/'
|
||||
| '/organization/settings/'
|
||||
| '/organization/cert-manager/overview'
|
||||
| '/organization/groups/$groupId'
|
||||
| '/organization/identities/$identityId'
|
||||
@@ -4392,6 +4451,7 @@ export interface FileRouteTypes {
|
||||
| '/kms/$projectId/kmip'
|
||||
| '/kms/$projectId/overview'
|
||||
| '/kms/$projectId/settings'
|
||||
| '/organization/settings/oauth/callback'
|
||||
| '/secret-manager/$projectId/allowlist'
|
||||
| '/secret-manager/$projectId/approval'
|
||||
| '/secret-manager/$projectId/overview'
|
||||
@@ -4544,7 +4604,6 @@ export interface FileRouteTypes {
|
||||
| '/organization/audit-logs'
|
||||
| '/organization/billing'
|
||||
| '/organization/secret-scanning'
|
||||
| '/organization/settings'
|
||||
| '/cert-manager/$projectId'
|
||||
| '/kms/$projectId'
|
||||
| '/secret-manager/$projectId'
|
||||
@@ -4552,6 +4611,7 @@ export interface FileRouteTypes {
|
||||
| '/organization/app-connections'
|
||||
| '/organization/gateways'
|
||||
| '/organization/secret-sharing'
|
||||
| '/organization/settings'
|
||||
| '/organization/cert-manager/overview'
|
||||
| '/organization/groups/$groupId'
|
||||
| '/organization/identities/$identityId'
|
||||
@@ -4568,6 +4628,7 @@ export interface FileRouteTypes {
|
||||
| '/kms/$projectId/kmip'
|
||||
| '/kms/$projectId/overview'
|
||||
| '/kms/$projectId/settings'
|
||||
| '/organization/settings/oauth/callback'
|
||||
| '/secret-manager/$projectId/allowlist'
|
||||
| '/secret-manager/$projectId/approval'
|
||||
| '/secret-manager/$projectId/overview'
|
||||
@@ -4728,17 +4789,18 @@ export interface FileRouteTypes {
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/audit-logs'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/billing'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/secret-scanning'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/settings'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/kms/$projectId'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/app-connections'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/gateways'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/settings'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/ssh/$projectId'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/gateways/'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/settings/'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/identities/$identityId'
|
||||
@@ -4759,6 +4821,7 @@ export interface FileRouteTypes {
|
||||
| '/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout/kmip'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout/overview'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout/settings'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/organization/settings/oauth/callback'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/allowlist'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/approval'
|
||||
| '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/overview'
|
||||
@@ -5117,10 +5180,10 @@ export const routeTree = rootRoute
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/audit-logs",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/billing",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/secret-scanning",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/app-connections",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/gateways",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/identities/$identityId",
|
||||
@@ -5162,10 +5225,6 @@ export const routeTree = rootRoute
|
||||
"filePath": "organization/SecretScanningPage/route.tsx",
|
||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization"
|
||||
},
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings": {
|
||||
"filePath": "organization/SettingsPage/route.tsx",
|
||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization"
|
||||
},
|
||||
"/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId": {
|
||||
"filePath": "",
|
||||
"parent": "/_authenticate/_inject-org-details/_org-layout",
|
||||
@@ -5203,6 +5262,14 @@ export const routeTree = rootRoute
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/settings"
|
||||
]
|
||||
},
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings": {
|
||||
"filePath": "",
|
||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization",
|
||||
"children": [
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings/",
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings/oauth/callback"
|
||||
]
|
||||
},
|
||||
"/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId": {
|
||||
"filePath": "",
|
||||
"parent": "/_authenticate/_inject-org-details/_org-layout",
|
||||
@@ -5229,6 +5296,10 @@ export const routeTree = rootRoute
|
||||
"filePath": "organization/SecretSharingPage/route.tsx",
|
||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing"
|
||||
},
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings/": {
|
||||
"filePath": "organization/SettingsPage/route.tsx",
|
||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization/settings"
|
||||
},
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview": {
|
||||
"filePath": "organization/CertManagerOverviewPage/route.tsx",
|
||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization"
|
||||
@@ -5354,6 +5425,10 @@ export const routeTree = rootRoute
|
||||
"filePath": "kms/SettingsPage/route.tsx",
|
||||
"parent": "/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout"
|
||||
},
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/settings/oauth/callback": {
|
||||
"filePath": "organization/SettingsPage/OauthCallbackPage/route.tsx",
|
||||
"parent": "/_authenticate/_inject-org-details/_org-layout/organization/settings"
|
||||
},
|
||||
"/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout/allowlist": {
|
||||
"filePath": "secret-manager/IPAllowlistPage/route.tsx",
|
||||
"parent": "/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/_secret-manager-layout"
|
||||
|
||||
@@ -20,7 +20,10 @@ const organizationRoutes = route("/organization", [
|
||||
index("organization/SecretSharingPage/route.tsx"),
|
||||
route("/settings", "organization/SecretSharingSettingsPage/route.tsx")
|
||||
]),
|
||||
route("/settings", "organization/SettingsPage/route.tsx"),
|
||||
route("/settings", [
|
||||
index("organization/SettingsPage/route.tsx"),
|
||||
route("/oauth/callback", "organization/SettingsPage/OauthCallbackPage/route.tsx")
|
||||
]),
|
||||
route("/secret-scanning", "organization/SecretScanningPage/route.tsx"),
|
||||
route("/groups/$groupId", "organization/GroupDetailsByIDPage/route.tsx"),
|
||||
route("/members/$membershipId", "organization/UserDetailsByIDPage/route.tsx"),
|
||||
|
||||
Reference in New Issue
Block a user