diff --git a/.changeset/dir-sync-google-wizard.md b/.changeset/dir-sync-google-wizard.md
new file mode 100644
index 00000000000..df50c10f76f
--- /dev/null
+++ b/.changeset/dir-sync-google-wizard.md
@@ -0,0 +1,8 @@
+---
+'@clerk/clerk-js': minor
+'@clerk/shared': minor
+'@clerk/ui': minor
+'@clerk/localizations': minor
+---
+
+Support Google Workspace directories in Directory Sync. Organization admins can upload a service account key and delegated admin email from the setup flow, start a sync on demand, and see the result of the last one. `DirectorySync` gains `setCredentials()`, `sync()`, `getSyncStatus()`, and `credentialsConfigured`.
diff --git a/packages/localizations/src/ar-SA.ts b/packages/localizations/src/ar-SA.ts
index abc75799054..8ecf259199e 100644
--- a/packages/localizations/src/ar-SA.ts
+++ b/packages/localizations/src/ar-SA.ts
@@ -242,14 +242,23 @@ export const arSA: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const arSA: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const arSA: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const arSA: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/be-BY.ts b/packages/localizations/src/be-BY.ts
index bdd953bd13c..b91d9fdb8d7 100644
--- a/packages/localizations/src/be-BY.ts
+++ b/packages/localizations/src/be-BY.ts
@@ -242,14 +242,23 @@ export const beBY: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const beBY: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const beBY: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const beBY: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/bg-BG.ts b/packages/localizations/src/bg-BG.ts
index 450becd0a65..e3cae98919a 100644
--- a/packages/localizations/src/bg-BG.ts
+++ b/packages/localizations/src/bg-BG.ts
@@ -243,14 +243,23 @@ export const bgBG: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -266,6 +275,13 @@ export const bgBG: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -276,10 +292,6 @@ export const bgBG: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -298,14 +310,28 @@ export const bgBG: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/bn-IN.ts b/packages/localizations/src/bn-IN.ts
index 701c5945ca9..43af449869d 100644
--- a/packages/localizations/src/bn-IN.ts
+++ b/packages/localizations/src/bn-IN.ts
@@ -248,14 +248,23 @@ export const bnIN: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -271,6 +280,13 @@ export const bnIN: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -281,10 +297,6 @@ export const bnIN: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -303,14 +315,28 @@ export const bnIN: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/ca-ES.ts b/packages/localizations/src/ca-ES.ts
index d98555fca89..ae2eaa6432e 100644
--- a/packages/localizations/src/ca-ES.ts
+++ b/packages/localizations/src/ca-ES.ts
@@ -249,14 +249,23 @@ export const caES: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -272,6 +281,13 @@ export const caES: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -282,10 +298,6 @@ export const caES: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -304,14 +316,28 @@ export const caES: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/cs-CZ.ts b/packages/localizations/src/cs-CZ.ts
index afae42d07de..63d0cff7de9 100644
--- a/packages/localizations/src/cs-CZ.ts
+++ b/packages/localizations/src/cs-CZ.ts
@@ -246,14 +246,23 @@ export const csCZ: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -269,6 +278,13 @@ export const csCZ: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -279,10 +295,6 @@ export const csCZ: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -301,14 +313,28 @@ export const csCZ: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/da-DK.ts b/packages/localizations/src/da-DK.ts
index 5b936ef9f7b..17de000bb61 100644
--- a/packages/localizations/src/da-DK.ts
+++ b/packages/localizations/src/da-DK.ts
@@ -242,14 +242,23 @@ export const daDK: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const daDK: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const daDK: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const daDK: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/de-DE.ts b/packages/localizations/src/de-DE.ts
index eeba2a2982e..e78b8fc0207 100644
--- a/packages/localizations/src/de-DE.ts
+++ b/packages/localizations/src/de-DE.ts
@@ -248,14 +248,23 @@ export const deDE: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -271,6 +280,13 @@ export const deDE: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -281,10 +297,6 @@ export const deDE: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -303,14 +315,28 @@ export const deDE: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/el-GR.ts b/packages/localizations/src/el-GR.ts
index 0ecafa33088..8af055a55ef 100644
--- a/packages/localizations/src/el-GR.ts
+++ b/packages/localizations/src/el-GR.ts
@@ -242,14 +242,23 @@ export const elGR: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const elGR: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const elGR: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const elGR: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/en-GB.ts b/packages/localizations/src/en-GB.ts
index d417e56a005..4538fdf8f82 100644
--- a/packages/localizations/src/en-GB.ts
+++ b/packages/localizations/src/en-GB.ts
@@ -242,14 +242,23 @@ export const enGB: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const enGB: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const enGB: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const enGB: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/en-US.ts b/packages/localizations/src/en-US.ts
index 9c07fb52146..4066136089a 100644
--- a/packages/localizations/src/en-US.ts
+++ b/packages/localizations/src/en-US.ts
@@ -237,15 +237,24 @@ export const enUS: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: 'Generate new token',
+ actionLabel__replaceKey: 'Replace JSON key',
actionLabel__retry: 'Try again',
+ actionLabel__uploadKey: 'Upload JSON key',
+ badge__credentialsConfigured: 'Configured',
+ badge__credentialsMissing: 'Not configured',
domainsLabel: 'Domains:',
+ error__invalidKeyFile: 'That file is not valid JSON. Upload the key file downloaded from Google.',
error__ssoRequired: {
subtitle:
'Directory Sync requires an SSO connection. Configure and verify your SSO connection first, then return here to set up provisioning.',
title: 'Single Sign-On is not configured yet',
},
+ formFieldHint__subjectEmail: 'The directory is read as this admin. They must be an active Workspace admin.',
+ formFieldInputPlaceholder__subjectEmail: 'admin@yourcompany.com',
formFieldInputPlaceholder__token: 'Generate a new token to reveal it',
formFieldLabel__endpointUrl: 'SCIM endpoint URL',
+ formFieldLabel__serviceAccountKey: 'Service account key',
+ formFieldLabel__subjectEmail: 'Google Workspace admin email',
formFieldLabel__token: 'Bearer token',
instructions: {
actionLabel__toggle: 'View instructions',
@@ -263,6 +272,16 @@ export const enUS: LocalizationResource = {
step3: 'Select Provisioning and set the provisioning mode to Automatic.',
step4: 'Assign the users and groups to provision, then turn provisioning On.',
},
+ google: {
+ step1:
+ 'In the Google Cloud console, create a project and a service account, then create a JSON key for it and download the file.',
+ step2: 'Enable the Admin SDK API for that project.',
+ step3:
+ 'In the Google Admin console, open Security, then API controls, then Domain-wide delegation, and add the service account using its client ID.',
+ step4:
+ 'Grant it the read-only directory scopes: https://www.googleapis.com/auth/admin.directory.user.readonly and https://www.googleapis.com/auth/admin.directory.group.readonly.',
+ step5: 'Upload the JSON key below and enter the email of a Google Workspace admin to read the directory as.',
+ },
okta: {
step1: 'In the Okta Admin Console, open the application used for your SSO connection.',
step2: 'Open the Provisioning tab and select the Integration setting.',
@@ -273,12 +292,8 @@ export const enUS: LocalizationResource = {
notice__tokenShownOnce: 'This token is only shown once. Generate a new token if you lose it.',
subtitle: 'Add these credentials to your identity provider to configure Directory Sync',
title: 'Configure',
- warning__googleUnsupported: {
- subtitle: 'Please contact support to set up your Google Workspace integration.',
- title: 'Google Workspace connections are not configurable via self-serve',
- },
warning__ssoInactive:
- 'Your SSO connection is configured but not active. Members can be provisioned now, but they can only sign in once SSO is activated.',
+ "This SSO connection is configured but not yet active. You can provision members, but they won't be able to sign in until it's active.",
},
navbar: {
title: 'Configure Directory Sync',
@@ -296,14 +311,29 @@ export const enUS: LocalizationResource = {
},
testStep: {
actionLabel__complete: 'Complete',
+ actionLabel__syncNow: 'Sync now',
badge__active: 'Active',
badge__deprovisioned: 'Deprovisioned',
description: 'Users appear here as your identity provider provisions them, most recent activity first.',
+ description__pull:
+ 'Your directory is read on a schedule. Start a sync to pull users now, most recent activity first.',
+ empty__noUsersProvisioned: 'No users have been provisioned yet.',
+ empty__waitingForFirstSync: 'Waiting for the first sync to finish…',
empty__waitingForFirstUser: 'Waiting for the first provisioned user…',
+ error__lastSyncFailed: 'The last sync failed',
error__loadUsers: 'Could not load provisioned users',
+ error__syncFailed: 'Could not start the sync. Check your connection and try again.',
note: 'only users with an email address from a configured domain will be processed.',
noteLabel: 'Note:',
subtitle: 'Assign or push a test user from {{provider}} to verify provisioning.',
+ syncRow: {
+ neverSynced: 'Not synced yet',
+ title: 'Directory sync',
+ },
+ syncStatus__cancelled: 'Cancelled',
+ syncStatus__failed: 'Failed',
+ syncStatus__running: 'Running',
+ syncStatus__succeeded: 'Succeeded',
title: 'Test provisioning',
},
},
diff --git a/packages/localizations/src/es-CR.ts b/packages/localizations/src/es-CR.ts
index 57879bf85b8..d00a4fb9e34 100644
--- a/packages/localizations/src/es-CR.ts
+++ b/packages/localizations/src/es-CR.ts
@@ -242,14 +242,23 @@ export const esCR: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const esCR: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const esCR: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const esCR: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/es-ES.ts b/packages/localizations/src/es-ES.ts
index a9117040297..7668b8273f2 100644
--- a/packages/localizations/src/es-ES.ts
+++ b/packages/localizations/src/es-ES.ts
@@ -248,14 +248,23 @@ export const esES: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -271,6 +280,13 @@ export const esES: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -281,10 +297,6 @@ export const esES: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -303,14 +315,28 @@ export const esES: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/es-MX.ts b/packages/localizations/src/es-MX.ts
index fec6f4d697b..45b270b36ee 100644
--- a/packages/localizations/src/es-MX.ts
+++ b/packages/localizations/src/es-MX.ts
@@ -243,14 +243,23 @@ export const esMX: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -266,6 +275,13 @@ export const esMX: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -276,10 +292,6 @@ export const esMX: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -298,14 +310,28 @@ export const esMX: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/es-UY.ts b/packages/localizations/src/es-UY.ts
index b2ee9573843..41a07137cdf 100644
--- a/packages/localizations/src/es-UY.ts
+++ b/packages/localizations/src/es-UY.ts
@@ -242,14 +242,23 @@ export const esUY: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const esUY: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const esUY: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const esUY: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/fa-IR.ts b/packages/localizations/src/fa-IR.ts
index 7b171d34f9f..2d8ec1d212d 100644
--- a/packages/localizations/src/fa-IR.ts
+++ b/packages/localizations/src/fa-IR.ts
@@ -247,14 +247,23 @@ export const faIR: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -270,6 +279,13 @@ export const faIR: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -280,10 +296,6 @@ export const faIR: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -302,14 +314,28 @@ export const faIR: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/fi-FI.ts b/packages/localizations/src/fi-FI.ts
index fb752974c2d..82263f7b180 100644
--- a/packages/localizations/src/fi-FI.ts
+++ b/packages/localizations/src/fi-FI.ts
@@ -248,14 +248,23 @@ export const fiFI: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -271,6 +280,13 @@ export const fiFI: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -281,10 +297,6 @@ export const fiFI: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -303,14 +315,28 @@ export const fiFI: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/fr-FR.ts b/packages/localizations/src/fr-FR.ts
index 7aeb57da5fa..57c087c439b 100644
--- a/packages/localizations/src/fr-FR.ts
+++ b/packages/localizations/src/fr-FR.ts
@@ -250,14 +250,23 @@ export const frFR: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -273,6 +282,13 @@ export const frFR: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -283,10 +299,6 @@ export const frFR: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -305,14 +317,28 @@ export const frFR: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/he-IL.ts b/packages/localizations/src/he-IL.ts
index e6858234500..6c66e2b782a 100644
--- a/packages/localizations/src/he-IL.ts
+++ b/packages/localizations/src/he-IL.ts
@@ -242,14 +242,23 @@ export const heIL: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const heIL: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const heIL: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const heIL: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/hi-IN.ts b/packages/localizations/src/hi-IN.ts
index 98d0c0fae13..5495af45e4b 100644
--- a/packages/localizations/src/hi-IN.ts
+++ b/packages/localizations/src/hi-IN.ts
@@ -248,14 +248,23 @@ export const hiIN: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -271,6 +280,13 @@ export const hiIN: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -281,10 +297,6 @@ export const hiIN: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -303,14 +315,28 @@ export const hiIN: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/hr-HR.ts b/packages/localizations/src/hr-HR.ts
index 3b734291016..b43ad2b32a3 100644
--- a/packages/localizations/src/hr-HR.ts
+++ b/packages/localizations/src/hr-HR.ts
@@ -249,14 +249,23 @@ export const hrHR: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -272,6 +281,13 @@ export const hrHR: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -282,10 +298,6 @@ export const hrHR: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -304,14 +316,28 @@ export const hrHR: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/hu-HU.ts b/packages/localizations/src/hu-HU.ts
index a8bff797e71..840c05f7a30 100644
--- a/packages/localizations/src/hu-HU.ts
+++ b/packages/localizations/src/hu-HU.ts
@@ -249,14 +249,23 @@ export const huHU: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -272,6 +281,13 @@ export const huHU: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -282,10 +298,6 @@ export const huHU: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -304,14 +316,28 @@ export const huHU: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/id-ID.ts b/packages/localizations/src/id-ID.ts
index 9c7ceb13b3a..f535eb018d4 100644
--- a/packages/localizations/src/id-ID.ts
+++ b/packages/localizations/src/id-ID.ts
@@ -242,14 +242,23 @@ export const idID: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const idID: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const idID: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const idID: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/is-IS.ts b/packages/localizations/src/is-IS.ts
index 351c10e08da..b1cf4775d36 100644
--- a/packages/localizations/src/is-IS.ts
+++ b/packages/localizations/src/is-IS.ts
@@ -248,14 +248,23 @@ export const isIS: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -271,6 +280,13 @@ export const isIS: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -281,10 +297,6 @@ export const isIS: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -303,14 +315,28 @@ export const isIS: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/it-IT.ts b/packages/localizations/src/it-IT.ts
index 31e52f8b457..7254b4112e6 100644
--- a/packages/localizations/src/it-IT.ts
+++ b/packages/localizations/src/it-IT.ts
@@ -248,14 +248,23 @@ export const itIT: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -271,6 +280,13 @@ export const itIT: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -281,10 +297,6 @@ export const itIT: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -303,14 +315,28 @@ export const itIT: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/ja-JP.ts b/packages/localizations/src/ja-JP.ts
index 5d8d3db8d89..9dfeec06a4f 100644
--- a/packages/localizations/src/ja-JP.ts
+++ b/packages/localizations/src/ja-JP.ts
@@ -249,14 +249,23 @@ export const jaJP: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -272,6 +281,13 @@ export const jaJP: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -282,10 +298,6 @@ export const jaJP: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -304,14 +316,28 @@ export const jaJP: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/kk-KZ.ts b/packages/localizations/src/kk-KZ.ts
index 4167b373d0e..34fabe33f2d 100644
--- a/packages/localizations/src/kk-KZ.ts
+++ b/packages/localizations/src/kk-KZ.ts
@@ -242,14 +242,23 @@ export const kkKZ: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const kkKZ: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const kkKZ: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const kkKZ: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/ko-KR.ts b/packages/localizations/src/ko-KR.ts
index ad5b4cf22d3..0c1326fc0fc 100644
--- a/packages/localizations/src/ko-KR.ts
+++ b/packages/localizations/src/ko-KR.ts
@@ -246,14 +246,23 @@ export const koKR: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -269,6 +278,13 @@ export const koKR: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -279,10 +295,6 @@ export const koKR: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -301,14 +313,28 @@ export const koKR: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/mn-MN.ts b/packages/localizations/src/mn-MN.ts
index b96fd7764c1..eb3f619b3bc 100644
--- a/packages/localizations/src/mn-MN.ts
+++ b/packages/localizations/src/mn-MN.ts
@@ -242,14 +242,23 @@ export const mnMN: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const mnMN: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const mnMN: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const mnMN: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/ms-MY.ts b/packages/localizations/src/ms-MY.ts
index 0f5febb75f6..17c20e97493 100644
--- a/packages/localizations/src/ms-MY.ts
+++ b/packages/localizations/src/ms-MY.ts
@@ -250,14 +250,23 @@ export const msMY: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -273,6 +282,13 @@ export const msMY: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -283,10 +299,6 @@ export const msMY: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -305,14 +317,28 @@ export const msMY: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/nb-NO.ts b/packages/localizations/src/nb-NO.ts
index ad3c06e17df..24bb5be3b7f 100644
--- a/packages/localizations/src/nb-NO.ts
+++ b/packages/localizations/src/nb-NO.ts
@@ -249,14 +249,23 @@ export const nbNO: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -272,6 +281,13 @@ export const nbNO: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -282,10 +298,6 @@ export const nbNO: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -304,14 +316,28 @@ export const nbNO: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/nl-BE.ts b/packages/localizations/src/nl-BE.ts
index 06b4956b051..b12667e42a6 100644
--- a/packages/localizations/src/nl-BE.ts
+++ b/packages/localizations/src/nl-BE.ts
@@ -242,14 +242,23 @@ export const nlBE: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const nlBE: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const nlBE: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const nlBE: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/nl-NL.ts b/packages/localizations/src/nl-NL.ts
index 8012f9bbd65..827f26616d6 100644
--- a/packages/localizations/src/nl-NL.ts
+++ b/packages/localizations/src/nl-NL.ts
@@ -242,14 +242,23 @@ export const nlNL: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const nlNL: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const nlNL: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const nlNL: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/pl-PL.ts b/packages/localizations/src/pl-PL.ts
index 22b7b268eb5..629ae7230be 100644
--- a/packages/localizations/src/pl-PL.ts
+++ b/packages/localizations/src/pl-PL.ts
@@ -242,14 +242,23 @@ export const plPL: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const plPL: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const plPL: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const plPL: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/pt-BR.ts b/packages/localizations/src/pt-BR.ts
index db238db5c0d..764bb071051 100644
--- a/packages/localizations/src/pt-BR.ts
+++ b/packages/localizations/src/pt-BR.ts
@@ -248,14 +248,23 @@ export const ptBR: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -271,6 +280,13 @@ export const ptBR: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -281,10 +297,6 @@ export const ptBR: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -303,14 +315,28 @@ export const ptBR: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/pt-PT.ts b/packages/localizations/src/pt-PT.ts
index fafe686c049..9c29d487a27 100644
--- a/packages/localizations/src/pt-PT.ts
+++ b/packages/localizations/src/pt-PT.ts
@@ -250,14 +250,23 @@ export const ptPT: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -273,6 +282,13 @@ export const ptPT: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -283,10 +299,6 @@ export const ptPT: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -305,14 +317,28 @@ export const ptPT: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/ro-RO.ts b/packages/localizations/src/ro-RO.ts
index 6c40143d2ae..43268667827 100644
--- a/packages/localizations/src/ro-RO.ts
+++ b/packages/localizations/src/ro-RO.ts
@@ -248,14 +248,23 @@ export const roRO: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -271,6 +280,13 @@ export const roRO: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -281,10 +297,6 @@ export const roRO: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -303,14 +315,28 @@ export const roRO: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/ru-RU.ts b/packages/localizations/src/ru-RU.ts
index aef3e518f58..4664a748889 100644
--- a/packages/localizations/src/ru-RU.ts
+++ b/packages/localizations/src/ru-RU.ts
@@ -242,14 +242,23 @@ export const ruRU: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const ruRU: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const ruRU: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const ruRU: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/sk-SK.ts b/packages/localizations/src/sk-SK.ts
index 082a1613e1f..742e6ec56ba 100644
--- a/packages/localizations/src/sk-SK.ts
+++ b/packages/localizations/src/sk-SK.ts
@@ -242,14 +242,23 @@ export const skSK: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const skSK: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const skSK: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const skSK: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/sr-RS.ts b/packages/localizations/src/sr-RS.ts
index f7d1166ad90..c09369a7cf8 100644
--- a/packages/localizations/src/sr-RS.ts
+++ b/packages/localizations/src/sr-RS.ts
@@ -242,14 +242,23 @@ export const srRS: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const srRS: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const srRS: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const srRS: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/sv-SE.ts b/packages/localizations/src/sv-SE.ts
index ac5f30f0c58..508866d8765 100644
--- a/packages/localizations/src/sv-SE.ts
+++ b/packages/localizations/src/sv-SE.ts
@@ -242,14 +242,23 @@ export const svSE: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const svSE: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const svSE: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const svSE: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/ta-IN.ts b/packages/localizations/src/ta-IN.ts
index 7e33a3f6738..de419b38460 100644
--- a/packages/localizations/src/ta-IN.ts
+++ b/packages/localizations/src/ta-IN.ts
@@ -250,14 +250,23 @@ export const taIN: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -273,6 +282,13 @@ export const taIN: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -283,10 +299,6 @@ export const taIN: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -305,14 +317,28 @@ export const taIN: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/te-IN.ts b/packages/localizations/src/te-IN.ts
index 296bfeaf459..c5dcaaafd3b 100644
--- a/packages/localizations/src/te-IN.ts
+++ b/packages/localizations/src/te-IN.ts
@@ -249,14 +249,23 @@ export const teIN: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -272,6 +281,13 @@ export const teIN: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -282,10 +298,6 @@ export const teIN: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -304,14 +316,28 @@ export const teIN: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/th-TH.ts b/packages/localizations/src/th-TH.ts
index 8f0b0007edf..9c966c37b22 100644
--- a/packages/localizations/src/th-TH.ts
+++ b/packages/localizations/src/th-TH.ts
@@ -246,14 +246,23 @@ export const thTH: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -269,6 +278,13 @@ export const thTH: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -279,10 +295,6 @@ export const thTH: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -301,14 +313,28 @@ export const thTH: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/tr-TR.ts b/packages/localizations/src/tr-TR.ts
index e5973ed6aba..f91f29111d8 100644
--- a/packages/localizations/src/tr-TR.ts
+++ b/packages/localizations/src/tr-TR.ts
@@ -242,14 +242,23 @@ export const trTR: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const trTR: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const trTR: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const trTR: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/uk-UA.ts b/packages/localizations/src/uk-UA.ts
index 0b5276288d3..fe89a0e14ea 100644
--- a/packages/localizations/src/uk-UA.ts
+++ b/packages/localizations/src/uk-UA.ts
@@ -242,14 +242,23 @@ export const ukUA: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const ukUA: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const ukUA: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const ukUA: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/vi-VN.ts b/packages/localizations/src/vi-VN.ts
index 91843807c98..1cb2a822051 100644
--- a/packages/localizations/src/vi-VN.ts
+++ b/packages/localizations/src/vi-VN.ts
@@ -248,14 +248,23 @@ export const viVN: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -271,6 +280,13 @@ export const viVN: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -281,10 +297,6 @@ export const viVN: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -303,14 +315,28 @@ export const viVN: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/zh-CN.ts b/packages/localizations/src/zh-CN.ts
index 16f338d03ef..2b64031e69c 100644
--- a/packages/localizations/src/zh-CN.ts
+++ b/packages/localizations/src/zh-CN.ts
@@ -242,14 +242,23 @@ export const zhCN: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -265,6 +274,13 @@ export const zhCN: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -275,10 +291,6 @@ export const zhCN: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -297,14 +309,28 @@ export const zhCN: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/localizations/src/zh-TW.ts b/packages/localizations/src/zh-TW.ts
index 8f6091c6a0a..847b62ead44 100644
--- a/packages/localizations/src/zh-TW.ts
+++ b/packages/localizations/src/zh-TW.ts
@@ -245,14 +245,23 @@ export const zhTW: LocalizationResource = {
},
configureStep: {
actionLabel__generateToken: undefined,
+ actionLabel__replaceKey: undefined,
actionLabel__retry: undefined,
+ actionLabel__uploadKey: undefined,
+ badge__credentialsConfigured: undefined,
+ badge__credentialsMissing: undefined,
domainsLabel: undefined,
+ error__invalidKeyFile: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
+ formFieldHint__subjectEmail: undefined,
+ formFieldInputPlaceholder__subjectEmail: undefined,
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
+ formFieldLabel__serviceAccountKey: undefined,
+ formFieldLabel__subjectEmail: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
@@ -268,6 +277,13 @@ export const zhTW: LocalizationResource = {
step3: undefined,
step4: undefined,
},
+ google: {
+ step1: undefined,
+ step2: undefined,
+ step3: undefined,
+ step4: undefined,
+ step5: undefined,
+ },
okta: {
step1: undefined,
step2: undefined,
@@ -278,10 +294,6 @@ export const zhTW: LocalizationResource = {
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
- warning__googleUnsupported: {
- subtitle: undefined,
- title: undefined,
- },
warning__ssoInactive: undefined,
},
navbar: {
@@ -300,14 +312,28 @@ export const zhTW: LocalizationResource = {
},
testStep: {
actionLabel__complete: undefined,
+ actionLabel__syncNow: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
+ description__pull: undefined,
+ empty__noUsersProvisioned: undefined,
+ empty__waitingForFirstSync: undefined,
empty__waitingForFirstUser: undefined,
+ error__lastSyncFailed: undefined,
error__loadUsers: undefined,
+ error__syncFailed: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
+ syncRow: {
+ neverSynced: undefined,
+ title: undefined,
+ },
+ syncStatus__cancelled: undefined,
+ syncStatus__failed: undefined,
+ syncStatus__running: undefined,
+ syncStatus__succeeded: undefined,
title: undefined,
},
},
diff --git a/packages/shared/src/__tests__/file.spec.ts b/packages/shared/src/__tests__/file.spec.ts
new file mode 100644
index 00000000000..06c9d1d90f3
--- /dev/null
+++ b/packages/shared/src/__tests__/file.spec.ts
@@ -0,0 +1,17 @@
+import { describe, expect, it } from 'vitest';
+
+import { readJSONFile } from '../file';
+
+describe('readJSONFile', () => {
+ it('resolves with the parsed contents', async () => {
+ const file = new File(['{"type":"service_account"}'], 'key.json', { type: 'application/json' });
+
+ await expect(readJSONFile(file)).resolves.toEqual({ type: 'service_account' });
+ });
+
+ it('rejects a file that is not JSON', async () => {
+ const file = new File(['not json'], 'key.json', { type: 'application/json' });
+
+ await expect(readJSONFile(file)).rejects.toThrow(SyntaxError);
+ });
+});
diff --git a/packages/shared/src/file.ts b/packages/shared/src/file.ts
index 88c4f85c3d5..1a1d524c922 100644
--- a/packages/shared/src/file.ts
+++ b/packages/shared/src/file.ts
@@ -4,17 +4,20 @@
* Probably paired with:
*
*/
-export function readJSONFile(file: File): Promise {
- return new Promise((resolve, reject) => {
+export async function readJSONFile(file: File): Promise {
+ const text = await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener('load', function () {
- const result = JSON.parse(reader.result as string);
- resolve(result);
+ resolve(reader.result as string);
});
reader.addEventListener('error', reject);
reader.readAsText(file);
});
+
+ // Parsed here rather than in the load listener, where a throw never reaches
+ // the promise and leaves it pending.
+ return JSON.parse(text);
}
const MimeTypeToExtensionMap = Object.freeze({
diff --git a/packages/shared/src/types/localization.ts b/packages/shared/src/types/localization.ts
index 37c552fdb49..6d2c93a776d 100644
--- a/packages/shared/src/types/localization.ts
+++ b/packages/shared/src/types/localization.ts
@@ -1603,11 +1603,16 @@ export type __internal_LocalizationResource = {
title: LocalizationValue;
subtitle: LocalizationValue;
};
- warning__googleUnsupported: {
- title: LocalizationValue;
- subtitle: LocalizationValue;
- };
warning__ssoInactive: LocalizationValue;
+ formFieldLabel__serviceAccountKey: LocalizationValue;
+ formFieldLabel__subjectEmail: LocalizationValue;
+ formFieldInputPlaceholder__subjectEmail: LocalizationValue;
+ formFieldHint__subjectEmail: LocalizationValue;
+ actionLabel__uploadKey: LocalizationValue;
+ actionLabel__replaceKey: LocalizationValue;
+ badge__credentialsConfigured: LocalizationValue;
+ badge__credentialsMissing: LocalizationValue;
+ error__invalidKeyFile: LocalizationValue;
domainsLabel: LocalizationValue;
instructions: {
actionLabel__toggle: LocalizationValue;
@@ -1629,6 +1634,13 @@ export type __internal_LocalizationResource = {
step3: LocalizationValue;
step4: LocalizationValue;
};
+ google: {
+ step1: LocalizationValue;
+ step2: LocalizationValue;
+ step3: LocalizationValue;
+ step4: LocalizationValue;
+ step5: LocalizationValue;
+ };
};
formFieldLabel__endpointUrl: LocalizationValue;
formFieldLabel__token: LocalizationValue;
@@ -1649,9 +1661,23 @@ export type __internal_LocalizationResource = {
title: LocalizationValue;
subtitle: LocalizationValue<'provider'>;
description: LocalizationValue;
+ description__pull: LocalizationValue;
noteLabel: LocalizationValue;
note: LocalizationValue;
empty__waitingForFirstUser: LocalizationValue;
+ empty__waitingForFirstSync: LocalizationValue;
+ empty__noUsersProvisioned: LocalizationValue;
+ actionLabel__syncNow: LocalizationValue;
+ error__lastSyncFailed: LocalizationValue;
+ error__syncFailed: LocalizationValue;
+ syncStatus__running: LocalizationValue;
+ syncStatus__succeeded: LocalizationValue;
+ syncStatus__failed: LocalizationValue;
+ syncStatus__cancelled: LocalizationValue;
+ syncRow: {
+ title: LocalizationValue;
+ neverSynced: LocalizationValue;
+ };
badge__active: LocalizationValue;
badge__deprovisioned: LocalizationValue;
error__loadUsers: LocalizationValue;
diff --git a/packages/ui/bundlewatch.config.json b/packages/ui/bundlewatch.config.json
index c2cd9a0e4f4..ec22fea446c 100644
--- a/packages/ui/bundlewatch.config.json
+++ b/packages/ui/bundlewatch.config.json
@@ -2,10 +2,10 @@
"files": [
{ "path": "./dist/ui.browser.js", "maxSize": "45KB" },
{ "path": "./dist/ui.legacy.browser.js", "maxSize": "85KB" },
- { "path": "./dist/ui.shared.browser.js", "maxSize": "42KB" },
+ { "path": "./dist/ui.shared.browser.js", "maxSize": "44KB" },
{ "path": "./dist/framework*.js", "maxSize": "44KB" },
{ "path": "./dist/vendors*.js", "maxSize": "73KB" },
- { "path": "./dist/ui-common*.js", "maxSize": "137KB" },
+ { "path": "./dist/ui-common*.js", "maxSize": "139KB" },
{ "path": "./dist/signin*.js", "maxSize": "19KB" },
{ "path": "./dist/signup*.js", "maxSize": "13KB" },
{ "path": "./dist/userprofile*.js", "maxSize": "16KB" },
diff --git a/packages/ui/src/components/ConfigureDirectorySync/ConfigureDirectorySyncContext.tsx b/packages/ui/src/components/ConfigureDirectorySync/ConfigureDirectorySyncContext.tsx
index e52e8468a1e..04a17a2cda2 100644
--- a/packages/ui/src/components/ConfigureDirectorySync/ConfigureDirectorySyncContext.tsx
+++ b/packages/ui/src/components/ConfigureDirectorySync/ConfigureDirectorySyncContext.tsx
@@ -2,7 +2,12 @@ import {
__internal_useOrganizationDirectorySync,
__internal_useOrganizationEnterpriseConnections,
} from '@clerk/shared/react';
-import type { DirectorySyncProvider, DirectorySyncResource, EnterpriseConnectionResource } from '@clerk/shared/types';
+import type {
+ DirectorySyncProvider,
+ DirectorySyncResource,
+ EnterpriseConnectionResource,
+ SetDirectorySyncCredentialsParams,
+} from '@clerk/shared/types';
import React, { type PropsWithChildren } from 'react';
import { sortEnterpriseConnections } from '../ConfigureSSO/domain/organizationEnterpriseConnection';
@@ -30,6 +35,10 @@ export interface ConfigureDirectorySyncData {
createDirectory: () => Promise;
rotateToken: () => Promise;
setDirectoryEnabled: (enabled: boolean) => Promise;
+ /** Stores the credential a pull directory reads the identity provider with. */
+ setCredentials: (params: SetDirectorySyncCredentialsParams) => Promise;
+ /** Starts a sync for a pull directory. */
+ syncDirectory: () => Promise;
onExit?: () => void;
}
@@ -61,6 +70,8 @@ export const ConfigureDirectorySyncProvider = ({
createDirectorySync,
updateDirectorySync,
rotateDirectorySyncToken,
+ setDirectorySyncCredentials,
+ syncDirectory,
} = __internal_useOrganizationDirectorySync({ enterpriseConnectionId });
// The token is stored with the connection it was issued for, so a response
@@ -104,6 +115,8 @@ export const ConfigureDirectorySyncProvider = ({
createDirectory,
rotateToken,
setDirectoryEnabled,
+ setCredentials: setDirectorySyncCredentials,
+ syncDirectory,
onExit,
};
diff --git a/packages/ui/src/components/ConfigureDirectorySync/GoogleCredentialsForm.tsx b/packages/ui/src/components/ConfigureDirectorySync/GoogleCredentialsForm.tsx
new file mode 100644
index 00000000000..e18b4508e09
--- /dev/null
+++ b/packages/ui/src/components/ConfigureDirectorySync/GoogleCredentialsForm.tsx
@@ -0,0 +1,204 @@
+import { readJSONFile } from '@clerk/shared/file';
+import { useCallback, useRef, useState } from 'react';
+
+import {
+ Badge,
+ Button,
+ Col,
+ descriptors,
+ Flex,
+ Input,
+ localizationKeys,
+ Text,
+ useLocalizations,
+} from '@/customizables';
+import { isEmail } from '@/ui/utils/emailUtils';
+
+import { useConfigureDirectorySync } from './ConfigureDirectorySyncContext';
+
+export type GoogleCredentialsState = {
+ fileName: string | null;
+ subjectEmail: string;
+ fileError: string | null;
+ isConfigured: boolean;
+ /** Whether the step can be left: a credential is stored, or one is ready to send. */
+ canContinue: boolean;
+ setSubjectEmail: (value: string) => void;
+ selectFile: (file: File | undefined) => Promise;
+ /** Sends the pending credential, if there is one. Rejects if the provider refuses it. */
+ submit: () => Promise;
+};
+
+/**
+ * Holds the credential a pull-based directory reads the identity provider with.
+ *
+ * State lives here rather than inside the form so the step footer can drive it:
+ * the wizard's Continue performs the submit, so the form has no button of its
+ * own and there is only one way forward.
+ */
+export const useGoogleCredentialsState = (): GoogleCredentialsState => {
+ const { directory, setCredentials } = useConfigureDirectorySync();
+ const { t } = useLocalizations();
+
+ const [serviceAccountJson, setServiceAccountJson] = useState('');
+ const [fileName, setFileName] = useState(null);
+ const [subjectEmail, setSubjectEmail] = useState('');
+ const [fileError, setFileError] = useState(null);
+
+ const isConfigured = Boolean(directory?.credentialsConfigured);
+ const trimmedSubjectEmail = subjectEmail.trim();
+ // Continue lives outside the form, so the input's type='email' never triggers
+ // native validation. Without this, whitespace alone enables it.
+ const hasPendingCredential = Boolean(serviceAccountJson) && isEmail(trimmedSubjectEmail);
+
+ const selectFile = useCallback(
+ async (file: File | undefined): Promise => {
+ if (!file) {
+ return;
+ }
+ // Drop whatever was selected before reading: a failed read must not leave
+ // the previous key staged and submittable.
+ setServiceAccountJson('');
+ setFileName(null);
+ setFileError(null);
+
+ let key: unknown;
+ try {
+ key = await readJSONFile(file);
+ } catch {
+ // Catch the obvious wrong-file case here; anything structurally valid is
+ // the identity provider's to judge, and its message is better than ours.
+ setFileError(t(localizationKeys('configureDirectorySync.configureStep.error__invalidKeyFile')));
+ return;
+ }
+ setServiceAccountJson(JSON.stringify(key));
+ setFileName(file.name);
+ },
+ [t],
+ );
+
+ const submit = useCallback(async (): Promise => {
+ if (!hasPendingCredential) {
+ return;
+ }
+ await setCredentials({ serviceAccountJson, subjectEmail: trimmedSubjectEmail });
+ setServiceAccountJson('');
+ setFileName(null);
+ }, [hasPendingCredential, setCredentials, serviceAccountJson, trimmedSubjectEmail]);
+
+ return {
+ fileName,
+ subjectEmail,
+ fileError,
+ isConfigured,
+ canContinue: isConfigured || hasPendingCredential,
+ setSubjectEmail,
+ selectFile,
+ submit,
+ };
+};
+
+/**
+ * Collects the service account key and the administrator it impersonates. The
+ * key is never held in wizard state, which outlives the request.
+ */
+export const GoogleCredentialsForm = ({ state }: { state: GoogleCredentialsState }): JSX.Element => {
+ const { t } = useLocalizations();
+ const fileInputRef = useRef(null);
+ const { fileName, subjectEmail, fileError, isConfigured, setSubjectEmail, selectFile } = state;
+
+ return (
+ ({ gap: t.space.$5 })}
+ >
+ ({ gap: t.space.$2 })}
+ >
+ ({ fontSize: t.fontSizes.$sm, fontWeight: t.fontWeights.$medium })}
+ />
+
+
+
+ ({ gap: t.space.$1x5 })}>
+ void selectFile(event.target.files?.[0])}
+ />
+ ({ gap: t.space.$2 })}
+ >
+
+ {fileError && (
+ ({ fontSize: t.fontSizes.$sm })}
+ >
+ {fileError}
+
+ )}
+
+
+ ({ gap: t.space.$1x5 })}>
+ ({ fontSize: t.fontSizes.$sm, fontWeight: t.fontWeights.$medium })}
+ />
+ setSubjectEmail(event.target.value)}
+ placeholder={t(
+ localizationKeys('configureDirectorySync.configureStep.formFieldInputPlaceholder__subjectEmail'),
+ )}
+ />
+ ({ fontSize: t.fontSizes.$sm })}
+ />
+
+
+ );
+};
diff --git a/packages/ui/src/components/ConfigureDirectorySync/SecurityDirectorySyncSection.tsx b/packages/ui/src/components/ConfigureDirectorySync/SecurityDirectorySyncSection.tsx
index 9a418e306ac..32e333957d2 100644
--- a/packages/ui/src/components/ConfigureDirectorySync/SecurityDirectorySyncSection.tsx
+++ b/packages/ui/src/components/ConfigureDirectorySync/SecurityDirectorySyncSection.tsx
@@ -15,7 +15,6 @@ import type { LocalizationKey } from '../../customizables';
import { Badge, Button, Col, descriptors, Flex, localizationKeys, Spinner, Text } from '../../customizables';
import { sortEnterpriseConnections } from '../ConfigureSSO/domain/organizationEnterpriseConnection';
import { ResetConnectionDialog } from '../ConfigureSSO/ResetConnectionDialog';
-import { directorySyncProviderForConnection } from './providerMeta';
type SecurityDirectorySyncSectionProps = {
organizationName: string;
@@ -59,7 +58,6 @@ export const SecurityDirectorySyncSection = ({
} = __internal_useOrganizationEnterpriseConnections();
const connection = sortEnterpriseConnections(connections ?? [])[0];
const hasSsoConnection = Boolean(connection);
- const isGoogle = connection ? directorySyncProviderForConnection(connection.provider) === 'google' : false;
const {
data: directory,
isLoading: isLoadingDirectory,
@@ -116,37 +114,29 @@ export const SecurityDirectorySyncSection = ({
gap={4}
>
- {isGoogle ? (
-
+
- ) : (
-
-
- {!hasSsoConnection && (
-
- )}
-
- )}
+ )}
+
) : (
diff --git a/packages/ui/src/components/ConfigureDirectorySync/SyncNowRow.tsx b/packages/ui/src/components/ConfigureDirectorySync/SyncNowRow.tsx
new file mode 100644
index 00000000000..79f30c4b01f
--- /dev/null
+++ b/packages/ui/src/components/ConfigureDirectorySync/SyncNowRow.tsx
@@ -0,0 +1,138 @@
+import type { DirectorySyncStatusResource } from '@clerk/shared/types';
+import { useState } from 'react';
+
+import { Badge, Button, Col, descriptors, Flex, localizationKeys, Text, useLocalizations } from '@/customizables';
+import { Alert } from '@/ui/elements/Alert';
+import { handleError } from '@/utils/errorHandler';
+
+type SyncNowRowProps = {
+ status: DirectorySyncStatusResource | undefined;
+ onSync: () => Promise;
+ onSynced: () => void;
+};
+
+const STATUS_COLOR_SCHEME = {
+ succeeded: 'success',
+ running: 'primary',
+ failed: 'danger',
+ cancelled: 'warning',
+} as const;
+
+/**
+ * Starts a sync and reports how the last one went.
+ *
+ * A pull directory is read on a schedule, so without this the setup flow shows
+ * an empty user list for minutes with no way to tell a slow sync from a broken
+ * one.
+ */
+export const SyncNowRow = ({ status, onSync, onSynced }: SyncNowRowProps): JSX.Element => {
+ const { t } = useLocalizations();
+ const [isSyncing, setIsSyncing] = useState(false);
+ const [error, setError] = useState(undefined);
+
+ const run = async (): Promise => {
+ if (isSyncing) {
+ return;
+ }
+ setError(undefined);
+ setIsSyncing(true);
+ try {
+ await onSync();
+ onSynced();
+ } catch (err) {
+ // Includes the already-running case, which is a normal thing to hit by
+ // clicking twice rather than a failure worth alarming about.
+ try {
+ handleError(err as Error, [], message => setError(typeof message === 'string' ? message : undefined));
+ } catch {
+ // handleError rethrows anything it does not recognise, and a network
+ // failure is exactly that. Without this the click would appear to do
+ // nothing at all.
+ setError(t(localizationKeys('configureDirectorySync.testStep.error__syncFailed')));
+ }
+ } finally {
+ setIsSyncing(false);
+ }
+ };
+
+ const lastStatus = status?.lastSyncStatus ?? null;
+
+ return (
+ ({
+ gap: t.space.$3,
+ padding: t.space.$4,
+ borderRadius: t.radii.$md,
+ borderWidth: t.borderWidths.$normal,
+ borderStyle: t.borderStyles.$solid,
+ borderColor: t.colors.$borderAlpha150,
+ })}
+ >
+ ({ gap: t.space.$3 })}
+ >
+ ({ gap: t.space.$0x5 })}>
+ ({ gap: t.space.$2 })}
+ >
+ ({ fontSize: t.fontSizes.$sm, fontWeight: t.fontWeights.$medium })}
+ />
+ {lastStatus && (
+
+ )}
+
+ ({ fontSize: t.fontSizes.$sm })}
+ localizationKey={
+ status?.lastSyncedAt ? undefined : localizationKeys('configureDirectorySync.testStep.syncRow.neverSynced')
+ }
+ >
+ {status?.lastSyncedAt ? status.lastSyncedAt.toLocaleString() : undefined}
+
+
+
+
+
+ {/* The provider's own failure message is the only thing that says what to
+ fix in the Workspace setup, so it is shown rather than summarized. */}
+ {status?.lastSyncError && (
+
+ )}
+
+ {error && (
+
+ )}
+
+ );
+};
diff --git a/packages/ui/src/components/ConfigureDirectorySync/__tests__/ConfigureDirectorySyncWizard.test.tsx b/packages/ui/src/components/ConfigureDirectorySync/__tests__/ConfigureDirectorySyncWizard.test.tsx
index dc697d65f46..adcdaeda135 100644
--- a/packages/ui/src/components/ConfigureDirectorySync/__tests__/ConfigureDirectorySyncWizard.test.tsx
+++ b/packages/ui/src/components/ConfigureDirectorySync/__tests__/ConfigureDirectorySyncWizard.test.tsx
@@ -2,7 +2,7 @@ import { ClerkAPIResponseError } from '@clerk/shared/error';
import { describe, expect, it, vi } from 'vitest';
import { bindCreateFixtures } from '@/test/create-fixtures';
-import { render, screen, waitFor } from '@/test/utils';
+import { fireEvent, render, screen, waitFor } from '@/test/utils';
import { ConfigureDirectorySyncWizard } from '../ConfigureDirectorySyncWizard';
@@ -35,6 +35,9 @@ const oktaConnection = {
const directory = (overrides: Record = {}) =>
({
id: 'scimdir_1',
+ // The sync status hook refuses a directory from another organization, and
+ // the fixture organization's id comes from the membership name.
+ organizationId: 'Org1',
enterpriseConnectionId: 'ent_1',
endpointUrl: 'https://api.example.com/scim/v2',
provider: 'okta',
@@ -48,6 +51,23 @@ const directory = (overrides: Record = {}) =>
...overrides,
}) as any;
+const googleConnection = { ...oktaConnection, provider: 'saml_google' };
+
+const googleDirectory = (overrides: Record = {}) =>
+ directory({
+ provider: 'google',
+ credentialsConfigured: false,
+ setCredentials: vi.fn(),
+ sync: vi.fn(),
+ getSyncStatus: vi.fn().mockResolvedValue({
+ lastSyncedAt: null,
+ lastSyncStatus: null,
+ lastSyncError: null,
+ lastSyncChangedUserCount: null,
+ }),
+ ...overrides,
+ });
+
const notFound = () =>
new ClerkAPIResponseError('Not found', { status: 404, data: [{ code: 'resource_not_found', message: '' }] });
@@ -98,6 +118,137 @@ describe('ConfigureDirectorySyncWizard configure step', () => {
expect(await screen.findByDisplayValue('tok_rotated')).toBeInTheDocument();
});
+ it('collects a credential for a Google Workspace connection instead of dead-ending', async () => {
+ const { wrapper, fixtures } = await createFixtures(withDirectorySyncFixtures);
+ fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([googleConnection]);
+ const created = googleDirectory();
+ fixtures.clerk.organization?.getDirectorySync.mockRejectedValueOnce(notFound()).mockResolvedValue(created);
+ fixtures.clerk.organization?.createDirectorySync.mockResolvedValue(created);
+
+ render(, { wrapper });
+
+ // Google used to render a "configure it in the Clerk Dashboard" notice here,
+ // which the organization admin has no account for.
+ expect(await screen.findByRole('button', { name: 'Upload JSON key' })).toBeInTheDocument();
+ expect(
+ screen.queryByText('Google Workspace connections are not configurable via self-serve'),
+ ).not.toBeInTheDocument();
+ // A pull directory has no endpoint or bearer token to hand out.
+ expect(screen.queryByDisplayValue('https://api.example.com/scim/v2')).not.toBeInTheDocument();
+ expect(screen.getByText('Not configured')).toBeInTheDocument();
+ });
+
+ it('sends the uploaded key and admin email, and does not keep the key afterwards', async () => {
+ const { wrapper, fixtures } = await createFixtures(withDirectorySyncFixtures);
+ fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([googleConnection]);
+ const existing = googleDirectory();
+ existing.setCredentials.mockResolvedValue(googleDirectory({ credentialsConfigured: true, enabled: true }));
+ fixtures.clerk.organization?.getDirectorySync.mockResolvedValue(existing);
+
+ const { userEvent } = render(, { wrapper });
+
+ await screen.findByRole('button', { name: 'Upload JSON key' });
+ // The input is hidden behind a styled button, which userEvent.upload will
+ // not interact with, so the change is dispatched directly.
+ const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
+ const keyFile = new File(['{"type":"service_account"}'], 'key.json', { type: 'application/json' });
+ fireEvent.change(fileInput, { target: { files: [keyFile] } });
+
+ // Reading the file is async, so the submit stays disabled until it lands.
+ expect(await screen.findByText('key.json')).toBeInTheDocument();
+
+ await userEvent.type(screen.getByPlaceholderText('admin@yourcompany.com'), 'admin@clerk.com');
+ // Continue is the submit; the form has no button of its own.
+ await userEvent.click(screen.getByRole('button', { name: 'Continue' }));
+
+ await waitFor(() =>
+ expect(existing.setCredentials).toHaveBeenCalledWith({
+ serviceAccountJson: '{"type":"service_account"}',
+ subjectEmail: 'admin@clerk.com',
+ }),
+ );
+
+ // The key is dropped once accepted; the form must not still be holding it.
+ await waitFor(() => expect(screen.queryByText('key.json')).not.toBeInTheDocument());
+ });
+
+ it('holds Continue until both the key and the admin email are given', async () => {
+ const { wrapper, fixtures } = await createFixtures(withDirectorySyncFixtures);
+ fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([googleConnection]);
+ fixtures.clerk.organization?.getDirectorySync.mockResolvedValue(googleDirectory());
+
+ const { userEvent } = render(, { wrapper });
+
+ await screen.findByRole('button', { name: 'Upload JSON key' });
+ expect(screen.getByRole('button', { name: 'Continue' })).toBeDisabled();
+
+ // An email on its own is not enough to send.
+ await userEvent.type(screen.getByPlaceholderText('admin@yourcompany.com'), 'admin@clerk.com');
+ expect(screen.getByRole('button', { name: 'Continue' })).toBeDisabled();
+
+ const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
+ fireEvent.change(fileInput, {
+ target: { files: [new File(['{"type":"service_account"}'], 'key.json', { type: 'application/json' })] },
+ });
+
+ await waitFor(() => expect(screen.getByRole('button', { name: 'Continue' })).toBeEnabled());
+ });
+
+ it('drops the staged key when a file that is not JSON replaces it', async () => {
+ const { wrapper, fixtures } = await createFixtures(withDirectorySyncFixtures);
+ fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([googleConnection]);
+ fixtures.clerk.organization?.getDirectorySync.mockResolvedValue(googleDirectory());
+
+ const { userEvent } = render(, { wrapper });
+
+ await screen.findByRole('button', { name: 'Upload JSON key' });
+ await userEvent.type(screen.getByPlaceholderText('admin@yourcompany.com'), 'admin@clerk.com');
+ const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
+ fireEvent.change(fileInput, {
+ target: { files: [new File(['{"type":"service_account"}'], 'key.json', { type: 'application/json' })] },
+ });
+ await waitFor(() => expect(screen.getByRole('button', { name: 'Continue' })).toBeEnabled());
+
+ fireEvent.change(fileInput, {
+ target: { files: [new File(['not json'], 'notes.json', { type: 'application/json' })] },
+ });
+
+ // The earlier key must not stay submittable behind the error.
+ expect(
+ await screen.findByText('That file is not valid JSON. Upload the key file downloaded from Google.'),
+ ).toBeInTheDocument();
+ expect(screen.getByRole('button', { name: 'Continue' })).toBeDisabled();
+ });
+
+ it('does not accept whitespace or a malformed address as the admin email', async () => {
+ const { wrapper, fixtures } = await createFixtures(withDirectorySyncFixtures);
+ fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([googleConnection]);
+ fixtures.clerk.organization?.getDirectorySync.mockResolvedValue(googleDirectory());
+
+ const { userEvent } = render(, { wrapper });
+
+ await screen.findByRole('button', { name: 'Upload JSON key' });
+ const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
+ fireEvent.change(fileInput, {
+ target: { files: [new File(['{"type":"service_account"}'], 'key.json', { type: 'application/json' })] },
+ });
+ await screen.findByText('key.json');
+
+ // Continue sits outside the form, so the input's type='email' never runs
+ // native validation. These would otherwise reach the provider as-is.
+ const emailInput = screen.getByPlaceholderText('admin@yourcompany.com');
+ await userEvent.type(emailInput, ' ');
+ expect(screen.getByRole('button', { name: 'Continue' })).toBeDisabled();
+
+ await userEvent.clear(emailInput);
+ await userEvent.type(emailInput, 'not-an-email');
+ expect(screen.getByRole('button', { name: 'Continue' })).toBeDisabled();
+
+ await userEvent.clear(emailInput);
+ await userEvent.type(emailInput, ' admin@clerk.com ');
+ await waitFor(() => expect(screen.getByRole('button', { name: 'Continue' })).toBeEnabled());
+ });
+
it('blocks the step without an SSO connection', async () => {
const { wrapper, fixtures } = await createFixtures(withDirectorySyncFixtures);
fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([]);
@@ -130,4 +281,110 @@ describe('ConfigureDirectorySyncWizard test step', () => {
expect(screen.getByText('users unavailable')).toBeInTheDocument();
expect(screen.queryByText('Waiting for the first provisioned user…')).not.toBeInTheDocument();
});
+
+ it('stops waiting once a sync has finished without provisioning anyone', async () => {
+ const { wrapper, fixtures } = await createFixtures(withDirectorySyncFixtures);
+ fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([googleConnection]);
+ const existing = googleDirectory({ credentialsConfigured: true, enabled: true });
+ existing.getSyncStatus.mockResolvedValue({
+ lastSyncedAt: new Date(),
+ lastSyncStatus: 'succeeded',
+ lastSyncError: null,
+ lastSyncChangedUserCount: 0,
+ });
+ fixtures.clerk.organization?.getDirectorySync.mockResolvedValue(existing);
+
+ const { userEvent } = render(, { wrapper });
+
+ await screen.findByRole('button', { name: 'Upload JSON key' });
+ await userEvent.click(screen.getByRole('button', { name: 'Continue' }));
+ expect(await screen.findByText('Attribute review')).toBeInTheDocument();
+ await userEvent.click(screen.getByRole('button', { name: 'Continue' }));
+
+ // An empty directory is the sync's result, not a stage on the way to one,
+ // so the step must not keep implying users are still on their way.
+ expect(await screen.findByText('No users have been provisioned yet.')).toBeInTheDocument();
+ expect(screen.queryByText('Waiting for the first sync to finish…')).not.toBeInTheDocument();
+ });
+
+ it('keeps waiting while the list refreshed by a sync is still loading', async () => {
+ const { wrapper, fixtures } = await createFixtures(withDirectorySyncFixtures);
+ fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([googleConnection]);
+ const existing = googleDirectory({ credentialsConfigured: true, enabled: true });
+ let releaseUsers: ((value: unknown) => void) | null = null;
+ existing.sync.mockImplementation(async () => {
+ existing.getSyncStatus.mockResolvedValue({
+ lastSyncedAt: new Date(),
+ lastSyncStatus: 'succeeded',
+ lastSyncError: null,
+ lastSyncChangedUserCount: 3,
+ });
+ // The refreshed list is slow to arrive. Until it does, the list on screen
+ // is the one from before the sync.
+ existing.getUsers.mockImplementation(() => new Promise(resolve => (releaseUsers = resolve)));
+ });
+ fixtures.clerk.organization?.getDirectorySync.mockResolvedValue(existing);
+
+ const { userEvent } = render(, { wrapper });
+
+ await screen.findByRole('button', { name: 'Upload JSON key' });
+ await userEvent.click(screen.getByRole('button', { name: 'Continue' }));
+ expect(await screen.findByText('Attribute review')).toBeInTheDocument();
+ await userEvent.click(screen.getByRole('button', { name: 'Continue' }));
+
+ await userEvent.click(await screen.findByRole('button', { name: 'Sync now' }));
+
+ // The sync has reported success, but the users it provisioned have not been
+ // read yet, so calling the directory empty here would be wrong.
+ expect(await screen.findByText('Succeeded')).toBeInTheDocument();
+ expect(screen.queryByText('No users have been provisioned yet.')).not.toBeInTheDocument();
+
+ releaseUsers?.({
+ data: [{ id: 'dsu_1', identifier: 'someone@clerk.com', active: true, provisionedAt: new Date() }],
+ total_count: 1,
+ });
+
+ expect(await screen.findByText('someone@clerk.com')).toBeInTheDocument();
+ });
+
+ it('keeps waiting while the users a finished sync changed are still landing', async () => {
+ const { wrapper, fixtures } = await createFixtures(withDirectorySyncFixtures);
+ fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([googleConnection]);
+ const existing = googleDirectory({ credentialsConfigured: true, enabled: true });
+ // The sync changed users, but they are provisioned after it finishes, so
+ // the list is legitimately empty for a moment.
+ existing.getSyncStatus.mockResolvedValue({
+ lastSyncedAt: new Date(),
+ lastSyncStatus: 'succeeded',
+ lastSyncError: null,
+ lastSyncChangedUserCount: 4,
+ });
+ fixtures.clerk.organization?.getDirectorySync.mockResolvedValue(existing);
+
+ const { userEvent } = render(, { wrapper });
+
+ await screen.findByRole('button', { name: 'Upload JSON key' });
+ await userEvent.click(screen.getByRole('button', { name: 'Continue' }));
+ expect(await screen.findByText('Attribute review')).toBeInTheDocument();
+ await userEvent.click(screen.getByRole('button', { name: 'Continue' }));
+
+ expect(await screen.findByText('Waiting for the first sync to finish…')).toBeInTheDocument();
+ expect(screen.queryByText('No users have been provisioned yet.')).not.toBeInTheDocument();
+ });
+
+ it('keeps waiting while a pull directory has not finished a sync', async () => {
+ const { wrapper, fixtures } = await createFixtures(withDirectorySyncFixtures);
+ fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([googleConnection]);
+ const existing = googleDirectory({ credentialsConfigured: true, enabled: true });
+ fixtures.clerk.organization?.getDirectorySync.mockResolvedValue(existing);
+
+ const { userEvent } = render(, { wrapper });
+
+ await screen.findByRole('button', { name: 'Upload JSON key' });
+ await userEvent.click(screen.getByRole('button', { name: 'Continue' }));
+ expect(await screen.findByText('Attribute review')).toBeInTheDocument();
+ await userEvent.click(screen.getByRole('button', { name: 'Continue' }));
+
+ expect(await screen.findByText('Waiting for the first sync to finish…')).toBeInTheDocument();
+ });
});
diff --git a/packages/ui/src/components/ConfigureDirectorySync/providerMeta.ts b/packages/ui/src/components/ConfigureDirectorySync/providerMeta.ts
index 21317196fc6..3d359aa9d35 100644
--- a/packages/ui/src/components/ConfigureDirectorySync/providerMeta.ts
+++ b/packages/ui/src/components/ConfigureDirectorySync/providerMeta.ts
@@ -3,11 +3,19 @@ import type { DirectorySyncProvider } from '@clerk/shared/types';
import type { LocalizationKey } from '@/customizables';
import { localizationKeys } from '@/customizables';
+/**
+ * How the directory exchanges data with the identity provider.
+ *
+ * `push` providers hold a bearer token and push SCIM to Clerk's endpoint.
+ * `pull` providers hand Clerk a stored credential and Clerk reads from them on
+ * a schedule, so their setup collects a credential rather than handing one out.
+ */
+export type DirectorySyncMode = 'push' | 'pull';
+
export interface DirectorySyncProviderMeta {
name: LocalizationKey;
- /** Whether the IdP can push SCIM to Clerk's endpoint (self-serve supported). */
- supportsScim: boolean;
- /** Where the admin pastes the endpoint + token, as numbered instructions. */
+ mode: DirectorySyncMode;
+ /** Setup instructions for the admin, as numbered steps. */
instructions: LocalizationKey[];
}
@@ -18,25 +26,33 @@ const instructionKeys = (provider: 'okta' | 'entra' | 'custom'): LocalizationKey
localizationKeys(`configureDirectorySync.configureStep.instructions.${provider}.step4`),
];
+const googleInstructionKeys = (): LocalizationKey[] => [
+ localizationKeys('configureDirectorySync.configureStep.instructions.google.step1'),
+ localizationKeys('configureDirectorySync.configureStep.instructions.google.step2'),
+ localizationKeys('configureDirectorySync.configureStep.instructions.google.step3'),
+ localizationKeys('configureDirectorySync.configureStep.instructions.google.step4'),
+ localizationKeys('configureDirectorySync.configureStep.instructions.google.step5'),
+];
+
export const DIRECTORY_SYNC_PROVIDERS: Record = {
okta: {
name: localizationKeys('configureDirectorySync.providers.okta'),
- supportsScim: true,
+ mode: 'push',
instructions: instructionKeys('okta'),
},
entra: {
name: localizationKeys('configureDirectorySync.providers.entra'),
- supportsScim: true,
+ mode: 'push',
instructions: instructionKeys('entra'),
},
google: {
name: localizationKeys('configureDirectorySync.providers.google'),
- supportsScim: false,
- instructions: [],
+ mode: 'pull',
+ instructions: googleInstructionKeys(),
},
custom: {
name: localizationKeys('configureDirectorySync.providers.custom'),
- supportsScim: true,
+ mode: 'push',
instructions: instructionKeys('custom'),
},
};
diff --git a/packages/ui/src/components/ConfigureDirectorySync/steps/ConfigureStep.tsx b/packages/ui/src/components/ConfigureDirectorySync/steps/ConfigureStep.tsx
index d0f52a1442d..60206ca8fde 100644
--- a/packages/ui/src/components/ConfigureDirectorySync/steps/ConfigureStep.tsx
+++ b/packages/ui/src/components/ConfigureDirectorySync/steps/ConfigureStep.tsx
@@ -24,6 +24,7 @@ import { handleError } from '@/utils/errorHandler';
import { Step } from '../../ConfigureSSO/elements/Step';
import { useWizard } from '../../ConfigureSSO/elements/Wizard';
import { useConfigureDirectorySync } from '../ConfigureDirectorySyncContext';
+import { GoogleCredentialsForm, useGoogleCredentialsState } from '../GoogleCredentialsForm';
const FieldLabel = ({ id, localizationKey }: { id: string; localizationKey: LocalizationKey }): JSX.Element => (
{
const { goNext } = useWizard();
- const { connection, provider, providerMeta, directory, createDirectory, revealedToken, rotateToken } =
+ const { connection, providerMeta, directory, createDirectory, revealedToken, rotateToken } =
useConfigureDirectorySync();
const { t } = useLocalizations();
const card = useCardState();
const [isInstructionsOpen, setIsInstructionsOpen] = useState(false);
- const isGoogle = provider === 'google';
- const canProvision = Boolean(connection) && !isGoogle;
+ // Pull providers hand Clerk a credential instead of receiving a token, so the
+ // directory still has to exist first — it is what the credential attaches to.
+ const isPull = providerMeta?.mode === 'pull';
+ const credentials = useGoogleCredentialsState();
+ const canProvision = Boolean(connection);
const domains = connection?.domains ?? [];
const instructions = providerMeta?.instructions ?? [];
@@ -63,6 +67,11 @@ export const ConfigureStep = (): JSX.Element => {
}
};
+ const submitCredentialsAndContinue = async (): Promise => {
+ await credentials.submit();
+ goNext();
+ };
+
// The credentials only exist once the directory does, so create it on entry.
const hasAttemptedCreate = useRef(false);
useEffect(() => {
@@ -184,7 +193,7 @@ export const ConfigureStep = (): JSX.Element => {
as='ol'
sx={t => ({
gap: t.space.$1x5,
- padding: `0 ${t.space.$4} ${t.space.$4}`,
+ padding: t.space.$4,
paddingInlineStart: t.space.$8,
listStyle: 'decimal',
})}
@@ -205,17 +214,7 @@ export const ConfigureStep = (): JSX.Element => {
)}
- {isGoogle && (
-
- )}
-
- {!connection.active && !isGoogle && (
+ {!connection.active && (
{
)}
{directory ? (
- <>
- ({ gap: t.space.$1x5 })}>
-
-
-
-
- ({ gap: t.space.$1x5 })}>
-
- ({ gap: t.space.$2 })}
- >
- {revealedToken ? (
-
- ) : (
-
- )}
-
- ({ gap: t.space.$1x5 })}
- >
-
- ({ fontSize: t.fontSizes.$sm })}
+
+
+ ({ gap: t.space.$1x5 })}>
+
-
-
- >
+ ({ gap: t.space.$2 })}
+ >
+ {revealedToken ? (
+
+ ) : (
+
+ )}
+
+ ({ gap: t.space.$1x5 })}
+ >
+
+ ({ fontSize: t.fontSizes.$sm })}
+ />
+
+
+ >
+ )
) : (
canProvision &&
!card.error && (
@@ -343,8 +346,11 @@ export const ConfigureStep = (): JSX.Element => {
goNext()}
- isDisabled={!directory}
+ onClick={isPull ? () => void run(submitCredentialsAndContinue) : () => goNext()}
+ // For a pull directory this button is the submit, so it waits on the
+ // form being complete rather than just on the directory existing.
+ isDisabled={!directory || (isPull && !credentials.canContinue)}
+ isLoading={isPull && card.isLoading}
/>
>
diff --git a/packages/ui/src/components/ConfigureDirectorySync/steps/TestSyncStep.tsx b/packages/ui/src/components/ConfigureDirectorySync/steps/TestSyncStep.tsx
index 8fce5d83ee5..a032153c5a9 100644
--- a/packages/ui/src/components/ConfigureDirectorySync/steps/TestSyncStep.tsx
+++ b/packages/ui/src/components/ConfigureDirectorySync/steps/TestSyncStep.tsx
@@ -1,5 +1,9 @@
-import { __internal_useOrganizationDirectorySyncUsers } from '@clerk/shared/react';
+import {
+ __internal_useOrganizationDirectorySyncStatus,
+ __internal_useOrganizationDirectorySyncUsers,
+} from '@clerk/shared/react';
import type { DirectorySyncUserResource } from '@clerk/shared/types';
+import { useEffect, useState } from 'react';
import {
Badge,
@@ -18,6 +22,7 @@ import { Step } from '../../ConfigureSSO/elements/Step';
import { useWizard } from '../../ConfigureSSO/elements/Wizard';
import { useConfigureDirectorySync } from '../ConfigureDirectorySyncContext';
import { DIRECTORY_SYNC_PROVIDERS } from '../providerMeta';
+import { SyncNowRow } from '../SyncNowRow';
const ProvisionedUserRow = ({ user }: { user: DirectorySyncUserResource }): JSX.Element => {
const displayName = [user.firstName, user.lastName].filter(Boolean).join(' ');
@@ -85,14 +90,48 @@ const ProvisionedUserRow = ({ user }: { user: DirectorySyncUserResource }): JSX.
export const TestSyncStep = (): JSX.Element => {
const { goPrev } = useWizard();
- const { providerMeta, directory, onExit } = useConfigureDirectorySync();
+ const { providerMeta, directory, onExit, syncDirectory } = useConfigureDirectorySync();
const { t } = useLocalizations();
+ const isPull = providerMeta?.mode === 'pull';
// The list doubles as a live feed while the admin pushes test users from the
// IdP, so poll for as long as this step is mounted.
const users = __internal_useOrganizationDirectorySyncUsers({ directory, poll: true });
+ // A pull directory has nothing to report until a run happens, and a run can
+ // be minutes away, so the status is only worth watching for those.
+ const syncStatus = __internal_useOrganizationDirectorySyncStatus({ directory, poll: isPull, enabled: isPull });
const rows = users.data ?? [];
const providerName = t((providerMeta ?? DIRECTORY_SYNC_PROVIDERS.custom).name);
+ const lastSyncStatus = syncStatus.data?.lastSyncStatus ?? null;
+ const lastSyncedAt = syncStatus.data?.lastSyncedAt ?? null;
+
+ // The two queries poll independently, so a finished run is reported while the
+ // list on screen still predates it. Refresh the list for every run, whoever
+ // started it, and keep waiting until that lands: otherwise the stale empty
+ // list reads as the run's result.
+ const [isRefreshingAfterSync, setIsRefreshingAfterSync] = useState(false);
+ const { revalidate: revalidateUsers } = users;
+ useEffect(() => {
+ if (!isPull || !lastSyncedAt) {
+ return;
+ }
+ setIsRefreshingAfterSync(true);
+ void revalidateUsers().finally(() => setIsRefreshingAfterSync(false));
+ }, [isPull, lastSyncedAt?.getTime(), revalidateUsers]);
+
+ // The run reports how many users it changed, and those users are provisioned
+ // after it finishes. A count above zero with nothing listed yet means they
+ // are still landing; zero is the settled answer that the run changed nobody.
+ // The count is absent on a backend that predates it, and then the refresh
+ // above is all there is to go on.
+ const changedUserCount = syncStatus.data?.lastSyncChangedUserCount ?? null;
+ const hasUsersStillLanding = changedUserCount !== null && changedUserCount > 0;
+
+ // A push directory is always waiting: the IdP provisions whenever it likes.
+ // A pull directory that has finished a run is not — an empty list is that
+ // run's result, and spinning implies work that will never happen.
+ const isWaitingForUsers =
+ !isPull || lastSyncStatus === null || lastSyncStatus === 'running' || hasUsersStillLanding || isRefreshingAfterSync;
return (
<>
@@ -106,9 +145,21 @@ export const TestSyncStep = (): JSX.Element => {
+ {isPull && (
+ void syncStatus.revalidate()}
+ />
+ )}
+
{
borderColor: t.colors.$borderAlpha150,
})}
>
-
+ {isWaitingForUsers && (
+
+ )}
) : (
diff --git a/packages/ui/src/components/OrganizationProfile/InviteMembersForm.tsx b/packages/ui/src/components/OrganizationProfile/InviteMembersForm.tsx
index 42b5923b70d..ad0a95589fd 100644
--- a/packages/ui/src/components/OrganizationProfile/InviteMembersForm.tsx
+++ b/packages/ui/src/components/OrganizationProfile/InviteMembersForm.tsx
@@ -13,6 +13,7 @@ import {
getSeatUnitPrice,
organizationAndInvitationsExceedsPurchasedSeats,
} from '@/ui/utils/billingPlanSeats';
+import { isEmail } from '@/ui/utils/emailUtils';
import { handleError } from '@/ui/utils/errorHandler';
import { getClosestProfileScrollBoxFromElement } from '@/ui/utils/getClosestProfileScrollBox';
import { createListFormat } from '@/ui/utils/passwordUtils';
@@ -26,8 +27,6 @@ import { localizationKeys, useLocalizations } from '../../localization';
import { mqu } from '../../styledSystem';
import { RoleSelect } from './MemberListTable';
-const isEmail = (str: string) => /^\S+@\S+\.\S+$/.test(str);
-
type InviteMembersFormProps = {
onSuccess?: () => void;
onReset?: () => void;
diff --git a/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx b/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx
index 263ef75fdd9..f0f815460e9 100644
--- a/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx
+++ b/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx
@@ -524,7 +524,7 @@ describe('OrganizationSecurityPage', () => {
expect(fixtures.clerk.organization?.getDirectorySync).not.toHaveBeenCalled();
});
- it('replaces setup with an unsupported notice when the SSO connection is Google Workspace', async () => {
+ it('offers setup for a Google Workspace connection like any other provider', async () => {
const { wrapper, fixtures } = await createFixtures(withDirectorySyncFixtures);
withActiveConnection(fixtures);
fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([
@@ -536,11 +536,12 @@ describe('OrganizationSecurityPage', () => {
renderPage(wrapper);
+ // Google used to be sent to the Clerk Dashboard here, which is the Clerk
+ // customer's account rather than the admin's, so setup dead-ended.
+ expect(await screen.findByRole('button', { name: 'Start configuration' })).toBeEnabled();
expect(
- await screen.findByText('Google Workspace connections are not configurable via self-serve'),
- ).toBeInTheDocument();
- expect(screen.queryByRole('button', { name: 'Start configuration' })).not.toBeInTheDocument();
- expect(screen.queryByText('SSO Required')).not.toBeInTheDocument();
+ screen.queryByText('Google Workspace connections are not configurable via self-serve'),
+ ).not.toBeInTheDocument();
});
it('lists Edit and Deactivate for an active directory', async () => {
diff --git a/packages/ui/src/components/SignIn/utils.ts b/packages/ui/src/components/SignIn/utils.ts
index 0f8873d0094..697bd08adea 100644
--- a/packages/ui/src/components/SignIn/utils.ts
+++ b/packages/ui/src/components/SignIn/utils.ts
@@ -8,6 +8,7 @@ import type {
import { titleize } from '@clerk/shared/underscore';
import { isWebAuthnSupported } from '@clerk/shared/webauthn';
+import { isEmail } from '@/ui/utils/emailUtils';
import { getPreferredPhoneCodeChannelByCountry } from '@/ui/utils/phoneUtils';
import type { FormControlState } from '@/ui/utils/useFormControl';
@@ -118,7 +119,6 @@ const resetPasswordStrategies: SignInStrategy[] = ['reset_password_phone_code',
export const isResetPasswordStrategy = (strategy: SignInStrategy | string | null | undefined) =>
!!strategy && resetPasswordStrategies.includes(strategy as SignInStrategy);
-const isEmail = (str: string) => /^\S+@\S+\.\S+$/.test(str);
export function getSignUpAttributeFromIdentifier(identifier: FormControlState<'identifier'>) {
if (identifier.type === 'tel') {
return 'phoneNumber';
diff --git a/packages/ui/src/customizables/elementDescriptors.ts b/packages/ui/src/customizables/elementDescriptors.ts
index 50199a04a29..bfad65bb647 100644
--- a/packages/ui/src/customizables/elementDescriptors.ts
+++ b/packages/ui/src/customizables/elementDescriptors.ts
@@ -692,6 +692,15 @@ export const APPEARANCE_KEYS = containsAllElementsConfigKeys([
'configureDirectorySyncUserStatusBadge',
'configureDirectorySyncUsersEmpty',
'configureDirectorySyncCompleteButton',
+ 'configureDirectorySyncCredentialsForm',
+ 'configureDirectorySyncCredentialsBadge',
+ 'configureDirectorySyncUploadKeyButton',
+ 'configureDirectorySyncUploadedFileName',
+ 'configureDirectorySyncSubjectEmailInput',
+ 'configureDirectorySyncSyncRow',
+ 'configureDirectorySyncSyncNowButton',
+ 'configureDirectorySyncStatusBadge',
+ 'configureDirectorySyncLastSyncedAt',
'web3SolanaWalletButtonsRoot',
'web3SolanaWalletButtons',
diff --git a/packages/ui/src/internal/appearance.ts b/packages/ui/src/internal/appearance.ts
index 99c1f1f7537..5d1a89785ff 100644
--- a/packages/ui/src/internal/appearance.ts
+++ b/packages/ui/src/internal/appearance.ts
@@ -828,6 +828,15 @@ export type ElementsConfig = {
configureDirectorySyncUserStatusBadge: WithOptions;
configureDirectorySyncUsersEmpty: WithOptions;
configureDirectorySyncCompleteButton: WithOptions;
+ configureDirectorySyncCredentialsForm: WithOptions;
+ configureDirectorySyncCredentialsBadge: WithOptions;
+ configureDirectorySyncUploadKeyButton: WithOptions;
+ configureDirectorySyncUploadedFileName: WithOptions;
+ configureDirectorySyncSubjectEmailInput: WithOptions;
+ configureDirectorySyncSyncRow: WithOptions;
+ configureDirectorySyncSyncNowButton: WithOptions;
+ configureDirectorySyncStatusBadge: WithOptions;
+ configureDirectorySyncLastSyncedAt: WithOptions;
web3SolanaWalletButtonsRoot: WithOptions;
web3SolanaWalletButtons: WithOptions;
diff --git a/packages/ui/src/utils/emailUtils.ts b/packages/ui/src/utils/emailUtils.ts
new file mode 100644
index 00000000000..db36b5703f0
--- /dev/null
+++ b/packages/ui/src/utils/emailUtils.ts
@@ -0,0 +1,5 @@
+/**
+ * A loose shape check, enough to catch an obviously malformed address. Not a
+ * full validator: the server has the final say.
+ */
+export const isEmail = (str: string): boolean => /^\S+@\S+\.\S+$/.test(str);