Skip to content

Commit

Permalink
fix(nextjs): Warn about missing encryption key while preserving keyle…
Browse files Browse the repository at this point in the history
…ss mode support
  • Loading branch information
panteliselef committed Dec 12, 2024
1 parent a6ee05b commit 3549874
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 7 deletions.
5 changes: 4 additions & 1 deletion packages/nextjs/src/server/clerkMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,10 @@ export const clerkMiddleware: ClerkMiddleware = (...args: unknown[]) => {
setRequestHeadersOnNextResponse(handlerResult, clerkRequest, { [constants.Headers.EnableDebug]: 'true' });
}

decorateRequest(clerkRequest, handlerResult, requestState, { ...resolvedParams, ...options });
decorateRequest(clerkRequest, handlerResult, requestState, resolvedParams, {
publishableKey: keyless?.publishableKey,
secretKey: keyless?.secretKey,
});

return handlerResult;
});
Expand Down
18 changes: 12 additions & 6 deletions packages/nextjs/src/server/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export function decorateRequest(
res: Response,
requestState: RequestState,
requestData: AuthenticateRequestOptions,
keylessMode: Pick<AuthenticateRequestOptions, 'publishableKey' | 'secretKey'>,
): Response {
const { reason, message, status, token } = requestState;
// pass-through case, convert to next()
Expand Down Expand Up @@ -132,12 +133,14 @@ export function decorateRequest(
}

if (rewriteURL) {
const clerkRequestData = encryptClerkRequestData(requestData);
const clerkRequestData = encryptClerkRequestData(requestData, keylessMode);

setRequestHeadersOnNextResponse(res, req, {
[constants.Headers.AuthStatus]: status,
[constants.Headers.AuthToken]: token || '',
[constants.Headers.AuthSignature]: token ? createTokenSignature(token, requestData?.secretKey ?? SECRET_KEY) : '',
[constants.Headers.AuthSignature]: token
? createTokenSignature(token, requestData?.secretKey || SECRET_KEY || keylessMode.secretKey || '')
: '',
[constants.Headers.AuthMessage]: message || '',
[constants.Headers.AuthReason]: reason || '',
[constants.Headers.ClerkUrl]: req.clerkUrl.toString(),
Expand Down Expand Up @@ -230,12 +233,15 @@ const KEYLESS_ENCRYPTION_KEY = 'clerk_keyless_dummy_key';
* Encrypt request data propagated between server requests.
* @internal
**/
export function encryptClerkRequestData(requestData?: Partial<AuthenticateRequestOptions>) {
if (!requestData || !Object.values(requestData).length) {
export function encryptClerkRequestData(
requestData: Partial<AuthenticateRequestOptions>,
keylessMode: Pick<AuthenticateRequestOptions, 'publishableKey' | 'secretKey'>,
) {
if ((!requestData || !Object.values(requestData).length) && (!keylessMode || !Object.values(keylessMode).length)) {
return;
}

if (requestData.secretKey && !ENCRYPTION_KEY && isProductionEnvironment()) {
if (requestData.secretKey && !ENCRYPTION_KEY) {
// TODO SDK-1833: change this to an error in the next major version of `@clerk/nextjs`
logger.warnOnce(
'Clerk: Missing `CLERK_ENCRYPTION_KEY`. Required for propagating `secretKey` middleware option. See docs: https://clerk.com/docs/references/nextjs/clerk-middleware#dynamic-keys',
Expand All @@ -248,7 +254,7 @@ export function encryptClerkRequestData(requestData?: Partial<AuthenticateReques
? ENCRYPTION_KEY || assertKey(SECRET_KEY, () => errorThrower.throwMissingSecretKeyError())
: ENCRYPTION_KEY || SECRET_KEY || KEYLESS_ENCRYPTION_KEY;

return AES.encrypt(JSON.stringify(requestData), maybeKeylessEncryptionKey).toString();
return AES.encrypt(JSON.stringify({ ...keylessMode, ...requestData }), maybeKeylessEncryptionKey).toString();
}

/**
Expand Down

0 comments on commit 3549874

Please sign in to comment.