@burdenoff/be-sdk 2026.528.2 → 2026.529.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.
- package/dist/{chunk-XUU5IBVU.js → chunk-VWNL2O3G.js} +60 -3
- package/dist/chunk-VWNL2O3G.js.map +1 -0
- package/dist/index.js +2 -2
- package/dist/server/index.d.ts +3 -1
- package/dist/server/index.js +7 -4
- package/dist/server/index.js.map +1 -1
- package/dist/workspace-guard-3JLBFAMH.js +5 -0
- package/dist/{workspace-guard-3TKZULCO.js.map → workspace-guard-3JLBFAMH.js.map} +1 -1
- package/package.json +1 -1
- package/dist/chunk-XUU5IBVU.js.map +0 -1
- package/dist/workspace-guard-3TKZULCO.js +0 -5
|
@@ -68,6 +68,19 @@ var TECHNICAL_MESSAGE_PATTERNS = [
|
|
|
68
68
|
/Build failed \(exit \d+\)/i,
|
|
69
69
|
/JSON\.stringify/i
|
|
70
70
|
];
|
|
71
|
+
var GRAPHQL_VALIDATION_MESSAGE_PATTERNS = [
|
|
72
|
+
/^Syntax Error:/i,
|
|
73
|
+
/^Cannot query field\b/i,
|
|
74
|
+
/^Cannot return null for non-nullable field\b/i,
|
|
75
|
+
/^Unknown (argument|directive|type)\b/i,
|
|
76
|
+
/^Variable "\$[^\"]+" got invalid value/i,
|
|
77
|
+
/^Field "[^"]+" of required type/i,
|
|
78
|
+
/^Field "[^"]+" must not have a selection/i,
|
|
79
|
+
/^Field "[^"]+" must have a selection/i,
|
|
80
|
+
/^Fragment "[^"]+" cannot be spread here/i,
|
|
81
|
+
/^There can be only one/i,
|
|
82
|
+
/Did you mean /i
|
|
83
|
+
];
|
|
71
84
|
function isRecord(value) {
|
|
72
85
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
73
86
|
}
|
|
@@ -107,6 +120,9 @@ function normalizeCode(code) {
|
|
|
107
120
|
__name(normalizeCode, "normalizeCode");
|
|
108
121
|
function inferCodeFromMessage(message) {
|
|
109
122
|
const lower = message.toLowerCase();
|
|
123
|
+
if (GRAPHQL_VALIDATION_MESSAGE_PATTERNS.some((pattern) => pattern.test(message))) {
|
|
124
|
+
return "BAD_USER_INPUT";
|
|
125
|
+
}
|
|
110
126
|
if (lower.includes("unauthenticated") || lower.includes("not authenticated") || lower.includes("authentication required") || lower.includes("unauthorized") || lower.includes("please sign in") || lower.includes("sign in to")) {
|
|
111
127
|
return "UNAUTHENTICATED";
|
|
112
128
|
}
|
|
@@ -164,6 +180,7 @@ function isLikelyTechnicalMessage(message) {
|
|
|
164
180
|
if (message.length > 220) return true;
|
|
165
181
|
if (message.includes("\n")) return true;
|
|
166
182
|
if (message.includes("{") && message.includes("}")) return true;
|
|
183
|
+
if (GRAPHQL_VALIDATION_MESSAGE_PATTERNS.some((pattern) => pattern.test(message))) return true;
|
|
167
184
|
return TECHNICAL_MESSAGE_PATTERNS.some((pattern) => pattern.test(message));
|
|
168
185
|
}
|
|
169
186
|
__name(isLikelyTechnicalMessage, "isLikelyTechnicalMessage");
|
|
@@ -281,12 +298,52 @@ function toUserFacingGraphQLError(error, options = {}) {
|
|
|
281
298
|
}
|
|
282
299
|
__name(toUserFacingGraphQLError, "toUserFacingGraphQLError");
|
|
283
300
|
function normalizeExecutionResultErrors(result, options = {}) {
|
|
301
|
+
if (Array.isArray(result)) {
|
|
302
|
+
result.forEach((entry) => normalizeExecutionResultErrors(entry, options));
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
284
305
|
if (!isRecord(result)) return;
|
|
285
306
|
const errors = result["errors"];
|
|
286
307
|
if (!Array.isArray(errors) || errors.length === 0) return;
|
|
287
308
|
result["errors"] = errors.map((error) => toUserFacingGraphQLError(error, options));
|
|
288
309
|
}
|
|
289
310
|
__name(normalizeExecutionResultErrors, "normalizeExecutionResultErrors");
|
|
311
|
+
function normalizeGraphQLResponsePayload(payload, options = {}) {
|
|
312
|
+
normalizeExecutionResultErrors(payload, options);
|
|
313
|
+
return payload;
|
|
314
|
+
}
|
|
315
|
+
__name(normalizeGraphQLResponsePayload, "normalizeGraphQLResponsePayload");
|
|
316
|
+
async function normalizeGraphQLResponse(response, options = {}) {
|
|
317
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
318
|
+
if (!contentType.toLowerCase().includes("json")) {
|
|
319
|
+
return response;
|
|
320
|
+
}
|
|
321
|
+
const text = await response.text();
|
|
322
|
+
if (!text) {
|
|
323
|
+
return new Response(text, {
|
|
324
|
+
status: response.status,
|
|
325
|
+
statusText: response.statusText,
|
|
326
|
+
headers: response.headers
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
let payload;
|
|
330
|
+
try {
|
|
331
|
+
payload = JSON.parse(text);
|
|
332
|
+
} catch {
|
|
333
|
+
return new Response(text, {
|
|
334
|
+
status: response.status,
|
|
335
|
+
statusText: response.statusText,
|
|
336
|
+
headers: response.headers
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
normalizeGraphQLResponsePayload(payload, options);
|
|
340
|
+
return new Response(JSON.stringify(payload), {
|
|
341
|
+
status: response.status,
|
|
342
|
+
statusText: response.statusText,
|
|
343
|
+
headers: response.headers
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
__name(normalizeGraphQLResponse, "normalizeGraphQLResponse");
|
|
290
347
|
function createHumanReadableErrorPlugin(options = {}) {
|
|
291
348
|
return {
|
|
292
349
|
onExecute() {
|
|
@@ -444,6 +501,6 @@ function createWorkspaceGuardPlugin(config) {
|
|
|
444
501
|
}
|
|
445
502
|
__name(createWorkspaceGuardPlugin, "createWorkspaceGuardPlugin");
|
|
446
503
|
|
|
447
|
-
export { UserFacingGraphQLError, createHttpErrorResponse, createHumanReadableErrorPlugin, createWorkspaceGuardPlugin, formatHttpError, normalizeError, normalizeExecutionResultErrors, toUserFacingGraphQLError };
|
|
448
|
-
//# sourceMappingURL=chunk-
|
|
449
|
-
//# sourceMappingURL=chunk-
|
|
504
|
+
export { UserFacingGraphQLError, createHttpErrorResponse, createHumanReadableErrorPlugin, createWorkspaceGuardPlugin, formatHttpError, normalizeError, normalizeExecutionResultErrors, normalizeGraphQLResponse, normalizeGraphQLResponsePayload, toUserFacingGraphQLError };
|
|
505
|
+
//# sourceMappingURL=chunk-VWNL2O3G.js.map
|
|
506
|
+
//# sourceMappingURL=chunk-VWNL2O3G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/errors.ts","../src/server/workspace-guard.ts"],"names":["DEFAULT_ERROR_CODE","DEFAULT_HTTP_STATUS","DEFAULT_USER_MESSAGES","BAD_REQUEST","BAD_USER_INPUT","CAPTCHA_FAILED","CAPTCHA_REQUIRED","COMPLEXITY_TOO_HIGH","CONFLICT","FORBIDDEN","INTERNAL_SERVER_ERROR","INVALID_PASSWORD","NOT_FOUND","PERMISSION_DENIED","QUOTA_EXCEEDED","QUOTA_EXHAUSTED","RATE_LIMITED","RESOURCE_CAP_EXCEEDED","STORAGE_QUOTA_EXCEEDED","TIMEOUT","UNAUTHENTICATED","VALIDATION_ERROR","WORKSPACE_REQUIRED","DEFAULT_STATUS_BY_CODE","SENSITIVE_EXTENSION_KEYS","Set","TECHNICAL_MESSAGE_PATTERNS","GRAPHQL_VALIDATION_MESSAGE_PATTERNS","isRecord","value","Array","isArray","readString","record","key","trim","length","readExtensions","error","extensions","readOriginalError","GraphQLError","originalError","Error","undefined","sanitizeExtensions","sanitized","Object","entries","has","normalizeCode","code","replace","toUpperCase","inferCodeFromMessage","message","lower","toLowerCase","some","pattern","test","includes","inferCode","extensionCode","originalCode","directCode","readErrorMessage","isLikelyTechnicalMessage","readExplicitUserMessage","resolveUserMessage","explicit","fallback","resolveTechnicalMessage","options","environment","serviceName","readHttpStatus","http","normalizeError","originalExtensions","directExtensions","mergedExtensions","userMessage","technicalMessage","status","UserFacingGraphQLError","details","httpStatus","cause","name","toUserFacingGraphQLError","normalized","nodes","source","positions","path","normalizeExecutionResultErrors","result","forEach","entry","errors","map","normalizeGraphQLResponsePayload","payload","normalizeGraphQLResponse","response","contentType","headers","get","text","Response","statusText","JSON","parse","stringify","createHumanReadableErrorPlugin","onExecute","onExecuteDone","formatHttpError","body","createHttpErrorResponse","formatted","WorkspaceRequiredError","isFieldPublic","field","directives","astNode","dir","args","arguments","arg","kind","resolveOperationType","document","operationName","defs","definitions","def","operation","allRootFieldsPublic","schema","opType","rootType","getMutationType","getSubscriptionType","getQueryType","fields","getFields","opDef","find","d","selections","selectionSet","sel","fieldName","startsWith","fieldDef","createWorkspaceGuardPlugin","config","enabled","whitelistedOperations","allowPublicDirective","errorMessage","logger","info","context","contextValue","workspaceId","workspace","id","headerWorkspaceId","request","warn"],"mappings":"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","file":"chunk-VWNL2O3G.js","sourcesContent":["import { GraphQLError } from 'graphql';\n\nimport type { YogaPlugin } from './types.js';\n\nexport interface UserFacingErrorOptions {\n code: string;\n userMessage: string;\n technicalMessage?: string;\n details?: Record<string, unknown>;\n httpStatus?: number;\n cause?: Error;\n}\n\nexport interface ErrorNormalizationOptions {\n serviceName?: string;\n environment?: string;\n}\n\nexport interface NormalizedErrorState {\n code: string;\n userMessage: string;\n technicalMessage: string;\n extensions: Record<string, unknown>;\n status: number;\n}\n\nexport interface HttpErrorPayload {\n error: string;\n message: string;\n userMessage: string;\n technicalMessage: string;\n code: string;\n extensions: Record<string, unknown>;\n}\n\nexport interface HttpErrorResult {\n status: number;\n body: HttpErrorPayload;\n}\n\nconst DEFAULT_ERROR_CODE = 'INTERNAL_SERVER_ERROR';\nconst DEFAULT_HTTP_STATUS = 500;\n\nconst DEFAULT_USER_MESSAGES: Record<string, string> = {\n BAD_REQUEST: 'Please check the request and try again.',\n BAD_USER_INPUT: 'Please check the information and try again.',\n CAPTCHA_FAILED: 'The verification failed. Please try again.',\n CAPTCHA_REQUIRED: 'Please complete the verification to continue.',\n COMPLEXITY_TOO_HIGH: 'This request is too large to process. Please simplify it and try again.',\n CONFLICT: 'This change conflicts with existing data. Please refresh and try again.',\n FORBIDDEN: 'You do not have permission to do that.',\n INTERNAL_SERVER_ERROR: 'Something went wrong. Please try again.',\n INVALID_PASSWORD: 'The password you entered is incorrect.',\n NOT_FOUND: 'We could not find the requested item.',\n PERMISSION_DENIED: 'You do not have permission to do that.',\n QUOTA_EXCEEDED: \"You've reached your usage limit.\",\n QUOTA_EXHAUSTED: \"You've reached your usage limit.\",\n RATE_LIMITED: 'Too many requests. Please wait a moment and try again.',\n RESOURCE_CAP_EXCEEDED: \"You've reached your plan limit. Upgrade your plan to continue.\",\n STORAGE_QUOTA_EXCEEDED: \"You've reached your storage limit. Upgrade your plan to continue.\",\n TIMEOUT: 'The request took too long. Please try again.',\n UNAUTHENTICATED: 'Please sign in to continue.',\n VALIDATION_ERROR: 'Please check the information and try again.',\n WORKSPACE_REQUIRED: 'Please choose a workspace and try again.',\n};\n\nconst DEFAULT_STATUS_BY_CODE: Record<string, number> = {\n BAD_REQUEST: 400,\n BAD_USER_INPUT: 400,\n CAPTCHA_FAILED: 400,\n CAPTCHA_REQUIRED: 400,\n COMPLEXITY_TOO_HIGH: 400,\n CONFLICT: 409,\n FORBIDDEN: 403,\n INVALID_PASSWORD: 400,\n NOT_FOUND: 404,\n PERMISSION_DENIED: 403,\n QUOTA_EXCEEDED: 429,\n QUOTA_EXHAUSTED: 429,\n RATE_LIMITED: 429,\n RESOURCE_CAP_EXCEEDED: 429,\n STORAGE_QUOTA_EXCEEDED: 429,\n TIMEOUT: 504,\n UNAUTHENTICATED: 401,\n VALIDATION_ERROR: 400,\n WORKSPACE_REQUIRED: 403,\n};\n\nconst SENSITIVE_EXTENSION_KEYS = new Set(['exception', 'originalError', 'stack', 'stacktrace']);\n\nconst TECHNICAL_MESSAGE_PATTERNS = [\n /\\bprisma\\b/i,\n /\\bsql\\b/i,\n /\\bconstraint\\b/i,\n /\\bstack\\b/i,\n /\\bundefined\\b/i,\n /\\bnull\\b/i,\n /\\bECONN[A-Z_]*\\b/,\n /\\bETIMEDOUT\\b/,\n /\\bENOTFOUND\\b/,\n /\\bP\\d{4}\\b/,\n /Cannot (read|set|find|access)/i,\n /Build failed \\(exit \\d+\\)/i,\n /JSON\\.stringify/i,\n];\n\nconst GRAPHQL_VALIDATION_MESSAGE_PATTERNS = [\n /^Syntax Error:/i,\n /^Cannot query field\\b/i,\n /^Cannot return null for non-nullable field\\b/i,\n /^Unknown (argument|directive|type)\\b/i,\n /^Variable \"\\$[^\\\"]+\" got invalid value/i,\n /^Field \"[^\"]+\" of required type/i,\n /^Field \"[^\"]+\" must not have a selection/i,\n /^Field \"[^\"]+\" must have a selection/i,\n /^Fragment \"[^\"]+\" cannot be spread here/i,\n /^There can be only one/i,\n /Did you mean /i,\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readString(record: Record<string, unknown>, key: string): string | null {\n const value = record[key];\n return typeof value === 'string' && value.trim().length > 0 ? value : null;\n}\n\nfunction readExtensions(error: unknown): Record<string, unknown> {\n if (!isRecord(error)) return {};\n const extensions = error['extensions'];\n return isRecord(extensions) ? extensions : {};\n}\n\nfunction readOriginalError(error: unknown): Error | undefined {\n if (error instanceof GraphQLError && error.originalError instanceof Error) {\n return error.originalError;\n }\n return undefined;\n}\n\nfunction sanitizeExtensions(extensions: Record<string, unknown>): Record<string, unknown> {\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(extensions)) {\n if (!SENSITIVE_EXTENSION_KEYS.has(key)) {\n sanitized[key] = value;\n }\n }\n return sanitized;\n}\n\nfunction normalizeCode(code: string | null): string {\n if (!code) return DEFAULT_ERROR_CODE;\n return code\n .trim()\n .replace(/[\\s-]+/g, '_')\n .toUpperCase();\n}\n\nfunction inferCodeFromMessage(message: string): string {\n const lower = message.toLowerCase();\n\n if (GRAPHQL_VALIDATION_MESSAGE_PATTERNS.some((pattern) => pattern.test(message))) {\n return 'BAD_USER_INPUT';\n }\n\n if (\n lower.includes('unauthenticated') ||\n lower.includes('not authenticated') ||\n lower.includes('authentication required') ||\n lower.includes('unauthorized') ||\n lower.includes('please sign in') ||\n lower.includes('sign in to')\n ) {\n return 'UNAUTHENTICATED';\n }\n\n if (lower.includes('workspace context') || lower.includes('switch to a workspace')) {\n return 'WORKSPACE_REQUIRED';\n }\n\n if (\n lower.includes('forbidden') ||\n lower.includes('access denied') ||\n lower.includes('permission denied') ||\n lower.includes('not authorized')\n ) {\n return 'FORBIDDEN';\n }\n\n if (lower.includes('not found') || lower.includes('disappeared')) {\n return 'NOT_FOUND';\n }\n\n if (lower.includes('already exists') || lower.includes('already taken') || lower.includes('conflict')) {\n return 'CONFLICT';\n }\n\n if (lower.includes('quota') || lower.includes('cap exceeded') || lower.includes('limit reached')) {\n return 'QUOTA_EXCEEDED';\n }\n\n if (lower.includes('timeout') || lower.includes('timed out')) {\n return 'TIMEOUT';\n }\n\n if (\n lower.includes('required') ||\n lower.includes('invalid') ||\n lower.includes('missing') ||\n lower.includes('unsupported')\n ) {\n return 'BAD_USER_INPUT';\n }\n\n return DEFAULT_ERROR_CODE;\n}\n\nfunction inferCode(error: unknown, extensions: Record<string, unknown>, originalError: Error | undefined): string {\n const extensionCode = typeof extensions['code'] === 'string' ? extensions['code'] : null;\n if (extensionCode) return normalizeCode(extensionCode);\n\n if (isRecord(originalError)) {\n const originalCode = readString(originalError, 'code');\n if (originalCode) return normalizeCode(originalCode);\n }\n\n if (isRecord(error)) {\n const directCode = readString(error, 'code');\n if (directCode) return normalizeCode(directCode);\n }\n\n const message = readErrorMessage(error);\n return inferCodeFromMessage(message);\n}\n\nfunction readErrorMessage(error: unknown): string {\n if (error instanceof Error && error.message.trim().length > 0) {\n return error.message;\n }\n if (isRecord(error)) {\n const message = readString(error, 'message');\n if (message) return message;\n }\n return DEFAULT_USER_MESSAGES[DEFAULT_ERROR_CODE] ?? 'Something went wrong. Please try again.';\n}\n\nfunction isLikelyTechnicalMessage(message: string): boolean {\n if (message.length > 220) return true;\n if (message.includes('\\n')) return true;\n if (message.includes('{') && message.includes('}')) return true;\n if (GRAPHQL_VALIDATION_MESSAGE_PATTERNS.some((pattern) => pattern.test(message))) return true;\n return TECHNICAL_MESSAGE_PATTERNS.some((pattern) => pattern.test(message));\n}\n\nfunction readExplicitUserMessage(extensions: Record<string, unknown>): string | null {\n return (\n readString(extensions, 'userMessage') ??\n readString(extensions, 'humanMessage') ??\n readString(extensions, 'displayMessage')\n );\n}\n\nfunction resolveUserMessage(code: string, message: string, extensions: Record<string, unknown>): string {\n const explicit = readExplicitUserMessage(extensions);\n if (explicit) return explicit;\n\n const fallback =\n DEFAULT_USER_MESSAGES[code] ??\n DEFAULT_USER_MESSAGES[DEFAULT_ERROR_CODE] ??\n 'Something went wrong. Please try again.';\n if (code === DEFAULT_ERROR_CODE) {\n return fallback;\n }\n\n if (!isLikelyTechnicalMessage(message)) {\n return message;\n }\n\n return fallback;\n}\n\nfunction resolveTechnicalMessage(\n code: string,\n message: string,\n extensions: Record<string, unknown>,\n options: ErrorNormalizationOptions\n): string {\n const explicit = readString(extensions, 'technicalMessage');\n if (explicit) return explicit;\n\n if (options.environment === 'production' && code === DEFAULT_ERROR_CODE) {\n return options.serviceName ? `${options.serviceName} returned ${DEFAULT_ERROR_CODE}` : DEFAULT_ERROR_CODE;\n }\n\n return message;\n}\n\nfunction readHttpStatus(extensions: Record<string, unknown>, code: string): number {\n const http = extensions['http'];\n if (isRecord(http) && typeof http['status'] === 'number') {\n return http['status'];\n }\n return DEFAULT_STATUS_BY_CODE[code] ?? DEFAULT_HTTP_STATUS;\n}\n\nexport function normalizeError(error: unknown, options: ErrorNormalizationOptions = {}): NormalizedErrorState {\n const originalError = readOriginalError(error);\n const originalExtensions = readExtensions(originalError);\n const directExtensions = readExtensions(error);\n const mergedExtensions = sanitizeExtensions({ ...originalExtensions, ...directExtensions });\n const message = readErrorMessage(error);\n const code = inferCode(error, mergedExtensions, originalError);\n const userMessage = resolveUserMessage(code, message, mergedExtensions);\n const technicalMessage = resolveTechnicalMessage(code, message, mergedExtensions, options);\n const status = readHttpStatus(mergedExtensions, code);\n\n const extensions: Record<string, unknown> = {\n ...mergedExtensions,\n code,\n userMessage,\n technicalMessage,\n };\n\n if (options.serviceName) {\n extensions['serviceName'] = options.serviceName;\n }\n\n if (!isRecord(extensions['http'])) {\n extensions['http'] = { status };\n }\n\n return {\n code,\n userMessage,\n technicalMessage,\n extensions,\n status,\n };\n}\n\nexport class UserFacingGraphQLError extends GraphQLError {\n constructor(options: UserFacingErrorOptions) {\n const extensions: Record<string, unknown> = {\n code: normalizeCode(options.code),\n userMessage: options.userMessage,\n technicalMessage: options.technicalMessage ?? options.userMessage,\n };\n\n if (options.details) {\n extensions['details'] = options.details;\n }\n\n if (options.httpStatus) {\n extensions['http'] = { status: options.httpStatus };\n }\n\n super(options.userMessage, {\n originalError: options.cause,\n extensions,\n });\n this.name = 'UserFacingGraphQLError';\n }\n}\n\nexport function toUserFacingGraphQLError(error: unknown, options: ErrorNormalizationOptions = {}): GraphQLError {\n const normalized = normalizeError(error, options);\n\n if (error instanceof GraphQLError) {\n return new GraphQLError(normalized.userMessage, {\n nodes: error.nodes,\n source: error.source,\n positions: error.positions,\n path: error.path,\n originalError: error.originalError,\n extensions: normalized.extensions,\n });\n }\n\n return new GraphQLError(normalized.userMessage, {\n originalError: error instanceof Error ? error : undefined,\n extensions: normalized.extensions,\n });\n}\n\nexport function normalizeExecutionResultErrors(result: unknown, options: ErrorNormalizationOptions = {}): void {\n if (Array.isArray(result)) {\n result.forEach((entry) => normalizeExecutionResultErrors(entry, options));\n return;\n }\n\n if (!isRecord(result)) return;\n const errors = result['errors'];\n if (!Array.isArray(errors) || errors.length === 0) return;\n\n result['errors'] = errors.map((error) => toUserFacingGraphQLError(error, options));\n}\n\nexport function normalizeGraphQLResponsePayload(\n payload: unknown,\n options: ErrorNormalizationOptions = {}\n): unknown {\n normalizeExecutionResultErrors(payload, options);\n return payload;\n}\n\nexport async function normalizeGraphQLResponse(\n response: Response,\n options: ErrorNormalizationOptions = {}\n): Promise<Response> {\n const contentType = response.headers.get('content-type') ?? '';\n if (!contentType.toLowerCase().includes('json')) {\n return response;\n }\n\n const text = await response.text();\n if (!text) {\n return new Response(text, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n\n let payload: unknown;\n try {\n payload = JSON.parse(text) as unknown;\n } catch {\n return new Response(text, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n\n normalizeGraphQLResponsePayload(payload, options);\n\n return new Response(JSON.stringify(payload), {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n}\n\nexport function createHumanReadableErrorPlugin(options: ErrorNormalizationOptions = {}): YogaPlugin {\n return {\n onExecute() {\n return {\n onExecuteDone({ result }: { result: unknown }) {\n normalizeExecutionResultErrors(result, options);\n },\n };\n },\n };\n}\n\nexport function formatHttpError(error: unknown, options: ErrorNormalizationOptions = {}): HttpErrorResult {\n const normalized = normalizeError(error, options);\n return {\n status: normalized.status,\n body: {\n error: normalized.userMessage,\n message: normalized.userMessage,\n userMessage: normalized.userMessage,\n technicalMessage: normalized.technicalMessage,\n code: normalized.code,\n extensions: normalized.extensions,\n },\n };\n}\n\nexport function createHttpErrorResponse(error: unknown, options: ErrorNormalizationOptions = {}): Response {\n const formatted = formatHttpError(error, options);\n return new Response(JSON.stringify(formatted.body), {\n status: formatted.status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n","/**\n * Workspace Guard Plugin for GraphQL Yoga\n *\n * Blocks GraphQL operations that lack a valid workspace context (x-workspace-id header).\n * This provides defense-in-depth at the GraphQL layer — even if the gateway allows a request\n * through, the service itself will reject it if workspace context is missing.\n *\n * **Whitelisted operations** (e.g., workspace creation) can bypass the guard.\n *\n * **Public schema fields** marked with `@public` or `@rbac(public: true)` are auto-bypassed\n * when `allowPublicDirective` is enabled (default true). This lets anonymous public-link\n * resolvers (e.g. `accessShare`) be reached through the federation gateway without an\n * `x-workspace-id` header.\n *\n * @module server/workspace-guard\n * @category Security\n */\n\nimport { logger } from '../logger/index.js';\nimport { UserFacingGraphQLError } from './errors.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Configuration for the workspace guard plugin\n */\nexport interface WorkspaceGuardConfig {\n /**\n * Enable the workspace guard.\n * @default true\n */\n enabled?: boolean;\n\n /**\n * GraphQL operation names that can run without workspace context.\n * These are typically operations like `createWorkspace` that execute\n * before a workspace exists.\n *\n * Matching is case-sensitive against the operation name in the GraphQL document.\n *\n * @default []\n *\n * @example\n * ```typescript\n * whitelistedOperations: ['createWorkspace', 'validateTokens']\n * ```\n */\n whitelistedOperations?: string[];\n\n /**\n * Custom error message when workspace context is missing.\n * @default 'Workspace context required. Provide a valid X-Workspace-Authorization header.'\n */\n errorMessage?: string;\n\n /**\n * If true, fields whose schema definition carries the `@public` directive or\n * `@rbac(public: true)` are bypassed by the guard automatically — no need to\n * list them in `whitelistedOperations`. The check uses the GraphQL schema\n * passed to the executor at request time.\n *\n * Set to false to fall back to the legacy operation-name allowlist only.\n *\n * @default true\n */\n allowPublicDirective?: boolean;\n}\n\n// ============================================================================\n// GraphQL Error\n// ============================================================================\n\n/**\n * Workspace required error with proper GraphQL error extensions\n */\nclass WorkspaceRequiredError extends UserFacingGraphQLError {\n constructor(message: string) {\n super({\n code: 'WORKSPACE_REQUIRED',\n userMessage: 'Please choose a workspace and try again.',\n technicalMessage: message,\n httpStatus: 403,\n });\n this.name = 'WorkspaceRequiredError';\n }\n}\n\n// ============================================================================\n// Schema directive helpers\n// ============================================================================\n\n/**\n * Minimal structural typings for the bits of the GraphQL schema we look at.\n * We avoid importing the GraphQL types directly so the SDK keeps `graphql`\n * as a peer dep without a runtime hard dependency.\n */\ninterface FieldLikeDef {\n astNode?: {\n directives?: ReadonlyArray<{\n name: { value: string };\n arguments?: ReadonlyArray<{\n name: { value: string };\n value: { kind: string; value?: unknown };\n }>;\n }>;\n };\n}\n\ninterface SchemaLike {\n getQueryType?: () => { getFields: () => Record<string, FieldLikeDef> } | null | undefined;\n getMutationType?: () => { getFields: () => Record<string, FieldLikeDef> } | null | undefined;\n getSubscriptionType?: () => { getFields: () => Record<string, FieldLikeDef> } | null | undefined;\n}\n\n/**\n * Returns true iff the field carries either:\n * - `@public` directive, OR\n * - `@rbac(public: true)` directive (any arg-order)\n */\nfunction isFieldPublic(field: FieldLikeDef | undefined): boolean {\n const directives = field?.astNode?.directives;\n if (!directives || directives.length === 0) return false;\n\n for (const dir of directives) {\n const name = dir.name?.value;\n if (name === 'public') return true;\n if (name === 'rbac') {\n const args = dir.arguments ?? [];\n for (const arg of args) {\n if (arg.name?.value === 'public' && arg.value?.kind === 'BooleanValue' && arg.value.value === true) {\n return true;\n }\n }\n }\n }\n return false;\n}\n\ninterface DocumentLike {\n definitions?: ReadonlyArray<{\n kind?: string;\n operation?: string;\n name?: { value?: string };\n selectionSet?: {\n selections?: ReadonlyArray<{\n kind?: string;\n name?: { value?: string };\n }>;\n };\n }>;\n}\n\n/**\n * Resolve the operation type ('query' | 'mutation' | 'subscription') for the\n * primary operation in the document. Falls back to 'query'.\n */\nfunction resolveOperationType(\n document: DocumentLike | undefined,\n operationName: string | null | undefined\n): 'query' | 'mutation' | 'subscription' {\n const defs = document?.definitions ?? [];\n for (const def of defs) {\n if (def.kind !== 'OperationDefinition') {\n // Older parsers may not set kind; fall through to the operation property check below.\n }\n if (def.operation && (!operationName || def.name?.value === operationName)) {\n return def.operation as 'query' | 'mutation' | 'subscription';\n }\n }\n return 'query';\n}\n\n/**\n * Returns true iff every root field in the document selection set is marked\n * public on the schema. Empty selection sets return false (fail-closed).\n */\nfunction allRootFieldsPublic(\n schema: SchemaLike | undefined,\n document: DocumentLike | undefined,\n operationName: string | null | undefined\n): boolean {\n if (!schema || !document) return false;\n\n const opType = resolveOperationType(document, operationName);\n let rootType: ReturnType<NonNullable<SchemaLike['getQueryType']>> | undefined;\n if (opType === 'mutation') {\n rootType = schema.getMutationType?.();\n } else if (opType === 'subscription') {\n rootType = schema.getSubscriptionType?.();\n } else {\n rootType = schema.getQueryType?.();\n }\n\n if (!rootType) return false;\n\n const fields = rootType.getFields();\n const defs = document.definitions ?? [];\n\n // Find the operation definition matching operationName (or first one).\n const opDef = defs.find((d) => d.operation && (!operationName || d.name?.value === operationName));\n const selections = opDef?.selectionSet?.selections ?? [];\n if (selections.length === 0) return false;\n\n for (const sel of selections) {\n // Only consider plain Field selections (skip fragments — fragments at the root\n // shouldn't drive a public bypass; fail-closed there).\n if (sel.kind && sel.kind !== 'Field') return false;\n const fieldName = sel.name?.value;\n if (!fieldName) return false;\n // __schema / __type introspection is always allowed without workspace context;\n // treat them as public.\n if (fieldName.startsWith('__')) continue;\n const fieldDef = fields[fieldName];\n if (!isFieldPublic(fieldDef)) return false;\n }\n return true;\n}\n\n// ============================================================================\n// Plugin\n// ============================================================================\n\n/**\n * Create a GraphQL Yoga plugin that guards operations requiring workspace context.\n *\n * The plugin inspects the GraphQL context for workspace information (set by the SDK's\n * buildContext from the x-workspace-id header). If missing and the operation is not\n * whitelisted (and not all-public per directive), it throws a WORKSPACE_REQUIRED error.\n *\n * @param config - Guard configuration\n * @returns A Yoga-compatible plugin\n *\n * @example\n * ```typescript\n * import { createWorkspaceGuardPlugin } from '@burdenoff/be-sdk/server';\n *\n * const guardPlugin = createWorkspaceGuardPlugin({\n * whitelistedOperations: ['createWorkspace'],\n * allowPublicDirective: true, // default\n * });\n * ```\n */\nexport function createWorkspaceGuardPlugin(config?: WorkspaceGuardConfig) {\n const enabled = config?.enabled ?? true;\n const whitelistedOperations = new Set(config?.whitelistedOperations ?? []);\n const allowPublicDirective = config?.allowPublicDirective ?? true;\n const errorMessage =\n config?.errorMessage ??\n 'Workspace context required. Ensure the request includes a valid workspace context (x-workspace-id header).';\n\n if (!enabled) {\n logger.info('[WorkspaceGuard] Workspace guard disabled');\n return {};\n }\n\n logger.info('[WorkspaceGuard] Workspace guard enabled', {\n whitelistedOperations: [...whitelistedOperations],\n allowPublicDirective,\n });\n\n return {\n onExecute({\n args,\n }: {\n args: {\n schema?: SchemaLike;\n document?: DocumentLike;\n operationName?: string | null;\n contextValue?: { workspace?: { id?: string }; request?: Request };\n };\n }) {\n // Extract operation name from args or document\n let operationName = args.operationName;\n\n if (!operationName && args.document?.definitions) {\n for (const def of args.document.definitions) {\n if (def.operation && def.name?.value) {\n operationName = def.name.value;\n break;\n }\n }\n }\n\n // Check if operation is whitelisted by name\n if (operationName && whitelistedOperations.has(operationName)) {\n return undefined;\n }\n\n // Check schema-directive-based public bypass (Option C)\n if (allowPublicDirective && allRootFieldsPublic(args.schema, args.document, operationName)) {\n return undefined;\n }\n\n // Check for workspace context\n const context = args.contextValue;\n const workspaceId = context?.workspace?.id;\n\n // Also check the raw header as a fallback\n const headerWorkspaceId = context?.request?.headers?.get?.('x-workspace-id');\n\n if (!workspaceId && !headerWorkspaceId) {\n logger.warn('[WorkspaceGuard] Blocked operation without workspace context', {\n operationName: operationName ?? '<anonymous>',\n });\n throw new WorkspaceRequiredError(errorMessage);\n }\n\n return undefined;\n },\n };\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -11,8 +11,8 @@ import './chunk-REF7PANB.js';
|
|
|
11
11
|
export { middleware_exports as Middleware } from './chunk-2HANKZZM.js';
|
|
12
12
|
import { TenantNotificationsModule, NotificationsModule } from './chunk-RMDKB5O7.js';
|
|
13
13
|
export { tenant_notifications_exports as Notifications, NotificationsModule } from './chunk-RMDKB5O7.js';
|
|
14
|
-
export { observability_exports as Observability } from './chunk-5LXDPGDH.js';
|
|
15
14
|
export { platform_exports as Platform } from './chunk-PHKK7725.js';
|
|
15
|
+
export { observability_exports as Observability } from './chunk-5LXDPGDH.js';
|
|
16
16
|
export { export_exports as Export } from './chunk-SVONGBQR.js';
|
|
17
17
|
export { feature_flags_exports as FeatureFlags } from './chunk-VWCN5PMD.js';
|
|
18
18
|
import { GraphModule } from './chunk-TGTJ653K.js';
|
|
@@ -34,8 +34,8 @@ import { AuthModule } from './chunk-7NUQXGA7.js';
|
|
|
34
34
|
export { AuthModule } from './chunk-7NUQXGA7.js';
|
|
35
35
|
export { utils_exports as Utils } from './chunk-B7I4TABG.js';
|
|
36
36
|
export { cache_exports as Cache } from './chunk-PDSV3TFO.js';
|
|
37
|
-
export { createInternalClient, createInternalClientForTenant, createInternalClientForWorkspaces } from './chunk-VI4VSNTI.js';
|
|
38
37
|
export { captcha_exports as Captcha, isCaptchaEnabled, verifyCaptcha, verifyCaptchaIfEnabled } from './chunk-YMZEUTD2.js';
|
|
38
|
+
export { createInternalClient, createInternalClientForTenant, createInternalClientForWorkspaces } from './chunk-VI4VSNTI.js';
|
|
39
39
|
export { crypto_exports as Crypto } from './chunk-SBS4S2PJ.js';
|
|
40
40
|
import { DatabaseModule } from './chunk-UFQQSQG6.js';
|
|
41
41
|
export { DatabaseModule } from './chunk-UFQQSQG6.js';
|
package/dist/server/index.d.ts
CHANGED
|
@@ -393,8 +393,10 @@ declare class UserFacingGraphQLError extends GraphQLError {
|
|
|
393
393
|
}
|
|
394
394
|
declare function toUserFacingGraphQLError(error: unknown, options?: ErrorNormalizationOptions): GraphQLError;
|
|
395
395
|
declare function normalizeExecutionResultErrors(result: unknown, options?: ErrorNormalizationOptions): void;
|
|
396
|
+
declare function normalizeGraphQLResponsePayload(payload: unknown, options?: ErrorNormalizationOptions): unknown;
|
|
397
|
+
declare function normalizeGraphQLResponse(response: Response, options?: ErrorNormalizationOptions): Promise<Response>;
|
|
396
398
|
declare function createHumanReadableErrorPlugin(options?: ErrorNormalizationOptions): YogaPlugin;
|
|
397
399
|
declare function formatHttpError(error: unknown, options?: ErrorNormalizationOptions): HttpErrorResult;
|
|
398
400
|
declare function createHttpErrorResponse(error: unknown, options?: ErrorNormalizationOptions): Response;
|
|
399
401
|
|
|
400
|
-
export { type AuthConfig, type ConsentContext, type ContextBuilderOptions, type ElysiaApp, type ErrorNormalizationOptions, type FetchWorkspaceSecretFn, type GraphQLContext, type HttpErrorPayload, type HttpErrorResult, I18nContext, type IActor, type IContextFilterInput, type IOperationContext, type IOrganization, type IProduct, type IProject, type ITenant, type ITracking, type IWorkspace, type JWTPayload, LocaleCode, type ModuleGraphConfig, type NormalizedErrorState, PrismaClientBase, type PrismaClientConstructor, type RESTEndpoint, type ServerConfig, type ServerDefinition, type ServerI18nConfig, type ServerInfo, type ServerInstance, type UserFacingErrorOptions, UserFacingGraphQLError, type WorkspaceGuardConfig, type WorkspaceSecret, type WspaceGraphQLContext, type YogaPlugin, authCheck, buildContext, configureAuth, configureContext, configureDefaultAuth, configureServerAuth, createHttpErrorResponse, createHumanReadableErrorPlugin, createServer, createWorkspaceGuardPlugin, decodeJWT, fetchWorkspaceSecret, formatHttpError, generateSymmetricSecret, getContextOptions, normalizeError, normalizeExecutionResultErrors, orgCheck, requireWorkspace, tenantCheck, toUserFacingGraphQLError, verifyJWT, workspaceCheck };
|
|
402
|
+
export { type AuthConfig, type ConsentContext, type ContextBuilderOptions, type ElysiaApp, type ErrorNormalizationOptions, type FetchWorkspaceSecretFn, type GraphQLContext, type HttpErrorPayload, type HttpErrorResult, I18nContext, type IActor, type IContextFilterInput, type IOperationContext, type IOrganization, type IProduct, type IProject, type ITenant, type ITracking, type IWorkspace, type JWTPayload, LocaleCode, type ModuleGraphConfig, type NormalizedErrorState, PrismaClientBase, type PrismaClientConstructor, type RESTEndpoint, type ServerConfig, type ServerDefinition, type ServerI18nConfig, type ServerInfo, type ServerInstance, type UserFacingErrorOptions, UserFacingGraphQLError, type WorkspaceGuardConfig, type WorkspaceSecret, type WspaceGraphQLContext, type YogaPlugin, authCheck, buildContext, configureAuth, configureContext, configureDefaultAuth, configureServerAuth, createHttpErrorResponse, createHumanReadableErrorPlugin, createServer, createWorkspaceGuardPlugin, decodeJWT, fetchWorkspaceSecret, formatHttpError, generateSymmetricSecret, getContextOptions, normalizeError, normalizeExecutionResultErrors, normalizeGraphQLResponse, normalizeGraphQLResponsePayload, orgCheck, requireWorkspace, tenantCheck, toUserFacingGraphQLError, verifyJWT, workspaceCheck };
|
package/dist/server/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createHumanReadableErrorPlugin, formatHttpError, createHttpErrorResponse } from '../chunk-
|
|
2
|
-
export { UserFacingGraphQLError, createHttpErrorResponse, createHumanReadableErrorPlugin, createWorkspaceGuardPlugin, formatHttpError, normalizeError, normalizeExecutionResultErrors, toUserFacingGraphQLError } from '../chunk-
|
|
1
|
+
import { createHumanReadableErrorPlugin, formatHttpError, normalizeGraphQLResponse, createHttpErrorResponse } from '../chunk-VWNL2O3G.js';
|
|
2
|
+
export { UserFacingGraphQLError, createHttpErrorResponse, createHumanReadableErrorPlugin, createWorkspaceGuardPlugin, formatHttpError, normalizeError, normalizeExecutionResultErrors, normalizeGraphQLResponse, normalizeGraphQLResponsePayload, toUserFacingGraphQLError } from '../chunk-VWNL2O3G.js';
|
|
3
3
|
import { setWorkspaceContext } from '../chunk-GTEMQXCA.js';
|
|
4
4
|
import { I18n } from '../chunk-ULFFX3YE.js';
|
|
5
5
|
import { logger } from '../chunk-CBZNP6RF.js';
|
|
@@ -473,7 +473,7 @@ async function createServer(definition) {
|
|
|
473
473
|
const { initializeDatabase, getDb: getDb2, getDatabaseManager } = await import('../prisma/index.js');
|
|
474
474
|
const { createSecurityPlugin } = await import('../middleware/index.js');
|
|
475
475
|
const { createMetricsPlugin } = await import('../observability/index.js');
|
|
476
|
-
const { createWorkspaceGuardPlugin: createWorkspaceGuardPlugin2 } = await import('../workspace-guard-
|
|
476
|
+
const { createWorkspaceGuardPlugin: createWorkspaceGuardPlugin2 } = await import('../workspace-guard-3JLBFAMH.js');
|
|
477
477
|
logger.info(`[Server] Initializing ${config.serviceName}...`);
|
|
478
478
|
const boundary = config.boundary ?? (config.serviceName.startsWith("wspace-") ? "wspace" : config.serviceName.startsWith("global-") ? "global" : "wspace");
|
|
479
479
|
const shouldEnableWorkspaceExtension = disableWorkspaceExtension === true ? false : disableWorkspaceExtension === false ? true : boundary === "wspace";
|
|
@@ -733,7 +733,10 @@ async function createServer(definition) {
|
|
|
733
733
|
headers: corsHeaders
|
|
734
734
|
});
|
|
735
735
|
}
|
|
736
|
-
const yogaResponse = await yoga.fetch(request)
|
|
736
|
+
const yogaResponse = await normalizeGraphQLResponse(await yoga.fetch(request), {
|
|
737
|
+
serviceName: config.serviceName,
|
|
738
|
+
environment: config.environment
|
|
739
|
+
});
|
|
737
740
|
const headers = new Headers(yogaResponse.headers);
|
|
738
741
|
for (const [key, value] of Object.entries(corsHeaders)) {
|
|
739
742
|
headers.set(key, value);
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/auth.ts","../../src/server/context.ts","../../src/server/security.ts","../../src/server/server.ts"],"names":["getDbFn","getDb","prismaModule","joseModule","jwtModule","getJose","getJwt","jwt","default","authConfig","configureAuth","config","logger","debug","fetchWorkspaceSecret","workspaceId","db","workspace","client","findUnique","where","id","jwtSecret","JSON","parse","stringify","error","warn","configureDefaultAuth","generateSymmetricSecret","joseLib","secret","generateSecret","jwk","exportJWK","verifyJWT","token","options","decoded","decode","complete","payload","verifiedJwt","verify","mapPayloadToActor","decodedJwt","decodeJwt","workspace_id","workspaceSecret","keyLikeSecret","importJWK","jwtVerify","err","decodeJWT","sub","type","actor_type","tenant_id","org_id","isAdmin","authCheck","actor","Error","workspaceCheck","context","actorId","requireWorkspace","orgCheck","organization","orgId","tenantCheck","tenant","contextOptions","configureContext","getHeader","request","key","headers","get","toLowerCase","undefined","compareSecret","provided","expected","providedBuffer","Buffer","from","expectedBuffer","length","crypto","timingSafeEqual","shouldTrustActorHeaders","nodeEnv","process","env","expectedGatewayToken","providedGatewayToken","extractTracking","forwardedFor","realIp","ip","split","trim","userAgent","extractActor","actorType","userRole","authHeader","startsWith","substring","extractTenant","tenantId","tenantEndpoint","endpoint","defaultTenant","extractOrganization","extractWorkspace","extractProject","projectId","extractProduct","productId","extractGeography","country","currency","timezone","toUpperCase","extractConsentContext","grantedBy","scopesHeader","grantedAtHeader","expiresAtHeader","scopes","map","s","grantedAt","Date","expiresAt","buildContext","project","product","tracking","consentContext","i18n","createContextFromRequest","geo","locale","language","t","tp","formatNumber","value","String","formatCurrency","formatDate","date","formatRelativeTime","unit","onBehalfOf","wsCtxPayload","organizationId","rawHeader","setWorkspaceContext","responseHeaders","Headers","getContextOptions","LOCALHOST_ORIGINS","normalizeCorsOrigins","origins","environment","normalized","Array","isArray","origin","filter","Boolean","includes","resolveAllowedCorsOrigin","requestOrigin","allowedOrigins","canAccessGraphExport","serverStartTime","createServer","definition","prismaClient","schema","moduleGraph","restEndpoints","yogaPlugins","customBuildContext","workspaceExtensionConfig","disableWorkspaceExtension","onShutdown","Elysia","BunAdapter","cors","createYoga","initializeDatabase","getDatabaseManager","createSecurityPlugin","createMetricsPlugin","createWorkspaceGuardPlugin","info","serviceName","boundary","shouldEnableWorkspaceExtension","workspaceExtension","connect","registerShutdownHandlers","enableWorkspaceExtension","i18nInstance","enabled","localesPath","I18n","defaultLocale","fallbackLocale","supportedLocales","namespace","lazyLoad","logMissing","enableCache","returnKeyOnMissing","initialize","getSupportedLocales","join","isDev","enablePlayground","workspaceGuardEnabled","workspaceGuard","workspaceGuardPlugins","whitelistedOperations","graphqlEndpoint","responseHeadersPlugin","onResponse","response","serverContext","yogaContext","forEach","append","yoga","graphiql","logging","args","plugins","createHumanReadableErrorPlugin","defaultContext","app","adapter","corsOrigins","use","credentials","allowedHeaders","methods","rawBodyEndpoints","ep","rawBody","rawBodyPaths","Map","path","rawBodyMatchers","regexPattern","replace","regex","RegExp","matchRawBodyEndpoint","pathname","exactMatch","isMatch","test","onRequest","url","URL","method","isHealthRoute","buildCorsHeaders","allowedOrigin","rawBodyEndpoint","corsHeaders","Response","status","text","result","handler","Object","entries","set","body","statusText","formatted","formatHttpError","promClientMod","prom","collectDefaultMetrics","register","metrics","contentType","yogaRoutes","shouldHandleByYoga","yogaResponse","fetch","csrfSkipRoutes","loginEndpoints","enableCSRF","enableSessionSecurity","healthResponse","service","version","serviceVersion","timestamp","toISOString","getSchema","query","exportAll","types","entityTypes","exportEntities","exportRelationships","createHttpErrorResponse","post","put","patch","delete","host","port","serverInstance","server","start","listen","hostname","elysiaApp","stop","shutdown","disconnect","getInfo","uptime","Math","floor","now","getTime","startedAt","gracefulShutdown","signal","exit","on","configureServerAuth"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Server Auth Module\n *\n * JWT verification with workspace secret fetching for microservices.\n * Handles HS256 tokens with secrets stored in workspace database.\n */\n\nimport { logger } from '../logger/index.js';\nimport type { IActor, JWTPayload, WorkspaceSecret } from './types.js';\n\n// Type imports from packages\nimport type * as jose from 'jose';\nimport type { VerifyOptions, Jwt, JwtPayload } from 'jsonwebtoken';\n\n/**\n * Workspace model interface for fetching JWT secrets\n */\ninterface WorkspaceModel {\n findUnique: (args: { where: { id: string } }) => Promise<{ jwtSecret?: unknown } | null>;\n}\n\ninterface DbClient {\n client: {\n workspace: WorkspaceModel;\n };\n}\n\n// Import getDb dynamically to avoid circular dependencies\nlet getDbFn: (() => DbClient) | null = null;\n\nasync function getDb(): Promise<DbClient> {\n if (!getDbFn) {\n const prismaModule = await import('../prisma/index.js');\n // Use unknown first then cast to avoid type inference issues\n getDbFn = prismaModule.getDb as unknown as () => DbClient;\n }\n return getDbFn();\n}\n\n// Interface for the subset of jsonwebtoken we use\ninterface JwtModule {\n decode(token: string, options?: { complete?: boolean }): string | Jwt | JwtPayload | null;\n verify(token: string, secretOrPublicKey: string, options?: VerifyOptions): string | JwtPayload;\n}\n\n// Module cache for dynamic imports\nlet joseModule: typeof jose | null = null;\nlet jwtModule: JwtModule | null = null;\n\nasync function getJose(): Promise<typeof jose> {\n if (!joseModule) {\n joseModule = await import('jose');\n }\n return joseModule;\n}\n\nasync function getJwt(): Promise<JwtModule> {\n if (!jwtModule) {\n const jwt = await import('jsonwebtoken');\n // Handle both ESM and CJS module formats\n jwtModule = (jwt as { default?: JwtModule }).default ?? jwt;\n }\n return jwtModule;\n}\n\n/**\n * Fetch workspace secret callback type\n */\nexport type FetchWorkspaceSecretFn = (workspaceId: string) => Promise<WorkspaceSecret | null>;\n\n/**\n * Auth configuration\n */\nexport interface AuthConfig {\n /** Function to fetch workspace JWT secret from database */\n fetchWorkspaceSecret: FetchWorkspaceSecretFn;\n}\n\nlet authConfig: AuthConfig | null = null;\n\n/**\n * Configure auth module with workspace secret fetching\n */\nexport function configureAuth(config: AuthConfig): void {\n authConfig = config;\n logger.debug('[ServerAuth] Auth configured');\n}\n\n/**\n * Default workspace secret fetcher\n *\n * Fetches JWT secret from workspace database. This is the standard implementation\n * that works with any microservice that has access to the workspace model.\n *\n * @param workspaceId - Workspace ID from JWT\n * @returns WorkspaceSecret or null if not found\n */\nexport async function fetchWorkspaceSecret(workspaceId: string): Promise<WorkspaceSecret | null> {\n try {\n const db = await getDb();\n const workspace = await db.client.workspace.findUnique({\n where: { id: workspaceId },\n });\n\n if (!workspace?.jwtSecret) {\n logger.debug('[ServerAuth] No JWT secret found for workspace', { workspaceId });\n return null;\n }\n\n return JSON.parse(JSON.stringify(workspace.jwtSecret)) as WorkspaceSecret;\n } catch (error) {\n logger.warn('[ServerAuth] Error fetching workspace secret', { workspaceId, error });\n return null;\n }\n}\n\n/**\n * Configure auth with default workspace secret fetcher\n *\n * This is automatically called by createServer if no custom auth is configured.\n */\nexport function configureDefaultAuth(): void {\n if (!authConfig) {\n configureAuth({ fetchWorkspaceSecret });\n logger.debug('[ServerAuth] Default auth configured with built-in workspace secret fetcher');\n }\n}\n\n/**\n * Generate a symmetric secret key for JWT signing\n * @returns JWK object with the generated key\n */\nexport async function generateSymmetricSecret(): Promise<jose.JWK> {\n const joseLib = await getJose();\n const secret = await joseLib.generateSecret('HS256');\n const jwk = await joseLib.exportJWK(secret);\n return jwk;\n}\n\n/**\n * Verify JWT token for workspace-scoped authentication\n *\n * @param token - JWT token to verify\n * @param secret - Optional secret for verification (if not provided, fetches from workspace)\n * @param options - JWT verification options\n * @returns Verified actor information or null if invalid\n */\nexport async function verifyJWT(token: string, secret?: string, options: VerifyOptions = {}): Promise<IActor | null> {\n try {\n const jwt = await getJwt();\n const joseLib = await getJose();\n\n // Decode to check algorithm and extract workspace_id\n const decoded = jwt.decode(token, { complete: true });\n\n if (!decoded || typeof decoded === 'string' || !decoded.payload || typeof decoded.payload !== 'object') {\n logger.warn('[ServerAuth] Invalid token format');\n return null;\n }\n\n // For workspace-scoped HS256 tokens\n if (secret) {\n // Use provided secret\n const verifiedJwt = jwt.verify(token, secret, options) as JWTPayload;\n return mapPayloadToActor(verifiedJwt);\n }\n\n // Fetch secret from workspace database\n const decodedJwt = joseLib.decodeJwt(token) as JWTPayload;\n if (!decodedJwt.workspace_id) {\n logger.warn('[ServerAuth] No workspace_id found in token');\n return null;\n }\n\n if (!authConfig?.fetchWorkspaceSecret) {\n logger.error('[ServerAuth] Auth not configured - call configureAuth() first');\n return null;\n }\n\n const workspaceSecret = await authConfig.fetchWorkspaceSecret(decodedJwt.workspace_id);\n if (!workspaceSecret) {\n logger.warn('[ServerAuth] Workspace secret not found');\n return null;\n }\n\n const keyLikeSecret = await joseLib.importJWK(workspaceSecret, 'HS256');\n const verifiedJwt = await joseLib.jwtVerify(token, keyLikeSecret, options as jose.JWTVerifyOptions);\n return mapPayloadToActor(verifiedJwt.payload as unknown as JWTPayload);\n } catch (err) {\n logger.warn('[ServerAuth] Error verifying JWT:', err);\n return null;\n }\n}\n\n/**\n * Decode JWT without verification (for extracting claims)\n */\nexport async function decodeJWT(token: string): Promise<JWTPayload | null> {\n try {\n const joseLib = await getJose();\n return await joseLib.decodeJwt(token);\n } catch {\n return null;\n }\n}\n\n/**\n * Map JWT payload to IActor interface\n */\nfunction mapPayloadToActor(payload: JWTPayload): IActor {\n return {\n id: payload.sub,\n type: payload.actor_type ?? 'user',\n workspace_id: payload.workspace_id,\n tenant_id: payload.tenant_id,\n org_id: payload.org_id,\n isAdmin: payload['isAdmin'] as boolean | undefined,\n };\n}\n\n/**\n * Check if actor is authenticated\n */\nexport function authCheck(actor: IActor | null): IActor {\n if (!actor) {\n throw new Error('Please sign in');\n }\n return actor;\n}\n\n/**\n * Check workspace context and return actor ID and workspace ID\n */\nexport function workspaceCheck(context: { actor: IActor | null; workspace: { id: string } | null }): {\n actorId: string;\n workspaceId: string;\n} {\n const actor = authCheck(context.actor);\n\n if (!context.workspace?.id) {\n throw new Error('Please switch to a workspace');\n }\n\n return {\n actorId: actor.id,\n workspaceId: context.workspace.id,\n };\n}\n\n/**\n * Require workspace context - type narrowing guard for wspace layer services\n *\n * Validates that both actor and workspace are present in the context,\n * and returns a type-narrowed context where workspace and actor are guaranteed non-null.\n * Use this at the start of resolvers in wspace services to get typed access\n * to workspace context without optional chaining.\n *\n * @throws Error if actor is not authenticated\n * @throws Error if workspace context is missing\n *\n * @example\n * ```typescript\n * // In a resolver:\n * const ctx = requireWorkspace(context);\n * const workspaceId = ctx.workspace.id; // no optional chaining needed\n * const actorId = ctx.actor.id; // no optional chaining needed\n * ```\n */\nexport function requireWorkspace<T extends { actor: IActor | null; workspace: { id: string } | null }>(\n context: T\n): T & { actor: IActor; workspace: { id: string } } {\n // Validate actor is authenticated (throws if null)\n authCheck(context.actor);\n\n if (!context.workspace?.id) {\n throw new Error('Please switch to a workspace');\n }\n\n // Return the same context object with narrowed types\n return context as T & { actor: IActor; workspace: { id: string } };\n}\n\n/**\n * Check organization context and return actor ID and org ID\n */\nexport function orgCheck(context: { actor: IActor | null; organization: { id: string } | null }): {\n actorId: string;\n orgId: string;\n} {\n const actor = authCheck(context.actor);\n\n if (!context.organization?.id) {\n throw new Error('Please switch to an organization');\n }\n\n return {\n actorId: actor.id,\n orgId: context.organization.id,\n };\n}\n\n/**\n * Check tenant context and return tenant ID\n */\nexport function tenantCheck(context: { tenant: { id: string } | null }): string {\n if (!context.tenant?.id) {\n throw new Error('Tenant context is required');\n }\n return context.tenant.id;\n}\n\n/**\n * Get effective actor ID for \"on behalf of\" tracking\n *\n * When an app or service acts with user consent, returns the delegating user's ID.\n * Otherwise returns the direct actor ID.\n *\n * This is used to determine the `onBehalfOf` field in database audit trails:\n * - If actor is user → returns user ID (self-action)\n * - If actor is app/service with consent → returns grantedBy user ID\n * - If actor is app/service without consent → returns actor ID (self-action)\n *\n * @param context - GraphQL context with actor and optional consent context\n * @returns Effective actor ID (the responsible principal)\n *\n * @example\n * ```typescript\n * // User acting directly\n * context.actor = { id: \"user-123\", type: \"user\" }\n * context.consentContext = undefined\n * getEffectiveActorId(context) // → \"user-123\"\n *\n * // Bot acting on behalf of user\n * context.actor = { id: \"bot-456\", type: \"service\" }\n * context.consentContext = { grantedBy: \"user-789\" }\n * getEffectiveActorId(context) // → \"user-789\"\n *\n * // App acting without consent (self-action)\n * context.actor = { id: \"app-abc\", type: \"app\" }\n * context.consentContext = undefined\n * getEffectiveActorId(context) // → \"app-abc\"\n * ```\n */\nexport function getEffectiveActorId(context: {\n actor: IActor | null;\n consentContext?: { grantedBy: string } | null;\n}): string | null {\n if (!context.actor) {\n return null;\n }\n\n // If actor is app or service acting with user consent, return the delegating user\n if (\n (context.actor.type === 'app' || context.actor.type === 'service' || context.actor.type === 'service_account') &&\n context.consentContext?.grantedBy\n ) {\n return context.consentContext.grantedBy;\n }\n\n // Otherwise return the direct actor (user self-action or app/service self-action)\n return context.actor.id;\n}\n","/**\n * Server Context Module\n *\n * Builds GraphQL context from request headers, JWT, and configuration.\n * Automatically populates actor, tenant, workspace, and tracking information.\n *\n * **Actor-Based Authentication:**\n * - Production: Gateway verifies JWT → populates x-actor-* headers → services trust headers\n * - Development: Services verify JWT directly and build actor from payload\n *\n * Uses standard Web API Request (compatible with Bun/Elysia).\n */\n\nimport { logger } from '../logger/index.js';\nimport crypto from 'node:crypto';\nimport { verifyJWT } from './auth.js';\nimport type {\n GraphQLContext,\n IActor,\n ITenant,\n IOrganization,\n IWorkspace,\n IProject,\n IProduct,\n ITracking,\n} from './types.js';\nimport type { I18n, I18nContext } from '../i18n/index.js';\nimport { setWorkspaceContext } from '../prisma/workspace-extension.js';\n\n/**\n * Context builder options\n */\nexport interface ContextBuilderOptions {\n /** Database getter function */\n getDb: () => unknown;\n /** Default tenant info (optional) */\n defaultTenant?: ITenant;\n /** I18n instance (optional) */\n i18n?: I18n;\n}\n\nlet contextOptions: ContextBuilderOptions | null = null;\n\n/**\n * Configure context builder\n */\nexport function configureContext(options: ContextBuilderOptions): void {\n contextOptions = options;\n logger.debug('[ServerContext] Context builder configured');\n}\n\n/**\n * Extract header value from standard Web API Request\n */\nfunction getHeader(request: Request, key: string): string | undefined {\n return request.headers.get(key.toLowerCase()) ?? undefined;\n}\n\nfunction compareSecret(provided: string, expected: string): boolean {\n const providedBuffer = Buffer.from(provided);\n const expectedBuffer = Buffer.from(expected);\n\n if (providedBuffer.length !== expectedBuffer.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(providedBuffer, expectedBuffer);\n}\n\nexport function shouldTrustActorHeaders(\n request: Request,\n nodeEnv: string | undefined = process.env['NODE_ENV'],\n expectedGatewayToken: string | undefined = process.env['TRUSTED_GATEWAY_TOKEN'] ??\n process.env['INTERNAL_SERVICE_TOKEN']\n): boolean {\n if (!getHeader(request, 'x-actor-id')) {\n return false;\n }\n\n if (nodeEnv === 'production') {\n return true;\n }\n\n const providedGatewayToken =\n getHeader(request, 'x-internal-service-token') || getHeader(request, 'x-gateway-auth-token');\n if (!expectedGatewayToken || !providedGatewayToken) {\n return false;\n }\n\n return compareSecret(providedGatewayToken, expectedGatewayToken);\n}\n\n/**\n * Extract tracking information from request\n */\nfunction extractTracking(request: Request): ITracking {\n // Get IP from various possible headers\n const forwardedFor = getHeader(request, 'x-forwarded-for');\n const realIp = getHeader(request, 'x-real-ip');\n const ip = forwardedFor?.split(',')[0]?.trim() || realIp || undefined;\n\n return {\n ip,\n userAgent: getHeader(request, 'user-agent'),\n };\n}\n\n/**\n * Extract actor from gateway-injected headers or authorization header\n *\n * **Actor-Based Authentication:**\n * - If x-actor-id header exists, trust it (gateway-authenticated)\n * - Otherwise fall back to JWT verification (direct access in dev)\n *\n * This allows:\n * - Production: Gateway verifies JWT → populates x-actor-* headers → services trust headers\n * - Development: Direct service access with JWT → service verifies JWT itself\n * - Development testing: Direct headers → service trusts headers\n */\nasync function extractActor(request: Request): Promise<IActor | null> {\n // Check for gateway-injected actor headers first\n const actorId = getHeader(request, 'x-actor-id');\n\n if (actorId && shouldTrustActorHeaders(request)) {\n // Gateway has already verified JWT and populated context headers\n // Trust the headers (gateway is the security perimeter)\n logger.debug('[ServerContext] Using gateway-authenticated actor from headers');\n\n const actorType = getHeader(request, 'x-actor-type') || 'user';\n const userRole = getHeader(request, 'x-user-role');\n\n return {\n id: actorId,\n type: actorType,\n workspace_id: getHeader(request, 'x-workspace-id'),\n tenant_id: getHeader(request, 'x-tenant-id'),\n org_id: getHeader(request, 'x-org-id') || getHeader(request, 'x-organization-id'),\n isAdmin:\n actorType === 'super_admin' ||\n userRole === 'TENANT_ADMIN' ||\n userRole === 'SUPER_ADMIN' ||\n userRole === 'PLATFORM_ADMIN',\n };\n }\n\n if (actorId) {\n logger.warn('[ServerContext] Ignoring untrusted actor headers and falling back to JWT verification');\n }\n\n // FALLBACK: No gateway headers, verify JWT directly (dev/testing mode)\n const authHeader = getHeader(request, 'authorization');\n\n if (!authHeader?.startsWith('Bearer ')) {\n return null;\n }\n\n const token = authHeader.substring(7);\n\n try {\n logger.debug('[ServerContext] No gateway headers, verifying JWT directly for actor (dev mode)');\n const payload = await verifyJWT(token);\n\n if (!payload) {\n return null;\n }\n\n // Build actor from JWT payload\n return {\n id: payload.id,\n type: 'user', // Default to 'user' if not specified\n workspace_id: payload.workspace_id,\n };\n } catch (error) {\n logger.warn('[ServerContext] Invalid JWT token:', error);\n return null;\n }\n}\n\n/**\n * Extract tenant from headers\n */\nfunction extractTenant(request: Request): ITenant | null {\n // Check headers\n const tenantId = getHeader(request, 'x-tenant-id');\n const tenantEndpoint = getHeader(request, 'x-tenant-endpoint');\n\n if (tenantId) {\n return {\n id: tenantId,\n endpoint: tenantEndpoint || '',\n };\n }\n\n // Fall back to default tenant if configured\n return contextOptions?.defaultTenant || null;\n}\n\n/**\n * Extract organization from headers\n */\nfunction extractOrganization(request: Request): IOrganization | null {\n const orgId = getHeader(request, 'x-org-id') || getHeader(request, 'x-organization-id');\n\n if (orgId) {\n return { id: orgId };\n }\n\n return null;\n}\n\n/**\n * Extract workspace from headers or actor\n */\nfunction extractWorkspace(request: Request, actor: IActor | null): IWorkspace | null {\n // Check headers first\n const workspaceId = getHeader(request, 'x-workspace-id');\n\n if (workspaceId) {\n return { id: workspaceId };\n }\n\n // Fall back to workspace_id from actor\n if (actor?.workspace_id) {\n return { id: actor.workspace_id };\n }\n\n return null;\n}\n\n/**\n * Extract project from headers\n */\nfunction extractProject(request: Request): IProject | null {\n const projectId = getHeader(request, 'x-project-id');\n\n if (projectId) {\n return { id: projectId };\n }\n\n return null;\n}\n\n/**\n * Extract product from headers\n */\nfunction extractProduct(request: Request): IProduct | null {\n const productId = getHeader(request, 'x-product-id');\n\n if (productId) {\n return { id: productId };\n }\n\n return null;\n}\n\n/**\n * Extract geography context from headers\n *\n * Geography headers carry the user's selected location context,\n * used for currency defaults, tax calculations, payment routing,\n * data residency, and regional support.\n *\n * Headers:\n * - x-geo-country: ISO 3166-1 alpha-2 country code (e.g., 'IN', 'US', 'DE')\n * - x-geo-currency: ISO 4217 currency code (e.g., 'INR', 'USD', 'EUR')\n * - x-geo-timezone: IANA timezone (e.g., 'Asia/Kolkata', 'America/New_York')\n */\nfunction extractGeography(request: Request): { country?: string; currency?: string; timezone?: string } {\n const country = getHeader(request, 'x-geo-country');\n const currency = getHeader(request, 'x-geo-currency');\n const timezone = getHeader(request, 'x-geo-timezone');\n\n return {\n country: country?.toUpperCase() || undefined,\n currency: currency?.toUpperCase() || undefined,\n timezone: timezone || undefined,\n };\n}\n\n/**\n * Extract consent context from headers\n *\n * When an app or service acts on behalf of a user (with user consent),\n * the gateway forwards consent headers. This function extracts them.\n *\n * Headers:\n * - x-consent-granted-by: Actor ID who granted consent (delegating user)\n * - x-consent-scope: Comma-separated scopes\n * - x-consent-granted-at: ISO timestamp when consent was granted\n * - x-consent-expires-at: ISO timestamp when consent expires\n */\nfunction extractConsentContext(request: Request): import('./types.js').ConsentContext | null {\n const grantedBy = getHeader(request, 'x-consent-granted-by');\n\n // If no grantedBy, there's no consent delegation\n if (!grantedBy) {\n return null;\n }\n\n const scopesHeader = getHeader(request, 'x-consent-scope');\n const grantedAtHeader = getHeader(request, 'x-consent-granted-at');\n const expiresAtHeader = getHeader(request, 'x-consent-expires-at');\n\n return {\n grantedBy,\n scopes: scopesHeader ? scopesHeader.split(',').map((s) => s.trim()) : undefined,\n grantedAt: grantedAtHeader ? new Date(grantedAtHeader) : undefined,\n expiresAt: expiresAtHeader ? new Date(expiresAtHeader) : undefined,\n };\n}\n\n/**\n * Build GraphQL context from standard Web Request\n *\n * Also sets the workspace context in AsyncLocalStorage for automatic\n * Prisma workspaceId injection via the workspace extension.\n */\nexport async function buildContext(request: Request): Promise<GraphQLContext> {\n if (!contextOptions) {\n throw new Error('[ServerContext] Context not configured - call configureContext() first');\n }\n\n // Extract actor from headers/JWT\n const actor = await extractActor(request);\n\n // Extract all context parts\n const tenant = extractTenant(request);\n const organization = extractOrganization(request);\n const workspace = extractWorkspace(request, actor);\n const project = extractProject(request);\n const product = extractProduct(request);\n const tracking = extractTracking(request);\n const consentContext = extractConsentContext(request);\n\n // Build i18n context if configured\n let i18n: I18nContext | undefined;\n if (contextOptions.i18n) {\n i18n = contextOptions.i18n.createContextFromRequest(request);\n }\n\n // Merge geography context from x-geo-* headers into i18n\n const geo = extractGeography(request);\n if (geo.country || geo.currency || geo.timezone) {\n if (i18n) {\n // Merge geography fields into existing i18n context\n if (geo.country) i18n.country = geo.country;\n if (geo.currency) i18n.currency = geo.currency;\n if (geo.timezone) i18n.timezone = geo.timezone;\n } else {\n // Create minimal i18n context with geography only (when i18n module not configured)\n i18n = {\n locale: 'en-US',\n language: 'en',\n country: geo.country,\n currency: geo.currency,\n timezone: geo.timezone,\n t: (key: string) => key,\n tp: (key: string) => key,\n formatNumber: (value: number) => String(value),\n formatCurrency: (value: number, currency: string) => `${currency} ${value}`,\n formatDate: (date: Date | string) => String(date),\n formatRelativeTime: (value: number, unit: Intl.RelativeTimeFormatUnit) => `${value} ${unit}`,\n };\n }\n }\n\n // Determine onBehalfOf for audit trails\n // If actor is app/service with consent → use grantedBy (delegating user)\n // Otherwise → use actor.id (self-action)\n const onBehalfOf =\n (actor?.type === 'app' || actor?.type === 'service' || actor?.type === 'service_account') &&\n consentContext?.grantedBy\n ? consentContext.grantedBy\n : actor?.id;\n\n // Set workspace context in AsyncLocalStorage for Prisma workspace extension\n // This enables automatic workspaceId injection on create/update operations\n const wsCtxPayload = {\n workspaceId: workspace?.id,\n tenantId: tenant?.id,\n actorId: actor?.id,\n actorType: actor?.type,\n organizationId: organization?.id,\n projectId: project?.id,\n onBehalfOf,\n };\n\n logger.debug('[ServerContext] Setting workspace context', {\n workspaceId: wsCtxPayload.workspaceId ?? 'NONE',\n actorId: wsCtxPayload.actorId ?? 'NONE',\n rawHeader: getHeader(request, 'x-workspace-id') ?? 'MISSING',\n });\n\n setWorkspaceContext(wsCtxPayload);\n\n return {\n request,\n actor,\n tenant,\n organization,\n workspace,\n project,\n product,\n tracking,\n consentContext: consentContext || undefined,\n onBehalfOf: onBehalfOf || actor?.id || '',\n db: contextOptions.getDb(),\n i18n,\n responseHeaders: new Headers(),\n };\n}\n\n/**\n * Get context options\n */\nexport function getContextOptions(): ContextBuilderOptions | null {\n return contextOptions;\n}\n","import type { IActor } from './types.js';\n\nconst LOCALHOST_ORIGINS = [\n 'http://localhost:3000',\n 'http://localhost:4000',\n 'http://localhost:5173',\n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:4000',\n 'http://127.0.0.1:5173',\n];\n\nexport function normalizeCorsOrigins(\n origins: string | string[] | undefined,\n environment: 'development' | 'staging' | 'production' | undefined\n): string[] {\n const normalized = (Array.isArray(origins) ? origins : origins?.split(',') || [])\n .map((origin) => origin.trim())\n .filter(Boolean);\n\n if (normalized.length === 0) {\n return environment === 'production' ? [] : LOCALHOST_ORIGINS;\n }\n\n if (normalized.includes('*')) {\n return environment === 'production' ? [] : LOCALHOST_ORIGINS;\n }\n\n return normalized;\n}\n\nexport function resolveAllowedCorsOrigin(requestOrigin: string | null, allowedOrigins: string[]): string | null {\n if (!requestOrigin) {\n return allowedOrigins[0] ?? null;\n }\n\n return allowedOrigins.includes(requestOrigin) ? requestOrigin : null;\n}\n\nexport function canAccessGraphExport(actor: IActor | null): boolean {\n if (!actor) {\n return false;\n }\n\n return actor.isAdmin === true || ['service', 'super_admin'].includes(actor.type);\n}\n","/**\n * Server Module\n *\n * Main server bootstrapping with Elysia, GraphQL Yoga, and middleware.\n * Uses Bun runtime for high-performance GraphQL services.\n *\n * Provides a simple API for microservices to start a fully configured server.\n */\n\nimport { logger } from '../logger/index.js';\nimport { configureAuth, configureDefaultAuth, type FetchWorkspaceSecretFn } from './auth.js';\nimport { configureContext, buildContext } from './context.js';\nimport type {\n ServerDefinition,\n ServerInstance,\n ServerInfo,\n ElysiaApp,\n BunServerHandle,\n YogaPlugin,\n GraphQLContext,\n} from './types.js';\nimport { I18n } from '../i18n/index.js';\nimport { canAccessGraphExport, normalizeCorsOrigins, resolveAllowedCorsOrigin } from './security.js';\nimport { createHttpErrorResponse, createHumanReadableErrorPlugin, formatHttpError } from './errors.js';\n\n// Store startup time for uptime calculation\nlet serverStartTime: Date | null = null;\n\n/**\n * Create and configure a server instance using Elysia + GraphQL Yoga\n */\nexport async function createServer(definition: ServerDefinition): Promise<ServerInstance> {\n const {\n config,\n prismaClient,\n schema,\n moduleGraph,\n restEndpoints,\n yogaPlugins,\n buildContext: customBuildContext,\n workspaceExtensionConfig,\n disableWorkspaceExtension,\n onShutdown,\n } = definition;\n\n // Dynamic imports to avoid requiring these as hard dependencies\n const { Elysia } = await import('elysia');\n const { BunAdapter } = await import('elysia/adapter/bun');\n const { cors } = await import('@elysiajs/cors');\n const { createYoga } = await import('graphql-yoga');\n const { initializeDatabase, getDb, getDatabaseManager } = await import('../prisma/index.js');\n const { createSecurityPlugin } = await import('../middleware/index.js');\n const { createMetricsPlugin } = await import('../observability/index.js');\n const { createWorkspaceGuardPlugin } = await import('./workspace-guard.js');\n\n logger.info(`[Server] Initializing ${config.serviceName}...`);\n\n // Detect boundary from config or service name — needed before database and guard setup\n const boundary =\n config.boundary ??\n (config.serviceName.startsWith('wspace-')\n ? 'wspace'\n : config.serviceName.startsWith('global-')\n ? 'global'\n : 'wspace'); // fail-closed: default to wspace (stricter)\n\n // Initialize database\n // Workspace extension is auto-disabled for global boundary services unless explicitly enabled\n const shouldEnableWorkspaceExtension =\n disableWorkspaceExtension === true ? false : disableWorkspaceExtension === false ? true : boundary === 'wspace'; // auto-detect: enabled for wspace, disabled for global\n\n logger.info('[Server] Initializing database...', {\n boundary,\n workspaceExtension: shouldEnableWorkspaceExtension,\n });\n\n const { connect } = initializeDatabase(prismaClient, config.serviceName, {\n registerShutdownHandlers: false, // Server manages shutdown handlers itself\n enableWorkspaceExtension: shouldEnableWorkspaceExtension,\n ...(workspaceExtensionConfig ? { workspaceExtensionConfig } : {}),\n });\n await connect();\n\n // Initialize i18n if configured\n let i18nInstance: I18n | undefined;\n if (config.i18n?.enabled && config.i18n.localesPath) {\n logger.info('[Server] Initializing i18n...');\n i18nInstance = new I18n({\n defaultLocale: config.i18n.defaultLocale || 'en-US',\n fallbackLocale: config.i18n.fallbackLocale || 'en-US',\n localesPath: config.i18n.localesPath,\n supportedLocales: config.i18n.supportedLocales,\n namespace: config.i18n.namespace || config.serviceName,\n lazyLoad: config.i18n.lazyLoad,\n logMissing: config.i18n.logMissing ?? true,\n enableCache: true,\n returnKeyOnMissing: true,\n });\n await i18nInstance.initialize();\n logger.info(`[Server] i18n initialized with locales: ${i18nInstance.getSupportedLocales().join(', ')}`);\n }\n\n // Configure context builder\n configureContext({\n getDb: () => getDb(),\n i18n: i18nInstance,\n });\n\n // Auto-configure auth with default workspace secret fetcher if not already configured\n configureDefaultAuth();\n\n // Initialize module graph if provided\n if (moduleGraph) {\n logger.info('[Server] Initializing module graph...');\n await moduleGraph.initialize();\n }\n\n // Determine if playground/introspection should be enabled\n const isDev = config.environment !== 'production';\n const enablePlayground = config.enablePlayground ?? isDev;\n\n // Build workspace guard plugin — auto-enabled for wspace boundary only\n const workspaceGuardEnabled = config.workspaceGuard?.enabled ?? boundary === 'wspace';\n logger.info(`[Server] Boundary: ${boundary}, workspace guard: ${workspaceGuardEnabled ? 'enabled' : 'disabled'}`);\n\n const workspaceGuardPlugins = workspaceGuardEnabled\n ? [\n createWorkspaceGuardPlugin({\n enabled: true,\n whitelistedOperations: config.workspaceGuard?.whitelistedOperations,\n }),\n ]\n : [];\n\n // Create GraphQL Yoga instance\n const graphqlEndpoint = config.graphqlEndpoint || '/graphql';\n logger.info('[Server] Setting up GraphQL Yoga with provided schema...');\n\n const responseHeadersPlugin: YogaPlugin = {\n onResponse: ({ response, serverContext }: { response: Response; serverContext: unknown }) => {\n const yogaContext = serverContext as GraphQLContext;\n if (yogaContext?.responseHeaders) {\n yogaContext.responseHeaders.forEach((value: string, key: string) => {\n response.headers.append(key, value);\n });\n }\n },\n };\n\n const yoga = createYoga<{ request: Request }>({\n graphqlEndpoint,\n schema, // Use the schema provided by microservice\n graphiql: enablePlayground,\n logging: {\n debug: (...args) => logger.debug('[GraphQL]', ...args),\n info: (...args) => logger.info('[GraphQL]', ...args),\n warn: (...args) => logger.warn('[GraphQL]', ...args),\n error: (...args) => logger.error('[GraphQL]', ...args),\n },\n plugins: [\n createHumanReadableErrorPlugin({ serviceName: config.serviceName, environment: config.environment }),\n ...workspaceGuardPlugins,\n responseHeadersPlugin,\n ...(yogaPlugins || []),\n ],\n context: async ({ request }) => {\n // Build default context\n const defaultContext = await buildContext(request);\n\n // Apply custom context builder if provided\n if (customBuildContext) {\n return customBuildContext(defaultContext);\n }\n\n return defaultContext;\n },\n });\n\n // Create Elysia instance with Bun adapter\n const app = new Elysia({ adapter: BunAdapter });\n\n // Register CORS middleware\n const corsOrigins = normalizeCorsOrigins(config.corsOrigins, config.environment);\n\n app.use(\n cors({\n origin: corsOrigins,\n credentials: corsOrigins.length > 0,\n allowedHeaders: [\n 'Content-Type',\n 'Authorization',\n 'X-Tenant-ID',\n 'X-Workspace-ID',\n 'X-Org-ID',\n 'X-Project-ID',\n 'X-Product-ID',\n 'X-CSRF-Token',\n 'X-Service-Name',\n 'Accept-Language',\n 'X-Locale',\n 'X-Language',\n 'X-Geo-Country',\n 'X-Geo-Currency',\n 'X-Geo-Timezone',\n // Actor headers (gateway-injected or dev mode)\n 'X-Actor-ID',\n 'X-Actor-Type',\n 'X-Internal-Service-Token',\n 'X-Gateway-Auth-Token',\n ],\n methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],\n })\n );\n\n // Collect raw body endpoints for early interception\n const rawBodyEndpoints = (restEndpoints || []).filter((ep) => ep.rawBody);\n const rawBodyPaths = new Map(rawBodyEndpoints.map((ep) => [ep.path, ep]));\n const rawBodyMatchers = rawBodyEndpoints.map((endpoint) => {\n const regexPattern = endpoint.path.replace(/:[^/]+/g, '[^/]+');\n return {\n endpoint,\n regexPattern,\n regex: new RegExp(`^${regexPattern}$`),\n };\n });\n\n // Helper to match pathname against endpoint patterns (including :param placeholders)\n const matchRawBodyEndpoint = (pathname: string): (typeof rawBodyEndpoints)[0] | undefined => {\n // First try exact match (for non-parameterized paths)\n const exactMatch = rawBodyPaths.get(pathname);\n if (exactMatch) return exactMatch;\n\n // Try pattern matching for parameterized paths like /webhooks/slack/:channelId\n for (const { endpoint, regex, regexPattern } of rawBodyMatchers) {\n const isMatch = regex.test(pathname);\n logger.debug(\n `[Server] Checking ${pathname} against pattern ${endpoint.path} (regex: ${regexPattern}), match: ${isMatch}`\n );\n if (isMatch) {\n logger.debug(`[Server] Matched ${pathname} to pattern ${endpoint.path}`);\n return endpoint;\n }\n }\n\n logger.debug(`[Server] No raw body endpoint match for ${pathname}, rawBodyEndpoints: ${rawBodyEndpoints.length}`);\n return undefined;\n };\n\n // Handle GraphQL, metrics, and raw body requests BEFORE any middleware that consumes the body\n // This is critical because Yoga needs the raw request body stream\n // and webhook endpoints need raw body for signature verification\n // onRequest runs before onParse (body parsing) and onBeforeHandle\n app.onRequest(async ({ request }) => {\n const url = new URL(request.url);\n const pathname = url.pathname;\n logger.debug(`[Server] onRequest: ${request.method} ${pathname}`);\n const isHealthRoute = pathname === '/health' || pathname.startsWith('/health/');\n\n // Build CORS headers helper\n const buildCorsHeaders = (): Record<string, string> => {\n const origin = request.headers.get('origin') || '*';\n const allowedOrigin = resolveAllowedCorsOrigin(origin === '*' ? null : origin, corsOrigins);\n const headers: Record<string, string> = {\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers':\n 'Content-Type, Authorization, X-Tenant-ID, X-Workspace-ID, X-Org-ID, X-Project-ID, X-Product-ID, X-CSRF-Token, X-Service-Name, Accept-Language, X-Locale, X-Language, X-Geo-Country, X-Geo-Currency, X-Geo-Timezone, X-Actor-ID, X-Actor-Type, X-Internal-Service-Token, X-Gateway-Auth-Token',\n };\n\n if (allowedOrigin) {\n headers['Access-Control-Allow-Origin'] = allowedOrigin;\n headers['Access-Control-Allow-Credentials'] = 'true';\n }\n\n return headers;\n };\n\n // Check if this is a raw body endpoint (webhooks) - now supports parameterized paths\n const rawBodyEndpoint = isHealthRoute ? undefined : matchRawBodyEndpoint(pathname);\n if (rawBodyEndpoint) {\n logger.debug(`[Server] Matched raw body endpoint: ${pathname} -> ${rawBodyEndpoint.path}`);\n const corsHeaders = buildCorsHeaders();\n\n // Handle CORS preflight for raw body endpoints\n if (request.method === 'OPTIONS') {\n return new Response(null, {\n status: 204,\n headers: corsHeaders,\n });\n }\n\n // Only process if method matches\n if (request.method !== rawBodyEndpoint.method) {\n return undefined; // Let other handlers deal with it\n }\n\n try {\n // Read raw body BEFORE any parsing\n const rawBody = await request.text();\n\n // Build context without consuming body (body already read)\n const context = await buildContext(request);\n\n // Call the handler with raw body\n const result = await rawBodyEndpoint.handler(request, context, rawBody);\n\n // If handler returns a Response, use it directly\n if (result instanceof Response) {\n // Add CORS headers\n const headers = new Headers(result.headers);\n for (const [key, value] of Object.entries(corsHeaders)) {\n headers.set(key, value);\n }\n return new Response(result.body, {\n status: result.status,\n statusText: result.statusText,\n headers,\n });\n }\n\n // Otherwise, serialize as JSON\n const headers = new Headers({\n 'Content-Type': 'application/json',\n ...corsHeaders,\n });\n\n return new Response(JSON.stringify(result), {\n status: 200,\n headers,\n });\n } catch (error) {\n logger.error(`[Server] Raw body endpoint error (${pathname}):`, error);\n const corsHeaders = buildCorsHeaders();\n const formatted = formatHttpError(error, {\n serviceName: config.serviceName,\n environment: config.environment,\n });\n return new Response(JSON.stringify(formatted.body), {\n status: formatted.status,\n headers: {\n 'Content-Type': 'application/json',\n ...corsHeaders,\n },\n });\n }\n }\n\n // Serve Prometheus metrics via prom-client at /metrics.\n // The graphql-yoga prometheus plugin populates the same default registry,\n // so GraphQL-level metrics (operation durations, error counts, etc.) are\n // included automatically without needing Yoga to handle this route.\n if (pathname === '/metrics' && request.method === 'GET') {\n try {\n const promClientMod = 'prom-client';\n const prom = (await import(promClientMod)) as unknown as {\n register: { metrics: () => Promise<string> | string; contentType?: string };\n collectDefaultMetrics: (opts?: Record<string, unknown>) => void;\n };\n try {\n prom.collectDefaultMetrics({ register: prom.register });\n } catch {\n /* already called */\n }\n const body = await prom.register.metrics();\n return new Response(body, {\n status: 200,\n headers: {\n 'Content-Type': prom.register.contentType ?? 'text/plain; version=0.0.4; charset=utf-8',\n },\n });\n } catch {\n // fall through — prom-client not installed; let Yoga handle as fallback\n }\n }\n\n // Routes that should be handled by Yoga (GraphQL endpoint only)\n const yogaRoutes = [graphqlEndpoint, `${graphqlEndpoint}/`, '/metrics'];\n const shouldHandleByYoga = yogaRoutes.includes(pathname);\n\n if (shouldHandleByYoga) {\n const corsHeaders = buildCorsHeaders();\n\n // Handle CORS preflight\n if (request.method === 'OPTIONS') {\n return new Response(null, {\n status: 204,\n headers: corsHeaders,\n });\n }\n\n // Get response from Yoga\n const yogaResponse = await yoga.fetch(request);\n\n // Add CORS headers to Yoga response\n const headers = new Headers(yogaResponse.headers);\n for (const [key, value] of Object.entries(corsHeaders)) {\n headers.set(key, value);\n }\n\n // Return response with CORS headers\n return new Response(yogaResponse.body, {\n status: yogaResponse.status,\n statusText: yogaResponse.statusText,\n headers,\n });\n }\n // Return undefined to continue to next handlers for non-GraphQL requests\n return undefined;\n });\n\n // Register metrics middleware (after GraphQL interception)\n app.use(createMetricsPlugin());\n\n // Register security middleware (after GraphQL interception)\n app.use(\n createSecurityPlugin({\n csrfSkipRoutes: config.csrfSkipRoutes || ['/graphql', '/health', '/api/graph/'],\n loginEndpoints: config.loginEndpoints || [],\n enableCSRF: config.enableCSRF ?? false, // Disabled by default for GraphQL services\n enableSessionSecurity: config.enableSessionSecurity ?? false,\n })\n );\n\n // Health check endpoints\n // /health - General health check\n // /health/live - Kubernetes liveness probe\n // /health/ready - Kubernetes readiness probe\n // /health/startup - Kubernetes startup probe\n const healthResponse = () => ({\n status: 'healthy',\n service: config.serviceName,\n version: config.serviceVersion || '1.0.0',\n timestamp: new Date().toISOString(),\n });\n\n app.get('/health', healthResponse);\n app.get('/health/live', healthResponse);\n app.get('/health/ready', healthResponse);\n app.get('/health/startup', healthResponse);\n\n // Graph API endpoints (if moduleGraph provided)\n if (moduleGraph) {\n // Get graph configuration schema\n app.get('/api/graph/schema', async ({ request, set }) => {\n const context = await buildContext(request);\n if (!canAccessGraphExport(context.actor)) {\n set.status = 403;\n return { error: 'Forbidden' };\n }\n\n return moduleGraph.getSchema();\n });\n\n // Export all graph data\n app.get('/api/graph/export', async ({ query, request, set }) => {\n const context = await buildContext(request);\n if (!canAccessGraphExport(context.actor)) {\n set.status = 403;\n return { error: 'Forbidden' };\n }\n\n const { organizationId, workspaceId } = query as { organizationId?: string; workspaceId?: string };\n return moduleGraph.exportAll(organizationId, workspaceId);\n });\n\n // Export entities only\n app.get('/api/graph/entities', async ({ query, request, set }) => {\n const context = await buildContext(request);\n if (!canAccessGraphExport(context.actor)) {\n set.status = 403;\n return { error: 'Forbidden' };\n }\n\n const { organizationId, workspaceId, types } = query as {\n organizationId?: string;\n workspaceId?: string;\n types?: string;\n };\n const entityTypes = types?.split(',').map((t) => t.trim());\n return moduleGraph.exportEntities(organizationId, workspaceId, entityTypes);\n });\n\n // Export relationships only\n app.get('/api/graph/relationships', async ({ query, request, set }) => {\n const context = await buildContext(request);\n if (!canAccessGraphExport(context.actor)) {\n set.status = 403;\n return { error: 'Forbidden' };\n }\n\n const { organizationId, workspaceId } = query as { organizationId?: string; workspaceId?: string };\n return moduleGraph.exportRelationships(organizationId, workspaceId);\n });\n }\n\n // Register custom REST endpoints (skip rawBody endpoints - they're handled in onRequest)\n if (restEndpoints && restEndpoints.length > 0) {\n for (const endpoint of restEndpoints) {\n // Skip rawBody endpoints - they're intercepted in onRequest before body parsing\n if (endpoint.rawBody) {\n logger.info(`[Server] Raw body endpoint registered: ${endpoint.method} ${endpoint.path}`);\n continue;\n }\n\n const handler = async ({ request }: { request: Request }): Promise<unknown> => {\n try {\n const context = await buildContext(request);\n return await endpoint.handler(request, context);\n } catch (error) {\n logger.error(`[Server] REST endpoint error (${endpoint.path}):`, error);\n return createHttpErrorResponse(error, {\n serviceName: config.serviceName,\n environment: config.environment,\n });\n }\n };\n\n switch (endpoint.method) {\n case 'GET':\n app.get(endpoint.path, handler);\n break;\n case 'POST':\n app.post(endpoint.path, handler);\n break;\n case 'PUT':\n app.put(endpoint.path, handler);\n break;\n case 'PATCH':\n app.patch(endpoint.path, handler);\n break;\n case 'DELETE':\n app.delete(endpoint.path, handler);\n break;\n }\n }\n }\n\n const host = config.host || '0.0.0.0';\n const port = config.port;\n\n // Create server instance\n const serverInstance: ServerInstance = {\n app: app as unknown as ElysiaApp,\n server: null,\n start: async () => {\n serverStartTime = new Date();\n\n // Call listen() which starts the server and makes app.server available\n app.listen({\n port,\n hostname: host,\n });\n\n // Access the Bun server instance from the app\n // Cast through unknown to satisfy TypeScript since Elysia's types are complex\n const elysiaApp = app as unknown as { server: BunServerHandle | null };\n serverInstance.server = elysiaApp.server;\n\n logger.info(`🚀 ${config.serviceName} is running at http://${host}:${port}${graphqlEndpoint}`);\n },\n stop: async () => {\n logger.info(`[Server] Stopping ${config.serviceName}...`);\n\n if (onShutdown) {\n await onShutdown();\n }\n\n if (moduleGraph) {\n await moduleGraph.shutdown();\n }\n\n await getDatabaseManager().disconnect();\n\n if (serverInstance.server) {\n serverInstance.server.stop();\n }\n\n logger.info(`[Server] ${config.serviceName} stopped`);\n },\n getInfo: (): ServerInfo => {\n const uptime = serverStartTime ? Math.floor((Date.now() - serverStartTime.getTime()) / 1000) : 0;\n\n return {\n serviceName: config.serviceName,\n serviceVersion: config.serviceVersion || '1.0.0',\n environment: config.environment || 'development',\n port,\n host,\n graphqlEndpoint,\n startedAt: serverStartTime?.toISOString() || '',\n uptime,\n };\n },\n };\n\n // Setup graceful shutdown handlers\n const gracefulShutdown = async (signal: string): Promise<never> => {\n logger.info(`[Server] ${signal} received, shutting down gracefully...`);\n await serverInstance.stop();\n process.exit(0);\n };\n\n process.on('SIGTERM', () => {\n void gracefulShutdown('SIGTERM');\n });\n process.on('SIGINT', () => {\n void gracefulShutdown('SIGINT');\n });\n\n return serverInstance;\n}\n\n/**\n * Configure auth with workspace secret fetcher\n *\n * This should be called before creating the server if using workspace-scoped JWT\n */\nexport function configureServerAuth(fetchWorkspaceSecret: FetchWorkspaceSecretFn): void {\n configureAuth({ fetchWorkspaceSecret });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/server/auth.ts","../../src/server/context.ts","../../src/server/security.ts","../../src/server/server.ts"],"names":["getDbFn","getDb","prismaModule","joseModule","jwtModule","getJose","getJwt","jwt","default","authConfig","configureAuth","config","logger","debug","fetchWorkspaceSecret","workspaceId","db","workspace","client","findUnique","where","id","jwtSecret","JSON","parse","stringify","error","warn","configureDefaultAuth","generateSymmetricSecret","joseLib","secret","generateSecret","jwk","exportJWK","verifyJWT","token","options","decoded","decode","complete","payload","verifiedJwt","verify","mapPayloadToActor","decodedJwt","decodeJwt","workspace_id","workspaceSecret","keyLikeSecret","importJWK","jwtVerify","err","decodeJWT","sub","type","actor_type","tenant_id","org_id","isAdmin","authCheck","actor","Error","workspaceCheck","context","actorId","requireWorkspace","orgCheck","organization","orgId","tenantCheck","tenant","contextOptions","configureContext","getHeader","request","key","headers","get","toLowerCase","undefined","compareSecret","provided","expected","providedBuffer","Buffer","from","expectedBuffer","length","crypto","timingSafeEqual","shouldTrustActorHeaders","nodeEnv","process","env","expectedGatewayToken","providedGatewayToken","extractTracking","forwardedFor","realIp","ip","split","trim","userAgent","extractActor","actorType","userRole","authHeader","startsWith","substring","extractTenant","tenantId","tenantEndpoint","endpoint","defaultTenant","extractOrganization","extractWorkspace","extractProject","projectId","extractProduct","productId","extractGeography","country","currency","timezone","toUpperCase","extractConsentContext","grantedBy","scopesHeader","grantedAtHeader","expiresAtHeader","scopes","map","s","grantedAt","Date","expiresAt","buildContext","project","product","tracking","consentContext","i18n","createContextFromRequest","geo","locale","language","t","tp","formatNumber","value","String","formatCurrency","formatDate","date","formatRelativeTime","unit","onBehalfOf","wsCtxPayload","organizationId","rawHeader","setWorkspaceContext","responseHeaders","Headers","getContextOptions","LOCALHOST_ORIGINS","normalizeCorsOrigins","origins","environment","normalized","Array","isArray","origin","filter","Boolean","includes","resolveAllowedCorsOrigin","requestOrigin","allowedOrigins","canAccessGraphExport","serverStartTime","createServer","definition","prismaClient","schema","moduleGraph","restEndpoints","yogaPlugins","customBuildContext","workspaceExtensionConfig","disableWorkspaceExtension","onShutdown","Elysia","BunAdapter","cors","createYoga","initializeDatabase","getDatabaseManager","createSecurityPlugin","createMetricsPlugin","createWorkspaceGuardPlugin","info","serviceName","boundary","shouldEnableWorkspaceExtension","workspaceExtension","connect","registerShutdownHandlers","enableWorkspaceExtension","i18nInstance","enabled","localesPath","I18n","defaultLocale","fallbackLocale","supportedLocales","namespace","lazyLoad","logMissing","enableCache","returnKeyOnMissing","initialize","getSupportedLocales","join","isDev","enablePlayground","workspaceGuardEnabled","workspaceGuard","workspaceGuardPlugins","whitelistedOperations","graphqlEndpoint","responseHeadersPlugin","onResponse","response","serverContext","yogaContext","forEach","append","yoga","graphiql","logging","args","plugins","createHumanReadableErrorPlugin","defaultContext","app","adapter","corsOrigins","use","credentials","allowedHeaders","methods","rawBodyEndpoints","ep","rawBody","rawBodyPaths","Map","path","rawBodyMatchers","regexPattern","replace","regex","RegExp","matchRawBodyEndpoint","pathname","exactMatch","isMatch","test","onRequest","url","URL","method","isHealthRoute","buildCorsHeaders","allowedOrigin","rawBodyEndpoint","corsHeaders","Response","status","text","result","handler","Object","entries","set","body","statusText","formatted","formatHttpError","promClientMod","prom","collectDefaultMetrics","register","metrics","contentType","yogaRoutes","shouldHandleByYoga","yogaResponse","normalizeGraphQLResponse","fetch","csrfSkipRoutes","loginEndpoints","enableCSRF","enableSessionSecurity","healthResponse","service","version","serviceVersion","timestamp","toISOString","getSchema","query","exportAll","types","entityTypes","exportEntities","exportRelationships","createHttpErrorResponse","post","put","patch","delete","host","port","serverInstance","server","start","listen","hostname","elysiaApp","stop","shutdown","disconnect","getInfo","uptime","Math","floor","now","getTime","startedAt","gracefulShutdown","signal","exit","on","configureServerAuth"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Server Auth Module\n *\n * JWT verification with workspace secret fetching for microservices.\n * Handles HS256 tokens with secrets stored in workspace database.\n */\n\nimport { logger } from '../logger/index.js';\nimport type { IActor, JWTPayload, WorkspaceSecret } from './types.js';\n\n// Type imports from packages\nimport type * as jose from 'jose';\nimport type { VerifyOptions, Jwt, JwtPayload } from 'jsonwebtoken';\n\n/**\n * Workspace model interface for fetching JWT secrets\n */\ninterface WorkspaceModel {\n findUnique: (args: { where: { id: string } }) => Promise<{ jwtSecret?: unknown } | null>;\n}\n\ninterface DbClient {\n client: {\n workspace: WorkspaceModel;\n };\n}\n\n// Import getDb dynamically to avoid circular dependencies\nlet getDbFn: (() => DbClient) | null = null;\n\nasync function getDb(): Promise<DbClient> {\n if (!getDbFn) {\n const prismaModule = await import('../prisma/index.js');\n // Use unknown first then cast to avoid type inference issues\n getDbFn = prismaModule.getDb as unknown as () => DbClient;\n }\n return getDbFn();\n}\n\n// Interface for the subset of jsonwebtoken we use\ninterface JwtModule {\n decode(token: string, options?: { complete?: boolean }): string | Jwt | JwtPayload | null;\n verify(token: string, secretOrPublicKey: string, options?: VerifyOptions): string | JwtPayload;\n}\n\n// Module cache for dynamic imports\nlet joseModule: typeof jose | null = null;\nlet jwtModule: JwtModule | null = null;\n\nasync function getJose(): Promise<typeof jose> {\n if (!joseModule) {\n joseModule = await import('jose');\n }\n return joseModule;\n}\n\nasync function getJwt(): Promise<JwtModule> {\n if (!jwtModule) {\n const jwt = await import('jsonwebtoken');\n // Handle both ESM and CJS module formats\n jwtModule = (jwt as { default?: JwtModule }).default ?? jwt;\n }\n return jwtModule;\n}\n\n/**\n * Fetch workspace secret callback type\n */\nexport type FetchWorkspaceSecretFn = (workspaceId: string) => Promise<WorkspaceSecret | null>;\n\n/**\n * Auth configuration\n */\nexport interface AuthConfig {\n /** Function to fetch workspace JWT secret from database */\n fetchWorkspaceSecret: FetchWorkspaceSecretFn;\n}\n\nlet authConfig: AuthConfig | null = null;\n\n/**\n * Configure auth module with workspace secret fetching\n */\nexport function configureAuth(config: AuthConfig): void {\n authConfig = config;\n logger.debug('[ServerAuth] Auth configured');\n}\n\n/**\n * Default workspace secret fetcher\n *\n * Fetches JWT secret from workspace database. This is the standard implementation\n * that works with any microservice that has access to the workspace model.\n *\n * @param workspaceId - Workspace ID from JWT\n * @returns WorkspaceSecret or null if not found\n */\nexport async function fetchWorkspaceSecret(workspaceId: string): Promise<WorkspaceSecret | null> {\n try {\n const db = await getDb();\n const workspace = await db.client.workspace.findUnique({\n where: { id: workspaceId },\n });\n\n if (!workspace?.jwtSecret) {\n logger.debug('[ServerAuth] No JWT secret found for workspace', { workspaceId });\n return null;\n }\n\n return JSON.parse(JSON.stringify(workspace.jwtSecret)) as WorkspaceSecret;\n } catch (error) {\n logger.warn('[ServerAuth] Error fetching workspace secret', { workspaceId, error });\n return null;\n }\n}\n\n/**\n * Configure auth with default workspace secret fetcher\n *\n * This is automatically called by createServer if no custom auth is configured.\n */\nexport function configureDefaultAuth(): void {\n if (!authConfig) {\n configureAuth({ fetchWorkspaceSecret });\n logger.debug('[ServerAuth] Default auth configured with built-in workspace secret fetcher');\n }\n}\n\n/**\n * Generate a symmetric secret key for JWT signing\n * @returns JWK object with the generated key\n */\nexport async function generateSymmetricSecret(): Promise<jose.JWK> {\n const joseLib = await getJose();\n const secret = await joseLib.generateSecret('HS256');\n const jwk = await joseLib.exportJWK(secret);\n return jwk;\n}\n\n/**\n * Verify JWT token for workspace-scoped authentication\n *\n * @param token - JWT token to verify\n * @param secret - Optional secret for verification (if not provided, fetches from workspace)\n * @param options - JWT verification options\n * @returns Verified actor information or null if invalid\n */\nexport async function verifyJWT(token: string, secret?: string, options: VerifyOptions = {}): Promise<IActor | null> {\n try {\n const jwt = await getJwt();\n const joseLib = await getJose();\n\n // Decode to check algorithm and extract workspace_id\n const decoded = jwt.decode(token, { complete: true });\n\n if (!decoded || typeof decoded === 'string' || !decoded.payload || typeof decoded.payload !== 'object') {\n logger.warn('[ServerAuth] Invalid token format');\n return null;\n }\n\n // For workspace-scoped HS256 tokens\n if (secret) {\n // Use provided secret\n const verifiedJwt = jwt.verify(token, secret, options) as JWTPayload;\n return mapPayloadToActor(verifiedJwt);\n }\n\n // Fetch secret from workspace database\n const decodedJwt = joseLib.decodeJwt(token) as JWTPayload;\n if (!decodedJwt.workspace_id) {\n logger.warn('[ServerAuth] No workspace_id found in token');\n return null;\n }\n\n if (!authConfig?.fetchWorkspaceSecret) {\n logger.error('[ServerAuth] Auth not configured - call configureAuth() first');\n return null;\n }\n\n const workspaceSecret = await authConfig.fetchWorkspaceSecret(decodedJwt.workspace_id);\n if (!workspaceSecret) {\n logger.warn('[ServerAuth] Workspace secret not found');\n return null;\n }\n\n const keyLikeSecret = await joseLib.importJWK(workspaceSecret, 'HS256');\n const verifiedJwt = await joseLib.jwtVerify(token, keyLikeSecret, options as jose.JWTVerifyOptions);\n return mapPayloadToActor(verifiedJwt.payload as unknown as JWTPayload);\n } catch (err) {\n logger.warn('[ServerAuth] Error verifying JWT:', err);\n return null;\n }\n}\n\n/**\n * Decode JWT without verification (for extracting claims)\n */\nexport async function decodeJWT(token: string): Promise<JWTPayload | null> {\n try {\n const joseLib = await getJose();\n return await joseLib.decodeJwt(token);\n } catch {\n return null;\n }\n}\n\n/**\n * Map JWT payload to IActor interface\n */\nfunction mapPayloadToActor(payload: JWTPayload): IActor {\n return {\n id: payload.sub,\n type: payload.actor_type ?? 'user',\n workspace_id: payload.workspace_id,\n tenant_id: payload.tenant_id,\n org_id: payload.org_id,\n isAdmin: payload['isAdmin'] as boolean | undefined,\n };\n}\n\n/**\n * Check if actor is authenticated\n */\nexport function authCheck(actor: IActor | null): IActor {\n if (!actor) {\n throw new Error('Please sign in');\n }\n return actor;\n}\n\n/**\n * Check workspace context and return actor ID and workspace ID\n */\nexport function workspaceCheck(context: { actor: IActor | null; workspace: { id: string } | null }): {\n actorId: string;\n workspaceId: string;\n} {\n const actor = authCheck(context.actor);\n\n if (!context.workspace?.id) {\n throw new Error('Please switch to a workspace');\n }\n\n return {\n actorId: actor.id,\n workspaceId: context.workspace.id,\n };\n}\n\n/**\n * Require workspace context - type narrowing guard for wspace layer services\n *\n * Validates that both actor and workspace are present in the context,\n * and returns a type-narrowed context where workspace and actor are guaranteed non-null.\n * Use this at the start of resolvers in wspace services to get typed access\n * to workspace context without optional chaining.\n *\n * @throws Error if actor is not authenticated\n * @throws Error if workspace context is missing\n *\n * @example\n * ```typescript\n * // In a resolver:\n * const ctx = requireWorkspace(context);\n * const workspaceId = ctx.workspace.id; // no optional chaining needed\n * const actorId = ctx.actor.id; // no optional chaining needed\n * ```\n */\nexport function requireWorkspace<T extends { actor: IActor | null; workspace: { id: string } | null }>(\n context: T\n): T & { actor: IActor; workspace: { id: string } } {\n // Validate actor is authenticated (throws if null)\n authCheck(context.actor);\n\n if (!context.workspace?.id) {\n throw new Error('Please switch to a workspace');\n }\n\n // Return the same context object with narrowed types\n return context as T & { actor: IActor; workspace: { id: string } };\n}\n\n/**\n * Check organization context and return actor ID and org ID\n */\nexport function orgCheck(context: { actor: IActor | null; organization: { id: string } | null }): {\n actorId: string;\n orgId: string;\n} {\n const actor = authCheck(context.actor);\n\n if (!context.organization?.id) {\n throw new Error('Please switch to an organization');\n }\n\n return {\n actorId: actor.id,\n orgId: context.organization.id,\n };\n}\n\n/**\n * Check tenant context and return tenant ID\n */\nexport function tenantCheck(context: { tenant: { id: string } | null }): string {\n if (!context.tenant?.id) {\n throw new Error('Tenant context is required');\n }\n return context.tenant.id;\n}\n\n/**\n * Get effective actor ID for \"on behalf of\" tracking\n *\n * When an app or service acts with user consent, returns the delegating user's ID.\n * Otherwise returns the direct actor ID.\n *\n * This is used to determine the `onBehalfOf` field in database audit trails:\n * - If actor is user → returns user ID (self-action)\n * - If actor is app/service with consent → returns grantedBy user ID\n * - If actor is app/service without consent → returns actor ID (self-action)\n *\n * @param context - GraphQL context with actor and optional consent context\n * @returns Effective actor ID (the responsible principal)\n *\n * @example\n * ```typescript\n * // User acting directly\n * context.actor = { id: \"user-123\", type: \"user\" }\n * context.consentContext = undefined\n * getEffectiveActorId(context) // → \"user-123\"\n *\n * // Bot acting on behalf of user\n * context.actor = { id: \"bot-456\", type: \"service\" }\n * context.consentContext = { grantedBy: \"user-789\" }\n * getEffectiveActorId(context) // → \"user-789\"\n *\n * // App acting without consent (self-action)\n * context.actor = { id: \"app-abc\", type: \"app\" }\n * context.consentContext = undefined\n * getEffectiveActorId(context) // → \"app-abc\"\n * ```\n */\nexport function getEffectiveActorId(context: {\n actor: IActor | null;\n consentContext?: { grantedBy: string } | null;\n}): string | null {\n if (!context.actor) {\n return null;\n }\n\n // If actor is app or service acting with user consent, return the delegating user\n if (\n (context.actor.type === 'app' || context.actor.type === 'service' || context.actor.type === 'service_account') &&\n context.consentContext?.grantedBy\n ) {\n return context.consentContext.grantedBy;\n }\n\n // Otherwise return the direct actor (user self-action or app/service self-action)\n return context.actor.id;\n}\n","/**\n * Server Context Module\n *\n * Builds GraphQL context from request headers, JWT, and configuration.\n * Automatically populates actor, tenant, workspace, and tracking information.\n *\n * **Actor-Based Authentication:**\n * - Production: Gateway verifies JWT → populates x-actor-* headers → services trust headers\n * - Development: Services verify JWT directly and build actor from payload\n *\n * Uses standard Web API Request (compatible with Bun/Elysia).\n */\n\nimport { logger } from '../logger/index.js';\nimport crypto from 'node:crypto';\nimport { verifyJWT } from './auth.js';\nimport type {\n GraphQLContext,\n IActor,\n ITenant,\n IOrganization,\n IWorkspace,\n IProject,\n IProduct,\n ITracking,\n} from './types.js';\nimport type { I18n, I18nContext } from '../i18n/index.js';\nimport { setWorkspaceContext } from '../prisma/workspace-extension.js';\n\n/**\n * Context builder options\n */\nexport interface ContextBuilderOptions {\n /** Database getter function */\n getDb: () => unknown;\n /** Default tenant info (optional) */\n defaultTenant?: ITenant;\n /** I18n instance (optional) */\n i18n?: I18n;\n}\n\nlet contextOptions: ContextBuilderOptions | null = null;\n\n/**\n * Configure context builder\n */\nexport function configureContext(options: ContextBuilderOptions): void {\n contextOptions = options;\n logger.debug('[ServerContext] Context builder configured');\n}\n\n/**\n * Extract header value from standard Web API Request\n */\nfunction getHeader(request: Request, key: string): string | undefined {\n return request.headers.get(key.toLowerCase()) ?? undefined;\n}\n\nfunction compareSecret(provided: string, expected: string): boolean {\n const providedBuffer = Buffer.from(provided);\n const expectedBuffer = Buffer.from(expected);\n\n if (providedBuffer.length !== expectedBuffer.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(providedBuffer, expectedBuffer);\n}\n\nexport function shouldTrustActorHeaders(\n request: Request,\n nodeEnv: string | undefined = process.env['NODE_ENV'],\n expectedGatewayToken: string | undefined = process.env['TRUSTED_GATEWAY_TOKEN'] ??\n process.env['INTERNAL_SERVICE_TOKEN']\n): boolean {\n if (!getHeader(request, 'x-actor-id')) {\n return false;\n }\n\n if (nodeEnv === 'production') {\n return true;\n }\n\n const providedGatewayToken =\n getHeader(request, 'x-internal-service-token') || getHeader(request, 'x-gateway-auth-token');\n if (!expectedGatewayToken || !providedGatewayToken) {\n return false;\n }\n\n return compareSecret(providedGatewayToken, expectedGatewayToken);\n}\n\n/**\n * Extract tracking information from request\n */\nfunction extractTracking(request: Request): ITracking {\n // Get IP from various possible headers\n const forwardedFor = getHeader(request, 'x-forwarded-for');\n const realIp = getHeader(request, 'x-real-ip');\n const ip = forwardedFor?.split(',')[0]?.trim() || realIp || undefined;\n\n return {\n ip,\n userAgent: getHeader(request, 'user-agent'),\n };\n}\n\n/**\n * Extract actor from gateway-injected headers or authorization header\n *\n * **Actor-Based Authentication:**\n * - If x-actor-id header exists, trust it (gateway-authenticated)\n * - Otherwise fall back to JWT verification (direct access in dev)\n *\n * This allows:\n * - Production: Gateway verifies JWT → populates x-actor-* headers → services trust headers\n * - Development: Direct service access with JWT → service verifies JWT itself\n * - Development testing: Direct headers → service trusts headers\n */\nasync function extractActor(request: Request): Promise<IActor | null> {\n // Check for gateway-injected actor headers first\n const actorId = getHeader(request, 'x-actor-id');\n\n if (actorId && shouldTrustActorHeaders(request)) {\n // Gateway has already verified JWT and populated context headers\n // Trust the headers (gateway is the security perimeter)\n logger.debug('[ServerContext] Using gateway-authenticated actor from headers');\n\n const actorType = getHeader(request, 'x-actor-type') || 'user';\n const userRole = getHeader(request, 'x-user-role');\n\n return {\n id: actorId,\n type: actorType,\n workspace_id: getHeader(request, 'x-workspace-id'),\n tenant_id: getHeader(request, 'x-tenant-id'),\n org_id: getHeader(request, 'x-org-id') || getHeader(request, 'x-organization-id'),\n isAdmin:\n actorType === 'super_admin' ||\n userRole === 'TENANT_ADMIN' ||\n userRole === 'SUPER_ADMIN' ||\n userRole === 'PLATFORM_ADMIN',\n };\n }\n\n if (actorId) {\n logger.warn('[ServerContext] Ignoring untrusted actor headers and falling back to JWT verification');\n }\n\n // FALLBACK: No gateway headers, verify JWT directly (dev/testing mode)\n const authHeader = getHeader(request, 'authorization');\n\n if (!authHeader?.startsWith('Bearer ')) {\n return null;\n }\n\n const token = authHeader.substring(7);\n\n try {\n logger.debug('[ServerContext] No gateway headers, verifying JWT directly for actor (dev mode)');\n const payload = await verifyJWT(token);\n\n if (!payload) {\n return null;\n }\n\n // Build actor from JWT payload\n return {\n id: payload.id,\n type: 'user', // Default to 'user' if not specified\n workspace_id: payload.workspace_id,\n };\n } catch (error) {\n logger.warn('[ServerContext] Invalid JWT token:', error);\n return null;\n }\n}\n\n/**\n * Extract tenant from headers\n */\nfunction extractTenant(request: Request): ITenant | null {\n // Check headers\n const tenantId = getHeader(request, 'x-tenant-id');\n const tenantEndpoint = getHeader(request, 'x-tenant-endpoint');\n\n if (tenantId) {\n return {\n id: tenantId,\n endpoint: tenantEndpoint || '',\n };\n }\n\n // Fall back to default tenant if configured\n return contextOptions?.defaultTenant || null;\n}\n\n/**\n * Extract organization from headers\n */\nfunction extractOrganization(request: Request): IOrganization | null {\n const orgId = getHeader(request, 'x-org-id') || getHeader(request, 'x-organization-id');\n\n if (orgId) {\n return { id: orgId };\n }\n\n return null;\n}\n\n/**\n * Extract workspace from headers or actor\n */\nfunction extractWorkspace(request: Request, actor: IActor | null): IWorkspace | null {\n // Check headers first\n const workspaceId = getHeader(request, 'x-workspace-id');\n\n if (workspaceId) {\n return { id: workspaceId };\n }\n\n // Fall back to workspace_id from actor\n if (actor?.workspace_id) {\n return { id: actor.workspace_id };\n }\n\n return null;\n}\n\n/**\n * Extract project from headers\n */\nfunction extractProject(request: Request): IProject | null {\n const projectId = getHeader(request, 'x-project-id');\n\n if (projectId) {\n return { id: projectId };\n }\n\n return null;\n}\n\n/**\n * Extract product from headers\n */\nfunction extractProduct(request: Request): IProduct | null {\n const productId = getHeader(request, 'x-product-id');\n\n if (productId) {\n return { id: productId };\n }\n\n return null;\n}\n\n/**\n * Extract geography context from headers\n *\n * Geography headers carry the user's selected location context,\n * used for currency defaults, tax calculations, payment routing,\n * data residency, and regional support.\n *\n * Headers:\n * - x-geo-country: ISO 3166-1 alpha-2 country code (e.g., 'IN', 'US', 'DE')\n * - x-geo-currency: ISO 4217 currency code (e.g., 'INR', 'USD', 'EUR')\n * - x-geo-timezone: IANA timezone (e.g., 'Asia/Kolkata', 'America/New_York')\n */\nfunction extractGeography(request: Request): { country?: string; currency?: string; timezone?: string } {\n const country = getHeader(request, 'x-geo-country');\n const currency = getHeader(request, 'x-geo-currency');\n const timezone = getHeader(request, 'x-geo-timezone');\n\n return {\n country: country?.toUpperCase() || undefined,\n currency: currency?.toUpperCase() || undefined,\n timezone: timezone || undefined,\n };\n}\n\n/**\n * Extract consent context from headers\n *\n * When an app or service acts on behalf of a user (with user consent),\n * the gateway forwards consent headers. This function extracts them.\n *\n * Headers:\n * - x-consent-granted-by: Actor ID who granted consent (delegating user)\n * - x-consent-scope: Comma-separated scopes\n * - x-consent-granted-at: ISO timestamp when consent was granted\n * - x-consent-expires-at: ISO timestamp when consent expires\n */\nfunction extractConsentContext(request: Request): import('./types.js').ConsentContext | null {\n const grantedBy = getHeader(request, 'x-consent-granted-by');\n\n // If no grantedBy, there's no consent delegation\n if (!grantedBy) {\n return null;\n }\n\n const scopesHeader = getHeader(request, 'x-consent-scope');\n const grantedAtHeader = getHeader(request, 'x-consent-granted-at');\n const expiresAtHeader = getHeader(request, 'x-consent-expires-at');\n\n return {\n grantedBy,\n scopes: scopesHeader ? scopesHeader.split(',').map((s) => s.trim()) : undefined,\n grantedAt: grantedAtHeader ? new Date(grantedAtHeader) : undefined,\n expiresAt: expiresAtHeader ? new Date(expiresAtHeader) : undefined,\n };\n}\n\n/**\n * Build GraphQL context from standard Web Request\n *\n * Also sets the workspace context in AsyncLocalStorage for automatic\n * Prisma workspaceId injection via the workspace extension.\n */\nexport async function buildContext(request: Request): Promise<GraphQLContext> {\n if (!contextOptions) {\n throw new Error('[ServerContext] Context not configured - call configureContext() first');\n }\n\n // Extract actor from headers/JWT\n const actor = await extractActor(request);\n\n // Extract all context parts\n const tenant = extractTenant(request);\n const organization = extractOrganization(request);\n const workspace = extractWorkspace(request, actor);\n const project = extractProject(request);\n const product = extractProduct(request);\n const tracking = extractTracking(request);\n const consentContext = extractConsentContext(request);\n\n // Build i18n context if configured\n let i18n: I18nContext | undefined;\n if (contextOptions.i18n) {\n i18n = contextOptions.i18n.createContextFromRequest(request);\n }\n\n // Merge geography context from x-geo-* headers into i18n\n const geo = extractGeography(request);\n if (geo.country || geo.currency || geo.timezone) {\n if (i18n) {\n // Merge geography fields into existing i18n context\n if (geo.country) i18n.country = geo.country;\n if (geo.currency) i18n.currency = geo.currency;\n if (geo.timezone) i18n.timezone = geo.timezone;\n } else {\n // Create minimal i18n context with geography only (when i18n module not configured)\n i18n = {\n locale: 'en-US',\n language: 'en',\n country: geo.country,\n currency: geo.currency,\n timezone: geo.timezone,\n t: (key: string) => key,\n tp: (key: string) => key,\n formatNumber: (value: number) => String(value),\n formatCurrency: (value: number, currency: string) => `${currency} ${value}`,\n formatDate: (date: Date | string) => String(date),\n formatRelativeTime: (value: number, unit: Intl.RelativeTimeFormatUnit) => `${value} ${unit}`,\n };\n }\n }\n\n // Determine onBehalfOf for audit trails\n // If actor is app/service with consent → use grantedBy (delegating user)\n // Otherwise → use actor.id (self-action)\n const onBehalfOf =\n (actor?.type === 'app' || actor?.type === 'service' || actor?.type === 'service_account') &&\n consentContext?.grantedBy\n ? consentContext.grantedBy\n : actor?.id;\n\n // Set workspace context in AsyncLocalStorage for Prisma workspace extension\n // This enables automatic workspaceId injection on create/update operations\n const wsCtxPayload = {\n workspaceId: workspace?.id,\n tenantId: tenant?.id,\n actorId: actor?.id,\n actorType: actor?.type,\n organizationId: organization?.id,\n projectId: project?.id,\n onBehalfOf,\n };\n\n logger.debug('[ServerContext] Setting workspace context', {\n workspaceId: wsCtxPayload.workspaceId ?? 'NONE',\n actorId: wsCtxPayload.actorId ?? 'NONE',\n rawHeader: getHeader(request, 'x-workspace-id') ?? 'MISSING',\n });\n\n setWorkspaceContext(wsCtxPayload);\n\n return {\n request,\n actor,\n tenant,\n organization,\n workspace,\n project,\n product,\n tracking,\n consentContext: consentContext || undefined,\n onBehalfOf: onBehalfOf || actor?.id || '',\n db: contextOptions.getDb(),\n i18n,\n responseHeaders: new Headers(),\n };\n}\n\n/**\n * Get context options\n */\nexport function getContextOptions(): ContextBuilderOptions | null {\n return contextOptions;\n}\n","import type { IActor } from './types.js';\n\nconst LOCALHOST_ORIGINS = [\n 'http://localhost:3000',\n 'http://localhost:4000',\n 'http://localhost:5173',\n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:4000',\n 'http://127.0.0.1:5173',\n];\n\nexport function normalizeCorsOrigins(\n origins: string | string[] | undefined,\n environment: 'development' | 'staging' | 'production' | undefined\n): string[] {\n const normalized = (Array.isArray(origins) ? origins : origins?.split(',') || [])\n .map((origin) => origin.trim())\n .filter(Boolean);\n\n if (normalized.length === 0) {\n return environment === 'production' ? [] : LOCALHOST_ORIGINS;\n }\n\n if (normalized.includes('*')) {\n return environment === 'production' ? [] : LOCALHOST_ORIGINS;\n }\n\n return normalized;\n}\n\nexport function resolveAllowedCorsOrigin(requestOrigin: string | null, allowedOrigins: string[]): string | null {\n if (!requestOrigin) {\n return allowedOrigins[0] ?? null;\n }\n\n return allowedOrigins.includes(requestOrigin) ? requestOrigin : null;\n}\n\nexport function canAccessGraphExport(actor: IActor | null): boolean {\n if (!actor) {\n return false;\n }\n\n return actor.isAdmin === true || ['service', 'super_admin'].includes(actor.type);\n}\n","/**\n * Server Module\n *\n * Main server bootstrapping with Elysia, GraphQL Yoga, and middleware.\n * Uses Bun runtime for high-performance GraphQL services.\n *\n * Provides a simple API for microservices to start a fully configured server.\n */\n\nimport { logger } from '../logger/index.js';\nimport { configureAuth, configureDefaultAuth, type FetchWorkspaceSecretFn } from './auth.js';\nimport { configureContext, buildContext } from './context.js';\nimport type {\n ServerDefinition,\n ServerInstance,\n ServerInfo,\n ElysiaApp,\n BunServerHandle,\n YogaPlugin,\n GraphQLContext,\n} from './types.js';\nimport { I18n } from '../i18n/index.js';\nimport { canAccessGraphExport, normalizeCorsOrigins, resolveAllowedCorsOrigin } from './security.js';\nimport {\n createHttpErrorResponse,\n createHumanReadableErrorPlugin,\n formatHttpError,\n normalizeGraphQLResponse,\n} from './errors.js';\n\n// Store startup time for uptime calculation\nlet serverStartTime: Date | null = null;\n\n/**\n * Create and configure a server instance using Elysia + GraphQL Yoga\n */\nexport async function createServer(definition: ServerDefinition): Promise<ServerInstance> {\n const {\n config,\n prismaClient,\n schema,\n moduleGraph,\n restEndpoints,\n yogaPlugins,\n buildContext: customBuildContext,\n workspaceExtensionConfig,\n disableWorkspaceExtension,\n onShutdown,\n } = definition;\n\n // Dynamic imports to avoid requiring these as hard dependencies\n const { Elysia } = await import('elysia');\n const { BunAdapter } = await import('elysia/adapter/bun');\n const { cors } = await import('@elysiajs/cors');\n const { createYoga } = await import('graphql-yoga');\n const { initializeDatabase, getDb, getDatabaseManager } = await import('../prisma/index.js');\n const { createSecurityPlugin } = await import('../middleware/index.js');\n const { createMetricsPlugin } = await import('../observability/index.js');\n const { createWorkspaceGuardPlugin } = await import('./workspace-guard.js');\n\n logger.info(`[Server] Initializing ${config.serviceName}...`);\n\n // Detect boundary from config or service name — needed before database and guard setup\n const boundary =\n config.boundary ??\n (config.serviceName.startsWith('wspace-')\n ? 'wspace'\n : config.serviceName.startsWith('global-')\n ? 'global'\n : 'wspace'); // fail-closed: default to wspace (stricter)\n\n // Initialize database\n // Workspace extension is auto-disabled for global boundary services unless explicitly enabled\n const shouldEnableWorkspaceExtension =\n disableWorkspaceExtension === true ? false : disableWorkspaceExtension === false ? true : boundary === 'wspace'; // auto-detect: enabled for wspace, disabled for global\n\n logger.info('[Server] Initializing database...', {\n boundary,\n workspaceExtension: shouldEnableWorkspaceExtension,\n });\n\n const { connect } = initializeDatabase(prismaClient, config.serviceName, {\n registerShutdownHandlers: false, // Server manages shutdown handlers itself\n enableWorkspaceExtension: shouldEnableWorkspaceExtension,\n ...(workspaceExtensionConfig ? { workspaceExtensionConfig } : {}),\n });\n await connect();\n\n // Initialize i18n if configured\n let i18nInstance: I18n | undefined;\n if (config.i18n?.enabled && config.i18n.localesPath) {\n logger.info('[Server] Initializing i18n...');\n i18nInstance = new I18n({\n defaultLocale: config.i18n.defaultLocale || 'en-US',\n fallbackLocale: config.i18n.fallbackLocale || 'en-US',\n localesPath: config.i18n.localesPath,\n supportedLocales: config.i18n.supportedLocales,\n namespace: config.i18n.namespace || config.serviceName,\n lazyLoad: config.i18n.lazyLoad,\n logMissing: config.i18n.logMissing ?? true,\n enableCache: true,\n returnKeyOnMissing: true,\n });\n await i18nInstance.initialize();\n logger.info(`[Server] i18n initialized with locales: ${i18nInstance.getSupportedLocales().join(', ')}`);\n }\n\n // Configure context builder\n configureContext({\n getDb: () => getDb(),\n i18n: i18nInstance,\n });\n\n // Auto-configure auth with default workspace secret fetcher if not already configured\n configureDefaultAuth();\n\n // Initialize module graph if provided\n if (moduleGraph) {\n logger.info('[Server] Initializing module graph...');\n await moduleGraph.initialize();\n }\n\n // Determine if playground/introspection should be enabled\n const isDev = config.environment !== 'production';\n const enablePlayground = config.enablePlayground ?? isDev;\n\n // Build workspace guard plugin — auto-enabled for wspace boundary only\n const workspaceGuardEnabled = config.workspaceGuard?.enabled ?? boundary === 'wspace';\n logger.info(`[Server] Boundary: ${boundary}, workspace guard: ${workspaceGuardEnabled ? 'enabled' : 'disabled'}`);\n\n const workspaceGuardPlugins = workspaceGuardEnabled\n ? [\n createWorkspaceGuardPlugin({\n enabled: true,\n whitelistedOperations: config.workspaceGuard?.whitelistedOperations,\n }),\n ]\n : [];\n\n // Create GraphQL Yoga instance\n const graphqlEndpoint = config.graphqlEndpoint || '/graphql';\n logger.info('[Server] Setting up GraphQL Yoga with provided schema...');\n\n const responseHeadersPlugin: YogaPlugin = {\n onResponse: ({ response, serverContext }: { response: Response; serverContext: unknown }) => {\n const yogaContext = serverContext as GraphQLContext;\n if (yogaContext?.responseHeaders) {\n yogaContext.responseHeaders.forEach((value: string, key: string) => {\n response.headers.append(key, value);\n });\n }\n },\n };\n\n const yoga = createYoga<{ request: Request }>({\n graphqlEndpoint,\n schema, // Use the schema provided by microservice\n graphiql: enablePlayground,\n logging: {\n debug: (...args) => logger.debug('[GraphQL]', ...args),\n info: (...args) => logger.info('[GraphQL]', ...args),\n warn: (...args) => logger.warn('[GraphQL]', ...args),\n error: (...args) => logger.error('[GraphQL]', ...args),\n },\n plugins: [\n createHumanReadableErrorPlugin({ serviceName: config.serviceName, environment: config.environment }),\n ...workspaceGuardPlugins,\n responseHeadersPlugin,\n ...(yogaPlugins || []),\n ],\n context: async ({ request }) => {\n // Build default context\n const defaultContext = await buildContext(request);\n\n // Apply custom context builder if provided\n if (customBuildContext) {\n return customBuildContext(defaultContext);\n }\n\n return defaultContext;\n },\n });\n\n // Create Elysia instance with Bun adapter\n const app = new Elysia({ adapter: BunAdapter });\n\n // Register CORS middleware\n const corsOrigins = normalizeCorsOrigins(config.corsOrigins, config.environment);\n\n app.use(\n cors({\n origin: corsOrigins,\n credentials: corsOrigins.length > 0,\n allowedHeaders: [\n 'Content-Type',\n 'Authorization',\n 'X-Tenant-ID',\n 'X-Workspace-ID',\n 'X-Org-ID',\n 'X-Project-ID',\n 'X-Product-ID',\n 'X-CSRF-Token',\n 'X-Service-Name',\n 'Accept-Language',\n 'X-Locale',\n 'X-Language',\n 'X-Geo-Country',\n 'X-Geo-Currency',\n 'X-Geo-Timezone',\n // Actor headers (gateway-injected or dev mode)\n 'X-Actor-ID',\n 'X-Actor-Type',\n 'X-Internal-Service-Token',\n 'X-Gateway-Auth-Token',\n ],\n methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],\n })\n );\n\n // Collect raw body endpoints for early interception\n const rawBodyEndpoints = (restEndpoints || []).filter((ep) => ep.rawBody);\n const rawBodyPaths = new Map(rawBodyEndpoints.map((ep) => [ep.path, ep]));\n const rawBodyMatchers = rawBodyEndpoints.map((endpoint) => {\n const regexPattern = endpoint.path.replace(/:[^/]+/g, '[^/]+');\n return {\n endpoint,\n regexPattern,\n regex: new RegExp(`^${regexPattern}$`),\n };\n });\n\n // Helper to match pathname against endpoint patterns (including :param placeholders)\n const matchRawBodyEndpoint = (pathname: string): (typeof rawBodyEndpoints)[0] | undefined => {\n // First try exact match (for non-parameterized paths)\n const exactMatch = rawBodyPaths.get(pathname);\n if (exactMatch) return exactMatch;\n\n // Try pattern matching for parameterized paths like /webhooks/slack/:channelId\n for (const { endpoint, regex, regexPattern } of rawBodyMatchers) {\n const isMatch = regex.test(pathname);\n logger.debug(\n `[Server] Checking ${pathname} against pattern ${endpoint.path} (regex: ${regexPattern}), match: ${isMatch}`\n );\n if (isMatch) {\n logger.debug(`[Server] Matched ${pathname} to pattern ${endpoint.path}`);\n return endpoint;\n }\n }\n\n logger.debug(`[Server] No raw body endpoint match for ${pathname}, rawBodyEndpoints: ${rawBodyEndpoints.length}`);\n return undefined;\n };\n\n // Handle GraphQL, metrics, and raw body requests BEFORE any middleware that consumes the body\n // This is critical because Yoga needs the raw request body stream\n // and webhook endpoints need raw body for signature verification\n // onRequest runs before onParse (body parsing) and onBeforeHandle\n app.onRequest(async ({ request }) => {\n const url = new URL(request.url);\n const pathname = url.pathname;\n logger.debug(`[Server] onRequest: ${request.method} ${pathname}`);\n const isHealthRoute = pathname === '/health' || pathname.startsWith('/health/');\n\n // Build CORS headers helper\n const buildCorsHeaders = (): Record<string, string> => {\n const origin = request.headers.get('origin') || '*';\n const allowedOrigin = resolveAllowedCorsOrigin(origin === '*' ? null : origin, corsOrigins);\n const headers: Record<string, string> = {\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers':\n 'Content-Type, Authorization, X-Tenant-ID, X-Workspace-ID, X-Org-ID, X-Project-ID, X-Product-ID, X-CSRF-Token, X-Service-Name, Accept-Language, X-Locale, X-Language, X-Geo-Country, X-Geo-Currency, X-Geo-Timezone, X-Actor-ID, X-Actor-Type, X-Internal-Service-Token, X-Gateway-Auth-Token',\n };\n\n if (allowedOrigin) {\n headers['Access-Control-Allow-Origin'] = allowedOrigin;\n headers['Access-Control-Allow-Credentials'] = 'true';\n }\n\n return headers;\n };\n\n // Check if this is a raw body endpoint (webhooks) - now supports parameterized paths\n const rawBodyEndpoint = isHealthRoute ? undefined : matchRawBodyEndpoint(pathname);\n if (rawBodyEndpoint) {\n logger.debug(`[Server] Matched raw body endpoint: ${pathname} -> ${rawBodyEndpoint.path}`);\n const corsHeaders = buildCorsHeaders();\n\n // Handle CORS preflight for raw body endpoints\n if (request.method === 'OPTIONS') {\n return new Response(null, {\n status: 204,\n headers: corsHeaders,\n });\n }\n\n // Only process if method matches\n if (request.method !== rawBodyEndpoint.method) {\n return undefined; // Let other handlers deal with it\n }\n\n try {\n // Read raw body BEFORE any parsing\n const rawBody = await request.text();\n\n // Build context without consuming body (body already read)\n const context = await buildContext(request);\n\n // Call the handler with raw body\n const result = await rawBodyEndpoint.handler(request, context, rawBody);\n\n // If handler returns a Response, use it directly\n if (result instanceof Response) {\n // Add CORS headers\n const headers = new Headers(result.headers);\n for (const [key, value] of Object.entries(corsHeaders)) {\n headers.set(key, value);\n }\n return new Response(result.body, {\n status: result.status,\n statusText: result.statusText,\n headers,\n });\n }\n\n // Otherwise, serialize as JSON\n const headers = new Headers({\n 'Content-Type': 'application/json',\n ...corsHeaders,\n });\n\n return new Response(JSON.stringify(result), {\n status: 200,\n headers,\n });\n } catch (error) {\n logger.error(`[Server] Raw body endpoint error (${pathname}):`, error);\n const corsHeaders = buildCorsHeaders();\n const formatted = formatHttpError(error, {\n serviceName: config.serviceName,\n environment: config.environment,\n });\n return new Response(JSON.stringify(formatted.body), {\n status: formatted.status,\n headers: {\n 'Content-Type': 'application/json',\n ...corsHeaders,\n },\n });\n }\n }\n\n // Serve Prometheus metrics via prom-client at /metrics.\n // The graphql-yoga prometheus plugin populates the same default registry,\n // so GraphQL-level metrics (operation durations, error counts, etc.) are\n // included automatically without needing Yoga to handle this route.\n if (pathname === '/metrics' && request.method === 'GET') {\n try {\n const promClientMod = 'prom-client';\n const prom = (await import(promClientMod)) as unknown as {\n register: { metrics: () => Promise<string> | string; contentType?: string };\n collectDefaultMetrics: (opts?: Record<string, unknown>) => void;\n };\n try {\n prom.collectDefaultMetrics({ register: prom.register });\n } catch {\n /* already called */\n }\n const body = await prom.register.metrics();\n return new Response(body, {\n status: 200,\n headers: {\n 'Content-Type': prom.register.contentType ?? 'text/plain; version=0.0.4; charset=utf-8',\n },\n });\n } catch {\n // fall through — prom-client not installed; let Yoga handle as fallback\n }\n }\n\n // Routes that should be handled by Yoga (GraphQL endpoint only)\n const yogaRoutes = [graphqlEndpoint, `${graphqlEndpoint}/`, '/metrics'];\n const shouldHandleByYoga = yogaRoutes.includes(pathname);\n\n if (shouldHandleByYoga) {\n const corsHeaders = buildCorsHeaders();\n\n // Handle CORS preflight\n if (request.method === 'OPTIONS') {\n return new Response(null, {\n status: 204,\n headers: corsHeaders,\n });\n }\n\n // Get response from Yoga\n const yogaResponse = await normalizeGraphQLResponse(await yoga.fetch(request), {\n serviceName: config.serviceName,\n environment: config.environment,\n });\n\n // Add CORS headers to Yoga response\n const headers = new Headers(yogaResponse.headers);\n for (const [key, value] of Object.entries(corsHeaders)) {\n headers.set(key, value);\n }\n\n // Return response with CORS headers\n return new Response(yogaResponse.body, {\n status: yogaResponse.status,\n statusText: yogaResponse.statusText,\n headers,\n });\n }\n // Return undefined to continue to next handlers for non-GraphQL requests\n return undefined;\n });\n\n // Register metrics middleware (after GraphQL interception)\n app.use(createMetricsPlugin());\n\n // Register security middleware (after GraphQL interception)\n app.use(\n createSecurityPlugin({\n csrfSkipRoutes: config.csrfSkipRoutes || ['/graphql', '/health', '/api/graph/'],\n loginEndpoints: config.loginEndpoints || [],\n enableCSRF: config.enableCSRF ?? false, // Disabled by default for GraphQL services\n enableSessionSecurity: config.enableSessionSecurity ?? false,\n })\n );\n\n // Health check endpoints\n // /health - General health check\n // /health/live - Kubernetes liveness probe\n // /health/ready - Kubernetes readiness probe\n // /health/startup - Kubernetes startup probe\n const healthResponse = () => ({\n status: 'healthy',\n service: config.serviceName,\n version: config.serviceVersion || '1.0.0',\n timestamp: new Date().toISOString(),\n });\n\n app.get('/health', healthResponse);\n app.get('/health/live', healthResponse);\n app.get('/health/ready', healthResponse);\n app.get('/health/startup', healthResponse);\n\n // Graph API endpoints (if moduleGraph provided)\n if (moduleGraph) {\n // Get graph configuration schema\n app.get('/api/graph/schema', async ({ request, set }) => {\n const context = await buildContext(request);\n if (!canAccessGraphExport(context.actor)) {\n set.status = 403;\n return { error: 'Forbidden' };\n }\n\n return moduleGraph.getSchema();\n });\n\n // Export all graph data\n app.get('/api/graph/export', async ({ query, request, set }) => {\n const context = await buildContext(request);\n if (!canAccessGraphExport(context.actor)) {\n set.status = 403;\n return { error: 'Forbidden' };\n }\n\n const { organizationId, workspaceId } = query as { organizationId?: string; workspaceId?: string };\n return moduleGraph.exportAll(organizationId, workspaceId);\n });\n\n // Export entities only\n app.get('/api/graph/entities', async ({ query, request, set }) => {\n const context = await buildContext(request);\n if (!canAccessGraphExport(context.actor)) {\n set.status = 403;\n return { error: 'Forbidden' };\n }\n\n const { organizationId, workspaceId, types } = query as {\n organizationId?: string;\n workspaceId?: string;\n types?: string;\n };\n const entityTypes = types?.split(',').map((t) => t.trim());\n return moduleGraph.exportEntities(organizationId, workspaceId, entityTypes);\n });\n\n // Export relationships only\n app.get('/api/graph/relationships', async ({ query, request, set }) => {\n const context = await buildContext(request);\n if (!canAccessGraphExport(context.actor)) {\n set.status = 403;\n return { error: 'Forbidden' };\n }\n\n const { organizationId, workspaceId } = query as { organizationId?: string; workspaceId?: string };\n return moduleGraph.exportRelationships(organizationId, workspaceId);\n });\n }\n\n // Register custom REST endpoints (skip rawBody endpoints - they're handled in onRequest)\n if (restEndpoints && restEndpoints.length > 0) {\n for (const endpoint of restEndpoints) {\n // Skip rawBody endpoints - they're intercepted in onRequest before body parsing\n if (endpoint.rawBody) {\n logger.info(`[Server] Raw body endpoint registered: ${endpoint.method} ${endpoint.path}`);\n continue;\n }\n\n const handler = async ({ request }: { request: Request }): Promise<unknown> => {\n try {\n const context = await buildContext(request);\n return await endpoint.handler(request, context);\n } catch (error) {\n logger.error(`[Server] REST endpoint error (${endpoint.path}):`, error);\n return createHttpErrorResponse(error, {\n serviceName: config.serviceName,\n environment: config.environment,\n });\n }\n };\n\n switch (endpoint.method) {\n case 'GET':\n app.get(endpoint.path, handler);\n break;\n case 'POST':\n app.post(endpoint.path, handler);\n break;\n case 'PUT':\n app.put(endpoint.path, handler);\n break;\n case 'PATCH':\n app.patch(endpoint.path, handler);\n break;\n case 'DELETE':\n app.delete(endpoint.path, handler);\n break;\n }\n }\n }\n\n const host = config.host || '0.0.0.0';\n const port = config.port;\n\n // Create server instance\n const serverInstance: ServerInstance = {\n app: app as unknown as ElysiaApp,\n server: null,\n start: async () => {\n serverStartTime = new Date();\n\n // Call listen() which starts the server and makes app.server available\n app.listen({\n port,\n hostname: host,\n });\n\n // Access the Bun server instance from the app\n // Cast through unknown to satisfy TypeScript since Elysia's types are complex\n const elysiaApp = app as unknown as { server: BunServerHandle | null };\n serverInstance.server = elysiaApp.server;\n\n logger.info(`🚀 ${config.serviceName} is running at http://${host}:${port}${graphqlEndpoint}`);\n },\n stop: async () => {\n logger.info(`[Server] Stopping ${config.serviceName}...`);\n\n if (onShutdown) {\n await onShutdown();\n }\n\n if (moduleGraph) {\n await moduleGraph.shutdown();\n }\n\n await getDatabaseManager().disconnect();\n\n if (serverInstance.server) {\n serverInstance.server.stop();\n }\n\n logger.info(`[Server] ${config.serviceName} stopped`);\n },\n getInfo: (): ServerInfo => {\n const uptime = serverStartTime ? Math.floor((Date.now() - serverStartTime.getTime()) / 1000) : 0;\n\n return {\n serviceName: config.serviceName,\n serviceVersion: config.serviceVersion || '1.0.0',\n environment: config.environment || 'development',\n port,\n host,\n graphqlEndpoint,\n startedAt: serverStartTime?.toISOString() || '',\n uptime,\n };\n },\n };\n\n // Setup graceful shutdown handlers\n const gracefulShutdown = async (signal: string): Promise<never> => {\n logger.info(`[Server] ${signal} received, shutting down gracefully...`);\n await serverInstance.stop();\n process.exit(0);\n };\n\n process.on('SIGTERM', () => {\n void gracefulShutdown('SIGTERM');\n });\n process.on('SIGINT', () => {\n void gracefulShutdown('SIGINT');\n });\n\n return serverInstance;\n}\n\n/**\n * Configure auth with workspace secret fetcher\n *\n * This should be called before creating the server if using workspace-scoped JWT\n */\nexport function configureServerAuth(fetchWorkspaceSecret: FetchWorkspaceSecretFn): void {\n configureAuth({ fetchWorkspaceSecret });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"workspace-guard-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"workspace-guard-3JLBFAMH.js"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/be-sdk",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.529.2",
|
|
4
4
|
"description": "Backend SDK for Burdenoff products providing unified access to notifications, RBAC, activity tracking, usage monitoring, and more",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/errors.ts","../src/server/workspace-guard.ts"],"names":["DEFAULT_ERROR_CODE","DEFAULT_HTTP_STATUS","DEFAULT_USER_MESSAGES","BAD_REQUEST","BAD_USER_INPUT","CAPTCHA_FAILED","CAPTCHA_REQUIRED","COMPLEXITY_TOO_HIGH","CONFLICT","FORBIDDEN","INTERNAL_SERVER_ERROR","INVALID_PASSWORD","NOT_FOUND","PERMISSION_DENIED","QUOTA_EXCEEDED","QUOTA_EXHAUSTED","RATE_LIMITED","RESOURCE_CAP_EXCEEDED","STORAGE_QUOTA_EXCEEDED","TIMEOUT","UNAUTHENTICATED","VALIDATION_ERROR","WORKSPACE_REQUIRED","DEFAULT_STATUS_BY_CODE","SENSITIVE_EXTENSION_KEYS","Set","TECHNICAL_MESSAGE_PATTERNS","isRecord","value","Array","isArray","readString","record","key","trim","length","readExtensions","error","extensions","readOriginalError","GraphQLError","originalError","Error","undefined","sanitizeExtensions","sanitized","Object","entries","has","normalizeCode","code","replace","toUpperCase","inferCodeFromMessage","message","lower","toLowerCase","includes","inferCode","extensionCode","originalCode","directCode","readErrorMessage","isLikelyTechnicalMessage","some","pattern","test","readExplicitUserMessage","resolveUserMessage","explicit","fallback","resolveTechnicalMessage","options","environment","serviceName","readHttpStatus","http","normalizeError","originalExtensions","directExtensions","mergedExtensions","userMessage","technicalMessage","status","UserFacingGraphQLError","details","httpStatus","cause","name","toUserFacingGraphQLError","normalized","nodes","source","positions","path","normalizeExecutionResultErrors","result","errors","map","createHumanReadableErrorPlugin","onExecute","onExecuteDone","formatHttpError","body","createHttpErrorResponse","formatted","Response","JSON","stringify","headers","WorkspaceRequiredError","isFieldPublic","field","directives","astNode","dir","args","arguments","arg","kind","resolveOperationType","document","operationName","defs","definitions","def","operation","allRootFieldsPublic","schema","opType","rootType","getMutationType","getSubscriptionType","getQueryType","fields","getFields","opDef","find","d","selections","selectionSet","sel","fieldName","startsWith","fieldDef","createWorkspaceGuardPlugin","config","enabled","whitelistedOperations","allowPublicDirective","errorMessage","logger","info","context","contextValue","workspaceId","workspace","id","headerWorkspaceId","request","get","warn"],"mappings":"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","file":"chunk-XUU5IBVU.js","sourcesContent":["import { GraphQLError } from 'graphql';\n\nimport type { YogaPlugin } from './types.js';\n\nexport interface UserFacingErrorOptions {\n code: string;\n userMessage: string;\n technicalMessage?: string;\n details?: Record<string, unknown>;\n httpStatus?: number;\n cause?: Error;\n}\n\nexport interface ErrorNormalizationOptions {\n serviceName?: string;\n environment?: string;\n}\n\nexport interface NormalizedErrorState {\n code: string;\n userMessage: string;\n technicalMessage: string;\n extensions: Record<string, unknown>;\n status: number;\n}\n\nexport interface HttpErrorPayload {\n error: string;\n message: string;\n userMessage: string;\n technicalMessage: string;\n code: string;\n extensions: Record<string, unknown>;\n}\n\nexport interface HttpErrorResult {\n status: number;\n body: HttpErrorPayload;\n}\n\nconst DEFAULT_ERROR_CODE = 'INTERNAL_SERVER_ERROR';\nconst DEFAULT_HTTP_STATUS = 500;\n\nconst DEFAULT_USER_MESSAGES: Record<string, string> = {\n BAD_REQUEST: 'Please check the request and try again.',\n BAD_USER_INPUT: 'Please check the information and try again.',\n CAPTCHA_FAILED: 'The verification failed. Please try again.',\n CAPTCHA_REQUIRED: 'Please complete the verification to continue.',\n COMPLEXITY_TOO_HIGH: 'This request is too large to process. Please simplify it and try again.',\n CONFLICT: 'This change conflicts with existing data. Please refresh and try again.',\n FORBIDDEN: 'You do not have permission to do that.',\n INTERNAL_SERVER_ERROR: 'Something went wrong. Please try again.',\n INVALID_PASSWORD: 'The password you entered is incorrect.',\n NOT_FOUND: 'We could not find the requested item.',\n PERMISSION_DENIED: 'You do not have permission to do that.',\n QUOTA_EXCEEDED: \"You've reached your usage limit.\",\n QUOTA_EXHAUSTED: \"You've reached your usage limit.\",\n RATE_LIMITED: 'Too many requests. Please wait a moment and try again.',\n RESOURCE_CAP_EXCEEDED: \"You've reached your plan limit. Upgrade your plan to continue.\",\n STORAGE_QUOTA_EXCEEDED: \"You've reached your storage limit. Upgrade your plan to continue.\",\n TIMEOUT: 'The request took too long. Please try again.',\n UNAUTHENTICATED: 'Please sign in to continue.',\n VALIDATION_ERROR: 'Please check the information and try again.',\n WORKSPACE_REQUIRED: 'Please choose a workspace and try again.',\n};\n\nconst DEFAULT_STATUS_BY_CODE: Record<string, number> = {\n BAD_REQUEST: 400,\n BAD_USER_INPUT: 400,\n CAPTCHA_FAILED: 400,\n CAPTCHA_REQUIRED: 400,\n COMPLEXITY_TOO_HIGH: 400,\n CONFLICT: 409,\n FORBIDDEN: 403,\n INVALID_PASSWORD: 400,\n NOT_FOUND: 404,\n PERMISSION_DENIED: 403,\n QUOTA_EXCEEDED: 429,\n QUOTA_EXHAUSTED: 429,\n RATE_LIMITED: 429,\n RESOURCE_CAP_EXCEEDED: 429,\n STORAGE_QUOTA_EXCEEDED: 429,\n TIMEOUT: 504,\n UNAUTHENTICATED: 401,\n VALIDATION_ERROR: 400,\n WORKSPACE_REQUIRED: 403,\n};\n\nconst SENSITIVE_EXTENSION_KEYS = new Set(['exception', 'originalError', 'stack', 'stacktrace']);\n\nconst TECHNICAL_MESSAGE_PATTERNS = [\n /\\bprisma\\b/i,\n /\\bsql\\b/i,\n /\\bconstraint\\b/i,\n /\\bstack\\b/i,\n /\\bundefined\\b/i,\n /\\bnull\\b/i,\n /\\bECONN[A-Z_]*\\b/,\n /\\bETIMEDOUT\\b/,\n /\\bENOTFOUND\\b/,\n /\\bP\\d{4}\\b/,\n /Cannot (read|set|find|access)/i,\n /Build failed \\(exit \\d+\\)/i,\n /JSON\\.stringify/i,\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readString(record: Record<string, unknown>, key: string): string | null {\n const value = record[key];\n return typeof value === 'string' && value.trim().length > 0 ? value : null;\n}\n\nfunction readExtensions(error: unknown): Record<string, unknown> {\n if (!isRecord(error)) return {};\n const extensions = error['extensions'];\n return isRecord(extensions) ? extensions : {};\n}\n\nfunction readOriginalError(error: unknown): Error | undefined {\n if (error instanceof GraphQLError && error.originalError instanceof Error) {\n return error.originalError;\n }\n return undefined;\n}\n\nfunction sanitizeExtensions(extensions: Record<string, unknown>): Record<string, unknown> {\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(extensions)) {\n if (!SENSITIVE_EXTENSION_KEYS.has(key)) {\n sanitized[key] = value;\n }\n }\n return sanitized;\n}\n\nfunction normalizeCode(code: string | null): string {\n if (!code) return DEFAULT_ERROR_CODE;\n return code\n .trim()\n .replace(/[\\s-]+/g, '_')\n .toUpperCase();\n}\n\nfunction inferCodeFromMessage(message: string): string {\n const lower = message.toLowerCase();\n\n if (\n lower.includes('unauthenticated') ||\n lower.includes('not authenticated') ||\n lower.includes('authentication required') ||\n lower.includes('unauthorized') ||\n lower.includes('please sign in') ||\n lower.includes('sign in to')\n ) {\n return 'UNAUTHENTICATED';\n }\n\n if (lower.includes('workspace context') || lower.includes('switch to a workspace')) {\n return 'WORKSPACE_REQUIRED';\n }\n\n if (\n lower.includes('forbidden') ||\n lower.includes('access denied') ||\n lower.includes('permission denied') ||\n lower.includes('not authorized')\n ) {\n return 'FORBIDDEN';\n }\n\n if (lower.includes('not found') || lower.includes('disappeared')) {\n return 'NOT_FOUND';\n }\n\n if (lower.includes('already exists') || lower.includes('already taken') || lower.includes('conflict')) {\n return 'CONFLICT';\n }\n\n if (lower.includes('quota') || lower.includes('cap exceeded') || lower.includes('limit reached')) {\n return 'QUOTA_EXCEEDED';\n }\n\n if (lower.includes('timeout') || lower.includes('timed out')) {\n return 'TIMEOUT';\n }\n\n if (\n lower.includes('required') ||\n lower.includes('invalid') ||\n lower.includes('missing') ||\n lower.includes('unsupported')\n ) {\n return 'BAD_USER_INPUT';\n }\n\n return DEFAULT_ERROR_CODE;\n}\n\nfunction inferCode(error: unknown, extensions: Record<string, unknown>, originalError: Error | undefined): string {\n const extensionCode = typeof extensions['code'] === 'string' ? extensions['code'] : null;\n if (extensionCode) return normalizeCode(extensionCode);\n\n if (isRecord(originalError)) {\n const originalCode = readString(originalError, 'code');\n if (originalCode) return normalizeCode(originalCode);\n }\n\n if (isRecord(error)) {\n const directCode = readString(error, 'code');\n if (directCode) return normalizeCode(directCode);\n }\n\n const message = readErrorMessage(error);\n return inferCodeFromMessage(message);\n}\n\nfunction readErrorMessage(error: unknown): string {\n if (error instanceof Error && error.message.trim().length > 0) {\n return error.message;\n }\n if (isRecord(error)) {\n const message = readString(error, 'message');\n if (message) return message;\n }\n return DEFAULT_USER_MESSAGES[DEFAULT_ERROR_CODE] ?? 'Something went wrong. Please try again.';\n}\n\nfunction isLikelyTechnicalMessage(message: string): boolean {\n if (message.length > 220) return true;\n if (message.includes('\\n')) return true;\n if (message.includes('{') && message.includes('}')) return true;\n return TECHNICAL_MESSAGE_PATTERNS.some((pattern) => pattern.test(message));\n}\n\nfunction readExplicitUserMessage(extensions: Record<string, unknown>): string | null {\n return (\n readString(extensions, 'userMessage') ??\n readString(extensions, 'humanMessage') ??\n readString(extensions, 'displayMessage')\n );\n}\n\nfunction resolveUserMessage(code: string, message: string, extensions: Record<string, unknown>): string {\n const explicit = readExplicitUserMessage(extensions);\n if (explicit) return explicit;\n\n const fallback =\n DEFAULT_USER_MESSAGES[code] ??\n DEFAULT_USER_MESSAGES[DEFAULT_ERROR_CODE] ??\n 'Something went wrong. Please try again.';\n if (code === DEFAULT_ERROR_CODE) {\n return fallback;\n }\n\n if (!isLikelyTechnicalMessage(message)) {\n return message;\n }\n\n return fallback;\n}\n\nfunction resolveTechnicalMessage(\n code: string,\n message: string,\n extensions: Record<string, unknown>,\n options: ErrorNormalizationOptions\n): string {\n const explicit = readString(extensions, 'technicalMessage');\n if (explicit) return explicit;\n\n if (options.environment === 'production' && code === DEFAULT_ERROR_CODE) {\n return options.serviceName ? `${options.serviceName} returned ${DEFAULT_ERROR_CODE}` : DEFAULT_ERROR_CODE;\n }\n\n return message;\n}\n\nfunction readHttpStatus(extensions: Record<string, unknown>, code: string): number {\n const http = extensions['http'];\n if (isRecord(http) && typeof http['status'] === 'number') {\n return http['status'];\n }\n return DEFAULT_STATUS_BY_CODE[code] ?? DEFAULT_HTTP_STATUS;\n}\n\nexport function normalizeError(error: unknown, options: ErrorNormalizationOptions = {}): NormalizedErrorState {\n const originalError = readOriginalError(error);\n const originalExtensions = readExtensions(originalError);\n const directExtensions = readExtensions(error);\n const mergedExtensions = sanitizeExtensions({ ...originalExtensions, ...directExtensions });\n const message = readErrorMessage(error);\n const code = inferCode(error, mergedExtensions, originalError);\n const userMessage = resolveUserMessage(code, message, mergedExtensions);\n const technicalMessage = resolveTechnicalMessage(code, message, mergedExtensions, options);\n const status = readHttpStatus(mergedExtensions, code);\n\n const extensions: Record<string, unknown> = {\n ...mergedExtensions,\n code,\n userMessage,\n technicalMessage,\n };\n\n if (options.serviceName) {\n extensions['serviceName'] = options.serviceName;\n }\n\n if (!isRecord(extensions['http'])) {\n extensions['http'] = { status };\n }\n\n return {\n code,\n userMessage,\n technicalMessage,\n extensions,\n status,\n };\n}\n\nexport class UserFacingGraphQLError extends GraphQLError {\n constructor(options: UserFacingErrorOptions) {\n const extensions: Record<string, unknown> = {\n code: normalizeCode(options.code),\n userMessage: options.userMessage,\n technicalMessage: options.technicalMessage ?? options.userMessage,\n };\n\n if (options.details) {\n extensions['details'] = options.details;\n }\n\n if (options.httpStatus) {\n extensions['http'] = { status: options.httpStatus };\n }\n\n super(options.userMessage, {\n originalError: options.cause,\n extensions,\n });\n this.name = 'UserFacingGraphQLError';\n }\n}\n\nexport function toUserFacingGraphQLError(error: unknown, options: ErrorNormalizationOptions = {}): GraphQLError {\n const normalized = normalizeError(error, options);\n\n if (error instanceof GraphQLError) {\n return new GraphQLError(normalized.userMessage, {\n nodes: error.nodes,\n source: error.source,\n positions: error.positions,\n path: error.path,\n originalError: error.originalError,\n extensions: normalized.extensions,\n });\n }\n\n return new GraphQLError(normalized.userMessage, {\n originalError: error instanceof Error ? error : undefined,\n extensions: normalized.extensions,\n });\n}\n\nexport function normalizeExecutionResultErrors(result: unknown, options: ErrorNormalizationOptions = {}): void {\n if (!isRecord(result)) return;\n const errors = result['errors'];\n if (!Array.isArray(errors) || errors.length === 0) return;\n\n result['errors'] = errors.map((error) => toUserFacingGraphQLError(error, options));\n}\n\nexport function createHumanReadableErrorPlugin(options: ErrorNormalizationOptions = {}): YogaPlugin {\n return {\n onExecute() {\n return {\n onExecuteDone({ result }: { result: unknown }) {\n normalizeExecutionResultErrors(result, options);\n },\n };\n },\n };\n}\n\nexport function formatHttpError(error: unknown, options: ErrorNormalizationOptions = {}): HttpErrorResult {\n const normalized = normalizeError(error, options);\n return {\n status: normalized.status,\n body: {\n error: normalized.userMessage,\n message: normalized.userMessage,\n userMessage: normalized.userMessage,\n technicalMessage: normalized.technicalMessage,\n code: normalized.code,\n extensions: normalized.extensions,\n },\n };\n}\n\nexport function createHttpErrorResponse(error: unknown, options: ErrorNormalizationOptions = {}): Response {\n const formatted = formatHttpError(error, options);\n return new Response(JSON.stringify(formatted.body), {\n status: formatted.status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n","/**\n * Workspace Guard Plugin for GraphQL Yoga\n *\n * Blocks GraphQL operations that lack a valid workspace context (x-workspace-id header).\n * This provides defense-in-depth at the GraphQL layer — even if the gateway allows a request\n * through, the service itself will reject it if workspace context is missing.\n *\n * **Whitelisted operations** (e.g., workspace creation) can bypass the guard.\n *\n * **Public schema fields** marked with `@public` or `@rbac(public: true)` are auto-bypassed\n * when `allowPublicDirective` is enabled (default true). This lets anonymous public-link\n * resolvers (e.g. `accessShare`) be reached through the federation gateway without an\n * `x-workspace-id` header.\n *\n * @module server/workspace-guard\n * @category Security\n */\n\nimport { logger } from '../logger/index.js';\nimport { UserFacingGraphQLError } from './errors.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Configuration for the workspace guard plugin\n */\nexport interface WorkspaceGuardConfig {\n /**\n * Enable the workspace guard.\n * @default true\n */\n enabled?: boolean;\n\n /**\n * GraphQL operation names that can run without workspace context.\n * These are typically operations like `createWorkspace` that execute\n * before a workspace exists.\n *\n * Matching is case-sensitive against the operation name in the GraphQL document.\n *\n * @default []\n *\n * @example\n * ```typescript\n * whitelistedOperations: ['createWorkspace', 'validateTokens']\n * ```\n */\n whitelistedOperations?: string[];\n\n /**\n * Custom error message when workspace context is missing.\n * @default 'Workspace context required. Provide a valid X-Workspace-Authorization header.'\n */\n errorMessage?: string;\n\n /**\n * If true, fields whose schema definition carries the `@public` directive or\n * `@rbac(public: true)` are bypassed by the guard automatically — no need to\n * list them in `whitelistedOperations`. The check uses the GraphQL schema\n * passed to the executor at request time.\n *\n * Set to false to fall back to the legacy operation-name allowlist only.\n *\n * @default true\n */\n allowPublicDirective?: boolean;\n}\n\n// ============================================================================\n// GraphQL Error\n// ============================================================================\n\n/**\n * Workspace required error with proper GraphQL error extensions\n */\nclass WorkspaceRequiredError extends UserFacingGraphQLError {\n constructor(message: string) {\n super({\n code: 'WORKSPACE_REQUIRED',\n userMessage: 'Please choose a workspace and try again.',\n technicalMessage: message,\n httpStatus: 403,\n });\n this.name = 'WorkspaceRequiredError';\n }\n}\n\n// ============================================================================\n// Schema directive helpers\n// ============================================================================\n\n/**\n * Minimal structural typings for the bits of the GraphQL schema we look at.\n * We avoid importing the GraphQL types directly so the SDK keeps `graphql`\n * as a peer dep without a runtime hard dependency.\n */\ninterface FieldLikeDef {\n astNode?: {\n directives?: ReadonlyArray<{\n name: { value: string };\n arguments?: ReadonlyArray<{\n name: { value: string };\n value: { kind: string; value?: unknown };\n }>;\n }>;\n };\n}\n\ninterface SchemaLike {\n getQueryType?: () => { getFields: () => Record<string, FieldLikeDef> } | null | undefined;\n getMutationType?: () => { getFields: () => Record<string, FieldLikeDef> } | null | undefined;\n getSubscriptionType?: () => { getFields: () => Record<string, FieldLikeDef> } | null | undefined;\n}\n\n/**\n * Returns true iff the field carries either:\n * - `@public` directive, OR\n * - `@rbac(public: true)` directive (any arg-order)\n */\nfunction isFieldPublic(field: FieldLikeDef | undefined): boolean {\n const directives = field?.astNode?.directives;\n if (!directives || directives.length === 0) return false;\n\n for (const dir of directives) {\n const name = dir.name?.value;\n if (name === 'public') return true;\n if (name === 'rbac') {\n const args = dir.arguments ?? [];\n for (const arg of args) {\n if (arg.name?.value === 'public' && arg.value?.kind === 'BooleanValue' && arg.value.value === true) {\n return true;\n }\n }\n }\n }\n return false;\n}\n\ninterface DocumentLike {\n definitions?: ReadonlyArray<{\n kind?: string;\n operation?: string;\n name?: { value?: string };\n selectionSet?: {\n selections?: ReadonlyArray<{\n kind?: string;\n name?: { value?: string };\n }>;\n };\n }>;\n}\n\n/**\n * Resolve the operation type ('query' | 'mutation' | 'subscription') for the\n * primary operation in the document. Falls back to 'query'.\n */\nfunction resolveOperationType(\n document: DocumentLike | undefined,\n operationName: string | null | undefined\n): 'query' | 'mutation' | 'subscription' {\n const defs = document?.definitions ?? [];\n for (const def of defs) {\n if (def.kind !== 'OperationDefinition') {\n // Older parsers may not set kind; fall through to the operation property check below.\n }\n if (def.operation && (!operationName || def.name?.value === operationName)) {\n return def.operation as 'query' | 'mutation' | 'subscription';\n }\n }\n return 'query';\n}\n\n/**\n * Returns true iff every root field in the document selection set is marked\n * public on the schema. Empty selection sets return false (fail-closed).\n */\nfunction allRootFieldsPublic(\n schema: SchemaLike | undefined,\n document: DocumentLike | undefined,\n operationName: string | null | undefined\n): boolean {\n if (!schema || !document) return false;\n\n const opType = resolveOperationType(document, operationName);\n let rootType: ReturnType<NonNullable<SchemaLike['getQueryType']>> | undefined;\n if (opType === 'mutation') {\n rootType = schema.getMutationType?.();\n } else if (opType === 'subscription') {\n rootType = schema.getSubscriptionType?.();\n } else {\n rootType = schema.getQueryType?.();\n }\n\n if (!rootType) return false;\n\n const fields = rootType.getFields();\n const defs = document.definitions ?? [];\n\n // Find the operation definition matching operationName (or first one).\n const opDef = defs.find((d) => d.operation && (!operationName || d.name?.value === operationName));\n const selections = opDef?.selectionSet?.selections ?? [];\n if (selections.length === 0) return false;\n\n for (const sel of selections) {\n // Only consider plain Field selections (skip fragments — fragments at the root\n // shouldn't drive a public bypass; fail-closed there).\n if (sel.kind && sel.kind !== 'Field') return false;\n const fieldName = sel.name?.value;\n if (!fieldName) return false;\n // __schema / __type introspection is always allowed without workspace context;\n // treat them as public.\n if (fieldName.startsWith('__')) continue;\n const fieldDef = fields[fieldName];\n if (!isFieldPublic(fieldDef)) return false;\n }\n return true;\n}\n\n// ============================================================================\n// Plugin\n// ============================================================================\n\n/**\n * Create a GraphQL Yoga plugin that guards operations requiring workspace context.\n *\n * The plugin inspects the GraphQL context for workspace information (set by the SDK's\n * buildContext from the x-workspace-id header). If missing and the operation is not\n * whitelisted (and not all-public per directive), it throws a WORKSPACE_REQUIRED error.\n *\n * @param config - Guard configuration\n * @returns A Yoga-compatible plugin\n *\n * @example\n * ```typescript\n * import { createWorkspaceGuardPlugin } from '@burdenoff/be-sdk/server';\n *\n * const guardPlugin = createWorkspaceGuardPlugin({\n * whitelistedOperations: ['createWorkspace'],\n * allowPublicDirective: true, // default\n * });\n * ```\n */\nexport function createWorkspaceGuardPlugin(config?: WorkspaceGuardConfig) {\n const enabled = config?.enabled ?? true;\n const whitelistedOperations = new Set(config?.whitelistedOperations ?? []);\n const allowPublicDirective = config?.allowPublicDirective ?? true;\n const errorMessage =\n config?.errorMessage ??\n 'Workspace context required. Ensure the request includes a valid workspace context (x-workspace-id header).';\n\n if (!enabled) {\n logger.info('[WorkspaceGuard] Workspace guard disabled');\n return {};\n }\n\n logger.info('[WorkspaceGuard] Workspace guard enabled', {\n whitelistedOperations: [...whitelistedOperations],\n allowPublicDirective,\n });\n\n return {\n onExecute({\n args,\n }: {\n args: {\n schema?: SchemaLike;\n document?: DocumentLike;\n operationName?: string | null;\n contextValue?: { workspace?: { id?: string }; request?: Request };\n };\n }) {\n // Extract operation name from args or document\n let operationName = args.operationName;\n\n if (!operationName && args.document?.definitions) {\n for (const def of args.document.definitions) {\n if (def.operation && def.name?.value) {\n operationName = def.name.value;\n break;\n }\n }\n }\n\n // Check if operation is whitelisted by name\n if (operationName && whitelistedOperations.has(operationName)) {\n return undefined;\n }\n\n // Check schema-directive-based public bypass (Option C)\n if (allowPublicDirective && allRootFieldsPublic(args.schema, args.document, operationName)) {\n return undefined;\n }\n\n // Check for workspace context\n const context = args.contextValue;\n const workspaceId = context?.workspace?.id;\n\n // Also check the raw header as a fallback\n const headerWorkspaceId = context?.request?.headers?.get?.('x-workspace-id');\n\n if (!workspaceId && !headerWorkspaceId) {\n logger.warn('[WorkspaceGuard] Blocked operation without workspace context', {\n operationName: operationName ?? '<anonymous>',\n });\n throw new WorkspaceRequiredError(errorMessage);\n }\n\n return undefined;\n },\n };\n}\n"]}
|