{
>
)}
-
+
{
)}
/>
-
- (
-
- )}
- />
-
+ {connector.type === ConnectorType.Social && (
+
+ (
+
+ )}
+ />
+
+ )}
);
};
diff --git a/packages/console/src/pages/Connectors/components/Guide/index.tsx b/packages/console/src/pages/Connectors/components/Guide/index.tsx
index ef7f791a0..8ee20b6e6 100644
--- a/packages/console/src/pages/Connectors/components/Guide/index.tsx
+++ b/packages/console/src/pages/Connectors/components/Guide/index.tsx
@@ -6,6 +6,7 @@ import i18next from 'i18next';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
+import { useNavigate } from 'react-router-dom';
import Close from '@/assets/images/close.svg';
import Button from '@/components/Button';
@@ -30,6 +31,7 @@ type Props = {
const Guide = ({ connector, onClose }: Props) => {
const api = useApi();
+ const navigate = useNavigate();
const { updateSettings } = useSettings();
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { id: connectorId, type: connectorType, name, readme, isStandard } = connector;
@@ -65,19 +67,24 @@ const Guide = ({ connector, onClose }: Props) => {
const { id: connectorId } = connector;
- await api
+ const basePayload = {
+ config: result.data,
+ connectorId,
+ metadata: conditional(
+ isStandard && {
+ ...otherData,
+ name: { en: name },
+ }
+ ),
+ };
+
+ const payload = isSocialConnector
+ ? { ...basePayload, syncProfile: syncProfile === SyncProfileMode.EachSignIn }
+ : basePayload;
+
+ const createdConnector = await api
.post('/api/connectors', {
- json: {
- config: result.data,
- connectorId,
- syncProfile: syncProfile === SyncProfileMode.EachSignIn,
- metadata: conditional(
- isStandard && {
- ...otherData,
- name: { en: name },
- }
- ),
- },
+ json: payload,
})
.json();
@@ -88,6 +95,7 @@ const Guide = ({ connector, onClose }: Props) => {
onClose();
toast.success(t('general.saved'));
+ navigate(`/connectors/${createdConnector.id}`);
});
return (
diff --git a/packages/console/src/pages/SignInExperience/components/Preview/index.tsx b/packages/console/src/pages/SignInExperience/components/Preview/index.tsx
index 27b42155f..cc9f7d355 100644
--- a/packages/console/src/pages/SignInExperience/components/Preview/index.tsx
+++ b/packages/console/src/pages/SignInExperience/components/Preview/index.tsx
@@ -194,7 +194,7 @@ const Preview = ({ signInExperience, className }: Props) => {
style={conditional(
platform === 'desktopWeb' && {
// Set background color to match iframe's background color on both dark and light mode.
- backgroundColor: mode === AppearanceMode.DarkMode ? '#2A2C31' : '#e5e1ec',
+ backgroundColor: mode === AppearanceMode.DarkMode ? '#000' : '#e5e1ec',
}
)}
>
diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SignInMethodEditBox/AddButton.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SignInMethodEditBox/AddButton.tsx
index e0a516fe0..78e6e9280 100644
--- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SignInMethodEditBox/AddButton.tsx
+++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SignInMethodEditBox/AddButton.tsx
@@ -3,6 +3,7 @@ import classNames from 'classnames';
import { useTranslation } from 'react-i18next';
import { snakeCase } from 'snake-case';
+import CirclePlus from '@/assets/images/circle-plus.svg';
import Plus from '@/assets/images/plus.svg';
import ActionMenu from '@/components/ActionMenu';
import type { Props as ButtonProps } from '@/components/Button';
@@ -33,6 +34,7 @@ const AddButton = ({ options, onSelected, hasSelectedIdentifiers }: Props) => {
type: 'text',
size: 'small',
title: 'general.add_another',
+ icon: ,
};
return (
diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SocialConnectorEditBox/AddButton.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SocialConnectorEditBox/AddButton.tsx
index dbc1a50e1..08183c726 100644
--- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SocialConnectorEditBox/AddButton.tsx
+++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SocialConnectorEditBox/AddButton.tsx
@@ -1,5 +1,6 @@
import classNames from 'classnames';
+import CirclePlus from '@/assets/images/circle-plus.svg';
import Plus from '@/assets/images/plus.svg';
import ActionMenu from '@/components/ActionMenu';
import type { Props as ButtonProps } from '@/components/Button';
@@ -32,6 +33,7 @@ const AddButton = ({ options, onSelected, hasSelectedConnectors }: Props) => {
type: 'text',
size: 'small',
title: 'general.add_another',
+ icon: ,
};
return (
diff --git a/packages/console/src/utilities/a11y.ts b/packages/console/src/utilities/a11y.ts
index e46b51f8b..6f65b62c1 100644
--- a/packages/console/src/utilities/a11y.ts
+++ b/packages/console/src/utilities/a11y.ts
@@ -15,7 +15,11 @@ export const onKeyDownHandler =
}
if (typeof callback === 'object') {
- callback[key]?.(event);
- event.preventDefault();
+ const handler = callback[key];
+
+ if (handler) {
+ handler(event);
+ event.preventDefault();
+ }
}
};
diff --git a/packages/core/src/queries/user.test.ts b/packages/core/src/queries/user.test.ts
index 523c514ca..98db64fd1 100644
--- a/packages/core/src/queries/user.test.ts
+++ b/packages/core/src/queries/user.test.ts
@@ -307,6 +307,7 @@ describe('user query', () => {
where ${fields.primaryEmail} ilike $1 or ${fields.primaryPhone} ilike $2 or ${
fields.username
} ilike $3 or ${fields.name} ilike $4
+ order by "created_at" desc
limit $5
offset $6
`;
@@ -339,6 +340,7 @@ describe('user query', () => {
and (${fields.primaryEmail} ilike $2 or ${fields.primaryPhone} ilike $3 or ${
fields.username
} ilike $4 or ${fields.name} ilike $5)
+ order by "created_at" desc
limit $6
offset $7
`;
@@ -371,6 +373,7 @@ describe('user query', () => {
where ${fields.primaryEmail} like $1 or ${fields.primaryPhone} like $2 or ${
fields.username
} like $3 or ${fields.name} like $4
+ order by "created_at" desc
limit $5
offset $6
`;
diff --git a/packages/core/src/queries/user.ts b/packages/core/src/queries/user.ts
index 3f099f56a..a53fb165b 100644
--- a/packages/core/src/queries/user.ts
+++ b/packages/core/src/queries/user.ts
@@ -145,6 +145,7 @@ export const findUsers = async (
select ${sql.join(Object.values(fields), sql`,`)}
from ${table}
${buildUserConditions(search, hideAdminUser, isCaseSensitive)}
+ order by ${fields.createdAt} desc
limit ${limit}
offset ${offset}
`
diff --git a/packages/core/src/routes/connector.test.ts b/packages/core/src/routes/connector.test.ts
index f0fd3caa6..e4398ac9b 100644
--- a/packages/core/src/routes/connector.test.ts
+++ b/packages/core/src/routes/connector.test.ts
@@ -188,7 +188,6 @@ describe('connector route', () => {
metadata: { ...mockConnectorFactory.metadata, id: 'connectorId' },
},
]);
- countConnectorByConnectorId.mockResolvedValueOnce({ count: 0 });
const response = await connectorRequest.post('/connectors').send({
connectorId: 'id0',
config: { cliend_id: 'client_id', client_secret: 'client_secret' },
@@ -255,7 +254,7 @@ describe('connector route', () => {
{
...mockConnectorFactory,
type: ConnectorType.Sms,
- metadata: { ...mockConnectorFactory.metadata, id: 'id0', isStandard: true },
+ metadata: { ...mockConnectorFactory.metadata, id: 'id1' },
},
]);
getLogtoConnectors.mockResolvedValueOnce([
@@ -266,20 +265,19 @@ describe('connector route', () => {
...mockLogtoConnector,
},
]);
+ countConnectorByConnectorId.mockResolvedValueOnce({ count: 0 });
const response = await connectorRequest.post('/connectors').send({
- connectorId: 'id0',
+ connectorId: 'id1',
config: { cliend_id: 'client_id', client_secret: 'client_secret' },
- metadata: { target: 'target', name: { en: '' }, logo: '', logoDark: null },
});
expect(response).toHaveProperty('statusCode', 200);
expect(response.body).toMatchObject(
expect.objectContaining({
- connectorId: 'id0',
+ connectorId: 'id1',
config: {
cliend_id: 'client_id',
client_secret: 'client_secret',
},
- metadata: { target: 'target' },
})
);
expect(deleteConnectorByIds).toHaveBeenCalledWith(['id']);
@@ -347,6 +345,7 @@ describe('connector route', () => {
]);
const response = await connectorRequest.post('/connectors').send({
connectorId: 'id0',
+ metadata: { target: 'target' },
});
expect(response).toHaveProperty('statusCode', 422);
});
diff --git a/packages/core/src/routes/connector.ts b/packages/core/src/routes/connector.ts
index b30fb5e68..8673c615d 100644
--- a/packages/core/src/routes/connector.ts
+++ b/packages/core/src/routes/connector.ts
@@ -3,7 +3,6 @@ import { emailRegEx, phoneRegEx } from '@logto/core-kit';
import type { ConnectorFactoryResponse, ConnectorResponse } from '@logto/schemas';
import { arbitraryObjectGuard, Connectors, ConnectorType } from '@logto/schemas';
import { buildIdGenerator } from '@logto/shared';
-import { conditional } from '@silverhand/essentials';
import cleanDeep from 'clean-deep';
import { object, string } from 'zod';
@@ -114,9 +113,9 @@ export default function connectorRoutes(router: T) {
// eslint-disable-next-line complexity
async (ctx, next) => {
const {
- body: { connectorId },
- body,
+ body: { connectorId, metadata, config, syncProfile },
} = ctx.guard;
+
const connectorFactories = await loadConnectorFactories();
const connectorFactory = connectorFactories.find(
({ metadata: { id } }) => id === connectorId
@@ -129,6 +128,15 @@ export default function connectorRoutes(router: T) {
});
}
+ assertThat(
+ connectorFactory.metadata.isStandard !== true || metadata?.target,
+ 'connector.can_not_modify_target'
+ );
+ assertThat(
+ connectorFactory.metadata.isStandard === true || metadata === undefined,
+ 'connector.cannot_change_metadata_for_non_standard_connector'
+ );
+
const { count } = await countConnectorByConnectorId(connectorId);
assertThat(
count === 0 || connectorFactory.metadata.isStandard === true,
@@ -140,25 +148,23 @@ export default function connectorRoutes(router: T) {
if (connectorFactory.type === ConnectorType.Social) {
const connectors = await getLogtoConnectors();
- const connectorTarget = body.metadata?.target ?? connectorFactory.metadata.target;
assertThat(
!connectors
.filter(({ type }) => type === ConnectorType.Social)
.some(
({ metadata: { target, platform } }) =>
- target === connectorTarget && platform === connectorFactory.metadata.platform
+ target === cleanDeep(metadata)?.target &&
+ platform === connectorFactory.metadata.platform
),
new RequestError({ code: 'connector.multiple_target_with_same_platform', status: 422 })
);
}
const insertConnectorId = generateConnectorId();
- const { metadata, ...rest } = body;
-
ctx.body = await insertConnector({
id: insertConnectorId,
- ...conditional(metadata && { metadata: cleanDeep(metadata) }),
- ...rest,
+ connectorId,
+ ...cleanDeep({ syncProfile, config, metadata }),
});
/**
@@ -194,17 +200,25 @@ export default function connectorRoutes(router: T) {
.pick({ config: true, metadata: true, syncProfile: true })
.partial(),
}),
-
async (ctx, next) => {
const {
params: { id },
- body: { config },
- body,
+ body: { config, metadata, syncProfile },
} = ctx.guard;
- const { type, validateConfig } = await getLogtoConnectorById(id);
+ const { type, validateConfig, metadata: originalMetadata } = await getLogtoConnectorById(id);
- if (body.syncProfile) {
+ assertThat(
+ originalMetadata.isStandard !== true || metadata?.target === originalMetadata.target,
+ 'connector.can_not_modify_target'
+ );
+
+ assertThat(
+ originalMetadata.isStandard === true || metadata === undefined,
+ 'connector.cannot_change_metadata_for_non_standard_connector'
+ );
+
+ if (syncProfile) {
assertThat(
type === ConnectorType.Social,
new RequestError({ code: 'connector.invalid_type_for_syncing_profile', status: 422 })
@@ -214,12 +228,9 @@ export default function connectorRoutes(router: T) {
if (config) {
validateConfig(config);
}
- // Once created, target can not be modified.
- assertThat(body.metadata?.target === undefined, 'connector.can_not_modify_target');
- const { metadata: databaseMetadata, ...rest } = body;
await updateConnector({
- set: databaseMetadata ? { metadata: cleanDeep(databaseMetadata), ...rest } : rest,
+ set: cleanDeep({ config, metadata, syncProfile }),
where: { id },
jsonbMode: 'replace',
});
diff --git a/packages/core/src/routes/connector.update.test.ts b/packages/core/src/routes/connector.update.test.ts
index b295476e5..f71e1bae0 100644
--- a/packages/core/src/routes/connector.update.test.ts
+++ b/packages/core/src/routes/connector.update.test.ts
@@ -120,7 +120,7 @@ describe('connector PATCH routes', () => {
updateConnector.mockResolvedValueOnce({
...mockConnector,
metadata: {
- target: 'target',
+ target: 'connector',
name: { en: 'connector_name', fr: 'connector_name' },
logo: 'new_logo.png',
},
@@ -131,6 +131,7 @@ describe('connector PATCH routes', () => {
name: { en: 'connector_name', fr: 'connector_name' },
logo: 'new_logo.png',
logoDark: null,
+ target: 'connector',
},
});
expect(updateConnector).toHaveBeenCalledWith(
@@ -141,6 +142,7 @@ describe('connector PATCH routes', () => {
metadata: {
name: { en: 'connector_name', fr: 'connector_name' },
logo: 'new_logo.png',
+ target: 'connector',
},
},
jsonbMode: 'replace',
@@ -161,24 +163,20 @@ describe('connector PATCH routes', () => {
updateConnector.mockResolvedValueOnce({
...mockConnector,
metadata: {
- target: '',
+ target: 'connector',
name: { en: '' },
logo: '',
logoDark: '',
},
});
const response = await connectorRequest.patch('/connectors/id').send({
- metadata: {
- name: { en: '' },
- logo: '',
- logoDark: '',
- },
+ metadata: { target: 'connector', name: { en: '' }, logo: '', logoDark: '' },
});
expect(updateConnector).toHaveBeenCalledWith(
expect.objectContaining({
where: { id: 'id' },
set: {
- metadata: {},
+ metadata: { target: 'connector' },
},
jsonbMode: 'replace',
})
diff --git a/packages/integration-tests/src/api/connector.ts b/packages/integration-tests/src/api/connector.ts
index aff29c381..2f82d2f66 100644
--- a/packages/integration-tests/src/api/connector.ts
+++ b/packages/integration-tests/src/api/connector.ts
@@ -9,22 +9,26 @@ export const getConnector = async (connectorId: string) =>
authedAdminApi.get(`connectors/${connectorId}`).json();
// FIXME @Darcy: correct use of `id` and `connectorId`.
-export const postConnector = async (connectorId: string) =>
+export const postConnector = async (connectorId: string, metadata?: Record) =>
authedAdminApi
.post({
url: `connectors`,
- json: { connectorId },
+ json: { connectorId, metadata },
})
.json();
export const deleteConnectorById = async (id: string) =>
authedAdminApi.delete({ url: `connectors/${id}` }).json();
-export const updateConnectorConfig = async (connectorId: string, config: Record) =>
+export const updateConnectorConfig = async (
+ connectorId: string,
+ config: Record,
+ metadata?: Record
+) =>
authedAdminApi
.patch({
url: `connectors/${connectorId}`,
- json: { config },
+ json: { config, metadata },
})
.json();
diff --git a/packages/integration-tests/src/tests/api/connector.test.ts b/packages/integration-tests/src/tests/api/connector.test.ts
index 00c3d1dca..bbf5d4208 100644
--- a/packages/integration-tests/src/tests/api/connector.test.ts
+++ b/packages/integration-tests/src/tests/api/connector.test.ts
@@ -71,13 +71,18 @@ test('connector set-up flow', async () => {
/*
* Change to another SMS/Email connector
*/
- const { id } = await postConnector(mockStandardEmailConnectorId);
- await updateConnectorConfig(id, mockStandardEmailConnectorConfig);
+ const { id } = await postConnector(mockStandardEmailConnectorId, {
+ target: 'mock-standard-mail',
+ }); // TODO [LOG-4862]: update mock connector
+ await updateConnectorConfig(id, mockStandardEmailConnectorConfig, {
+ target: 'mock-standard-mail',
+ }); // TODO [LOG-4862]: update mock connector
connectorIdMap.set(mockStandardEmailConnectorId, id);
const currentConnectors = await listConnectors();
expect(
currentConnectors.some((connector) => connector.connectorId === mockEmailConnectorId)
).toBeFalsy();
+ connectorIdMap.delete(mockEmailConnectorId);
expect(
currentConnectors.some((connector) => connector.connectorId === mockStandardEmailConnectorId)
).toBeTruthy();
@@ -85,7 +90,6 @@ test('connector set-up flow', async () => {
currentConnectors.find((connector) => connector.connectorId === mockStandardEmailConnectorId)
?.config
).toEqual(mockStandardEmailConnectorConfig);
- connectorIdMap.delete(mockEmailConnectorId);
/*
* Delete (i.e. disable) a connector
diff --git a/packages/phrases/src/locales/de/errors.ts b/packages/phrases/src/locales/de/errors.ts
index 00bcdeefa..a5097f1dd 100644
--- a/packages/phrases/src/locales/de/errors.ts
+++ b/packages/phrases/src/locales/de/errors.ts
@@ -112,6 +112,8 @@ const errors = {
can_not_modify_target: 'The connector target can not be modified.',
multiple_target_with_same_platform:
'You can not have multiple social connectors that have same target and platform.',
+ cannot_change_metadata_for_non_standard_connector:
+ "This connector's `metadata` cannot be changed.",
},
passcode: {
phone_email_empty: 'Telefonnummer oder E-Mail darf nicht leer sein.',
diff --git a/packages/phrases/src/locales/de/translation/admin-console/application-details.ts b/packages/phrases/src/locales/de/translation/admin-console/application-details.ts
index 5a906234a..b804c71d4 100644
--- a/packages/phrases/src/locales/de/translation/admin-console/application-details.ts
+++ b/packages/phrases/src/locales/de/translation/admin-console/application-details.ts
@@ -33,7 +33,6 @@ const application_details = {
cors_allowed_origins_placeholder: 'https://your.website.de',
cors_allowed_origins_tip:
'Es sind standardmäßig alle Umleitungs-URI Origins erlaubt. Normalerweise ist dieses Feld nicht erforderlich. See the MDN doc for detailed info.', // UNTRANSLATED
- add_another: 'Weitere hinzufügen',
id_token_expiration: 'ID Token Ablaufzeit',
refresh_token_expiration: 'Refresh Token Ablaufzeit',
token_endpoint: 'Token Endpoint',
diff --git a/packages/phrases/src/locales/de/translation/admin-console/general.ts b/packages/phrases/src/locales/de/translation/admin-console/general.ts
index f8d3bbe52..03af0d8ec 100644
--- a/packages/phrases/src/locales/de/translation/admin-console/general.ts
+++ b/packages/phrases/src/locales/de/translation/admin-console/general.ts
@@ -30,7 +30,7 @@ const general = {
copying: 'Kopiere',
copied: 'Kopiert',
required: 'Erforderlich',
- add_another: '+ Weitere hinzufügen',
+ add_another: 'Weitere hinzufügen',
deletion_confirmation: 'Willst du {{title}} wirklich löschen?',
settings_nav: 'Einstellungen',
unsaved_changes_warning:
diff --git a/packages/phrases/src/locales/en/errors.ts b/packages/phrases/src/locales/en/errors.ts
index ffe1a535e..eed909db1 100644
--- a/packages/phrases/src/locales/en/errors.ts
+++ b/packages/phrases/src/locales/en/errors.ts
@@ -111,6 +111,8 @@ const errors = {
can_not_modify_target: 'The connector target can not be modified.',
multiple_target_with_same_platform:
'You can not have multiple social connectors that have same target and platform.',
+ cannot_change_metadata_for_non_standard_connector:
+ "This connector's `metadata` cannot be changed.",
},
passcode: {
phone_email_empty: 'Both phone and email are empty.',
diff --git a/packages/phrases/src/locales/en/translation/admin-console/application-details.ts b/packages/phrases/src/locales/en/translation/admin-console/application-details.ts
index 71d51326c..4d6724103 100644
--- a/packages/phrases/src/locales/en/translation/admin-console/application-details.ts
+++ b/packages/phrases/src/locales/en/translation/admin-console/application-details.ts
@@ -33,7 +33,6 @@ const application_details = {
cors_allowed_origins_placeholder: 'https://your.website.com',
cors_allowed_origins_tip:
'By default, all the origins of Redirect URIs will be allowed. Usually no action is required for this field. See the MDN doc for detailed info.',
- add_another: 'Add Another',
id_token_expiration: 'ID Token expiration',
refresh_token_expiration: 'Refresh Token expiration',
token_endpoint: 'Token Endpoint',
diff --git a/packages/phrases/src/locales/en/translation/admin-console/general.ts b/packages/phrases/src/locales/en/translation/admin-console/general.ts
index 8ee71ab3d..809110051 100644
--- a/packages/phrases/src/locales/en/translation/admin-console/general.ts
+++ b/packages/phrases/src/locales/en/translation/admin-console/general.ts
@@ -30,7 +30,7 @@ const general = {
copying: 'Copying',
copied: 'Copied',
required: 'Required',
- add_another: '+ Add Another',
+ add_another: 'Add Another',
deletion_confirmation: 'Are you sure you want to delete this {{title}}?',
settings_nav: 'Settings',
unsaved_changes_warning: 'You have made some changes. Are you sure you want to leave this page?',
diff --git a/packages/phrases/src/locales/fr/errors.ts b/packages/phrases/src/locales/fr/errors.ts
index dd75d6499..97ff0bec0 100644
--- a/packages/phrases/src/locales/fr/errors.ts
+++ b/packages/phrases/src/locales/fr/errors.ts
@@ -118,6 +118,8 @@ const errors = {
can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED
multiple_target_with_same_platform:
'You can not have multiple social connectors that have same target and platform.', // UNTRANSLATED
+ cannot_change_metadata_for_non_standard_connector:
+ "This connector's `metadata` cannot be changed.", // UNTRANSLATED
},
passcode: {
phone_email_empty: "Le téléphone et l'email sont vides.",
diff --git a/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts b/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts
index c927d50ad..73fb6ec15 100644
--- a/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts
+++ b/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts
@@ -33,7 +33,6 @@ const application_details = {
cors_allowed_origins_placeholder: 'https://votre.site.com',
cors_allowed_origins_tip:
"Par défaut, toutes les origines des URI de redirection seront autorisées. En général, aucune action n'est requise pour ce champ. See the MDN doc for detailed info.", // UNTRANSLATED
- add_another: 'Ajouter un autre',
id_token_expiration: "Expiration du jeton d'identification",
refresh_token_expiration: "Rafraîchir l'expiration du jeton",
token_endpoint: 'Token Endpoint',
diff --git a/packages/phrases/src/locales/fr/translation/admin-console/general.ts b/packages/phrases/src/locales/fr/translation/admin-console/general.ts
index 2c584e716..cf7a76f47 100644
--- a/packages/phrases/src/locales/fr/translation/admin-console/general.ts
+++ b/packages/phrases/src/locales/fr/translation/admin-console/general.ts
@@ -30,7 +30,7 @@ const general = {
copying: 'Copie',
copied: 'Copié',
required: 'Requis',
- add_another: '+ Ajouter un autre',
+ add_another: 'Ajouter un autre',
deletion_confirmation: 'Êtes-vous sûr de vouloir supprimer ce {{title}} ?',
settings_nav: 'Paramètres',
unsaved_changes_warning:
diff --git a/packages/phrases/src/locales/ko/errors.ts b/packages/phrases/src/locales/ko/errors.ts
index 2cf32646b..f1ee88d42 100644
--- a/packages/phrases/src/locales/ko/errors.ts
+++ b/packages/phrases/src/locales/ko/errors.ts
@@ -110,6 +110,8 @@ const errors = {
can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED
multiple_target_with_same_platform:
'You can not have multiple social connectors that have same target and platform.', // UNTRANSLATED
+ cannot_change_metadata_for_non_standard_connector:
+ "This connector's `metadata` cannot be changed.", // UNTRANSLATED
},
passcode: {
phone_email_empty: '휴대전화번호 그리고 이메일이 비어있어요.',
diff --git a/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts b/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts
index f611c5229..dd92631c9 100644
--- a/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts
+++ b/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts
@@ -33,7 +33,6 @@ const application_details = {
cors_allowed_origins_placeholder: 'https://your.website.com',
cors_allowed_origins_tip:
'기본으로 모든 리다이렉트의 오리진들은 허용되요. 대체적으로 이 값을 건들 필요는 없어요. See the MDN doc for detailed info.', // UNTRANSLATED
- add_another: '새로 추가',
id_token_expiration: 'ID 토큰 만료',
refresh_token_expiration: 'Refresh 토큰 만료',
token_endpoint: '토큰 End-Point',
diff --git a/packages/phrases/src/locales/ko/translation/admin-console/general.ts b/packages/phrases/src/locales/ko/translation/admin-console/general.ts
index 65468a1f5..a0917946c 100644
--- a/packages/phrases/src/locales/ko/translation/admin-console/general.ts
+++ b/packages/phrases/src/locales/ko/translation/admin-console/general.ts
@@ -30,7 +30,7 @@ const general = {
copying: '복사 중',
copied: '복사됨',
required: '필수',
- add_another: '+ 새로 추가',
+ add_another: '새로 추가',
deletion_confirmation: '정말로 {{title}}을/를 삭제할까요?',
settings_nav: '설정',
unsaved_changes_warning: '수정된 내용이 있어요. 정말로 현재 페이지를 벗어날까요?',
diff --git a/packages/phrases/src/locales/pt-br/errors.ts b/packages/phrases/src/locales/pt-br/errors.ts
index fc22265e5..71439ef8a 100644
--- a/packages/phrases/src/locales/pt-br/errors.ts
+++ b/packages/phrases/src/locales/pt-br/errors.ts
@@ -115,6 +115,8 @@ const errors = {
can_not_modify_target: 'O destino do conector não pode ser modificado.',
multiple_target_with_same_platform:
'Você não pode ter vários conectores sociais com o mesmo destino e plataforma.',
+ cannot_change_metadata_for_non_standard_connector:
+ "This connector's `metadata` cannot be changed.", // UNTRANSLATED
},
passcode: {
phone_email_empty: 'Telefone e e-mail estão vazios.',
diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts
index daab4da54..e84b034c7 100644
--- a/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts
+++ b/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts
@@ -33,7 +33,6 @@ const application_details = {
cors_allowed_origins_placeholder: 'https://your.website.com',
cors_allowed_origins_tip:
'Por padrão, todas as origens de URIs de redirecionamento serão permitidas. Normalmente, nenhuma ação é necessária para este campo. See the MDN doc for detailed info.', // UNTRANSLATED
- add_another: 'Adicionar outro',
id_token_expiration: 'Expiração do token de ID',
refresh_token_expiration: 'Expiração Refresh Token',
token_endpoint: 'Token Endpoint',
diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts
index ff8c68750..a640d2e5f 100644
--- a/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts
+++ b/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts
@@ -30,7 +30,7 @@ const general = {
copying: 'Copiando',
copied: 'Copiado',
required: 'Obrigatório',
- add_another: '+ Adicionar outro',
+ add_another: 'Adicionar outro',
deletion_confirmation: 'Tem certeza de que deseja excluir este {{title}}?',
settings_nav: 'Configurações',
unsaved_changes_warning:
diff --git a/packages/phrases/src/locales/pt-pt/errors.ts b/packages/phrases/src/locales/pt-pt/errors.ts
index df664d633..919084e60 100644
--- a/packages/phrases/src/locales/pt-pt/errors.ts
+++ b/packages/phrases/src/locales/pt-pt/errors.ts
@@ -113,6 +113,8 @@ const errors = {
can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED
multiple_target_with_same_platform:
'You can not have multiple social connectors that have same target and platform.', // UNTRANSLATED
+ cannot_change_metadata_for_non_standard_connector:
+ "This connector's `metadata` cannot be changed.", // UNTRANSLATED
},
passcode: {
phone_email_empty: 'O campos telefone e email estão vazios.',
diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts
index 29f16112b..7bbbf69de 100644
--- a/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts
+++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts
@@ -33,7 +33,6 @@ const application_details = {
cors_allowed_origins_placeholder: 'https://your.website.com',
cors_allowed_origins_tip:
'Por padrão, todas as origens de redirecionamento serão permitidas. Recomenda-se restringir isto. See the MDN doc for detailed info.', // UNTRANSLATED
- add_another: 'Adicionar outro',
id_token_expiration: 'Expiração do token de ID',
refresh_token_expiration: 'Expiração do token de atualização',
token_endpoint: 'Endpoint Token',
diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts
index b0560d298..becbc80e5 100644
--- a/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts
+++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts
@@ -30,7 +30,7 @@ const general = {
copying: 'Copiando',
copied: 'Copiado',
required: 'Necessário',
- add_another: '+ Adicionar outro',
+ add_another: 'Adicionar outro',
deletion_confirmation: 'Tem a certeza que deseja eliminar isso {{title}}?',
settings_nav: 'Definições',
unsaved_changes_warning: 'Fez algumas alterações. Tem a certeza que deseja sair desta página?',
diff --git a/packages/phrases/src/locales/tr-tr/errors.ts b/packages/phrases/src/locales/tr-tr/errors.ts
index 5c8343819..a213c2254 100644
--- a/packages/phrases/src/locales/tr-tr/errors.ts
+++ b/packages/phrases/src/locales/tr-tr/errors.ts
@@ -112,6 +112,8 @@ const errors = {
can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED
multiple_target_with_same_platform:
'You can not have multiple social connectors that have same target and platform.', // UNTRANSLATED
+ cannot_change_metadata_for_non_standard_connector:
+ "This connector's `metadata` cannot be changed.", // UNTRANSLATED
},
passcode: {
phone_email_empty: 'Hem telefon hem de e-posta adresi yok.',
diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts
index 5b2d977fd..408fd0747 100644
--- a/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts
+++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts
@@ -33,7 +33,6 @@ const application_details = {
cors_allowed_origins_placeholder: 'https://your.website.com',
cors_allowed_origins_tip:
'Varsayılan olarak, Yönlendirme URIlerinin tüm originlerine izin verilir. Genellikle bu alan için herhangi bir işlem gerekmez. See the MDN doc for detailed info.', // UNTRANSLATED
- add_another: 'Bir tane daha ekle',
id_token_expiration: 'ID Token sona erme süresi',
refresh_token_expiration: 'Refresh Token sona erme süresi',
token_endpoint: 'Token bitiş noktası',
diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts
index 59be64348..7e715c678 100644
--- a/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts
+++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts
@@ -30,7 +30,7 @@ const general = {
copying: 'Kopyalanıyor',
copied: 'Kopyalandı',
required: 'Gerekli',
- add_another: '+ Bir tane daha ekle',
+ add_another: 'Bir tane daha ekle',
deletion_confirmation: 'Bu dosyayı silmek istediğinize emin misiniz: {{title}}?',
settings_nav: 'Ayarlar',
unsaved_changes_warning:
diff --git a/packages/phrases/src/locales/zh-cn/errors.ts b/packages/phrases/src/locales/zh-cn/errors.ts
index c432762e6..a4b3f66f4 100644
--- a/packages/phrases/src/locales/zh-cn/errors.ts
+++ b/packages/phrases/src/locales/zh-cn/errors.ts
@@ -103,6 +103,7 @@ const errors = {
invalid_type_for_syncing_profile: '只有社交连接器可以开启用户档案同步。',
can_not_modify_target: '不可修改连接器 target。',
multiple_target_with_same_platform: '不能同时存在多个有相同 target 和平台类型的社交连接器。',
+ cannot_change_metadata_for_non_standard_connector: '不可配置该连接器的 metadata 参数。',
},
passcode: {
phone_email_empty: '手机号与邮箱地址均为空',
diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts
index 4f0821285..a75e1a1b0 100644
--- a/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts
+++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts
@@ -33,7 +33,6 @@ const application_details = {
cors_allowed_origins_placeholder: 'https://your.website.com',
cors_allowed_origins_tip:
'所有 Redirect URI 的 origin 将默认被允许。通常不需要对此字段进行操作。参见 MDN 文档以了解更多',
- add_another: '新增',
id_token_expiration: 'ID Token 过期时间',
refresh_token_expiration: 'Refresh Token 过期时间',
token_endpoint: 'Token Endpoint',
diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts
index 112557c35..44c7c4a3f 100644
--- a/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts
+++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts
@@ -30,7 +30,7 @@ const general = {
copying: '复制中',
copied: '已复制',
required: '必填',
- add_another: '+ 新增',
+ add_another: '新增',
deletion_confirmation: '你确定要删除这个 {{title}} 吗?',
settings_nav: '设置',
unsaved_changes_warning: '还有未保存的变更, 确定要离开吗?',