@devorash/node 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}
package/dist/hmac.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Request signing v3 primitives for Node.js (node:crypto).
3
+ * @module @devorash/node
4
+ */
5
+ import { type SigningDirection } from "@devorash/core";
6
+ /** Lowercase hex SHA-256 of exact bytes. */
7
+ export declare function sha256Hex(bytes: Uint8Array): string;
8
+ /** Lowercase hex HMAC-SHA256 of a canonical string, keyed by the secret's ASCII bytes. */
9
+ export declare function hmacHex(secretKey: string, canonical: string): string;
10
+ /**
11
+ * Constant-time comparison of a provided signature with the expected one.
12
+ * The provided value must be exactly 64 lowercase hex characters; it is never
13
+ * decoded leniently.
14
+ */
15
+ export declare function signatureMatches(secretKey: string, canonical: string, provided: string): boolean;
16
+ /** Headers for an outgoing signed request. */
17
+ export declare function signRequest(input: {
18
+ secretKey: string;
19
+ direction: SigningDirection;
20
+ keyId: string;
21
+ orgId: string;
22
+ method: string;
23
+ path: string;
24
+ query?: string;
25
+ body?: Uint8Array;
26
+ }): Record<string, string>;
27
+ //# sourceMappingURL=hmac.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmac.d.ts","sourceRoot":"","sources":["../src/hmac.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAKN,KAAK,gBAAgB,EACrB,MAAM,gBAAgB,CAAA;AAEvB,4CAA4C;AAC5C,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEnD;AAED,0FAA0F;AAC1F,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAIpE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMhG;AAED,8CAA8C;AAC9C,wBAAgB,WAAW,CAAC,KAAK,EAAE;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,gBAAgB,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,UAAU,CAAA;CACjB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBzB"}
package/dist/hmac.js ADDED
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Request signing v3 primitives for Node.js (node:crypto).
3
+ * @module @devorash/node
4
+ */
5
+ import { createHash, createHmac, randomUUID, timingSafeEqual } from "crypto";
6
+ import { SECURITY_HEADERS, SIGNING, SIGNED_HEADER_PATTERNS, buildCanonicalString, } from "@devorash/core";
7
+ /** Lowercase hex SHA-256 of exact bytes. */
8
+ export function sha256Hex(bytes) {
9
+ return createHash("sha256").update(bytes).digest("hex");
10
+ }
11
+ /** Lowercase hex HMAC-SHA256 of a canonical string, keyed by the secret's ASCII bytes. */
12
+ export function hmacHex(secretKey, canonical) {
13
+ return createHmac("sha256", Buffer.from(secretKey, "ascii"))
14
+ .update(Buffer.from(canonical, "ascii"))
15
+ .digest("hex");
16
+ }
17
+ /**
18
+ * Constant-time comparison of a provided signature with the expected one.
19
+ * The provided value must be exactly 64 lowercase hex characters; it is never
20
+ * decoded leniently.
21
+ */
22
+ export function signatureMatches(secretKey, canonical, provided) {
23
+ if (!SIGNED_HEADER_PATTERNS.signature.test(provided))
24
+ return false;
25
+ return timingSafeEqual(Buffer.from(hmacHex(secretKey, canonical), "hex"), Buffer.from(provided, "hex"));
26
+ }
27
+ /** Headers for an outgoing signed request. */
28
+ export function signRequest(input) {
29
+ const body = input.body ?? new Uint8Array();
30
+ const sentAt = String(Math.floor(Date.now() / 1000));
31
+ const requestId = randomUUID();
32
+ const canonical = buildCanonicalString({
33
+ direction: input.direction,
34
+ keyId: input.keyId,
35
+ orgId: input.orgId,
36
+ sentAt,
37
+ requestId,
38
+ method: input.method,
39
+ path: input.path,
40
+ query: input.query ?? "",
41
+ bodySha256: sha256Hex(body),
42
+ });
43
+ return {
44
+ [SECURITY_HEADERS.SIGNATURE_VERSION]: SIGNING.VERSION,
45
+ [SECURITY_HEADERS.KEY_ID]: input.keyId,
46
+ [SECURITY_HEADERS.ORG_ID]: input.orgId,
47
+ [SECURITY_HEADERS.SENT_AT]: sentAt,
48
+ [SECURITY_HEADERS.REQUEST_ID]: requestId,
49
+ [SECURITY_HEADERS.SIGNATURE]: hmacHex(input.secretKey, canonical),
50
+ ...(body.byteLength > 0 ? { "Content-Type": "application/json" } : {}),
51
+ };
52
+ }
53
+ //# sourceMappingURL=hmac.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmac.js","sourceRoot":"","sources":["../src/hmac.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AAC5E,OAAO,EACN,gBAAgB,EAChB,OAAO,EACP,sBAAsB,EACtB,oBAAoB,GAEpB,MAAM,gBAAgB,CAAA;AAEvB,4CAA4C;AAC5C,MAAM,UAAU,SAAS,CAAC,KAAiB;IAC1C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACxD,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,OAAO,CAAC,SAAiB,EAAE,SAAiB;IAC3D,OAAO,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;SAC1D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;SACvC,MAAM,CAAC,KAAK,CAAC,CAAA;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,SAAiB,EAAE,QAAgB;IACtF,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAA;IAClE,OAAO,eAAe,CACrB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,EACjD,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAC5B,CAAA;AACF,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,WAAW,CAAC,KAS3B;IACA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,IAAI,UAAU,EAAE,CAAA;IAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAA;IACpD,MAAM,SAAS,GAAG,UAAU,EAAE,CAAA;IAC9B,MAAM,SAAS,GAAG,oBAAoB,CAAC;QACtC,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM;QACN,SAAS;QACT,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;QACxB,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAA;IACF,OAAO;QACN,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC,OAAO;QACrD,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,KAAK;QACtC,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,KAAK;QACtC,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM;QAClC,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,SAAS;QACxC,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC;QACjE,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtE,CAAA;AACF,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Devora Node.js Backend SDK
3
+ *
4
+ * Secure backend SDK for enabling impersonation in your Node.js application.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { devoraSDK, DEVORA_ENDPOINTS } from "@devorash/node";
9
+ *
10
+ * const sdk = devoraSDK({
11
+ * apiKey: process.env.DEVORA_API_KEY!,
12
+ * secretKey: process.env.DEVORA_SECRET_KEY!,
13
+ * orgId: "your-org-id",
14
+ * });
15
+ *
16
+ * const routes = [
17
+ * sdk.register(DEVORA_ENDPOINTS.USER_SEARCH, async (req) => {
18
+ * const { term } = req.query;
19
+ * return { users: await searchUsers(term) };
20
+ * }),
21
+ * sdk.register(DEVORA_ENDPOINTS.IMPERSONATE, async (req) => {
22
+ * const { id } = req.params;
23
+ * return { token: await generateToken(id), data: {} };
24
+ * }),
25
+ * sdk.register(DEVORA_ENDPOINTS.TERMINATE, async (req) => {
26
+ * const { id } = req.params;
27
+ * await invalidateSession(id);
28
+ * return { success: true };
29
+ * }),
30
+ * ];
31
+ * ```
32
+ *
33
+ * @packageDocumentation
34
+ * @module @devorash/node
35
+ */
36
+ export { devoraSDK, resolveEnvironment } from "./sdk.js";
37
+ export { sha256Hex, signRequest } from "./hmac.js";
38
+ export { controlPlaneFetch, readBoundedJsonObject, ControlPlaneResponseError, MAX_CONTROL_RESPONSE_BYTES, } from "./transport.js";
39
+ export { processRequest, createGenericHandler, stripMountPath, DEFAULT_MAX_BODY_SIZE, type AdapterRequest, } from "./handler.js";
40
+ export { createImpersonationGuard, validateImpersonationContext, resolveImpersonationIdentities, isWriteOperation, } from "./middleware.js";
41
+ export type { ImpersonationContext, ImpersonationContextResult, ImpersonationGuardOptions, MiddlewareRequest, MiddlewareResponse, MiddlewareNext, ScopeEndpoint, } from "./middleware.js";
42
+ export { createScopeConfigFetcher } from "./scope-config.js";
43
+ export type { ScopeConfig, ScopeConfigFetcherOptions } from "./scope-config.js";
44
+ export { InMemoryReplayStore } from "./replay-store.js";
45
+ export type { ReplayStore } from "./replay-store.js";
46
+ export type { NodeBackendSDKConfig, Logger, SDKRoute, DevoraBackendSDK, RegisterOptions, SDKStats, SessionStatusResult, ValidationResult, SignedRequestInput, FrameworkAdapter, DevoraEnvironment, } from "./types.js";
47
+ export { DEVORA_ENDPOINTS, ENDPOINT_METHODS, PROTECTED_ENDPOINTS, SECURITY_HEADERS, SDK_DEFAULTS, SDK_VERSION, ERROR_CODES, DevoraSDKError, DevoraSecurityError, DevoraValidationError, DevoraConfigError, matchPath, createSuccessResponse, createErrorResponse, } from "@devorash/core";
48
+ export type { DevoraRequest, DevoraResponse, DevoraUser, UserSearchRequest, UserSearchResponse, ImpersonationScope, ImpersonationDuration, DevoraImpersonationContext, ImpersonationStartRequest, ImpersonationStartResponse, ImpersonationTerminateRequest, ImpersonationTerminateResponse, RouteHandler, RouteDefinition, ConnectionTestResponse, HealthCheckResponse, } from "@devorash/core";
49
+ export { resolveBrowserSession, BROWSER_SESSION_RESPONSE_HEADERS, type ResolveBrowserSessionInput, } from "./browser-session.js";
50
+ export { BROWSER_SESSION_BRIDGE } from "@devorash/core";
51
+ export type { SessionBridgeResult, BrowserResumeCode } from "@devorash/core";
52
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAGxD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EACN,iBAAiB,EACjB,qBAAqB,EACrB,yBAAyB,EACzB,0BAA0B,GAC1B,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACN,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,KAAK,cAAc,GACnB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACN,wBAAwB,EACxB,4BAA4B,EAC5B,8BAA8B,EAC9B,gBAAgB,GAChB,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACX,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,aAAa,GACb,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,YAAY,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAG/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAGpD,YAAY,EACX,oBAAoB,EACpB,MAAM,EACN,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,GACjB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAEN,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EAEnB,gBAAgB,EAEhB,YAAY,EACZ,WAAW,EAEX,WAAW,EAEX,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EAEjB,SAAS,EACT,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,gBAAgB,CAAA;AAGvB,YAAY,EACX,aAAa,EACb,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,0BAA0B,EAC1B,yBAAyB,EACzB,0BAA0B,EAC1B,6BAA6B,EAC7B,8BAA8B,EAC9B,YAAY,EACZ,eAAe,EACf,sBAAsB,EACtB,mBAAmB,GACnB,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACN,qBAAqB,EACrB,gCAAgC,EAChC,KAAK,0BAA0B,GAC/B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Devora Node.js Backend SDK
3
+ *
4
+ * Secure backend SDK for enabling impersonation in your Node.js application.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { devoraSDK, DEVORA_ENDPOINTS } from "@devorash/node";
9
+ *
10
+ * const sdk = devoraSDK({
11
+ * apiKey: process.env.DEVORA_API_KEY!,
12
+ * secretKey: process.env.DEVORA_SECRET_KEY!,
13
+ * orgId: "your-org-id",
14
+ * });
15
+ *
16
+ * const routes = [
17
+ * sdk.register(DEVORA_ENDPOINTS.USER_SEARCH, async (req) => {
18
+ * const { term } = req.query;
19
+ * return { users: await searchUsers(term) };
20
+ * }),
21
+ * sdk.register(DEVORA_ENDPOINTS.IMPERSONATE, async (req) => {
22
+ * const { id } = req.params;
23
+ * return { token: await generateToken(id), data: {} };
24
+ * }),
25
+ * sdk.register(DEVORA_ENDPOINTS.TERMINATE, async (req) => {
26
+ * const { id } = req.params;
27
+ * await invalidateSession(id);
28
+ * return { success: true };
29
+ * }),
30
+ * ];
31
+ * ```
32
+ *
33
+ * @packageDocumentation
34
+ * @module @devorash/node
35
+ */
36
+ // Main SDK
37
+ export { devoraSDK, resolveEnvironment } from "./sdk.js";
38
+ // HMAC utilities
39
+ export { sha256Hex, signRequest } from "./hmac.js";
40
+ export { controlPlaneFetch, readBoundedJsonObject, ControlPlaneResponseError, MAX_CONTROL_RESPONSE_BYTES, } from "./transport.js";
41
+ // Request handler
42
+ export { processRequest, createGenericHandler, stripMountPath, DEFAULT_MAX_BODY_SIZE, } from "./handler.js";
43
+ // Impersonation middleware
44
+ export { createImpersonationGuard, validateImpersonationContext, resolveImpersonationIdentities, isWriteOperation, } from "./middleware.js";
45
+ // Scope configuration
46
+ export { createScopeConfigFetcher } from "./scope-config.js";
47
+ // Persistent replay protection
48
+ export { InMemoryReplayStore } from "./replay-store.js";
49
+ // Re-export commonly used items from core
50
+ export {
51
+ // Endpoints
52
+ DEVORA_ENDPOINTS, ENDPOINT_METHODS, PROTECTED_ENDPOINTS,
53
+ // Security headers
54
+ SECURITY_HEADERS,
55
+ // Defaults
56
+ SDK_DEFAULTS, SDK_VERSION,
57
+ // Error codes
58
+ ERROR_CODES,
59
+ // Errors
60
+ DevoraSDKError, DevoraSecurityError, DevoraValidationError, DevoraConfigError,
61
+ // Utilities
62
+ matchPath, createSuccessResponse, createErrorResponse, } from "@devorash/core";
63
+ // Browser-session bridge (server side)
64
+ export { resolveBrowserSession, BROWSER_SESSION_RESPONSE_HEADERS, } from "./browser-session.js";
65
+ export { BROWSER_SESSION_BRIDGE } from "@devorash/core";
66
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,WAAW;AACX,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAExD,iBAAiB;AACjB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EACN,iBAAiB,EACjB,qBAAqB,EACrB,yBAAyB,EACzB,0BAA0B,GAC1B,MAAM,gBAAgB,CAAA;AAEvB,kBAAkB;AAClB,OAAO,EACN,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,qBAAqB,GAErB,MAAM,cAAc,CAAA;AAErB,2BAA2B;AAC3B,OAAO,EACN,wBAAwB,EACxB,4BAA4B,EAC5B,8BAA8B,EAC9B,gBAAgB,GAChB,MAAM,iBAAiB,CAAA;AAWxB,sBAAsB;AACtB,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAG5D,+BAA+B;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAkBvD,0CAA0C;AAC1C,OAAO;AACN,YAAY;AACZ,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB;AACnB,mBAAmB;AACnB,gBAAgB;AAChB,WAAW;AACX,YAAY,EACZ,WAAW;AACX,cAAc;AACd,WAAW;AACX,SAAS;AACT,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB;AACjB,YAAY;AACZ,SAAS,EACT,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,gBAAgB,CAAA;AAsBvB,uCAAuC;AACvC,OAAO,EACN,qBAAqB,EACrB,gCAAgC,GAEhC,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Impersonation scope enforcement middleware
3
+ *
4
+ * Provides defense-in-depth by validating impersonation scope on the backend,
5
+ * blocking write operations in read-only mode even if the frontend SDK is bypassed.
6
+ *
7
+ * @module @devorash/node
8
+ */
9
+ import { type ImpersonationScope } from "@devorash/core";
10
+ import type { DevoraBackendSDK } from "./types.js";
11
+ /**
12
+ * Impersonation context extracted from JWT or request
13
+ */
14
+ export interface ImpersonationContext {
15
+ /** Whether this is an impersonation session */
16
+ isImpersonation: boolean;
17
+ /**
18
+ * The Devora agent actually performing the action. Optional only because
19
+ * `impersonator` (the field name the SDK handler emits) is accepted as an
20
+ * equivalent source; one of the two must be present.
21
+ */
22
+ actor?: {
23
+ id: string;
24
+ };
25
+ /**
26
+ * The authenticated customer user being represented. `targetUser` is
27
+ * accepted as an equivalent source.
28
+ */
29
+ subject?: {
30
+ id: string;
31
+ };
32
+ /** Access scope: "read" or "write" */
33
+ scope: ImpersonationScope;
34
+ /** Devora session ID */
35
+ sessionId?: string;
36
+ /** This is always a distinct customer impersonation session, never customer MFA. */
37
+ authMethod: "devora_impersonation";
38
+ /** How the Devora request was authorized. */
39
+ authorizationSource: "standard" | "self_approved" | "self_approved_read" | "break_glass";
40
+ /** Whether the customer backend permitted recording for this exact session. */
41
+ recordingAllowed: boolean;
42
+ /**
43
+ * When the session expires.
44
+ *
45
+ * IMPORTANT: This should be a Unix timestamp in MILLISECONDS (matching JavaScript's Date.now()).
46
+ * If your JWT uses seconds (standard Unix timestamp), multiply by 1000 when extracting.
47
+ *
48
+ * Example:
49
+ * ```typescript
50
+ * getImpersonationContext: (req) => ({
51
+ * ...req.user.devora,
52
+ * // Convert seconds to milliseconds if needed
53
+ * expiresAt: req.user.devora.expiresAt * 1000,
54
+ * })
55
+ * ```
56
+ */
57
+ expiresAt?: number;
58
+ /** Information about the impersonator (agent) */
59
+ impersonator?: {
60
+ id: string;
61
+ email?: string;
62
+ name?: string;
63
+ };
64
+ /** Information about the impersonated customer user */
65
+ targetUser?: {
66
+ id: string;
67
+ email?: string;
68
+ name?: string;
69
+ };
70
+ }
71
+ /**
72
+ * What a context extractor may return: the context, or `null`/`undefined` for
73
+ * ordinary (non-impersonated) traffic. Async extractors are awaited.
74
+ */
75
+ export type ImpersonationContextResult = ImpersonationContext | null | undefined | Promise<ImpersonationContext | null | undefined>;
76
+ /** Resolve the canonical actor/subject ids from either field-name convention. */
77
+ export declare function resolveImpersonationIdentities(context: Pick<ImpersonationContext, "actor" | "subject" | "impersonator" | "targetUser">): {
78
+ actorId?: string;
79
+ subjectId?: string;
80
+ };
81
+ /**
82
+ * Generic request interface for middleware
83
+ */
84
+ export interface MiddlewareRequest {
85
+ method: string;
86
+ path: string;
87
+ url?: string;
88
+ originalUrl?: string;
89
+ /** Express: the mount path of the router running the guard. */
90
+ baseUrl?: string;
91
+ /** Request headers (lower-case names); used to detect method-override headers. */
92
+ headers?: Record<string, string | string[] | undefined>;
93
+ /**
94
+ * Origin-form targets (`/path?query`, full client-visible path) the framework
95
+ * dispatches on after any rewrites. Adapters set this; the default is
96
+ * `baseUrl + url`. Safe-read allow rules must match every routed target and
97
+ * the original target; deny rules match any of them.
98
+ */
99
+ routedUrls?: string[];
100
+ /**
101
+ * Additional deny-only views of the same request (for example a path with a
102
+ * framework base path or locale prefix removed). They can only block.
103
+ */
104
+ aliasUrls?: string[];
105
+ }
106
+ /**
107
+ * Generic response interface for middleware
108
+ */
109
+ export interface MiddlewareResponse {
110
+ status: (code: number) => MiddlewareResponse;
111
+ json: (body: unknown) => void;
112
+ }
113
+ /**
114
+ * Next function type for middleware
115
+ */
116
+ export type MiddlewareNext = () => void | Promise<void>;
117
+ export type { ScopeEndpoint } from "./scope-config.js";
118
+ /**
119
+ * Options for the impersonation guard middleware
120
+ */
121
+ export interface ImpersonationGuardOptions<TRequest = MiddlewareRequest> {
122
+ /** Initialized Devora SDK used to load the centrally managed policy. */
123
+ sdk: DevoraBackendSDK;
124
+ /**
125
+ * Function to extract impersonation context from the request, typically from
126
+ * the authenticated session or JWT claims. Return `null` for ordinary traffic.
127
+ * May be async. Any other non-context value fails closed with a 500.
128
+ */
129
+ getImpersonationContext: (req: TRequest) => ImpersonationContextResult;
130
+ /**
131
+ * Callback when a request is blocked.
132
+ * Useful for logging or alerting. Errors it throws are ignored.
133
+ */
134
+ onBlocked?: (req: TRequest, context: ImpersonationContext) => void;
135
+ /**
136
+ * Custom response when a request is blocked.
137
+ * Defaults to a standard 403 response.
138
+ */
139
+ blockedResponse?: {
140
+ status?: number;
141
+ message?: string;
142
+ errorCode?: string;
143
+ };
144
+ /**
145
+ * Whether to show warnings in console when requests are blocked.
146
+ * Defaults to true in development.
147
+ */
148
+ showWarnings?: boolean;
149
+ /**
150
+ * Enforce server-side session liveness in addition to scope and expiry. When true, the
151
+ * guard asks Devora whether the request's session is still live and blocks it if the
152
+ * session was terminated or revoked early (before its hard expiry). On by default.
153
+ *
154
+ * Requires `getImpersonationContext` to return a `sessionId`. Adds at most one cached
155
+ * lookup per session per `livenessCacheTtlMs`.
156
+ */
157
+ enforceLiveness?: boolean;
158
+ /**
159
+ * How long, in milliseconds, to cache a liveness result per session. Lower values detect
160
+ * early termination faster at the cost of more lookups. Default 5000 (5 seconds).
161
+ */
162
+ livenessCacheTtlMs?: number;
163
+ /**
164
+ * Behavior when Devora cannot be reached for a liveness check:
165
+ * - "allow": fall back to scope and expiry enforcement (local development only).
166
+ * - "deny" (default): fail closed — block impersonated requests until Devora is reachable.
167
+ */
168
+ onLivenessUnavailable?: "allow" | "deny";
169
+ /**
170
+ * Path where you mounted the browser-session bridge handler, for example
171
+ * `/api/devora/browser-session`. When set, a `POST` to exactly this path is
172
+ * allowed in read scope (it mints a resume code, it is not a customer write).
173
+ * The blocklist and `isImpersonationAllowed` still apply. Off by default:
174
+ * only set it when the bridge is actually mounted at that path.
175
+ */
176
+ bridgePath?: string;
177
+ /**
178
+ * Semantic authorization hook for application-specific high-risk actions.
179
+ * It runs after the static blocklist and before scope allowlisting. Returning
180
+ * false blocks the impersonated request; normal customer traffic is untouched.
181
+ */
182
+ isImpersonationAllowed?: (req: TRequest, context: ImpersonationContext) => boolean | Promise<boolean>;
183
+ }
184
+ /**
185
+ * Create an impersonation guard middleware
186
+ *
187
+ * This middleware validates impersonation scope and blocks write operations
188
+ * in read-only mode. It provides defense-in-depth protection on the backend.
189
+ *
190
+ * Every request target the framework may dispatch on is judged: the original
191
+ * target, the effective target after rewrites/mounts, and any deny-only aliases.
192
+ * Policy patterns match the full client-visible path, including mount prefixes.
193
+ *
194
+ * Enforcement Priority:
195
+ * 1. Check blacklist first - if match, BLOCK (regardless of scope)
196
+ * 2. Run the application's isImpersonationAllowed hook
197
+ * 3. If scope is "write", ALLOW (blacklist already checked)
198
+ * 4. If scope is "read" and write method, check whitelist
199
+ * 5. If not in whitelist, BLOCK
200
+ */
201
+ export declare function createImpersonationGuard<TRequest extends MiddlewareRequest = MiddlewareRequest>(options: ImpersonationGuardOptions<TRequest>): (req: TRequest, res: MiddlewareResponse, next: MiddlewareNext) => Promise<void>;
202
+ /**
203
+ * Validate impersonation context
204
+ *
205
+ * Utility function to check if impersonation context is valid and not expired.
206
+ * Types are checked strictly; nothing is coerced.
207
+ */
208
+ export declare function validateImpersonationContext(context: ImpersonationContext | undefined | null): {
209
+ valid: boolean;
210
+ expired?: boolean;
211
+ error?: string;
212
+ };
213
+ /**
214
+ * Check if a request method is a write operation
215
+ *
216
+ * @deprecated Use isWriteMethod from @devorash/core instead
217
+ */
218
+ export declare function isWriteOperation(method: string): boolean;
219
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}