Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changeset/dir-sync-self-serve-wiring.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
'@clerk/clerk-js': minor
'@clerk/localizations': minor
'@clerk/react': minor
'@clerk/shared': minor
'@clerk/ui': minor
---
Expand Down
6 changes: 3 additions & 3 deletions packages/clerk-js/bundlewatch.config.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"files": [
{ "path": "./dist/clerk.js", "maxSize": "553KB" },
{ "path": "./dist/clerk.browser.js", "maxSize": "79.5KB" },
{ "path": "./dist/clerk.js", "maxSize": "554KB" },
{ "path": "./dist/clerk.browser.js", "maxSize": "81KB" },
{ "path": "./dist/clerk.legacy.browser.js", "maxSize": "122.5KB" },
{ "path": "./dist/clerk.no-rhc.js", "maxSize": "320KB" },
{ "path": "./dist/clerk.native.js", "maxSize": "79KB" },
{ "path": "./dist/clerk.native.js", "maxSize": "80KB" },
{ "path": "./dist/vendors*.js", "maxSize": "7KB" },
{ "path": "./dist/coinbase*.js", "maxSize": "36KB" },
{ "path": "./dist/base-account-sdk*.js", "maxSize": "207KB" },
Expand Down
6 changes: 6 additions & 0 deletions packages/clerk-js/sandbox/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const AVAILABLE_COMPONENTS = [
'pricingTable',
'apiKeys',
'configureSSO',
'configureDirectorySync',
'oauthConsent',
'oauthDeviceVerification',
'taskChooseOrganization',
Expand Down Expand Up @@ -154,6 +155,7 @@ const componentControls: Record<AvailableComponent, ComponentPropsControl> = {
pricingTable: buildComponentControls('pricingTable'),
apiKeys: buildComponentControls('apiKeys'),
configureSSO: buildComponentControls('configureSSO'),
configureDirectorySync: buildComponentControls('configureDirectorySync'),
oauthConsent: buildComponentControls('oauthConsent'),
oauthDeviceVerification: buildComponentControls('oauthDeviceVerification'),
taskChooseOrganization: buildComponentControls('taskChooseOrganization'),
Expand Down Expand Up @@ -431,6 +433,10 @@ void (async () => {
mount: '__internal_mountOAuthDeviceVerification',
component: 'oauthDeviceVerification',
},
'/configure-directory-sync': {
mount: '__internal_mountConfigureDirectorySync',
component: 'configureDirectorySync',
},
'/task-choose-organization': {
mount: 'mountTaskChooseOrganization',
component: 'taskChooseOrganization',
Expand Down
5 changes: 5 additions & 0 deletions packages/clerk-js/sandbox/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,11 @@
label="Configure SSO"
component="<ConfigureSSO />"
></nav-link>
<nav-link
href="/configure-directory-sync"
label="Configure Directory Sync"
component="<ConfigureDirectorySync />"
></nav-link>
<nav-link
href="/open-invite-members"
label="Open invite members"
Expand Down
72 changes: 72 additions & 0 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
disabledEmailAddressAttribute,
disabledOrganizationAPIKeysFeature,
disabledOrganizationsFeature,
disabledSelfServeDirectorySyncFeature,
disabledSelfServeSSOFeature,
disabledUserAPIKeysFeature,
isSignedInAndSingleSessionModeEnabled,
Expand Down Expand Up @@ -1718,6 +1719,77 @@ export class Clerk implements ClerkInterface {
void this.#clerkUI?.then(ui => ui.ensureMounted()).then(controls => controls.unmountComponent({ node }));
};

/**
* Mount the Directory Sync onboarding component at the target element.
* Directory Sync provisions members through the organization's SSO connection,
* so it requires organizations to be enabled and the self-serve Directory Sync
* feature to be turned on for the instance.
*
* @param targetNode Target to mount the ConfigureDirectorySync component.
* @param props Configuration parameters.
* @hidden
*/
public __internal_mountConfigureDirectorySync = (node: HTMLDivElement, props?: ConfigureSSOProps) => {
const { isEnabled: isOrganizationsEnabled } = this.__internal_attemptToEnableEnvironmentSetting({
for: 'organizations',
caller: 'ConfigureDirectorySync',
onClose: () => {
throw new ClerkRuntimeError(warnings.cannotRenderAnyOrganizationComponent('ConfigureDirectorySync'), {
code: CANNOT_RENDER_ORGANIZATIONS_DISABLED_ERROR_CODE,
});
},
});

if (!isOrganizationsEnabled) {
return;
}

const userExists = !noUserExists(this);
if (noOrganizationExists(this) && userExists) {
if (this.#instanceType === 'development') {
throw new ClerkRuntimeError(warnings.createCannotRenderComponentWhenOrgDoesNotExist('ConfigureDirectorySync'), {
code: CANNOT_RENDER_ORGANIZATION_MISSING_ERROR_CODE,
});
}
return;
}

if (disabledSelfServeDirectorySyncFeature(this, this.environment)) {
if (this.#instanceType === 'development') {
throw new ClerkRuntimeError(warnings.cannotRenderConfigureDirectorySyncComponentWhenDisabled, {
code: CANNOT_RENDER_SELF_SERVE_SSO_DISABLED_ERROR_CODE,
});
}
return;
}

this.assertComponentsReady(this.#clerkUI);
const component = 'ConfigureDirectorySync';
void this.#clerkUI
.then(ui => ui.ensureMounted({ preloadHint: component }))
.then(controls =>
controls.mountComponent({
name: component,
appearanceKey: 'configureDirectorySync',
node,
props,
}),
);

this.telemetry?.record(eventPrebuiltComponentMounted(component, props));
};

/**
* Unmount the Directory Sync onboarding component from the target element.
* If there is no component mounted at the target node, results in a noop.
*
* @param targetNode Target node to unmount the ConfigureDirectorySync component from.
* @hidden
*/
public __internal_unmountConfigureDirectorySync = (node: HTMLDivElement) => {
void this.#clerkUI?.then(ui => ui.ensureMounted()).then(controls => controls.unmountComponent({ node }));
};

public mountTaskChooseOrganization = (node: HTMLDivElement, props?: TaskChooseOrganizationProps) => {
const { isEnabled: isOrganizationsEnabled } = this.__internal_attemptToEnableEnvironmentSetting({
for: 'organizations',
Expand Down
96 changes: 96 additions & 0 deletions packages/localizations/src/ar-SA.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,83 @@ export const arSA: LocalizationResource = {
yearPerUnit: undefined,
years: undefined,
},
configureDirectorySync: {
attributeMappingStep: {
columns: {
clerkAttribute: undefined,
directoryAttribute: undefined,
},
subtitle: undefined,
title: undefined,
},
configureStep: {
actionLabel__generateToken: undefined,
actionLabel__retry: undefined,
domainsLabel: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
custom: {
step1: undefined,
step2: undefined,
step3: undefined,
step4: undefined,
},
entra: {
step1: undefined,
step2: undefined,
step3: undefined,
step4: undefined,
},
okta: {
step1: undefined,
step2: undefined,
step3: undefined,
step4: undefined,
},
},
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
warning__googleUnsupported: {
subtitle: undefined,
title: undefined,
},
warning__ssoInactive: undefined,
},
navbar: {
title: undefined,
},
providers: {
custom: undefined,
entra: undefined,
google: undefined,
okta: undefined,
},
stepper: {
attributes: undefined,
configure: undefined,
test: undefined,
},
testStep: {
actionLabel__complete: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
empty__waitingForFirstUser: undefined,
error__loadUsers: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
title: undefined,
},
},
configureSSO: {
activate: {
activateButton: undefined,
Expand Down Expand Up @@ -1202,6 +1279,25 @@ export const arSA: LocalizationResource = {
title: 'حذف النطاق',
},
securityPage: {
directorySyncSection: {
badge__active: undefined,
badge__inactive: undefined,
badge__ssoRequired: undefined,
badge__unconfigured: undefined,
description: undefined,
error__load: undefined,
menuAction__activate: undefined,
menuAction__deactivate: undefined,
menuAction__edit: undefined,
menuAction__remove: undefined,
primaryButton__startConfiguration: undefined,
removeDialog: {
confirmButton: undefined,
subtitle: undefined,
title: undefined,
},
title: undefined,
},
removeDialog: {
confirmButton: undefined,
subtitle: undefined,
Expand Down
96 changes: 96 additions & 0 deletions packages/localizations/src/be-BY.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,83 @@ export const beBY: LocalizationResource = {
yearPerUnit: undefined,
years: undefined,
},
configureDirectorySync: {
attributeMappingStep: {
columns: {
clerkAttribute: undefined,
directoryAttribute: undefined,
},
subtitle: undefined,
title: undefined,
},
configureStep: {
actionLabel__generateToken: undefined,
actionLabel__retry: undefined,
domainsLabel: undefined,
error__ssoRequired: {
subtitle: undefined,
title: undefined,
},
formFieldInputPlaceholder__token: undefined,
formFieldLabel__endpointUrl: undefined,
formFieldLabel__token: undefined,
instructions: {
actionLabel__toggle: undefined,
custom: {
step1: undefined,
step2: undefined,
step3: undefined,
step4: undefined,
},
entra: {
step1: undefined,
step2: undefined,
step3: undefined,
step4: undefined,
},
okta: {
step1: undefined,
step2: undefined,
step3: undefined,
step4: undefined,
},
},
notice__tokenShownOnce: undefined,
subtitle: undefined,
title: undefined,
warning__googleUnsupported: {
subtitle: undefined,
title: undefined,
},
warning__ssoInactive: undefined,
},
navbar: {
title: undefined,
},
providers: {
custom: undefined,
entra: undefined,
google: undefined,
okta: undefined,
},
stepper: {
attributes: undefined,
configure: undefined,
test: undefined,
},
testStep: {
actionLabel__complete: undefined,
badge__active: undefined,
badge__deprovisioned: undefined,
description: undefined,
empty__waitingForFirstUser: undefined,
error__loadUsers: undefined,
note: undefined,
noteLabel: undefined,
subtitle: undefined,
title: undefined,
},
},
configureSSO: {
activate: {
activateButton: undefined,
Expand Down Expand Up @@ -1205,6 +1282,25 @@ export const beBY: LocalizationResource = {
title: 'Выдаліць дамен',
},
securityPage: {
directorySyncSection: {
badge__active: undefined,
badge__inactive: undefined,
badge__ssoRequired: undefined,
badge__unconfigured: undefined,
description: undefined,
error__load: undefined,
menuAction__activate: undefined,
menuAction__deactivate: undefined,
menuAction__edit: undefined,
menuAction__remove: undefined,
primaryButton__startConfiguration: undefined,
removeDialog: {
confirmButton: undefined,
subtitle: undefined,
title: undefined,
},
title: undefined,
},
removeDialog: {
confirmButton: undefined,
subtitle: undefined,
Expand Down
Loading
Loading