Skip to content

Commit

Permalink
feat(backend,clerk-sdk-node): Simplify the signature of authenticateR…
Browse files Browse the repository at this point in the history
…equest (#1329)

- One pair of legacy or new instance keys are required  instead of all 4 of them in `authenticateRequest`
- `@clerk/backend` now can handle the `Bearer` prefix in Authorization header for better DX
- `host` parameter is now optional in `@clerk/backend`
  • Loading branch information
anagstef committed Jun 19, 2023
1 parent 1195481 commit de2347f
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 24 deletions.
9 changes: 9 additions & 0 deletions .changeset/pink-carpets-matter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@clerk/clerk-sdk-node': patch
'@clerk/backend': patch
---

Simplify the signature of the low-level `authenticateRequest` helper.
- One pair of legacy or new instance keys are required instead of all 4 of them in `authenticateRequest`
- `@clerk/backend` now can handle the `"Bearer "` prefix in Authorization header for better DX
- `host` parameter is now optional in `@clerk/backend`
2 changes: 2 additions & 0 deletions packages/backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { createBackendApiClient } from './api';
import type { CreateAuthenticateRequestOptions } from './tokens';
import { createAuthenticateRequest } from './tokens';

export type { InstanceKeys } from './tokens';

export * from './api/resources';
export * from './tokens';
export * from './tokens/jwt';
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/tokens/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export {
OptionalVerifyTokenOptions,
RequiredVerifyTokenOptions,
} from './request';
export type { InstanceKeys } from './request';
59 changes: 53 additions & 6 deletions packages/backend/src/tokens/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,59 @@ export type OptionalVerifyTokenOptions = Partial<
>
>;

export type AuthenticateRequestOptions = RequiredVerifyTokenOptions &
type PublicKeys =
| {
publishableKey: string;
/**
* @deprecated Use `publishableKey` instead.
*/
frontendApi: never;
}
| {
publishableKey: never;
/**
* @deprecated Use `publishableKey` instead.
*/
frontendApi: string;
}
| {
publishableKey: string;
/**
* @deprecated Use `publishableKey` instead.
*/
frontendApi: string;
};

type SecretKeys =
| {
secretKey: string;
/**
* @deprecated Use `secretKey` instead.
*/
apiKey: never;
}
| {
secretKey: never;
/**
* @deprecated Use `secretKey` instead.
*/
apiKey: string;
}
| {
secretKey: string;
/**
* @deprecated Use `secretKey` instead.
*/
apiKey: string;
};

export type InstanceKeys = PublicKeys & SecretKeys;

export type AuthenticateRequestOptions = InstanceKeys &
OptionalVerifyTokenOptions &
LoadResourcesOptions & {
apiVersion?: string;
apiUrl?: string;
/* Client token cookie value */
cookieToken?: string;
/* Client uat cookie value */
Expand All @@ -51,12 +101,8 @@ export type AuthenticateRequestOptions = RequiredVerifyTokenOptions &
headerToken?: string;
/* Request origin header value */
origin?: string;
/* Clerk frontend Api value */
frontendApi: string;
/* Clerk Publishable Key value */
publishableKey: string;
/* Request host header value */
host: string;
host?: string;
/* Request forwarded host value */
forwardedHost?: string;
/* Request forwarded port value */
Expand Down Expand Up @@ -105,6 +151,7 @@ export async function authenticateRequest(options: AuthenticateRequestOptions):
options.frontendApi = parsePublishableKey(options.publishableKey)?.frontendApi || options.frontendApi || '';
options.apiUrl = options.apiUrl || API_URL;
options.apiVersion = options.apiVersion || API_VERSION;
options.headerToken = options.headerToken?.replace('Bearer ', '');

assertValidSecretKey(options.secretKey || options.apiKey);

Expand Down
6 changes: 3 additions & 3 deletions packages/backend/src/util/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function checkCrossOrigin({
forwardedProto,
}: {
originURL: URL;
host: string;
host?: string | null;
forwardedHost?: string | null;
forwardedPort?: string | null;
forwardedProto?: string | null;
Expand All @@ -37,7 +37,7 @@ export function checkCrossOrigin({

const protocol = fwdProto || originProtocol;
/* The forwarded host prioritised over host to be checked against the referrer. */
const finalURL = convertHostHeaderValueToURL(forwardedHost || host, protocol);
const finalURL = convertHostHeaderValueToURL(forwardedHost || host || undefined, protocol);
finalURL.port = fwdPort || finalURL.port;

if (getPort(finalURL) !== getPort(originURL)) {
Expand All @@ -50,7 +50,7 @@ export function checkCrossOrigin({
return false;
}

export function convertHostHeaderValueToURL(host: string, protocol = 'https'): URL {
export function convertHostHeaderValueToURL(host?: string, protocol = 'https'): URL {
/**
* The protocol is added for the URL constructor to work properly.
* We do not check for the protocol at any point later on.
Expand Down
18 changes: 4 additions & 14 deletions packages/sdk-node/src/authenticateRequest.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import type { Clerk, RequestState } from '@clerk/backend';
import type { RequestState } from '@clerk/backend';
import { constants } from '@clerk/backend';
import cookie from 'cookie';
import type { IncomingMessage, ServerResponse } from 'http';

import { handleValueOrFn, isHttpOrHttps, isProxyUrlRelative, isValidProxyUrl } from './shared';
import type { ClerkMiddlewareOptions } from './types';
import type { AuthenticateRequestParams, ClerkClient } from './types';
import { loadApiEnv, loadClientEnv } from './utils';

const parseCookies = (req: IncomingMessage) => {
return cookie.parse(req.headers['cookie'] || '');
};

type ClerkClient = ReturnType<typeof Clerk>;

export async function loadInterstitial({
clerkClient,
requestState,
Expand Down Expand Up @@ -40,15 +38,7 @@ export async function loadInterstitial({
return await clerkClient.remotePrivateInterstitial();
}

export const authenticateRequest = (opts: {
clerkClient: ReturnType<typeof Clerk>;
apiKey: string;
secretKey: string;
frontendApi: string;
publishableKey: string;
req: IncomingMessage;
options?: ClerkMiddlewareOptions;
}) => {
export const authenticateRequest = (opts: AuthenticateRequestParams) => {
const { clerkClient, apiKey, secretKey, frontendApi, publishableKey, req, options } = opts;
const { jwtKey, authorizedParties, audience } = options || {};

Expand All @@ -67,7 +57,7 @@ export const authenticateRequest = (opts: {
throw new Error(satelliteAndMissingProxyUrlAndDomain);
}

if (isSatellite && !isHttpOrHttps(signInUrl) && isDevelopmentFromApiKey(secretKey)) {
if (isSatellite && !isHttpOrHttps(signInUrl) && isDevelopmentFromApiKey(secretKey || apiKey)) {
throw new Error(satelliteAndMissingSignInUrl);
}

Expand Down
11 changes: 10 additions & 1 deletion packages/sdk-node/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { AuthenticateRequestOptions, AuthObject, SignedInAuthObject } from '@clerk/backend';
import type { AuthenticateRequestOptions, AuthObject, Clerk, InstanceKeys, SignedInAuthObject } from '@clerk/backend';
import type { MultiDomainAndOrProxy } from '@clerk/types';
import type { NextFunction, Request, Response } from 'express';
import type { IncomingMessage } from 'http';

type LegacyAuthObject<T extends AuthObject> = Pick<T, 'sessionId' | 'userId' | 'actor' | 'getToken' | 'debug'> & {
claims: AuthObject['sessionClaims'];
Expand Down Expand Up @@ -34,3 +35,11 @@ export type ClerkMiddlewareOptions = {
strict?: boolean;
signInUrl?: string;
} & MultiDomainAndOrProxy;

export type ClerkClient = ReturnType<typeof Clerk>;

export type AuthenticateRequestParams = InstanceKeys & {
clerkClient: ClerkClient;
req: IncomingMessage;
options?: ClerkMiddlewareOptions;
};

0 comments on commit de2347f

Please sign in to comment.