actor-gate 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/package.json +51 -8
  2. package/src/config/index.js +5 -5
  3. package/src/config/nextjs-public-config.js +2 -2
  4. package/src/core/index.js +7 -7
  5. package/src/core/services/access-token-service.js +6 -6
  6. package/src/core/services/direct-auth-service.js +3 -3
  7. package/src/core/services/index.js +5 -5
  8. package/src/core/services/mcp-auth-service.js +3 -3
  9. package/src/core/services/oauth-service.js +3 -3
  10. package/src/core/tokens/access-claims.js +1 -1
  11. package/src/express/index.js +2 -2
  12. package/src/express/protected-route.d.ts +10 -0
  13. package/src/express/protected-route.js +14 -4
  14. package/src/index.js +8 -8
  15. package/src/mcp/index.js +1 -1
  16. package/src/next/app/catch-all.js +1 -1
  17. package/src/next/app/cookies.js +1 -1
  18. package/src/next/app/direct-auth-handlers.js +6 -6
  19. package/src/next/app/index.js +8 -8
  20. package/src/next/app/mcp-oauth-handlers.js +5 -5
  21. package/src/next/app/protected-route.d.ts +9 -0
  22. package/src/next/app/protected-route.js +12 -3
  23. package/src/next/app/request.js +1 -1
  24. package/src/next/app/response.js +1 -1
  25. package/src/next/app/wrapper.js +3 -3
  26. package/src/next/index.js +5 -5
  27. package/src/next/pages/catch-all.js +1 -1
  28. package/src/next/pages/direct-auth-handlers.js +6 -6
  29. package/src/next/pages/index.js +8 -8
  30. package/src/next/pages/mcp-oauth-handlers.js +5 -5
  31. package/src/next/pages/protected-route.d.ts +10 -0
  32. package/src/next/pages/protected-route.js +13 -3
  33. package/src/next/pages/response.js +1 -1
  34. package/src/next/pages/wrapper.js +3 -3
  35. package/src/next/rewrites.js +1 -1
  36. package/src/next/shared/auth-http.js +2 -2
  37. package/src/next/shared/direct-auth-utils.js +2 -2
  38. package/src/next/shared/oauth-utils.js +1 -1
  39. package/src/shared/protected-route-session.js +1 -1
  40. package/src/testing/in-memory/index.js +7 -7
  41. package/src/testing/index.js +1 -1
