@@ -525,7 +593,10 @@ export default function TokenUserAttributesSection({
renderValue={(selected) =>
!selected ? (
- {t('applications:edit.token.id_token.encryption_alg_placeholder')}
+ {t(
+ 'applications:edit.token.id_token.encryption_alg_placeholder',
+ 'Select encryption algorithm',
+ )}
) : (
selected
@@ -552,7 +623,10 @@ export default function TokenUserAttributesSection({
renderValue={(selected) =>
!selected ? (
- {t('applications:edit.token.id_token.encryption_enc_placeholder')}
+ {t(
+ 'applications:edit.token.id_token.encryption_enc_placeholder',
+ 'Select content encryption',
+ )}
) : (
selected
@@ -662,110 +736,118 @@ export default function TokenUserAttributesSection({
renderValue={(selected) =>
!selected ? (
- {t('applications:edit.token.user_info.response_type_placeholder')}
+ {t(
+ 'applications:edit.token.user_info.response_type_placeholder',
+ 'Select response type',
+ )}
) : (
- selected
+ responseTypeOption('user_info', String(selected)).label
)
}
>
- {TokenConstants.USER_INFO_RESPONSE_TYPES.map((type) => (
-
- ))}
+ {TokenConstants.USER_INFO_RESPONSE_TYPES.map((type) => {
+ const option = responseTypeOption('user_info', type);
+ return (
+
+ );
+ })}
- {/* Row 2: Algorithm fields */}
- {userInfoResponseType && userInfoResponseType !== 'JSON' && (
-
- {(userInfoResponseType === 'JWS' || userInfoResponseType === 'NESTED_JWT') && (
-
-
- {t('applications:edit.token.user_info.signing_alg', 'Signing Algorithm')}
-
-
-
+ {/* Read-only signing algorithm for signed formats (determined by the
+ server key). Only shown once resolved from discovery. */}
+ {signingAlg &&
+ (userInfoResponseType === 'JWS' || userInfoResponseType === 'NESTED_JWT') && (
+
+ {t('applications:edit.token.signed_with', 'Signed with {{alg}}.', {
+ alg: signingAlg,
+ })}
+
+ )}
+
+ {/* Certificate requirement for encrypted formats */}
+ {!hasCertificate && (
+
+ {t(
+ 'applications:edit.token.encryption_requires_certificate',
+ 'Encrypted formats require an OAuth client certificate (JWKS or JWKS URI) configured under the {{location}} tab.',
+ {location: certificateLocation},
)}
+
+ )}
- {(userInfoResponseType === 'JWE' || userInfoResponseType === 'NESTED_JWT') && (
- <>
-
-
- {t('applications:edit.token.user_info.encryption_alg', 'Encryption Algorithm')}
-
-
-
-
-
-
- {t('applications:edit.token.user_info.encryption_enc', 'Content Encryption')}
-
-
-
- >
- )}
+ {/* Row 2: Encryption fields */}
+ {isEncryptedFormat(userInfoResponseType) && (
+
+
+
+ {t('applications:edit.token.user_info.encryption_alg', 'Encryption Algorithm')}
+
+
+
+
+
+
+ {t('applications:edit.token.user_info.encryption_enc', 'Content Encryption')}
+
+
+
)}
diff --git a/frontend/apps/console/src/features/applications/components/edit-application/token-settings/__tests__/EditTokenSettings.test.tsx b/frontend/apps/console/src/features/applications/components/edit-application/token-settings/__tests__/EditTokenSettings.test.tsx
index a20d430f3c..e267bb46e6 100644
--- a/frontend/apps/console/src/features/applications/components/edit-application/token-settings/__tests__/EditTokenSettings.test.tsx
+++ b/frontend/apps/console/src/features/applications/components/edit-application/token-settings/__tests__/EditTokenSettings.test.tsx
@@ -16,7 +16,7 @@
* under the License.
*/
-import {render, screen, waitFor} from '@thunderid/test-utils';
+import {fireEvent, render, screen, waitFor} from '@thunderid/test-utils';
import {describe, it, expect, vi, beforeEach} from 'vitest';
import type {Application} from '../../../../models/application';
import type {OAuth2Config} from '../../../../models/oauth';
@@ -62,12 +62,16 @@ vi.mock('../TokenUserAttributesSection', () => ({
idTokenAttributes,
isUserInfoCustomAttributes,
onToggleUserInfo,
+ onIdTokenConfigChange,
+ onUserInfoConfigChange,
userAttributes,
}: {
accessTokenAttributes?: string[];
idTokenAttributes?: string[];
isUserInfoCustomAttributes?: boolean;
onToggleUserInfo?: (checked: boolean) => void;
+ onIdTokenConfigChange?: (field: string, value: string) => void;
+ onUserInfoConfigChange?: (field: string, value: string) => void;
userAttributes?: string[];
}) => {
const isOAuthMode = accessTokenAttributes !== undefined || idTokenAttributes !== undefined;
@@ -77,6 +81,12 @@ vi.mock('../TokenUserAttributesSection', () => ({
Access Token Attributes
ID Token Attributes
{userAttributes && {userAttributes.join(',')}
}
+
+