From 9ce6a4e3f763f5e75a59439f9e36dc1a2ec368c4 Mon Sep 17 00:00:00 2001 From: Peter Perlepes Date: Tue, 5 Jul 2022 16:01:41 +0300 Subject: [PATCH] feat(backend-core,edge): Add requireEdgeMiddlewareAuth --- .../__snapshots__/exports.test.ts.snap | 27 +++++++++++++++ packages/backend-core/src/index.ts | 2 +- packages/edge/src/vercel-edge/index.ts | 33 ++++++++++++++++--- packages/edge/src/vercel-edge/types.ts | 1 + .../edge/src/vercel-edge/utils/responses.ts | 16 +++++++++ packages/nextjs/api.js | 1 + 6 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 packages/edge/src/vercel-edge/utils/responses.ts diff --git a/packages/backend-core/src/__tests__/__snapshots__/exports.test.ts.snap b/packages/backend-core/src/__tests__/__snapshots__/exports.test.ts.snap index d3292e3e39..47ba6e6d19 100644 --- a/packages/backend-core/src/__tests__/__snapshots__/exports.test.ts.snap +++ b/packages/backend-core/src/__tests__/__snapshots__/exports.test.ts.snap @@ -4,6 +4,33 @@ exports[`module exports should not change unless explicitly set 1`] = ` Object { "API_KEY": "TEST_API_KEY", "AllowlistIdentifier": [Function], + "AuthErrorReason": Object { + "CookieAndUATMissing": "cookie-and-uat-missing", + "CookieEarly": "cookie-early", + "CookieExpired": "cookie-expired", + "CookieInvalid": "cookie-invalid", + "CookieInvalidIssuer": "cookie-invalid-issuer", + "CookieMissing": "cookie-missing", + "CookieOutDated": "cookie-outdated", + "CookieUnauthorizedParty": "cookie-unauthorized-party", + "CookieVerificationFailed": "cookie-verification-failed", + "CrossOriginReferrer": "cross-origin-referrer", + "HeaderEarly": "header-early", + "HeaderExpired": "header-expired", + "HeaderInvalid": "header-invalid", + "HeaderInvalidIssuer": "header-invalid-issuer", + "HeaderMissingCORS": "header-missing-cors", + "HeaderMissingNonBrowser": "header-missing-non-browser", + "HeaderUnauthorizedParty": "header-unauthorized-party", + "HeaderVerificationFailed": "header-verification-failed", + "InlineKeyInvalid": "inline-key-invalid", + "InlineKeyMissing": "inline-key-missing", + "InternalError": "internal-error", + "PublicKeyFetchError": "pk-fetch-error", + "StandardOut": "standard-out", + "UATMissing": "uat-missing", + "Unknown": "unknown", + }, "AuthStatus": Object { "Interstitial": "Interstitial", "SignedIn": "Signed in", diff --git a/packages/backend-core/src/index.ts b/packages/backend-core/src/index.ts index a45969e973..319d8773ad 100644 --- a/packages/backend-core/src/index.ts +++ b/packages/backend-core/src/index.ts @@ -2,7 +2,7 @@ export * from './Base'; export * from './api/ClerkBackendAPI'; export * from './api/resources'; export { createGetToken, createSignedOutState } from './util/createGetToken'; -export { AuthStatus } from './types'; +export { AuthStatus, AuthErrorReason } from './types'; export type { ClerkFetcher } from './api/utils/RestClient'; export type { Session } from './api/resources/Session'; export type { Nullable } from './util/nullable'; diff --git a/packages/edge/src/vercel-edge/index.ts b/packages/edge/src/vercel-edge/index.ts index f5460acde4..03e8c62050 100644 --- a/packages/edge/src/vercel-edge/index.ts +++ b/packages/edge/src/vercel-edge/index.ts @@ -1,6 +1,6 @@ import { AuthStatus, Base, createGetToken, createSignedOutState } from '@clerk/backend-core'; import { ClerkJWTClaims } from '@clerk/types'; -import { NextFetchEvent, NextRequest, NextResponse } from 'next/server'; +import { NextFetchEvent, NextRequest } from 'next/server'; import { ClerkAPI } from './ClerkAPI'; import { @@ -10,6 +10,7 @@ import { WithEdgeMiddlewareAuthOptions, } from './types'; import { injectAuthIntoRequest } from './utils'; +import { interstitialResponse, signedOutResponse } from './utils/responses'; /** * @@ -68,6 +69,27 @@ export function withEdgeMiddlewareAuth< ): WithEdgeMiddlewareAuthMiddlewareResult; export function withEdgeMiddlewareAuth( + handler: any, + options: any = { + loadSession: false, + loadUser: false, + strict: false, + }, +): any { + return vercelMiddlewareAuth(handler, { strict: false, ...options }); +} + +export function requireEdgeMiddlewareAuth( + handler: any, + options: any = { + loadSession: false, + loadUser: false, + }, +): any { + return vercelMiddlewareAuth(handler, { strict: true, ...options }); +} + +function vercelMiddlewareAuth( handler: any, options: any = { loadSession: false, @@ -97,13 +119,14 @@ export function withEdgeMiddlewareAuth( }); if (status === AuthStatus.Interstitial) { - return new NextResponse(interstitial, { - headers: { 'Content-Type': 'text/html', 'Auth-Result': errorReason || '' }, - status: 401, - }); + return interstitialResponse(interstitial as string, errorReason); } if (status === AuthStatus.SignedOut) { + if (options.strict) { + return signedOutResponse(); + } + const response = (await handler( injectAuthIntoRequest(req, createSignedOutState()), event, diff --git a/packages/edge/src/vercel-edge/types.ts b/packages/edge/src/vercel-edge/types.ts index 476f810474..c38e67f259 100644 --- a/packages/edge/src/vercel-edge/types.ts +++ b/packages/edge/src/vercel-edge/types.ts @@ -7,6 +7,7 @@ export type WithEdgeMiddlewareAuthOptions = { loadSession?: boolean; authorizedParties?: string[]; jwtKey?: string; + strict?: boolean; }; export type WithEdgeMiddlewareAuthCallback = ( diff --git a/packages/edge/src/vercel-edge/utils/responses.ts b/packages/edge/src/vercel-edge/utils/responses.ts new file mode 100644 index 0000000000..45e63f9a27 --- /dev/null +++ b/packages/edge/src/vercel-edge/utils/responses.ts @@ -0,0 +1,16 @@ +import { AuthErrorReason } from '@clerk/backend-core'; +import { NextResponse } from 'next/server'; + +export function signedOutResponse() { + return new NextResponse(JSON.stringify({ error: 'Unauthenticated' }), { + status: 401, + headers: { 'Content-Type': 'application/json' }, + }); +} + +export function interstitialResponse(interstitial: string, errorReason?: AuthErrorReason) { + return new NextResponse(interstitial, { + headers: { 'Content-Type': 'text/html', 'Auth-Result': errorReason || '' }, + status: 401, + }); +} diff --git a/packages/nextjs/api.js b/packages/nextjs/api.js index 09cb996536..ba0564f7bd 100644 --- a/packages/nextjs/api.js +++ b/packages/nextjs/api.js @@ -2,6 +2,7 @@ let exportLib; if (process.env.NEXT_RUNTIME === 'edge') { exportLib = require('./dist/edge-middleware'); exportLib.withAuth = exportLib.withEdgeMiddlewareAuth; + exportLib.requireAuth = exportLib.requireEdgeMiddlewareAuth; } else { exportLib = require('./dist/api'); }