@elnora-ai/mcp-server 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +2 -2
  2. package/dist/auth/clients-store.d.ts +13 -0
  3. package/dist/auth/clients-store.d.ts.map +1 -0
  4. package/dist/auth/clients-store.js +35 -0
  5. package/dist/auth/clients-store.js.map +1 -0
  6. package/dist/auth/provider.d.ts +55 -0
  7. package/dist/auth/provider.d.ts.map +1 -0
  8. package/dist/auth/provider.js +234 -0
  9. package/dist/auth/provider.js.map +1 -0
  10. package/dist/constants.d.ts +7 -2
  11. package/dist/constants.d.ts.map +1 -1
  12. package/dist/constants.js +18 -4
  13. package/dist/constants.js.map +1 -1
  14. package/dist/index.js +81 -13
  15. package/dist/index.js.map +1 -1
  16. package/dist/middleware/cors.d.ts +11 -0
  17. package/dist/middleware/cors.d.ts.map +1 -0
  18. package/dist/middleware/cors.js +42 -0
  19. package/dist/middleware/cors.js.map +1 -0
  20. package/dist/middleware/rate-limiter.d.ts +13 -0
  21. package/dist/middleware/rate-limiter.d.ts.map +1 -0
  22. package/dist/middleware/rate-limiter.js +59 -0
  23. package/dist/middleware/rate-limiter.js.map +1 -0
  24. package/dist/middleware/tool-logging.d.ts +11 -0
  25. package/dist/middleware/tool-logging.d.ts.map +1 -0
  26. package/dist/middleware/tool-logging.js +40 -0
  27. package/dist/middleware/tool-logging.js.map +1 -0
  28. package/dist/server.d.ts +6 -1
  29. package/dist/server.d.ts.map +1 -1
  30. package/dist/server.js +10 -6
  31. package/dist/server.js.map +1 -1
  32. package/dist/services/elnora-api-client.d.ts +0 -2
  33. package/dist/services/elnora-api-client.d.ts.map +1 -1
  34. package/dist/services/elnora-api-client.js +0 -4
  35. package/dist/services/elnora-api-client.js.map +1 -1
  36. package/dist/tools/files.d.ts +2 -1
  37. package/dist/tools/files.d.ts.map +1 -1
  38. package/dist/tools/files.js +8 -7
  39. package/dist/tools/files.js.map +1 -1
  40. package/dist/tools/messages.d.ts +2 -1
  41. package/dist/tools/messages.d.ts.map +1 -1
  42. package/dist/tools/messages.js +5 -4
  43. package/dist/tools/messages.js.map +1 -1
  44. package/dist/tools/protocols.d.ts +2 -1
  45. package/dist/tools/protocols.d.ts.map +1 -1
  46. package/dist/tools/protocols.js +4 -3
  47. package/dist/tools/protocols.js.map +1 -1
  48. package/dist/tools/scope-guard.d.ts +19 -0
  49. package/dist/tools/scope-guard.d.ts.map +1 -0
  50. package/dist/tools/scope-guard.js +33 -0
  51. package/dist/tools/scope-guard.js.map +1 -0
  52. package/dist/tools/tasks.d.ts +2 -1
  53. package/dist/tools/tasks.d.ts.map +1 -1
  54. package/dist/tools/tasks.js +8 -7
  55. package/dist/tools/tasks.js.map +1 -1
  56. package/dist/tools/with-guard.d.ts +19 -0
  57. package/dist/tools/with-guard.d.ts.map +1 -0
  58. package/dist/tools/with-guard.js +32 -0
  59. package/dist/tools/with-guard.js.map +1 -0
  60. package/dist/types.d.ts +32 -0
  61. package/dist/types.d.ts.map +1 -1
  62. package/package.json +5 -4
  63. package/dist/auth/middleware.d.ts +0 -12
  64. package/dist/auth/middleware.d.ts.map +0 -1
  65. package/dist/auth/middleware.js +0 -40
  66. package/dist/auth/middleware.js.map +0 -1
  67. package/dist/auth/protected-resource.d.ts +0 -4
  68. package/dist/auth/protected-resource.d.ts.map +0 -1
  69. package/dist/auth/protected-resource.js +0 -19
  70. package/dist/auth/protected-resource.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { handleApiError } from "../services/error-handler.js";
