mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 05:26:11 +00:00
feat: updated form for oidc auth
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { useInfiniteQuery, useQuery, UseQueryOptions } from "@tanstack/react-query";
|
import { useInfiniteQuery, useQuery, UseQueryOptions } from "@tanstack/react-query";
|
||||||
|
|
||||||
import { apiRequest } from "@app/config/request";
|
import { apiRequest } from "@app/config/request";
|
||||||
|
import { Identity } from "@app/hooks/api/identities/types";
|
||||||
|
|
||||||
import { User } from "../types";
|
import { User } from "../types";
|
||||||
import {
|
import {
|
||||||
@@ -10,7 +11,6 @@ import {
|
|||||||
TGetServerRootKmsEncryptionDetails,
|
TGetServerRootKmsEncryptionDetails,
|
||||||
TServerConfig
|
TServerConfig
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import { Identity } from "@app/hooks/api/identities/types";
|
|
||||||
|
|
||||||
export const adminStandaloneKeys = {
|
export const adminStandaloneKeys = {
|
||||||
getUsers: "get-users",
|
getUsers: "get-users",
|
||||||
|
|||||||
@@ -462,6 +462,7 @@ export const useUpdateIdentityOidcAuth = () => {
|
|||||||
boundIssuer,
|
boundIssuer,
|
||||||
boundAudiences,
|
boundAudiences,
|
||||||
boundClaims,
|
boundClaims,
|
||||||
|
claimMetadataMapping,
|
||||||
boundSubject
|
boundSubject
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
@@ -478,7 +479,8 @@ export const useUpdateIdentityOidcAuth = () => {
|
|||||||
accessTokenTTL,
|
accessTokenTTL,
|
||||||
accessTokenMaxTTL,
|
accessTokenMaxTTL,
|
||||||
accessTokenNumUsesLimit,
|
accessTokenNumUsesLimit,
|
||||||
accessTokenTrustedIps
|
accessTokenTrustedIps,
|
||||||
|
claimMetadataMapping
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -504,6 +506,7 @@ export const useAddIdentityOidcAuth = () => {
|
|||||||
boundIssuer,
|
boundIssuer,
|
||||||
boundAudiences,
|
boundAudiences,
|
||||||
boundClaims,
|
boundClaims,
|
||||||
|
claimMetadataMapping,
|
||||||
boundSubject,
|
boundSubject,
|
||||||
accessTokenTTL,
|
accessTokenTTL,
|
||||||
accessTokenMaxTTL,
|
accessTokenMaxTTL,
|
||||||
@@ -524,7 +527,8 @@ export const useAddIdentityOidcAuth = () => {
|
|||||||
accessTokenTTL,
|
accessTokenTTL,
|
||||||
accessTokenMaxTTL,
|
accessTokenMaxTTL,
|
||||||
accessTokenNumUsesLimit,
|
accessTokenNumUsesLimit,
|
||||||
accessTokenTrustedIps
|
accessTokenTrustedIps,
|
||||||
|
claimMetadataMapping
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -193,6 +193,7 @@ export type IdentityOidcAuth = {
|
|||||||
boundIssuer: string;
|
boundIssuer: string;
|
||||||
boundAudiences: string;
|
boundAudiences: string;
|
||||||
boundClaims: Record<string, string>;
|
boundClaims: Record<string, string>;
|
||||||
|
claimMetadataMapping: Record<string, string>;
|
||||||
boundSubject: string;
|
boundSubject: string;
|
||||||
accessTokenTTL: number;
|
accessTokenTTL: number;
|
||||||
accessTokenMaxTTL: number;
|
accessTokenMaxTTL: number;
|
||||||
@@ -208,6 +209,7 @@ export type AddIdentityOidcAuthDTO = {
|
|||||||
boundIssuer: string;
|
boundIssuer: string;
|
||||||
boundAudiences: string;
|
boundAudiences: string;
|
||||||
boundClaims: Record<string, string>;
|
boundClaims: Record<string, string>;
|
||||||
|
claimMetadataMapping: Record<string, string>;
|
||||||
boundSubject: string;
|
boundSubject: string;
|
||||||
accessTokenTTL: number;
|
accessTokenTTL: number;
|
||||||
accessTokenMaxTTL: number;
|
accessTokenMaxTTL: number;
|
||||||
@@ -225,6 +227,7 @@ export type UpdateIdentityOidcAuthDTO = {
|
|||||||
boundIssuer?: string;
|
boundIssuer?: string;
|
||||||
boundAudiences?: string;
|
boundAudiences?: string;
|
||||||
boundClaims?: Record<string, string>;
|
boundClaims?: Record<string, string>;
|
||||||
|
claimMetadataMapping?: Record<string, string>;
|
||||||
boundSubject?: string;
|
boundSubject?: string;
|
||||||
accessTokenTTL?: number;
|
accessTokenTTL?: number;
|
||||||
accessTokenMaxTTL?: number;
|
accessTokenMaxTTL?: number;
|
||||||
|
|||||||
@@ -28,13 +28,13 @@ import {
|
|||||||
useGetServerRootKmsEncryptionDetails,
|
useGetServerRootKmsEncryptionDetails,
|
||||||
useUpdateServerConfig
|
useUpdateServerConfig
|
||||||
} from "@app/hooks/api";
|
} from "@app/hooks/api";
|
||||||
|
import { IdentityPanel } from "@app/pages/admin/OverviewPage/components/IdentityPanel";
|
||||||
|
|
||||||
import { AuthPanel } from "./components/AuthPanel";
|
import { AuthPanel } from "./components/AuthPanel";
|
||||||
import { EncryptionPanel } from "./components/EncryptionPanel";
|
import { EncryptionPanel } from "./components/EncryptionPanel";
|
||||||
import { IntegrationPanel } from "./components/IntegrationPanel";
|
import { IntegrationPanel } from "./components/IntegrationPanel";
|
||||||
import { RateLimitPanel } from "./components/RateLimitPanel";
|
import { RateLimitPanel } from "./components/RateLimitPanel";
|
||||||
import { UserPanel } from "./components/UserPanel";
|
import { UserPanel } from "./components/UserPanel";
|
||||||
import { IdentityPanel } from "@app/pages/admin/OverviewPage/components/IdentityPanel";
|
|
||||||
|
|
||||||
enum TabSections {
|
enum TabSections {
|
||||||
Settings = "settings",
|
Settings = "settings",
|
||||||
|
|||||||
+104
@@ -52,6 +52,12 @@ const schema = z.object({
|
|||||||
value: z.string()
|
value: z.string()
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
claimMetadataMapping: z.array(
|
||||||
|
z.object({
|
||||||
|
key: z.string(),
|
||||||
|
value: z.string()
|
||||||
|
})
|
||||||
|
),
|
||||||
boundSubject: z.string().optional().default("")
|
boundSubject: z.string().optional().default("")
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -109,6 +115,15 @@ export const IdentityOidcAuthForm = ({
|
|||||||
name: "boundClaims"
|
name: "boundClaims"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
fields: claimMetadataMappingFields,
|
||||||
|
append: appendClaimMetadataMappingField,
|
||||||
|
remove: removeClaimMetadataMappingField
|
||||||
|
} = useFieldArray({
|
||||||
|
control,
|
||||||
|
name: "claimMetadataMapping"
|
||||||
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
fields: accessTokenTrustedIpsFields,
|
fields: accessTokenTrustedIpsFields,
|
||||||
append: appendAccessTokenTrustedIp,
|
append: appendAccessTokenTrustedIp,
|
||||||
@@ -126,6 +141,10 @@ export const IdentityOidcAuthForm = ({
|
|||||||
key,
|
key,
|
||||||
value
|
value
|
||||||
})),
|
})),
|
||||||
|
claimMetadataMapping: Object.entries(data.claimMetadataMapping).map(([key, value]) => ({
|
||||||
|
key,
|
||||||
|
value
|
||||||
|
})),
|
||||||
boundSubject: data.boundSubject,
|
boundSubject: data.boundSubject,
|
||||||
accessTokenTTL: String(data.accessTokenTTL),
|
accessTokenTTL: String(data.accessTokenTTL),
|
||||||
accessTokenMaxTTL: String(data.accessTokenMaxTTL),
|
accessTokenMaxTTL: String(data.accessTokenMaxTTL),
|
||||||
@@ -164,6 +183,7 @@ export const IdentityOidcAuthForm = ({
|
|||||||
boundIssuer,
|
boundIssuer,
|
||||||
boundAudiences,
|
boundAudiences,
|
||||||
boundClaims,
|
boundClaims,
|
||||||
|
claimMetadataMapping,
|
||||||
boundSubject
|
boundSubject
|
||||||
}: FormData) => {
|
}: FormData) => {
|
||||||
try {
|
try {
|
||||||
@@ -180,6 +200,9 @@ export const IdentityOidcAuthForm = ({
|
|||||||
boundIssuer,
|
boundIssuer,
|
||||||
boundAudiences,
|
boundAudiences,
|
||||||
boundClaims: Object.fromEntries(boundClaims.map((entry) => [entry.key, entry.value])),
|
boundClaims: Object.fromEntries(boundClaims.map((entry) => [entry.key, entry.value])),
|
||||||
|
claimMetadataMapping: Object.fromEntries(
|
||||||
|
claimMetadataMapping.map((entry) => [entry.key, entry.value])
|
||||||
|
),
|
||||||
boundSubject,
|
boundSubject,
|
||||||
accessTokenTTL: Number(accessTokenTTL),
|
accessTokenTTL: Number(accessTokenTTL),
|
||||||
accessTokenMaxTTL: Number(accessTokenMaxTTL),
|
accessTokenMaxTTL: Number(accessTokenMaxTTL),
|
||||||
@@ -194,6 +217,9 @@ export const IdentityOidcAuthForm = ({
|
|||||||
boundIssuer,
|
boundIssuer,
|
||||||
boundAudiences,
|
boundAudiences,
|
||||||
boundClaims: Object.fromEntries(boundClaims.map((entry) => [entry.key, entry.value])),
|
boundClaims: Object.fromEntries(boundClaims.map((entry) => [entry.key, entry.value])),
|
||||||
|
claimMetadataMapping: Object.fromEntries(
|
||||||
|
claimMetadataMapping.map((entry) => [entry.key, entry.value])
|
||||||
|
),
|
||||||
boundSubject,
|
boundSubject,
|
||||||
organizationId: orgId,
|
organizationId: orgId,
|
||||||
accessTokenTTL: Number(accessTokenTTL),
|
accessTokenTTL: Number(accessTokenTTL),
|
||||||
@@ -449,6 +475,84 @@ export const IdentityOidcAuthForm = ({
|
|||||||
Add Claims
|
Add Claims
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
{claimMetadataMappingFields.map(({ id }, index) => (
|
||||||
|
<div className="mb-3 flex items-end space-x-2" key={id}>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name={`claimMetadataMapping.${index}.key`}
|
||||||
|
render={({ field, fieldState: { error } }) => {
|
||||||
|
return (
|
||||||
|
<FormControl
|
||||||
|
className="mb-0 flex-grow"
|
||||||
|
label={index === 0 ? "Claim Metadata Mapping" : undefined}
|
||||||
|
icon={
|
||||||
|
index === 0 ? (
|
||||||
|
<Tooltip
|
||||||
|
className="text-center"
|
||||||
|
content="Map token claims to metadata. This can later be accessed in attribute based permission as identity.metadata.oidc.claims.<>."
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faQuestionCircle} size="sm" />
|
||||||
|
</Tooltip>
|
||||||
|
) : undefined
|
||||||
|
}
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
value={field.value}
|
||||||
|
onChange={(e) => field.onChange(e)}
|
||||||
|
placeholder="property"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name={`claimMetadataMapping.${index}.value`}
|
||||||
|
render={({ field, fieldState: { error } }) => {
|
||||||
|
return (
|
||||||
|
<FormControl
|
||||||
|
className="mb-0 flex-grow"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
value={field.value}
|
||||||
|
onChange={(e) => field.onChange(e)}
|
||||||
|
placeholder="key1.nested-key2"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
onClick={() => removeClaimMetadataMappingField(index)}
|
||||||
|
size="lg"
|
||||||
|
colorSchema="danger"
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="update"
|
||||||
|
className="p-3"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faXmark} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="my-4 ml-1">
|
||||||
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
|
onClick={() =>
|
||||||
|
appendClaimMetadataMappingField({
|
||||||
|
key: "",
|
||||||
|
value: ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
Add Mapping
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
||||||
<div className="mb-3 flex items-end space-x-2" key={id}>
|
<div className="mb-3 flex items-end space-x-2" key={id}>
|
||||||
<Controller
|
<Controller
|
||||||
|
|||||||
+20
@@ -111,6 +111,26 @@ export const ViewIdentityOidcAuthContent = ({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
</IdentityAuthFieldDisplay>
|
</IdentityAuthFieldDisplay>
|
||||||
|
<IdentityAuthFieldDisplay className="col-span-2" label="Claim Metadata Mapping">
|
||||||
|
{Object.keys(data.claimMetadataMapping).length && (
|
||||||
|
<Tooltip
|
||||||
|
side="right"
|
||||||
|
className="max-w-xl p-2"
|
||||||
|
content={
|
||||||
|
<pre className="whitespace-pre-wrap rounded bg-mineshaft-600 p-2">
|
||||||
|
{JSON.stringify(data.claimMetadataMapping, null, 2)}
|
||||||
|
</pre>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className="w-min">
|
||||||
|
<Badge className="flex h-5 w-min items-center gap-1.5 whitespace-nowrap bg-mineshaft-400/50 text-bunker-300">
|
||||||
|
<FontAwesomeIcon icon={faEye} />
|
||||||
|
<span>Reveal</span>
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</IdentityAuthFieldDisplay>
|
||||||
</ViewIdentityContentWrapper>
|
</ViewIdentityContentWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+4
-1
@@ -306,7 +306,10 @@ export const SecretItem = memo(
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div key="actions" className="flex h-full flex-shrink-0 self-start transition-all group-hover:gap-x-2">
|
<div
|
||||||
|
key="actions"
|
||||||
|
className="flex h-full flex-shrink-0 self-start transition-all group-hover:gap-x-2"
|
||||||
|
>
|
||||||
<Tooltip content="Copy secret">
|
<Tooltip content="Copy secret">
|
||||||
<IconButton
|
<IconButton
|
||||||
isDisabled={secret.secretValueHidden}
|
isDisabled={secret.secretValueHidden}
|
||||||
|
|||||||
Reference in New Issue
Block a user