diff --git a/.changeset/fifty-eels-work.md b/.changeset/fifty-eels-work.md
new file mode 100644
index 0000000000..813aa78bab
--- /dev/null
+++ b/.changeset/fifty-eels-work.md
@@ -0,0 +1,6 @@
+---
+'@clerk/clerk-js': minor
+'@clerk/types': minor
+---
+
+If user does not have permission to create an org, create org button will not display in the OrganizationSwitcher UI
diff --git a/packages/clerk-js/src/core/resources/User.ts b/packages/clerk-js/src/core/resources/User.ts
index b0d7754dbd..f0cb69f87a 100644
--- a/packages/clerk-js/src/core/resources/User.ts
+++ b/packages/clerk-js/src/core/resources/User.ts
@@ -80,6 +80,7 @@ export class User extends BaseResource implements UserResource {
publicMetadata: UserPublicMetadata = {};
unsafeMetadata: UserUnsafeMetadata = {};
lastSignInAt: Date | null = null;
+ createOrganizationEnabled = false;
deleteSelfEnabled = false;
updatedAt: Date | null = null;
createdAt: Date | null = null;
@@ -320,6 +321,7 @@ export class User extends BaseResource implements UserResource {
this.backupCodeEnabled = data.backup_code_enabled;
this.twoFactorEnabled = data.two_factor_enabled;
+ this.createOrganizationEnabled = data.create_organization_enabled;
this.deleteSelfEnabled = data.delete_self_enabled;
if (data.last_sign_in_at) {
diff --git a/packages/clerk-js/src/core/resources/UserSettings.ts b/packages/clerk-js/src/core/resources/UserSettings.ts
index 49d9e86d3b..82ec8eb6bc 100644
--- a/packages/clerk-js/src/core/resources/UserSettings.ts
+++ b/packages/clerk-js/src/core/resources/UserSettings.ts
@@ -1,6 +1,5 @@
import type {
Attributes,
- Actions,
OAuthProviders,
OAuthStrategy,
PasswordSettingsData,
@@ -17,6 +16,11 @@ import { BaseResource } from './internal';
const defaultMaxPasswordLength = 72;
const defaultMinPasswordLength = 8;
+export type Actions = {
+ create_organization: boolean;
+ delete_self: boolean;
+};
+
/**
* @internal
*/
diff --git a/packages/clerk-js/src/ui/components/OrganizationSwitcher/OtherOrganizationActions.tsx b/packages/clerk-js/src/ui/components/OrganizationSwitcher/OtherOrganizationActions.tsx
index 28a6a16f85..a37a18f664 100644
--- a/packages/clerk-js/src/ui/components/OrganizationSwitcher/OtherOrganizationActions.tsx
+++ b/packages/clerk-js/src/ui/components/OrganizationSwitcher/OtherOrganizationActions.tsx
@@ -84,7 +84,7 @@ export const OrganizationActionList = (props: OrganizationActionListProps) => {
))}
- {createOrganizationButton}
+ {user.createOrganizationEnabled && createOrganizationButton}
);
};
diff --git a/packages/clerk-js/src/ui/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx b/packages/clerk-js/src/ui/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx
index 915375fad2..7deeaf8934 100644
--- a/packages/clerk-js/src/ui/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx
+++ b/packages/clerk-js/src/ui/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx
@@ -46,7 +46,7 @@ describe('OrganizationSwitcher', () => {
it('opens the organization switcher popover when clicked', async () => {
const { wrapper, props } = await createFixtures(f => {
f.withOrganizations();
- f.withUser({ email_addresses: ['test@clerk.dev'] });
+ f.withUser({ email_addresses: ['test@clerk.dev'], create_organization_enabled: true });
});
props.setProps({ hidePersonal: true });
const { getByText, getByRole, userEvent } = render(, { wrapper });
@@ -107,6 +107,7 @@ describe('OrganizationSwitcher', () => {
f.withUser({
email_addresses: ['test@clerk.dev'],
organization_memberships: [{ name: 'Org1', role: 'basic_member' }],
+ create_organization_enabled: true,
});
});
props.setProps({ hidePersonal: true });
@@ -116,6 +117,20 @@ describe('OrganizationSwitcher', () => {
expect(fixtures.clerk.openCreateOrganization).toHaveBeenCalled();
});
+ it('does not display create organization button if permissions not present', async () => {
+ const { wrapper, props } = await createFixtures(f => {
+ f.withOrganizations();
+ f.withUser({
+ email_addresses: ['test@clerk.dev'],
+ organization_memberships: [{ name: 'Org1', role: 'basic_member' }],
+ create_organization_enabled: false,
+ });
+ });
+ props.setProps({ hidePersonal: true });
+ const { queryByRole } = render(, { wrapper });
+ expect(queryByRole('button', { name: 'Create Organization' })).not.toBeInTheDocument();
+ });
+
it.todo('switches between active organizations when one is clicked');
});
});
diff --git a/packages/types/src/json.ts b/packages/types/src/json.ts
index 7fa01eee3a..2373283a35 100644
--- a/packages/types/src/json.ts
+++ b/packages/types/src/json.ts
@@ -214,6 +214,7 @@ export interface UserJSON extends ClerkResourceJSON {
public_metadata: UserPublicMetadata;
unsafe_metadata: UserUnsafeMetadata;
last_sign_in_at: number | null;
+ create_organization_enabled: boolean;
delete_self_enabled: boolean;
updated_at: number;
created_at: number;
diff --git a/packages/types/src/user.ts b/packages/types/src/user.ts
index 24cefdf0d4..751abc84b4 100644
--- a/packages/types/src/user.ts
+++ b/packages/types/src/user.ts
@@ -77,6 +77,7 @@ export interface UserResource extends ClerkResource {
publicMetadata: UserPublicMetadata;
unsafeMetadata: UserUnsafeMetadata;
lastSignInAt: Date | null;
+ createOrganizationEnabled: boolean;
deleteSelfEnabled: boolean;
updatedAt: Date | null;
createdAt: Date | null;
diff --git a/packages/types/src/userSettings.ts b/packages/types/src/userSettings.ts
index 6ecff6a0fc..053992a097 100644
--- a/packages/types/src/userSettings.ts
+++ b/packages/types/src/userSettings.ts
@@ -91,6 +91,7 @@ export interface UserSettingsJSON extends ClerkResourceJSON {
id: never;
object: never;
attributes: AttributesJSON;
+ actions: Actions;
social: OAuthProviders;
/**
@@ -101,7 +102,6 @@ export interface UserSettingsJSON extends ClerkResourceJSON {
sign_in: SignInData;
sign_up: SignUpData;
password_settings: PasswordSettingsData;
- actions: Actions;
}
export interface UserSettingsResource extends ClerkResource {