3
- export function registerTaskTools(server, getClient) {
3
+ import { withGuard } from "./with-guard.js";
4
+ export function registerTaskTools(server, getClient, getContext) {
4
5
  server.registerTool("elnora_create_task", {
5
6
  title: "Create Task",
6
7
  description: "Create a new task (conversation) in Elnora. Tasks are the primary unit of interaction — each task is a chat thread where you can send messages and receive AI agent responses.",
@@ -13,7 +14,7 @@ export function registerTaskTools(server, getClient) {
13
14
  idempotentHint: false,
14
15
  openWorldHint: true,
15
16
  },
16
- }, async ({ title }) => {
17
+ }, withGuard("elnora_create_task", getContext, async ({ title }) => {
17
18
  try {
18
19
  const task = await getClient().createTask(title);
19
20
  return {
@@ -23,7 +24,7 @@ export function registerTaskTools(server, getClient) {
23
24
  catch (error) {
24
25
  return { content: [{ type: "text", text: handleApiError(error) }], isError: true };
25
26
  }
26
- });
27
+ }));
27
28
  server.registerTool("elnora_list_tasks", {
28
29
  title: "List Tasks",
29
30
  description: "List tasks in your Elnora workspace. Returns task summaries with status and timestamps.",
@@ -33,7 +34,7 @@ export function registerTaskTools(server, getClient) {
33
34
  offset: z.number().int().min(0).default(0).describe("Pagination offset"),
34
35
  },
35
36
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
36
- }, async ({ status, limit, offset }) => {
37
+ }, withGuard("elnora_list_tasks", getContext, async ({ status, limit, offset }) => {
37
38
  try {
38
39
  const result = await getClient().listTasks(status, limit, offset);
39
40
  return {
@@ -43,7 +44,7 @@ export function registerTaskTools(server, getClient) {
43
44
  catch (error) {
44
45
  return { content: [{ type: "text", text: handleApiError(error) }], isError: true };
45
46
  }
46
- });
47
+ }));
47
48
  server.registerTool("elnora_get_task_messages", {
48
49
  title: "Get Task Messages",
49
50
  description: "Get the message history for a specific task. Returns user and assistant messages in chronological order.",
@@ -53,7 +54,7 @@ export function registerTaskTools(server, getClient) {
53
54
  offset: z.number().int().min(0).default(0).describe("Pagination offset"),
54
55
  },
55
56
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
56
- }, async ({ task_id, limit, offset }) => {
57
+ }, withGuard("elnora_get_task_messages", getContext, async ({ task_id, limit, offset }) => {
57
58
  try {
58
59
  const result = await getClient().getTaskMessages(task_id, limit, offset);
59
60
  return {
@@ -63,6 +64,6 @@ export function registerTaskTools(server, getClient) {
63
64
  catch (error) {
64
65
  return { content: [{ type: "text", text: handleApiError(error) }], isError: true };
65
66
  }
66
- });
67
+ }));
67
68
  }
68
69
  //# sourceMappingURL=tasks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/tools/tasks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/tools/tasks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { RequestContext } from "../server.js";
2
+ /**
3
+ * Wraps a tool handler with scope enforcement and invocation logging.
4
+ * CoSAI MCP-T2 (scope enforcement) + MCP-T12 (audit logging).
5
+ */
6
+ export declare function withGuard<T extends Record<string, unknown>>(toolName: string, getContext: () => RequestContext, handler: (params: T) => Promise<{
7
+ content: {
8
+ type: "text";
9
+ text: string;
10
+ }[];
11
+ isError?: boolean;
12
+ }>): (params: T) => Promise<{
13
+ content: {
14
+ type: "text";
15
+ text: string;
16
+ }[];
17
+ isError?: boolean;
18
+ }>;
19
+ //# sourceMappingURL=with-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-guard.d.ts","sourceRoot":"","sources":["../../src/tools/with-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI9C;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,cAAc,EAChC,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAChG,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CA0B1F"}
@@ -0,0 +1,32 @@
1
+ import { checkToolScopes } from "./scope-guard.js";
2
+ import { logToolInvocation } from "../middleware/tool-logging.js";
3
+ /**
4
+ * Wraps a tool handler with scope enforcement and invocation logging.
5
+ * CoSAI MCP-T2 (scope enforcement) + MCP-T12 (audit logging).
6
+ */
7
+ export function withGuard(toolName, getContext, handler) {
8
+ return async (params) => {
9
+ const ctx = getContext();
10
+ const start = Date.now();
11
+ // Scope enforcement
12
+ const missing = checkToolScopes(toolName, ctx.scopes);
13
+ if (missing.length > 0) {
14
+ logToolInvocation(toolName, params, ctx.clientId, { success: false, durationMs: Date.now() - start });
15
+ return {
16
+ content: [{
17
+ type: "text",
18
+ text: `Error: Insufficient scope. Missing: ${missing.join(", ")}. Re-authenticate with the required scopes.`,
19
+ }],
20
+ isError: true,
21
+ };
22
+ }
23
+ // Execute handler
24
+ const result = await handler(params);
25
+ logToolInvocation(toolName, params, ctx.clientId, {
26
+ success: !result.isError,
27
+ durationMs: Date.now() - start,
28
+ });
29
+ return result;
30
+ };
31
+ }
32
+ //# sourceMappingURL=with-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-guard.js","sourceRoot":"","sources":["../../src/tools/with-guard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE;;;GAGG;AACH,MAAM,UAAU,SAAS,CACvB,QAAgB,EAChB,UAAgC,EAChC,OAAiG;IAEjG,OAAO,KAAK,EAAE,MAAS,EAAE,EAAE;QACzB,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,oBAAoB;QACpB,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;YACtG,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,uCAAuC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,6CAA6C;qBAC7G,CAAC;gBACF,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,kBAAkB;QAClB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE;YAChD,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO;YACxB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;SAC/B,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
package/dist/types.d.ts CHANGED
@@ -3,6 +3,16 @@ export interface ElnoraConfig {
3
3
  authUrl: string;
4
4
  tokenValidationUrl: string;
5
5
  port: number;
6
+ /** Public-facing base URL of the MCP server (e.g. https://mcp.elnora.ai) */
7
+ publicUrl: string;
8
+ /** URL of the Elnora platform login page */
9
+ loginUrl: string;
10
+ /** URL to exchange platform auth codes for platform tokens */
11
+ tokenExchangeUrl: string;
12
+ /** Client ID for the MCP server as an OAuth client of the Elnora platform */
13
+ platformClientId: string;
14
+ /** Client secret for the MCP server as an OAuth client of the Elnora platform */
15
+ platformClientSecret: string;
6
16
  }
7
17
  export interface AuthContext {
8
18
  userId: number;
@@ -46,4 +56,26 @@ export interface PaginatedResponse<T> {
46
56
  hasMore: boolean;
47
57
  nextOffset?: number;
48
58
  }
59
+ /** Stored authorization session for PKCE flow */
60
+ export interface AuthorizationSession {
61
+ clientId: string;
62
+ codeChallenge: string;
63
+ redirectUri: string;
64
+ scopes: string[];
65
+ state?: string;
66
+ resource?: string;
67
+ platformCode?: string;
68
+ createdAt: number;
69
+ }
70
+ /** Stored token mapping */
71
+ export interface TokenRecord {
72
+ accessToken: string;
73
+ refreshToken: string;
74
+ platformToken: string;
75
+ clientId: string;
76
+ scopes: string[];
77
+ resource?: string;
78
+ expiresAt: number;
79
+ createdAt: number;
80
+ }
49
81
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,gBAAgB,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,gBAAgB,EAAE,MAAM,CAAC;IACzB,iFAAiF;IACjF,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,2BAA2B;AAC3B,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB"}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@elnora-ai/mcp-server",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
+ "mcpName": "io.github.Elnora-AI/elnora-mcp-server",
4
5
  "description": "MCP server for Elnora Platform — AI-powered bioprotocol optimization",
5
6
  "type": "module",
6
7
  "main": "dist/index.js",
@@ -39,10 +40,10 @@
39
40
  "node": ">=18"
40
41
  },
41
42
  "dependencies": {
42
- "@modelcontextprotocol/sdk": "^1.12.0",
43
+ "@modelcontextprotocol/sdk": "^1.27.0",
44
+ "axios": "^1.8.0",
43
45
  "express": "^5.1.0",
44
- "zod": "^3.24.0",
45
- "axios": "^1.8.0"
46
+ "zod": "^3.24.0"
46
47
  },
47
48
  "devDependencies": {
48
49
  "@types/express": "^5.0.0",
@@ -1,12 +0,0 @@
1
- import { Request, Response, NextFunction } from "express";
2
- import { AuthContext, ElnoraConfig } from "../types.js";
3
- declare global {
4
- namespace Express {
5
- interface Request {
6
- authContext?: AuthContext;
7
- bearerToken?: string;
8
- }
9
- }
10
- }
11
- export declare function authMiddleware(config: ElnoraConfig): (req: Request, res: Response, next: NextFunction) => Promise<void>;
12
- //# sourceMappingURL=middleware.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/auth/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,WAAW,CAAC,EAAE,WAAW,CAAC;YAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;SACtB;KACF;CACF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,IACnC,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC,CA2C9E"}
@@ -1,40 +0,0 @@
1
- import { ElnoraApiClient } from "../services/elnora-api-client.js";
2
- export function authMiddleware(config) {
3
- return async (req, res, next) => {
4
- const authHeader = req.headers.authorization;
5
- if (!authHeader || !authHeader.startsWith("Bearer ")) {
6
- res.setHeader("WWW-Authenticate", `Bearer resource_metadata="${req.protocol}://${req.get("host")}/.well-known/oauth-protected-resource"`);
7
- res.status(401).json({
8
- error: "unauthorized",
9
- error_description: "Bearer token required",
10
- });
11
- return;
12
- }
13
- const token = authHeader.slice(7); // Remove "Bearer "
14
- try {
15
- const validation = await ElnoraApiClient.validateToken(config.tokenValidationUrl, token);
16
- if (!validation.valid || !validation.userId || !validation.organizationId) {
17
- res.status(401).json({
18
- error: "invalid_token",
19
- error_description: "Token is invalid or expired",
20
- });
21
- return;
22
- }
23
- req.authContext = {
24
- userId: validation.userId,
25
- organizationId: validation.organizationId,
26
- scopes: validation.scopes || "",
27
- tokenType: validation.tokenType || "unknown",
28
- };
29
- req.bearerToken = token;
30
- next();
31
- }
32
- catch {
33
- res.status(401).json({
34
- error: "invalid_token",
35
- error_description: "Token validation failed",
36
- });
37
- }
38
- };
39
- }
40
- //# sourceMappingURL=middleware.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/auth/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAanE,MAAM,UAAU,cAAc,CAAC,MAAoB;IACjD,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAiB,EAAE;QAC9E,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;QAE7C,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,SAAS,CACX,kBAAkB,EAClB,6BAA6B,GAAG,CAAC,QAAQ,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,wCAAwC,CACvG,CAAC;YACF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,cAAc;gBACrB,iBAAiB,EAAE,uBAAuB;aAC3C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB;QAEtD,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,aAAa,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;YAEzF,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC;gBAC1E,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,KAAK,EAAE,eAAe;oBACtB,iBAAiB,EAAE,6BAA6B;iBACjD,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,GAAG,CAAC,WAAW,GAAG;gBAChB,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,cAAc,EAAE,UAAU,CAAC,cAAc;gBACzC,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,EAAE;gBAC/B,SAAS,EAAE,UAAU,CAAC,SAAS,IAAI,SAAS;aAC7C,CAAC;YACF,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC;YACxB,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,eAAe;gBACtB,iBAAiB,EAAE,yBAAyB;aAC7C,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -1,4 +0,0 @@
1
- import { Request, Response } from "express";
2
- import { ElnoraConfig } from "../types.js";
3
- export declare function protectedResourceMetadataHandler(config: ElnoraConfig): (req: Request, res: Response) => void;
4
- //# sourceMappingURL=protected-resource.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"protected-resource.d.ts","sourceRoot":"","sources":["../../src/auth/protected-resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,YAAY,IAC3D,KAAK,OAAO,EAAE,KAAK,QAAQ,KAAG,IAAI,CAgB3C"}
@@ -1,19 +0,0 @@
1
- export function protectedResourceMetadataHandler(config) {
2
- return (req, res) => {
3
- const resource = process.env.RESOURCE_URL || `${req.protocol}://${req.get("host")}`;
4
- res.json({
5
- resource,
6
- authorization_servers: [config.authUrl],
7
- scopes_supported: [
8
- "tasks:read",
9
- "tasks:write",
10
- "files:read",
11
- "files:write",
12
- "messages:read",
13
- "messages:write",
14
- ],
15
- bearer_methods_supported: ["header"],
16
- });
17
- };
18
- }
19
- //# sourceMappingURL=protected-resource.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"protected-resource.js","sourceRoot":"","sources":["../../src/auth/protected-resource.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,gCAAgC,CAAC,MAAoB;IACnE,OAAO,CAAC,GAAY,EAAE,GAAa,EAAQ,EAAE;QAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,GAAG,GAAG,CAAC,QAAQ,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACpF,GAAG,CAAC,IAAI,CAAC;YACP,QAAQ;YACR,qBAAqB,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC;YACvC,gBAAgB,EAAE;gBAChB,YAAY;gBACZ,aAAa;gBACb,YAAY;gBACZ,aAAa;gBACb,eAAe;gBACf,gBAAgB;aACjB;YACD,wBAAwB,EAAE,CAAC,QAAQ,CAAC;SACrC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}