package/package.json CHANGED
@@ -1,20 +1,63 @@
1
1
  {
2
2
  "name": "actor-gate",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Schema-agnostic Next.js auth library for direct and MCP authentication flows.",
5
5
  "type": "module",
6
6
  "private": false,
7
7
  "exports": {
8
- ".": "./src/index.js",
9
- "./core": "./src/core/index.js",
10
- "./config": "./src/config/index.js",
11
- "./express": "./src/express/index.js",
12
- "./next": "./src/next/index.js",
13
- "./mcp": "./src/mcp/index.js",
14
- "./testing": "./src/testing/index.js"
8
+ ".": {
9
+ "types": "./src/index.d.ts",
10
+ "default": "./src/index.js"
11
+ },
12
+ "./core": {
13
+ "types": "./src/core/index.d.ts",
14
+ "default": "./src/core/index.js"
15
+ },
16
+ "./config": {
17
+ "types": "./src/config/index.d.ts",
18
+ "default": "./src/config/index.js"
19
+ },
20
+ "./express": {
21
+ "types": "./src/express/index.d.ts",
22
+ "default": "./src/express/index.js"
23
+ },
24
+ "./next": {
25
+ "types": "./src/next/index.d.ts",
26
+ "default": "./src/next/index.js"
27
+ },
28
+ "./mcp": {
29
+ "types": "./src/mcp/index.d.ts",
30
+ "default": "./src/mcp/index.js"
31
+ },
32
+ "./testing": {
33
+ "types": "./src/testing/index.d.ts",
34
+ "default": "./src/testing/index.js"
35
+ }
15
36
  },
16
37
  "main": "./src/index.js",
17
38
  "types": "./src/index.d.ts",
39
+ "typesVersions": {
40
+ "*": {
41
+ "core": [
42
+ "./src/core/index.d.ts"
43
+ ],
44
+ "config": [
45
+ "./src/config/index.d.ts"
46
+ ],
47
+ "express": [
48
+ "./src/express/index.d.ts"
49
+ ],
50
+ "next": [
51
+ "./src/next/index.d.ts"
52
+ ],
53
+ "mcp": [
54
+ "./src/mcp/index.d.ts"
55
+ ],
56
+ "testing": [
57
+ "./src/testing/index.d.ts"
58
+ ]
59
+ }
60
+ },
18
61
  "files": [
19
62
  "src/**/*.js",
20
63
  "src/**/*.d.ts"
@@ -1,5 +1,5 @@
1
- export { defineBaseAuthConfig, } from './base-config';
2
- export { defineNextJsPublicAuthConfig, toSerializableNextJsPublicAuthConfig, } from './nextjs-public-config';
3
- export { defineNextJsServerAuthConfig, } from './nextjs-server-config';
4
- export { defineReactAuthConfig, } from './react-config';
5
- export { ReactAuthClient, createReactAuthClient, } from './react-client';
1
+ export { defineBaseAuthConfig, } from './base-config.js';
2
+ export { defineNextJsPublicAuthConfig, toSerializableNextJsPublicAuthConfig, } from './nextjs-public-config.js';
3
+ export { defineNextJsServerAuthConfig, } from './nextjs-server-config.js';
4
+ export { defineReactAuthConfig, } from './react-config.js';
5
+ export { ReactAuthClient, createReactAuthClient, } from './react-client.js';
@@ -1,5 +1,5 @@
1
- import { buildAuthRoutePath, } from '../next/shared/auth-routes';
2
- import { buildAuthRewrites, } from '../next/rewrites';
1
+ import { buildAuthRoutePath, } from '../next/shared/auth-routes.js';
2
+ import { buildAuthRewrites, } from '../next/rewrites.js';
3
3
  function normalizePath(path) {
4
4
  const trimmed = path.trim();
5
5
  if (trimmed.length === 0) {
package/src/core/index.js CHANGED
@@ -1,7 +1,7 @@
1
- export { buildBearerChallengeHeader, } from './http/bearer-challenge';
2
- export { base64UrlEncode, createS256CodeChallenge, verifyPkce, } from './oauth/pkce';
3
- export { numberIdCodec, stringIdCodec } from './ids/id-codec';
4
- export { decodeSubjectClaims, encodeSubjectClaims, } from './tokens/id-claims';
5
- export * from './services/index';
6
- export { DEFAULT_TOKEN_CLAIMS_VERSION, buildAccessClaims, parseAccessClaims, } from './tokens/access-claims';
7
- export { buildClientSession } from './sessions/client-session';
1
+ export { buildBearerChallengeHeader, } from './http/bearer-challenge.js';
2
+ export { base64UrlEncode, createS256CodeChallenge, verifyPkce, } from './oauth/pkce.js';
3
+ export { numberIdCodec, stringIdCodec } from './ids/id-codec.js';
4
+ export { decodeSubjectClaims, encodeSubjectClaims, } from './tokens/id-claims.js';
5
+ export * from './services/index.js';
6
+ export { DEFAULT_TOKEN_CLAIMS_VERSION, buildAccessClaims, parseAccessClaims, } from './tokens/access-claims.js';
7
+ export { buildClientSession } from './sessions/client-session.js';
@@ -1,9 +1,9 @@
1
- import { buildClientSession } from '../sessions/client-session';
2
- import { decodeSubjectClaims } from '../tokens/id-claims';
3
- import { buildAccessClaims, parseAccessClaims } from '../tokens/access-claims';
4
- import { AuthServiceError, isAuthServiceError } from './auth-error';
5
- import { createRevocationDecisionEngine, shouldValidateSession, } from './revocation-policy';
6
- import { emitAuditEvent, emitMetric, reportServiceError, } from './observability';
1
+ import { buildClientSession } from '../sessions/client-session.js';
2
+ import { decodeSubjectClaims } from '../tokens/id-claims.js';
3
+ import { buildAccessClaims, parseAccessClaims } from '../tokens/access-claims.js';
4
+ import { AuthServiceError, isAuthServiceError } from './auth-error.js';
5
+ import { createRevocationDecisionEngine, shouldValidateSession, } from './revocation-policy.js';
6
+ import { emitAuditEvent, emitMetric, reportServiceError, } from './observability.js';
7
7
  function assertPositiveSafeInteger(value, fieldName) {
8
8
  if (!Number.isSafeInteger(value) || value <= 0) {
9
9
  throw new AuthServiceError({
@@ -1,6 +1,6 @@
1
- import { buildClientSession } from '../sessions/client-session';
2
- import { AuthServiceError, isAuthServiceError } from './auth-error';
3
- import { emitAuditEvent, emitMetric, reportServiceError, } from './observability';
1
+ import { buildClientSession } from '../sessions/client-session.js';
2
+ import { AuthServiceError, isAuthServiceError } from './auth-error.js';
3
+ import { emitAuditEvent, emitMetric, reportServiceError, } from './observability.js';
4
4
  function assertPositiveSafeInteger(value, fieldName) {
5
5
  if (!Number.isSafeInteger(value) || value <= 0) {
6
6
  throw new AuthServiceError({
@@ -1,5 +1,5 @@
1
- export { AuthServiceError, authErrorToHttpStatus, isAuthServiceError, } from './auth-error';
2
- export { createAccessTokenService, } from './access-token-service';
3
- export { createDirectAuthService, } from './direct-auth-service';
4
- export { createOAuthService, } from './oauth-service';
5
- export { createMcpAuthService, } from './mcp-auth-service';
1
+ export { AuthServiceError, authErrorToHttpStatus, isAuthServiceError, } from './auth-error.js';
2
+ export { createAccessTokenService, } from './access-token-service.js';
3
+ export { createDirectAuthService, } from './direct-auth-service.js';
4
+ export { createOAuthService, } from './oauth-service.js';
5
+ export { createMcpAuthService, } from './mcp-auth-service.js';
@@ -1,6 +1,6 @@
1
- import { DEFAULT_UNAUTHENTICATED_RPC_METHODS, getRpcMethodsFromBody, requiresAuth, } from '../../mcp/json-rpc-auth';
2
- import { AuthServiceError, isAuthServiceError } from './auth-error';
3
- import { emitAuditEvent, reportServiceError } from './observability';
1
+ import { DEFAULT_UNAUTHENTICATED_RPC_METHODS, getRpcMethodsFromBody, requiresAuth, } from '../../mcp/json-rpc-auth.js';
2
+ import { AuthServiceError, isAuthServiceError } from './auth-error.js';
3
+ import { emitAuditEvent, reportServiceError } from './observability.js';
4
4
  function extractToolNameFromPayload(payload) {
5
5
  if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
6
6
  return null;
@@ -1,6 +1,6 @@
1
- import { verifyPkce } from '../oauth/pkce';
2
- import { AuthServiceError, isAuthServiceError } from './auth-error';
3
- import { emitAuditEvent, reportServiceError } from './observability';
1
+ import { verifyPkce } from '../oauth/pkce.js';
2
+ import { AuthServiceError, isAuthServiceError } from './auth-error.js';
3
+ import { emitAuditEvent, reportServiceError } from './observability.js';
4
4
  function assertPositiveSafeInteger(value, fieldName) {
5
5
  if (!Number.isSafeInteger(value) || value <= 0) {
6
6
  throw new AuthServiceError({
@@ -1,5 +1,5 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { encodeSubjectClaims } from './id-claims';
2
+ import { encodeSubjectClaims } from './id-claims.js';
3
3
  export const DEFAULT_TOKEN_CLAIMS_VERSION = 1;
4
4
  const ALLOWED_TOP_LEVEL_CLAIM_KEYS = new Set([
5
5
  'sub',
@@ -1,2 +1,2 @@
1
- export { withExpressProtectedRoute, } from './protected-route';
2
- export { buildProtectedRouteSession, buildProtectedRouteSessionWithMeta, } from '../shared/protected-route-session';
1
+ export { withExpressProtectedRoute, } from './protected-route.js';
2
+ export { buildProtectedRouteSession, buildProtectedRouteSessionWithMeta, } from '../shared/protected-route-session.js';
@@ -40,5 +40,15 @@ export type WithExpressProtectedRouteOptions<TSessionId, TUserId, TActor extends
40
40
  resourceMetadataUrl?: string;
41
41
  };
42
42
  };
43
+ /**
44
+ * Wraps an Express route with access-token authentication and standardized
45
+ * auth/system error responses.
46
+ *
47
+ * Handler output behavior:
48
+ * - Return a non-`undefined` value to send `200` with `res.json(output)`.
49
+ * - Return `undefined` to send `204`.
50
+ * - If your handler already committed the response (for example via
51
+ * `res.status(...).json(...)`), this wrapper does not overwrite it.
52
+ */
43
53
  export declare function withExpressProtectedRoute<TSessionId, TUserId, TActor extends AuthActor = AuthActor, TServerSessionData extends Record<string, unknown> = Record<string, never>, TClientSessionData extends Record<string, unknown> = Record<string, never>, TExtClaims extends Record<string, unknown> = Record<string, never>, TReq extends ExpressRequestLike = ExpressRequestLike, TRes extends ExpressResponseLike = ExpressResponseLike, TOutput = unknown>(options: WithExpressProtectedRouteOptions<TSessionId, TUserId, TActor, TServerSessionData, TClientSessionData, TExtClaims, TReq, TRes, TOutput>): (req: TReq, res: TRes) => Promise<void>;
44
54
  export {};
@@ -1,7 +1,7 @@
1
- import { AuthServiceError, isAuthServiceError, } from '../core/services/auth-error';
2
- import { parseCookieHeader } from '../next/pages/request';
3
- import { buildAuthErrorHttpResponse, buildSystemErrorHttpResponse, } from '../next/shared/auth-http';
4
- import { assertBearerOnlyActorPolicy, getHeaderValue, resolveAccessTokenTransportAdapter, } from '../next/shared/direct-auth-utils';
1
+ import { AuthServiceError, isAuthServiceError, } from '../core/services/auth-error.js';
2
+ import { parseCookieHeader } from '../next/pages/request.js';
3
+ import { buildAuthErrorHttpResponse, buildSystemErrorHttpResponse, } from '../next/shared/auth-http.js';
4
+ import { assertBearerOnlyActorPolicy, getHeaderValue, resolveAccessTokenTransportAdapter, } from '../next/shared/direct-auth-utils.js';
5
5
  function normalizeRequestId(value) {
6
6
  return value;
7
7
  }
@@ -37,6 +37,16 @@ function sendExpressAuthError(res, error, input) {
37
37
  }
38
38
  res.status(built.statusCode).json(built.body);
39
39
  }
40
+ /**
41
+ * Wraps an Express route with access-token authentication and standardized
42
+ * auth/system error responses.
43
+ *
44
+ * Handler output behavior:
45
+ * - Return a non-`undefined` value to send `200` with `res.json(output)`.
46
+ * - Return `undefined` to send `204`.
47
+ * - If your handler already committed the response (for example via
48
+ * `res.status(...).json(...)`), this wrapper does not overwrite it.
49
+ */
40
50
  export function withExpressProtectedRoute(options) {
41
51
  const authorizationHeaderName = options.authorizationHeaderName ?? 'authorization';
42
52
  const requestIdHeaderName = options.requestIdHeaderName ?? 'x-request-id';
package/src/index.js CHANGED
@@ -1,8 +1,8 @@
1
- export * from './core/index';
2
- export * from './config/index';
3
- export * from './express/index';
4
- export * as config from './config/index';
5
- export * as express from './express/index';
6
- export * as mcp from './mcp/index';
7
- export * as next from './next/index';
8
- export * as testing from './testing/index';
1
+ export * from './core/index.js';
2
+ export * from './config/index.js';
3
+ export * from './express/index.js';
4
+ export * as config from './config/index.js';
5
+ export * as express from './express/index.js';
6
+ export * as mcp from './mcp/index.js';
7
+ export * as next from './next/index.js';
8
+ export * as testing from './testing/index.js';
package/src/mcp/index.js CHANGED
@@ -1 +1 @@
1
- export { DEFAULT_UNAUTHENTICATED_RPC_METHODS, getRpcMethodFromBody, getRpcMethodsFromBody, requiresAuth, requiresAuthForBody, } from './json-rpc-auth';
1
+ export { DEFAULT_UNAUTHENTICATED_RPC_METHODS, getRpcMethodFromBody, getRpcMethodsFromBody, requiresAuth, requiresAuthForBody, } from './json-rpc-auth.js';
@@ -1,4 +1,4 @@
1
- import { AUTH_ROUTE_HTTP_METHODS, isAuthRouteMethodAllowed, normalizeAuthRouteSegments, resolveAuthRoute, } from '../shared/auth-routes';
1
+ import { AUTH_ROUTE_HTTP_METHODS, isAuthRouteMethodAllowed, normalizeAuthRouteSegments, resolveAuthRoute, } from '../shared/auth-routes.js';
2
2
  function jsonResponse(statusCode, body, headers) {
3
3
  const responseHeaders = new Headers(headers);
4
4
  responseHeaders.set('Content-Type', 'application/json');
@@ -1,4 +1,4 @@
1
- import { serializeSetCookie, } from '../pages/cookies';
1
+ import { serializeSetCookie, } from '../pages/cookies.js';
2
2
  export function appendAppSetCookieHeader(headers, serializedCookie) {
3
3
  headers.append('Set-Cookie', serializedCookie);
4
4
  }
@@ -1,9 +1,9 @@
1
- import { AuthServiceError } from '../../core/services/auth-error';
2
- import { clearAppAuthCookie, setAppAuthCookie, } from './cookies';
3
- import { sendAppRedirect } from './response';
4
- import { withAppAuthRoute } from './wrapper';
5
- import { assertBearerOnlyActorPolicy, assertCsrfForCookieMutation, DEFAULT_ACCESS_TOKEN_COOKIE_NAME, DEFAULT_REFRESH_TOKEN_COOKIE_NAME, extractRefreshToken, parseNonNegativeSafeInteger, resolveAccessTokenTransportAdapter, resolveCookieSecureFlag, resolveLoginMethod, resolvePathnameFromUrl, } from '../shared/direct-auth-utils';
6
- import { parseBodyToRecord, toSingleString } from '../shared/oauth-utils';
1
+ import { AuthServiceError } from '../../core/services/auth-error.js';
2
+ import { clearAppAuthCookie, setAppAuthCookie, } from './cookies.js';
3
+ import { sendAppRedirect } from './response.js';
4
+ import { withAppAuthRoute } from './wrapper.js';
5
+ import { assertBearerOnlyActorPolicy, assertCsrfForCookieMutation, DEFAULT_ACCESS_TOKEN_COOKIE_NAME, DEFAULT_REFRESH_TOKEN_COOKIE_NAME, extractRefreshToken, parseNonNegativeSafeInteger, resolveAccessTokenTransportAdapter, resolveCookieSecureFlag, resolveLoginMethod, resolvePathnameFromUrl, } from '../shared/direct-auth-utils.js';
6
+ import { parseBodyToRecord, toSingleString } from '../shared/oauth-utils.js';
7
7
  function jsonResponse(statusCode, body, headers) {
8
8
  const responseHeaders = new Headers(headers);
9
9
  responseHeaders.set('Content-Type', 'application/json');
@@ -1,8 +1,8 @@
1
- export { buildAppAccessTokenTransportInput, getAppAuthorizationHeader, getAppCookies, getAppRequestId, } from './request';
2
- export { appendAppSetCookieHeader, clearAppAuthCookie, setAppAuthCookie, setAppCookie, } from './cookies';
3
- export { sendAppAuthError, sendAppRedirect, sendAppSystemError, } from './response';
4
- export { withAppAuthRoute, } from './wrapper';
5
- export { withAppProtectedRoute, } from './protected-route';
6
- export { APP_AUTH_CATCH_ALL_METHODS, createAppAuthCatchAllHandlers, } from './catch-all';
7
- export { createAppMcpHandler, createAppOAuthHandlers, createAppWellKnownHandlers, } from './mcp-oauth-handlers';
8
- export { createAppDirectAuthHandlers, } from './direct-auth-handlers';
1
+ export { buildAppAccessTokenTransportInput, getAppAuthorizationHeader, getAppCookies, getAppRequestId, } from './request.js';
2
+ export { appendAppSetCookieHeader, clearAppAuthCookie, setAppAuthCookie, setAppCookie, } from './cookies.js';
3
+ export { sendAppAuthError, sendAppRedirect, sendAppSystemError, } from './response.js';
4
+ export { withAppAuthRoute, } from './wrapper.js';
5
+ export { withAppProtectedRoute, } from './protected-route.js';
6
+ export { APP_AUTH_CATCH_ALL_METHODS, createAppAuthCatchAllHandlers, } from './catch-all.js';
7
+ export { createAppMcpHandler, createAppOAuthHandlers, createAppWellKnownHandlers, } from './mcp-oauth-handlers.js';
8
+ export { createAppDirectAuthHandlers, } from './direct-auth-handlers.js';
@@ -1,9 +1,9 @@
1
1
  import { randomUUID } from 'crypto';
2
- import { AuthServiceError } from '../../core/services/auth-error';
3
- import { sendAppRedirect } from './response';
4
- import { withAppAuthRoute } from './wrapper';
5
- import { appendUrlParams, parseAuthorizeRequest, parseBodyToRecord, parseBoolean, parseOAuthTokenRequest, parsePositiveSafeInteger, } from '../shared/oauth-utils';
6
- import { buildWellKnownMetadata, resolveRequestOrigin, } from '../shared/well-known-utils';
2
+ import { AuthServiceError } from '../../core/services/auth-error.js';
3
+ import { sendAppRedirect } from './response.js';
4
+ import { withAppAuthRoute } from './wrapper.js';
5
+ import { appendUrlParams, parseAuthorizeRequest, parseBodyToRecord, parseBoolean, parseOAuthTokenRequest, parsePositiveSafeInteger, } from '../shared/oauth-utils.js';
6
+ import { buildWellKnownMetadata, resolveRequestOrigin, } from '../shared/well-known-utils.js';
7
7
  function jsonResponse(statusCode, body, headers) {
8
8
  const responseHeaders = new Headers(headers);
9
9
  responseHeaders.set('Content-Type', 'application/json');
@@ -24,4 +24,13 @@ export type WithAppProtectedRouteOptions<TSessionId, TUserId, TActor extends Aut
24
24
  authorizationHeaderName?: string;
25
25
  challenge?: WithAppAuthRouteOptions<TOutput>['challenge'];
26
26
  };
27
+ /**
28
+ * Wraps a Next.js App Router handler with access-token authentication and
29
+ * standardized auth/system error handling.
30
+ *
31
+ * Handler output behavior:
32
+ * - Return a `Response` to fully control the HTTP response.
33
+ * - Return a non-`undefined` non-`Response` value to send `200` JSON.
34
+ * - Return `undefined` to send `204`.
35
+ */
27
36
  export declare function withAppProtectedRoute<TSessionId, TUserId, TActor extends AuthActor = AuthActor, TServerSessionData extends Record<string, unknown> = Record<string, never>, TClientSessionData extends Record<string, unknown> = Record<string, never>, TExtClaims extends Record<string, unknown> = Record<string, never>, TOutput = unknown>(options: WithAppProtectedRouteOptions<TSessionId, TUserId, TActor, TServerSessionData, TClientSessionData, TExtClaims, TOutput>): (req: Request) => Promise<Response>;
@@ -1,6 +1,15 @@
1
- import { AuthServiceError } from '../../core/services/auth-error';
2
- import { assertBearerOnlyActorPolicy, resolveAccessTokenTransportAdapter, } from '../shared/direct-auth-utils';
3
- import { withAppAuthRoute } from './wrapper';
1
+ import { AuthServiceError } from '../../core/services/auth-error.js';
2
+ import { assertBearerOnlyActorPolicy, resolveAccessTokenTransportAdapter, } from '../shared/direct-auth-utils.js';
3
+ import { withAppAuthRoute } from './wrapper.js';
4
+ /**
5
+ * Wraps a Next.js App Router handler with access-token authentication and
6
+ * standardized auth/system error handling.
7
+ *
8
+ * Handler output behavior:
9
+ * - Return a `Response` to fully control the HTTP response.
10
+ * - Return a non-`undefined` non-`Response` value to send `200` JSON.
11
+ * - Return `undefined` to send `204`.
12
+ */
4
13
  export function withAppProtectedRoute(options) {
5
14
  const accessTokenTransportAdapter = resolveAccessTokenTransportAdapter(options.accessTokenTransport);
6
15
  return withAppAuthRoute({
@@ -1,4 +1,4 @@
1
- import { parseCookieHeader } from '../pages/request';
1
+ import { parseCookieHeader } from '../pages/request.js';
2
2
  function getHeaderValue(headers, headerName) {
3
3
  const value = headers.get(headerName);
4
4
  if (value === null || value.length === 0) {
@@ -1,4 +1,4 @@
1
- import { buildAuthErrorHttpResponse, buildSystemErrorHttpResponse, } from '../shared/auth-http';
1
+ import { buildAuthErrorHttpResponse, buildSystemErrorHttpResponse, } from '../shared/auth-http.js';
2
2
  function createJsonResponse(input) {
3
3
  const headers = new Headers(input.headers);
4
4
  headers.set('Content-Type', 'application/json');
@@ -1,6 +1,6 @@
1
- import { isAuthServiceError } from '../../core/services/auth-error';
2
- import { buildAppAccessTokenTransportInput, getAppCookies, getAppRequestId, } from './request';
3
- import { sendAppAuthError, sendAppSystemError } from './response';
1
+ import { isAuthServiceError } from '../../core/services/auth-error.js';
2
+ import { buildAppAccessTokenTransportInput, getAppCookies, getAppRequestId, } from './request.js';
3
+ import { sendAppAuthError, sendAppSystemError } from './response.js';
4
4
  export function withAppAuthRoute(options) {
5
5
  return async function appAuthRoute(req) {
6
6
  const requestId = getAppRequestId(req, options.requestIdHeaderName);
package/src/next/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export const SUPPORTED_NEXT_ROUTERS = ['pages', 'app'];
2
- export { buildProtectedRouteSession, buildProtectedRouteSessionWithMeta, } from '../shared/protected-route-session';
3
- export * from './pages/index';
4
- export * from './app/index';
5
- export * from './shared/auth-routes';
6
- export * from './rewrites';
2
+ export { buildProtectedRouteSession, buildProtectedRouteSessionWithMeta, } from '../shared/protected-route-session.js';
3
+ export * from './pages/index.js';
4
+ export * from './app/index.js';
5
+ export * from './shared/auth-routes.js';
6
+ export * from './rewrites.js';
@@ -1,4 +1,4 @@
1
- import { isAuthRouteMethodAllowed, normalizeAuthRouteSegments, resolveAuthRoute, } from '../shared/auth-routes';
1
+ import { isAuthRouteMethodAllowed, normalizeAuthRouteSegments, resolveAuthRoute, } from '../shared/auth-routes.js';
2
2
  function sendUnsupportedRoute(res) {
3
3
  res.status(404).json({
4
4
  error: 'not_found',
@@ -1,9 +1,9 @@
1
- import { AuthServiceError } from '../../core/services/auth-error';
2
- import { clearPagesAuthCookie, setPagesAuthCookie, } from './cookies';
3
- import { sendPagesRedirect } from './response';
4
- import { withPagesAuthRoute } from './wrapper';
5
- import { assertBearerOnlyActorPolicy, assertCsrfForCookieMutation, DEFAULT_ACCESS_TOKEN_COOKIE_NAME, DEFAULT_REFRESH_TOKEN_COOKIE_NAME, extractRefreshToken, parseNonNegativeSafeInteger, resolveAccessTokenTransportAdapter, resolveCookieSecureFlag, resolveLoginMethod, resolvePathnameFromUrl, } from '../shared/direct-auth-utils';
6
- import { parseBodyToRecord, toSingleString } from '../shared/oauth-utils';
1
+ import { AuthServiceError } from '../../core/services/auth-error.js';
2
+ import { clearPagesAuthCookie, setPagesAuthCookie, } from './cookies.js';
3
+ import { sendPagesRedirect } from './response.js';
4
+ import { withPagesAuthRoute } from './wrapper.js';
5
+ import { assertBearerOnlyActorPolicy, assertCsrfForCookieMutation, DEFAULT_ACCESS_TOKEN_COOKIE_NAME, DEFAULT_REFRESH_TOKEN_COOKIE_NAME, extractRefreshToken, parseNonNegativeSafeInteger, resolveAccessTokenTransportAdapter, resolveCookieSecureFlag, resolveLoginMethod, resolvePathnameFromUrl, } from '../shared/direct-auth-utils.js';
6
+ import { parseBodyToRecord, toSingleString } from '../shared/oauth-utils.js';
7
7
  function sendMethodNotAllowed(res, allowedMethods) {
8
8
  res.setHeader('Allow', allowedMethods.join(', '));
9
9
  res.status(405).json({
@@ -1,8 +1,8 @@
1
- export { buildPagesAccessTokenTransportInput, getPagesAuthorizationHeader, getPagesCookies, getPagesRequestId, parseCookieHeader, } from './request';
2
- export { appendSetCookieHeader, clearPagesAuthCookie, serializeSetCookie, setPagesAuthCookie, setPagesCookie, } from './cookies';
3
- export { sendPagesAuthError, sendPagesRedirect, sendPagesSystemError, } from './response';
4
- export { withPagesAuthRoute, } from './wrapper';
5
- export { withPagesProtectedRoute, } from './protected-route';
6
- export { createPagesAuthCatchAllHandler, } from './catch-all';
7
- export { createPagesMcpHandler, createPagesOAuthHandlers, createPagesWellKnownHandlers, } from './mcp-oauth-handlers';
8
- export { createPagesDirectAuthHandlers, } from './direct-auth-handlers';
1
+ export { buildPagesAccessTokenTransportInput, getPagesAuthorizationHeader, getPagesCookies, getPagesRequestId, parseCookieHeader, } from './request.js';
2
+ export { appendSetCookieHeader, clearPagesAuthCookie, serializeSetCookie, setPagesAuthCookie, setPagesCookie, } from './cookies.js';
3
+ export { sendPagesAuthError, sendPagesRedirect, sendPagesSystemError, } from './response.js';
4
+ export { withPagesAuthRoute, } from './wrapper.js';
5
+ export { withPagesProtectedRoute, } from './protected-route.js';
6
+ export { createPagesAuthCatchAllHandler, } from './catch-all.js';
7
+ export { createPagesMcpHandler, createPagesOAuthHandlers, createPagesWellKnownHandlers, } from './mcp-oauth-handlers.js';
8
+ export { createPagesDirectAuthHandlers, } from './direct-auth-handlers.js';
@@ -1,9 +1,9 @@
1
1
  import { randomUUID } from 'crypto';
2
- import { AuthServiceError } from '../../core/services/auth-error';
3
- import { sendPagesRedirect } from './response';
4
- import { withPagesAuthRoute } from './wrapper';
5
- import { appendUrlParams, parseAuthorizeRequest, parseBodyToRecord, parseBoolean, parseOAuthTokenRequest, parsePositiveSafeInteger, toSingleString, } from '../shared/oauth-utils';
6
- import { buildWellKnownMetadata, resolveRequestOrigin, } from '../shared/well-known-utils';
2
+ import { AuthServiceError } from '../../core/services/auth-error.js';
3
+ import { sendPagesRedirect } from './response.js';
4
+ import { withPagesAuthRoute } from './wrapper.js';
5
+ import { appendUrlParams, parseAuthorizeRequest, parseBodyToRecord, parseBoolean, parseOAuthTokenRequest, parsePositiveSafeInteger, toSingleString, } from '../shared/oauth-utils.js';
6
+ import { buildWellKnownMetadata, resolveRequestOrigin, } from '../shared/well-known-utils.js';
7
7
  function sendMethodNotAllowed(res, allowedMethods) {
8
8
  res.setHeader('Allow', allowedMethods.join(', '));
9
9
  res.status(405).json({
@@ -25,4 +25,14 @@ export type WithPagesProtectedRouteOptions<TSessionId, TUserId, TActor extends A
25
25
  authorizationHeaderName?: string;
26
26
  challenge?: WithPagesAuthRouteOptions<TOutput>['challenge'];
27
27
  };
28
+ /**
29
+ * Wraps a Next.js Pages API route with access-token authentication and
30
+ * standardized auth/system error handling.
31
+ *
32
+ * Handler output behavior:
33
+ * - Return a non-`undefined` value to send `200` with `res.json(output)`.
34
+ * - Return `undefined` to send `204`.
35
+ * - If your handler already finished the response (for example by calling
36
+ * `res.status(...).json(...)` directly), the wrapper does not overwrite it.
37
+ */
28
38
  export declare function withPagesProtectedRoute<TSessionId, TUserId, TActor extends AuthActor = AuthActor, TServerSessionData extends Record<string, unknown> = Record<string, never>, TClientSessionData extends Record<string, unknown> = Record<string, never>, TExtClaims extends Record<string, unknown> = Record<string, never>, TOutput = unknown>(options: WithPagesProtectedRouteOptions<TSessionId, TUserId, TActor, TServerSessionData, TClientSessionData, TExtClaims, TOutput>): NextApiHandler;
@@ -1,6 +1,16 @@
1
- import { AuthServiceError } from '../../core/services/auth-error';
2
- import { assertBearerOnlyActorPolicy, resolveAccessTokenTransportAdapter, } from '../shared/direct-auth-utils';
3
- import { withPagesAuthRoute } from './wrapper';
1
+ import { AuthServiceError } from '../../core/services/auth-error.js';
2
+ import { assertBearerOnlyActorPolicy, resolveAccessTokenTransportAdapter, } from '../shared/direct-auth-utils.js';
3
+ import { withPagesAuthRoute } from './wrapper.js';
4
+ /**
5
+ * Wraps a Next.js Pages API route with access-token authentication and
6
+ * standardized auth/system error handling.
7
+ *
8
+ * Handler output behavior:
9
+ * - Return a non-`undefined` value to send `200` with `res.json(output)`.
10
+ * - Return `undefined` to send `204`.
11
+ * - If your handler already finished the response (for example by calling
12
+ * `res.status(...).json(...)` directly), the wrapper does not overwrite it.
13
+ */
4
14
  export function withPagesProtectedRoute(options) {
5
15
  const accessTokenTransportAdapter = resolveAccessTokenTransportAdapter(options.accessTokenTransport);
6
16
  return withPagesAuthRoute({
@@ -1,4 +1,4 @@
1
- import { buildAuthErrorHttpResponse, buildSystemErrorHttpResponse, } from '../shared/auth-http';
1
+ import { buildAuthErrorHttpResponse, buildSystemErrorHttpResponse, } from '../shared/auth-http.js';
2
2
  export function sendPagesAuthError(res, error, options) {
3
3
  const mapped = buildAuthErrorHttpResponse({
4
4
  error,
@@ -1,6 +1,6 @@
1
- import { isAuthServiceError } from '../../core/services/auth-error';
2
- import { buildPagesAccessTokenTransportInput, getPagesRequestId, } from './request';
3
- import { sendPagesAuthError, sendPagesSystemError } from './response';
1
+ import { isAuthServiceError } from '../../core/services/auth-error.js';
2
+ import { buildPagesAccessTokenTransportInput, getPagesRequestId, } from './request.js';
3
+ import { sendPagesAuthError, sendPagesSystemError } from './response.js';
4
4
  export function withPagesAuthRoute(options) {
5
5
  return async function pagesAuthRoute(req, res) {
6
6
  const requestId = getPagesRequestId(req, options.requestIdHeaderName);
@@ -1,4 +1,4 @@
1
- import { buildAuthRoutePath } from './shared/auth-routes';
1
+ import { buildAuthRoutePath } from './shared/auth-routes.js';
2
2
  function normalizePath(path) {
3
3
  const trimmed = path.trim();
4
4
  if (trimmed.length === 0) {
@@ -1,5 +1,5 @@
1
- import { buildBearerChallengeHeader } from '../../core/http/bearer-challenge';
2
- import { authErrorToHttpStatus, } from '../../core/services/auth-error';
1
+ import { buildBearerChallengeHeader } from '../../core/http/bearer-challenge.js';
2
+ import { authErrorToHttpStatus, } from '../../core/services/auth-error.js';
3
3
  function toBearerChallengeError(code) {
4
4
  return code === 'invalid_client' ? 'invalid_client' : 'invalid_token';
5
5
  }
@@ -1,5 +1,5 @@
1
- import { AuthServiceError } from '../../core/services/auth-error';
2
- import { toSingleString } from './oauth-utils';
1
+ import { AuthServiceError } from '../../core/services/auth-error.js';
2
+ import { toSingleString } from './oauth-utils.js';
3
3
  export const DEFAULT_ACCESS_TOKEN_COOKIE_NAME = 'access_token';
4
4
  export const DEFAULT_REFRESH_TOKEN_COOKIE_NAME = 'refresh_token';
5
5
  export const DEFAULT_CSRF_COOKIE_NAME = 'csrf_token';
@@ -1,4 +1,4 @@
1
- import { AuthServiceError } from '../../core/services/auth-error';
1
+ import { AuthServiceError } from '../../core/services/auth-error.js';
2
2
  function toNonEmptyString(value) {
3
3
  if (Array.isArray(value)) {
4
4
  for (const item of value) {
@@ -1,4 +1,4 @@
1
- import { AuthServiceError, } from '../core/services/auth-error';
1
+ import { AuthServiceError, } from '../core/services/auth-error.js';
2
2
  function buildMissingMetaError(options) {
3
3
  return new AuthServiceError({
4
4
  code: options?.errorCode ?? 'unauthorized',
@@ -1,7 +1,7 @@
1
- export { createInMemoryAccessTokenRevocationAdapter } from './in-memory-access-token-revocation-adapter';
2
- export { createInMemoryAuthorizationCodeAdapter } from './in-memory-authorization-code-adapter';
3
- export { createInMemoryOAuthClientAdapter, } from './in-memory-oauth-client-adapter';
4
- export { createInMemoryPendingAuthRequestAdapter } from './in-memory-pending-auth-request-adapter';
5
- export { createInMemoryRefreshTokenAdapter } from './in-memory-refresh-token-adapter';
6
- export { createInMemorySessionAdapter } from './in-memory-session-adapter';
7
- export { createIncrementingIdFactory, createStepClock } from './test-fixtures';
1
+ export { createInMemoryAccessTokenRevocationAdapter } from './in-memory-access-token-revocation-adapter.js';
2
+ export { createInMemoryAuthorizationCodeAdapter } from './in-memory-authorization-code-adapter.js';
3
+ export { createInMemoryOAuthClientAdapter, } from './in-memory-oauth-client-adapter.js';
4
+ export { createInMemoryPendingAuthRequestAdapter } from './in-memory-pending-auth-request-adapter.js';
5
+ export { createInMemoryRefreshTokenAdapter } from './in-memory-refresh-token-adapter.js';
6
+ export { createInMemorySessionAdapter } from './in-memory-session-adapter.js';
7
+ export { createIncrementingIdFactory, createStepClock } from './test-fixtures.js';
@@ -1,4 +1,4 @@
1
1
  export function createFixedUnixNow(unix) {
2
2
  return () => unix;
3
3
  }
4
- export * from './in-memory/index';
4
+ export * from './in-memory/index.js';