diff --git a/backend/src/server/plugins/auth/inject-identity.ts b/backend/src/server/plugins/auth/inject-identity.ts index 9005fbf96..5779b39f7 100644 --- a/backend/src/server/plugins/auth/inject-identity.ts +++ b/backend/src/server/plugins/auth/inject-identity.ts @@ -138,10 +138,12 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => { identityName: identity.name, authMethod: null }; - requestContext.set("identityAuthInfo", { - identityId: identity.identityId, - oidc: token?.identityAuth?.oidc - }); + if (token?.identityAuth?.oidc) { + requestContext.set("identityAuthInfo", { + identityId: identity.identityId, + oidc: token?.identityAuth?.oidc + }); + } break; } case AuthMode.SERVICE_TOKEN: { diff --git a/backend/src/server/routes/v1/identity-oidc-auth-router.ts b/backend/src/server/routes/v1/identity-oidc-auth-router.ts index a27c12daf..f3098c851 100644 --- a/backend/src/server/routes/v1/identity-oidc-auth-router.ts +++ b/backend/src/server/routes/v1/identity-oidc-auth-router.ts @@ -105,7 +105,7 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider) boundIssuer: z.string().min(1).describe(OIDC_AUTH.ATTACH.boundIssuer), boundAudiences: validateOidcAuthAudiencesField.describe(OIDC_AUTH.ATTACH.boundAudiences), boundClaims: validateOidcBoundClaimsField.describe(OIDC_AUTH.ATTACH.boundClaims), - claimMetadataMapping: validateOidcBoundClaimsField.describe(OIDC_AUTH.ATTACH.claimMetadataMapping), + claimMetadataMapping: validateOidcBoundClaimsField.describe(OIDC_AUTH.ATTACH.claimMetadataMapping).optional(), boundSubject: z.string().optional().default("").describe(OIDC_AUTH.ATTACH.boundSubject), accessTokenTrustedIps: z .object({ @@ -203,7 +203,7 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider) boundIssuer: z.string().min(1).describe(OIDC_AUTH.UPDATE.boundIssuer), boundAudiences: validateOidcAuthAudiencesField.describe(OIDC_AUTH.UPDATE.boundAudiences), boundClaims: validateOidcBoundClaimsField.describe(OIDC_AUTH.UPDATE.boundClaims), - claimMetadataMapping: validateOidcBoundClaimsField.describe(OIDC_AUTH.UPDATE.claimMetadataMapping), + claimMetadataMapping: validateOidcBoundClaimsField.describe(OIDC_AUTH.UPDATE.claimMetadataMapping).optional(), boundSubject: z.string().optional().default("").describe(OIDC_AUTH.UPDATE.boundSubject), accessTokenTrustedIps: z .object({ diff --git a/backend/src/services/identity-oidc-auth/identity-oidc-auth-types.ts b/backend/src/services/identity-oidc-auth/identity-oidc-auth-types.ts index 7f9f62296..9727285e7 100644 --- a/backend/src/services/identity-oidc-auth/identity-oidc-auth-types.ts +++ b/backend/src/services/identity-oidc-auth/identity-oidc-auth-types.ts @@ -7,7 +7,7 @@ export type TAttachOidcAuthDTO = { boundIssuer: string; boundAudiences: string; boundClaims: Record; - claimMetadataMapping: Record; + claimMetadataMapping?: Record; boundSubject: string; accessTokenTTL: number; accessTokenMaxTTL: number; diff --git a/frontend/src/hooks/api/identities/types.ts b/frontend/src/hooks/api/identities/types.ts index 9920fcf0b..86d35e086 100644 --- a/frontend/src/hooks/api/identities/types.ts +++ b/frontend/src/hooks/api/identities/types.ts @@ -193,7 +193,7 @@ export type IdentityOidcAuth = { boundIssuer: string; boundAudiences: string; boundClaims: Record; - claimMetadataMapping: Record; + claimMetadataMapping?: Record; boundSubject: string; accessTokenTTL: number; accessTokenMaxTTL: number; @@ -209,7 +209,7 @@ export type AddIdentityOidcAuthDTO = { boundIssuer: string; boundAudiences: string; boundClaims: Record; - claimMetadataMapping: Record; + claimMetadataMapping?: Record; boundSubject: string; accessTokenTTL: number; accessTokenMaxTTL: number; diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityOidcAuthForm.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityOidcAuthForm.tsx index 094be734e..21440457a 100644 --- a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityOidcAuthForm.tsx +++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityOidcAuthForm.tsx @@ -52,12 +52,15 @@ const schema = z.object({ value: z.string() }) ), - claimMetadataMapping: z.array( - z.object({ - key: z.string(), - value: z.string() - }) - ), + claimMetadataMapping: z + .array( + z.object({ + key: z.string(), + value: z.string() + }) + ) + .optional() + .nullable(), boundSubject: z.string().optional().default("") }); @@ -105,7 +108,6 @@ export const IdentityOidcAuthForm = ({ accessTokenTrustedIps: [{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }] } }); - const { fields: boundClaimsFields, append: appendBoundClaimField, @@ -141,10 +143,12 @@ export const IdentityOidcAuthForm = ({ key, value })), - claimMetadataMapping: Object.entries(data.claimMetadataMapping).map(([key, value]) => ({ - key, - value - })), + claimMetadataMapping: data?.claimMetadataMapping + ? Object.entries(data.claimMetadataMapping).map(([key, value]) => ({ + key, + value + })) + : undefined, boundSubject: data.boundSubject, accessTokenTTL: String(data.accessTokenTTL), accessTokenMaxTTL: String(data.accessTokenMaxTTL), @@ -200,9 +204,9 @@ export const IdentityOidcAuthForm = ({ boundIssuer, boundAudiences, boundClaims: Object.fromEntries(boundClaims.map((entry) => [entry.key, entry.value])), - claimMetadataMapping: Object.fromEntries( - claimMetadataMapping.map((entry) => [entry.key, entry.value]) - ), + claimMetadataMapping: claimMetadataMapping + ? Object.fromEntries(claimMetadataMapping.map((entry) => [entry.key, entry.value])) + : undefined, boundSubject, accessTokenTTL: Number(accessTokenTTL), accessTokenMaxTTL: Number(accessTokenMaxTTL), @@ -217,9 +221,9 @@ export const IdentityOidcAuthForm = ({ boundIssuer, boundAudiences, boundClaims: Object.fromEntries(boundClaims.map((entry) => [entry.key, entry.value])), - claimMetadataMapping: Object.fromEntries( - claimMetadataMapping.map((entry) => [entry.key, entry.value]) - ), + claimMetadataMapping: claimMetadataMapping + ? Object.fromEntries(claimMetadataMapping.map((entry) => [entry.key, entry.value])) + : undefined, boundSubject, organizationId: orgId, accessTokenTTL: Number(accessTokenTTL),