From c1766716d4fb21fc711ba1df5b4b93186514b8e7 Mon Sep 17 00:00:00 2001
From: panteliselef
Date: Fri, 17 Jan 2025 17:21:47 +0200
Subject: [PATCH 01/14] feat(nextjs): Run on keyless until after you dismiss
---
packages/clerk-js/src/core/clerk.ts | 1 +
packages/clerk-js/src/ui/Components.tsx | 1 +
packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx | 4 ++++
packages/nextjs/src/app-router/server/ClerkProvider.tsx | 5 ++++-
packages/nextjs/src/server/keyless-node.ts | 2 +-
packages/types/src/clerk.ts | 5 +++++
6 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts
index 755e6e83f8d..34cf8c71d1f 100644
--- a/packages/clerk-js/src/core/clerk.ts
+++ b/packages/clerk-js/src/core/clerk.ts
@@ -2104,6 +2104,7 @@ export class Clerk implements ClerkInterface {
options: {
__internal_claimKeylessApplicationUrl: this.#options.__internal_claimKeylessApplicationUrl,
__internal_copyInstanceKeysUrl: this.#options.__internal_copyInstanceKeysUrl,
+ __internal_keylessWithClaimedKeys: this.#options.__internal_keylessWithClaimedKeys,
},
});
});
diff --git a/packages/clerk-js/src/ui/Components.tsx b/packages/clerk-js/src/ui/Components.tsx
index 0e35b0a7236..95a4f023504 100644
--- a/packages/clerk-js/src/ui/Components.tsx
+++ b/packages/clerk-js/src/ui/Components.tsx
@@ -522,6 +522,7 @@ const Components = (props: ComponentsProps) => {
)}
diff --git a/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx b/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx
index bf2c3a3f2b7..f109de8419c 100644
--- a/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx
+++ b/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx
@@ -14,6 +14,7 @@ import { useRevalidateEnvironment } from './use-revalidate-environment';
type KeylessPromptProps = {
claimUrl: string;
copyKeysUrl: string;
+ success: boolean;
};
const buttonIdentifierPrefix = `--clerk-keyless-prompt`;
@@ -29,6 +30,9 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => {
const isForcedExpanded = claimed || success || isExpanded;
+ // Use this
+ // const showSuccessState = _props.success && claimed;
+
const baseElementStyles = css`
box-sizing: border-box;
padding: 0;
diff --git a/packages/nextjs/src/app-router/server/ClerkProvider.tsx b/packages/nextjs/src/app-router/server/ClerkProvider.tsx
index 6f7b8f8c97d..5b0f3ad2ebc 100644
--- a/packages/nextjs/src/app-router/server/ClerkProvider.tsx
+++ b/packages/nextjs/src/app-router/server/ClerkProvider.tsx
@@ -4,6 +4,7 @@ import React from 'react';
import { PromisifiedAuthProvider } from '../../client-boundary/PromisifiedAuthProvider';
import { getDynamicAuthData } from '../../server/buildClerkProps';
+import { safeParseClerkFile } from '../../server/keyless-node';
import type { NextClerkProviderProps } from '../../types';
import { canUseKeyless } from '../../utils/feature-flags';
import { mergeNextClerkPropsWithEnv } from '../../utils/mergeNextClerkPropsWithEnv';
@@ -69,7 +70,8 @@ export async function ClerkProvider(
);
- const shouldRunAsKeyless = !propsWithEnvs.publishableKey && canUseKeyless;
+ const runningWithClaimedKeys = propsWithEnvs.publishableKey === safeParseClerkFile()?.publishableKey;
+ const shouldRunAsKeyless = (!propsWithEnvs.publishableKey || runningWithClaimedKeys) && canUseKeyless;
if (shouldRunAsKeyless) {
// NOTE: Create or read keys on every render. Usually this means only on hard refresh or hard navigations.
@@ -85,6 +87,7 @@ export async function ClerkProvider(
publishableKey: newOrReadKeys.publishableKey,
__internal_claimKeylessApplicationUrl: newOrReadKeys.claimUrl,
__internal_copyInstanceKeysUrl: newOrReadKeys.apiKeysUrl,
+ __internal_keylessWithClaimedKeys: runningWithClaimedKeys,
})}
nonce={await generateNonce()}
initialState={await generateStatePromise()}
diff --git a/packages/nextjs/src/server/keyless-node.ts b/packages/nextjs/src/server/keyless-node.ts
index 28226dba7a6..30a19415809 100644
--- a/packages/nextjs/src/server/keyless-node.ts
+++ b/packages/nextjs/src/server/keyless-node.ts
@@ -64,7 +64,7 @@ const getKeylessReadMePath = () => generatePath(_TEMP_DIR_NAME, 'README.md');
let isCreatingFile = false;
-function safeParseClerkFile(): AccountlessApplication | undefined {
+export function safeParseClerkFile(): AccountlessApplication | undefined {
if (!nodeRuntime.fs) {
throwMissingFsModule();
}
diff --git a/packages/types/src/clerk.ts b/packages/types/src/clerk.ts
index 41bf0282eed..63901514768 100644
--- a/packages/types/src/clerk.ts
+++ b/packages/types/src/clerk.ts
@@ -777,6 +777,11 @@ export type ClerkOptions = ClerkOptionsNavigation &
*/
__internal_copyInstanceKeysUrl?: string;
+ /**
+ * When `true` a success state should be shown on Keyless prompt. It means that the developer has successfully using the claimed keys.
+ */
+ __internal_keylessWithClaimedKeys?: boolean;
+
/**
* [EXPERIMENTAL] Provide the underlying host router, required for the new experimental UI components.
*/
From 0a51adb4ec1c71ea22a924f8ccc7e8645a0a0806 Mon Sep 17 00:00:00 2001
From: panteliselef
Date: Fri, 17 Jan 2025 17:57:06 +0200
Subject: [PATCH 02/14] feat(nextjs): Run on keyless until after you dismiss 2
---
.../src/app-router/server/ClerkProvider.tsx | 36 ++++++++++---------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/packages/nextjs/src/app-router/server/ClerkProvider.tsx b/packages/nextjs/src/app-router/server/ClerkProvider.tsx
index 5b0f3ad2ebc..fd0a1585950 100644
--- a/packages/nextjs/src/app-router/server/ClerkProvider.tsx
+++ b/packages/nextjs/src/app-router/server/ClerkProvider.tsx
@@ -79,23 +79,27 @@ export async function ClerkProvider(
if (newOrReadKeys) {
const KeylessCookieSync = await import('../client/keyless-cookie-sync.js').then(mod => mod.KeylessCookieSync);
- output = (
-
-
- {children}
-
-
+ const clientProvider = (
+
+ {children}
+
);
+
+ if (runningWithClaimedKeys) {
+ output = clientProvider;
+ } else {
+ output = {clientProvider};
+ }
}
}
From ae68384fe20c15b5505ded7d2738d36c8c6a8958 Mon Sep 17 00:00:00 2001
From: panteliselef
Date: Fri, 17 Jan 2025 18:00:41 +0200
Subject: [PATCH 03/14] Delete `.clerk/` on dismiss
---
packages/clerk-js/src/ui/Components.tsx | 1 +
.../src/ui/components/KeylessPrompt/index.tsx | 15 ++++++-
.../nextjs/src/app-router/keyless-actions.ts | 9 +++++
.../src/app-router/server/ClerkProvider.tsx | 2 +
packages/nextjs/src/server/keyless-node.ts | 39 ++++++++++++++++++-
packages/types/src/clerk.ts | 5 +++
6 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/packages/clerk-js/src/ui/Components.tsx b/packages/clerk-js/src/ui/Components.tsx
index 95a4f023504..bab6baec864 100644
--- a/packages/clerk-js/src/ui/Components.tsx
+++ b/packages/clerk-js/src/ui/Components.tsx
@@ -523,6 +523,7 @@ const Components = (props: ComponentsProps) => {
claimUrl={state.options.__internal_claimKeylessApplicationUrl}
copyKeysUrl={state.options.__internal_copyInstanceKeysUrl}
success={state.options.__internal_keylessWithClaimedKeys || false}
+ onDismiss={state.options.__internal_keylessFinalize}
/>
)}
diff --git a/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx b/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx
index f109de8419c..747a07c3ac9 100644
--- a/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx
+++ b/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx
@@ -15,6 +15,7 @@ type KeylessPromptProps = {
claimUrl: string;
copyKeysUrl: string;
success: boolean;
+ onDismiss?: () => Promise;
};
const buttonIdentifierPrefix = `--clerk-keyless-prompt`;
@@ -25,7 +26,7 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => {
const [isExpanded, setIsExpanded] = useState(false);
const claimed = Boolean(useRevalidateEnvironment().authConfig.claimedAt);
- const success = false;
+ const success = _props.success && claimed;
const appName = useRevalidateEnvironment().displayConfig.applicationName;
const isForcedExpanded = claimed || success || isExpanded;
@@ -450,12 +451,24 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => {
+ {_props.onDismiss && (
+
+ )}
+
{isForcedExpanded &&
(success ? (