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
5 changes: 5 additions & 0 deletions .changeset/api-keys-org-context-user-disabled.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/clerk-js': patch
---

Fix the standalone `<APIKeys />` component failing to render when an organization is active and user API keys are disabled but organization API keys are enabled. The component now correctly checks the user API keys setting only when no organization is active.
38 changes: 38 additions & 0 deletions integration/tests/api-keys-component.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,44 @@ test.describe('api keys component @machine', () => {
await u.page.unrouteAll();
});

test('standalone API keys component renders in org context when user API keys are disabled', async ({
page,
context,
}) => {
const u = createTestUtils({ app, page, context });

await u.po.signIn.goTo();
await u.po.signIn.waitForMounted();
await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password });
await u.po.expect.toBeSignedIn();

await u.po.organizationSwitcher.goTo();
await u.po.organizationSwitcher.waitForMounted();
await u.po.organizationSwitcher.waitForAnOrganizationToSelected();

await mockAPIKeysEnvironmentSettings(u.page, { user_api_keys_enabled: false });

let capturedSubject: string | null = null;
const apiKeyRequestPromise = u.page.waitForRequest(request => {
if (request.url().includes('api_keys')) {
const url = new URL(request.url());
capturedSubject = url.searchParams.get('subject');
return true;
}
return false;
});

await u.po.page.goToRelative('/api-keys');
await u.po.apiKeys.waitForMounted();
await expect(u.page.locator('.cl-apiKeys-root')).toBeVisible();

// Org API keys are listed, so the subject must be the organization
await apiKeyRequestPromise;
expect(capturedSubject).toBe(fakeOrganization.organization.id);

await u.page.unrouteAll();
});

Comment on lines +391 to +428

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add focused unit coverage for both guard branches.

This Playwright test covers the happy path, but the changed logic in packages/clerk-js/src/core/clerk.ts also needs unit coverage for organization-active versus no-organization contexts, including the disabled-feature error/no-op behavior. Retain this integration test for the request-subject contract.

As per coding guidelines, unit tests are required for all new functionality and must cover error handling and edge cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@integration/tests/api-keys-component.test.ts` around lines 391 - 428, Add
focused unit tests for the changed logic in Clerk’s organization API-key
handling, covering both organization-active and no-organization contexts. Verify
the disabled-feature behavior for each branch, including the expected error or
no-op outcome, while retaining this Playwright test for validating the request
subject contract.

Source: Coding guidelines

test.describe('api key list invalidation', () => {
// Helper function to count actual API key rows (not empty state)
const createAPIKeyCountHelper = (u: any) => async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1454,7 +1454,7 @@ export class Clerk implements ClerkInterface {
return;
}

if (disabledUserAPIKeysFeature(this, this.environment)) {
if (!this.organization && disabledUserAPIKeysFeature(this, this.environment)) {
if (this.#instanceType === 'development') {
throw new ClerkRuntimeError(warnings.cannotRenderAPIKeysComponentForUserWhenDisabled, {
code: CANNOT_RENDER_API_KEYS_USER_DISABLED_ERROR_CODE,
Expand Down
Loading