Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(console,phrases): refactor the jwt customizer content #5527

Merged
merged 2 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/console/src/assets/icons/jwt-claims.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Box from '@/assets/icons/box.svg';
import Connection from '@/assets/icons/connection.svg';
import Gear from '@/assets/icons/gear.svg';
import Hook from '@/assets/icons/hook.svg';
import JwtClaims from '@/assets/icons/jwt-claims.svg';
import List from '@/assets/icons/list.svg';
import Organization from '@/assets/icons/organization.svg';
import UserProfile from '@/assets/icons/profile.svg';
Expand All @@ -16,7 +17,7 @@ import Role from '@/assets/icons/role.svg';
import SecurityLock from '@/assets/icons/security-lock.svg';
import EnterpriseSso from '@/assets/icons/single-sign-on.svg';
import Web from '@/assets/icons/web.svg';
import { isCloud } from '@/consts/env';
import { isDevFeaturesEnabled, isCloud } from '@/consts/env';

type SidebarItem = {
Icon: FC;
Expand Down Expand Up @@ -117,6 +118,11 @@ export const useSidebarMenuItems = (): {
Icon: Hook,
title: 'webhooks',
},
{
Icon: JwtClaims,
title: 'jwt_customizer',
isHidden: !isDevFeaturesEnabled,
},
],
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ export const defaultOptions: EditorProps['options'] = {
fontSize: 14,
automaticLayout: true,
tabSize: 2,
scrollBeyondLastLine: false,
};
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,10 @@ function MonacoCodeEditor({
language={activeModel.language}
path={activeModel.name}
theme="logto-dark"
options={defaultOptions}
options={{
...defaultOptions,
...activeModel.options,
}}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string is falsy
value={value || activeModel.defaultValue}
beforeMount={handleEditorWillMount}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type Monaco, type OnMount } from '@monaco-editor/react';
import { type EditorProps, type Monaco, type OnMount } from '@monaco-editor/react';

export type IStandaloneThemeData = Parameters<Monaco['editor']['defineTheme']>[1];

Expand All @@ -25,6 +25,7 @@ export type ModelSettings = {
* We use this to load the global type declarations for the active model
*/
extraLibs?: ExtraLibrary[];
options?: EditorProps['options'];
};

export type ModelControl = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ const isValidKey = (key: string) => {
return /^\w+$/.test(key);
};

function EnvironmentVariablesField() {
type Props = {
className?: string;
};

function EnvironmentVariablesField({ className }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });

const {
Expand Down Expand Up @@ -98,7 +102,7 @@ function EnvironmentVariablesField() {
);

return (
<FormField title="jwt_claims.environment_variables.input_field_title">
<FormField title="jwt_claims.environment_variables.input_field_title" className={className}>
<KeyValueInputField
fields={fields}
// Force envVariableErrors to be an array, otherwise return undefined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
sampleCodeEditorOptions,
typeDefinitionCodeEditorOptions,
fetchExternalDataCodeExample,
environmentVariablesCodeExample,
} from '../utils/config';
import {
accessTokenPayloadTypeDefinition,
Expand Down Expand Up @@ -82,7 +83,18 @@ function InstructionTab({ isActive }: Props) {
* In order to fix this, we need to re-render the EnvironmentVariablesField component when the tokenType changes.
* Achieve this by adding a key to the EnvironmentVariablesField component. Force a re-render when the tokenType changes.
*/}
<EnvironmentVariablesField key={tokenType} />
<EnvironmentVariablesField key={tokenType} className={styles.envVariablesField} />
<div className={styles.description}>
{t('jwt_claims.environment_variables.sample_code')}
</div>
<Editor
language="typescript"
className={styles.sampleCode}
value={environmentVariablesCodeExample}
height="400px"
theme="logto-dark"
options={sampleCodeEditorOptions}
/>
</GuideCard>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import MonacoCodeEditor, { type ModelControl } from '../MonacoCodeEditor/index.js';
import { type JwtClaimsFormType } from '../type.js';
import {
userTokenPayloadTestModel,
machineToMachineTokenPayloadTestModel,
userTokenContextTestModel,
accessTokenPayloadTestModel,
clientCredentialsPayloadTestModel,
userContextTestModel,
} from '../utils/config.js';

import TestResult, { type TestResultData } from './TestResult.js';
Expand All @@ -22,8 +22,8 @@
isActive: boolean;
};

const userTokenModelSettings = [userTokenPayloadTestModel, userTokenContextTestModel];
const machineToMachineTokenModelSettings = [machineToMachineTokenPayloadTestModel];
const userTokenModelSettings = [accessTokenPayloadTestModel, userContextTestModel];
const machineToMachineTokenModelSettings = [clientCredentialsPayloadTestModel];

function TestTab({ isActive }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console.jwt_claims' });
Expand All @@ -46,13 +46,13 @@
}, [editorModels, tokenType]);

const onTestHandler = useCallback(() => {
// TODO: API integration, read form data and send the request to the server

Check warning on line 49 in packages/console/src/pages/JwtClaims/SettingsSection/TestTab.tsx

View workflow job for this annotation

GitHub Actions / ESLint Report Analysis

packages/console/src/pages/JwtClaims/SettingsSection/TestTab.tsx#L49

[no-warning-comments] Unexpected 'todo' comment: 'TODO: API integration, read form data...'.
}, []);

const getModelControllerProps = useCallback(
({ value, onChange }: ControllerRenderProps<JwtClaimsFormType, 'testSample'>): ModelControl => {
// User access token context test model (user data)
if (activeModelName === userTokenContextTestModel.name) {
if (activeModelName === userContextTestModel.name) {
return {
value: value?.contextSample,
onChange: (newValue: string | undefined) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
> *:first-child {
margin-top: _.unit(6);
}

> *:not(:last-child) {
margin-bottom: _.unit(4);
}
}

.expandButton {
Expand Down Expand Up @@ -124,8 +128,6 @@
}

.sampleCode {
margin-top: _.unit(4);

:global {
/* stylelint-disable-next-line selector-class-pattern */
.monaco-editor {
Expand All @@ -144,6 +146,10 @@
}
}

.envVariablesField {
margin-bottom: _.unit(4);
}

.testResult {
margin-top: _.unit(3);
height: calc(50% - _.unit(3));
Expand Down
45 changes: 31 additions & 14 deletions packages/console/src/pages/JwtClaims/utils/config.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { type AccessTokenPayload, type ClientCredentialsPayload } from '@logto/schemas';
import { type EditorProps } from '@monaco-editor/react';

import TokenFileIcon from '@/assets/icons/token-file-icon.svg';
Expand Down Expand Up @@ -131,7 +132,6 @@ export const clientCredentialsModel: ModelSettings = {
/**
* JWT claims guide card configs
*/

export const sampleCodeEditorOptions: EditorProps['options'] = {
readOnly: true,
wordWrap: 'on',
Expand All @@ -142,14 +142,13 @@ export const sampleCodeEditorOptions: EditorProps['options'] = {
overviewRulerBorder: false,
overviewRulerLanes: 0,
lineNumbers: 'off',
scrollbar: { vertical: 'hidden', horizontal: 'hidden', handleMouseWheel: false },
folding: false,
tabSize: 2,
scrollBeyondLastLine: false,
};

export const typeDefinitionCodeEditorOptions: EditorProps['options'] = {
...sampleCodeEditorOptions,
scrollbar: { vertical: 'auto', horizontal: 'auto' },
folding: true,
};

Expand All @@ -165,24 +164,42 @@ return {
externalData: data,
};`;

export const environmentVariablesCodeExample = `exports.getCustomJwtClaims = async (token, data, envVariables) => {
const { apiKey } = envVariables;

const response = await fetch('https://api.example.com/data', {
headers: {
Authorization: apiKey,
}
});

const data = await response.json();

return {
externalData: data,
};
};`;

/**
* Tester Code Editor configs
*/
const standardTokenPayloadData = {
jti: '1234567890',
iat: 1_516_239_022,
exp: 1_516_239_022,
jti: 'f1d3d2d1-1f2d-3d4e-5d6f-7d8a9d0e1d2',
iat: 1_516_235_022,
exp: 1_516_235_022 + 3600,
client_id: 'my_app',
scope: 'read write',
aud: 'http://localhost:3000/api',
aud: 'http://localhost:3000/api/test',
};

const defaultUserTokenPayloadData = {
const defaultAccessTokenPayload: AccessTokenPayload = {
...standardTokenPayloadData,
grantId: 'grant_123',
accountId: 'uid_123',
kind: 'AccessToken',
};

const defaultMachineToMachineTokenPayloadData = {
const defaultClientCredentialsPayload: ClientCredentialsPayload = {
...standardTokenPayloadData,
kind: 'ClientCredentials',
};
Expand All @@ -200,23 +217,23 @@ const defaultUserTokenContextData = {
},
};

export const userTokenPayloadTestModel: ModelSettings = {
export const accessTokenPayloadTestModel: ModelSettings = {
language: 'json',
icon: <TokenFileIcon />,
name: 'user-token-payload.json',
title: 'Token',
defaultValue: JSON.stringify(defaultUserTokenPayloadData, null, '\t'),
defaultValue: JSON.stringify(defaultAccessTokenPayload, null, '\t'),
};

export const machineToMachineTokenPayloadTestModel: ModelSettings = {
export const clientCredentialsPayloadTestModel: ModelSettings = {
language: 'json',
icon: <TokenFileIcon />,
name: 'machine-to-machine-token-payload.json',
title: 'Token',
defaultValue: JSON.stringify(defaultMachineToMachineTokenPayloadData, null, '\t'),
defaultValue: JSON.stringify(defaultClientCredentialsPayload, null, '\t'),
};

export const userTokenContextTestModel: ModelSettings = {
export const userContextTestModel: ModelSettings = {
language: 'json',
icon: <UserFileIcon />,
name: 'user-token-context.json',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const jwt_claims = {
'Use environment variables to store sensitive information and access them in your custom claims handler.',
/** UNTRANSLATED */
input_field_title: 'Add environment variables',
/** UNTRANSLATED */
sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ',
},
/** UNTRANSLATED */
jwt_claims_hint:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const tabs = {
docs: 'Dokumentation',
tenant_settings: 'Einstellungen',
mfa: 'Multi-Faktor-Authentifizierung',
/** UNTRANSLATED */
jwt_customizer: 'JWT Claims',
};

export default Object.freeze(tabs);
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const jwt_claims = {
subtitle:
'Use environment variables to store sensitive information and access them in your custom claims handler.',
input_field_title: 'Add environment variables',
sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ',
},
jwt_claims_hint:
'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const tabs = {
docs: 'Docs',
tenant_settings: 'Settings',
mfa: 'Multi-factor auth',
jwt_customizer: 'JWT Claims',
};

export default Object.freeze(tabs);
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const jwt_claims = {
'Use environment variables to store sensitive information and access them in your custom claims handler.',
/** UNTRANSLATED */
input_field_title: 'Add environment variables',
/** UNTRANSLATED */
sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ',
},
/** UNTRANSLATED */
jwt_claims_hint:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const tabs = {
docs: 'Documentos',
tenant_settings: 'Configuraciones del inquilino',
mfa: 'Autenticación multifactor',
/** UNTRANSLATED */
jwt_customizer: 'JWT Claims',
};

export default Object.freeze(tabs);
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const jwt_claims = {
'Use environment variables to store sensitive information and access them in your custom claims handler.',
/** UNTRANSLATED */
input_field_title: 'Add environment variables',
/** UNTRANSLATED */
sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ',
},
/** UNTRANSLATED */
jwt_claims_hint:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const tabs = {
docs: 'Documentation',
tenant_settings: 'Paramètres du locataire',
mfa: 'Authentification multi-facteur',
/** UNTRANSLATED */
jwt_customizer: 'JWT Claims',
};

export default Object.freeze(tabs);
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const jwt_claims = {
'Use environment variables to store sensitive information and access them in your custom claims handler.',
/** UNTRANSLATED */
input_field_title: 'Add environment variables',
/** UNTRANSLATED */
sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ',
},
/** UNTRANSLATED */
jwt_claims_hint:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const tabs = {
docs: 'Documenti',
tenant_settings: 'Impostazioni',
mfa: 'Autenticazione multi-fattore',
/** UNTRANSLATED */
jwt_customizer: 'JWT Claims',
};

export default Object.freeze(tabs);
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const jwt_claims = {
'Use environment variables to store sensitive information and access them in your custom claims handler.',
/** UNTRANSLATED */
input_field_title: 'Add environment variables',
/** UNTRANSLATED */
sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ',
},
/** UNTRANSLATED */
jwt_claims_hint:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const tabs = {
docs: 'ドキュメント',
tenant_settings: '設定',
mfa: 'Multi-factor auth',
/** UNTRANSLATED */
jwt_customizer: 'JWT Claims',
};

export default Object.freeze(tabs);
Loading
Loading