@ash-ai/server 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +34 -0
  2. package/dist/__tests__/auth.test.js +1 -1
  3. package/dist/__tests__/auth.test.js.map +1 -1
  4. package/dist/__tests__/files.test.js +3 -0
  5. package/dist/__tests__/files.test.js.map +1 -1
  6. package/dist/__tests__/multi-tenant.test.d.ts +2 -0
  7. package/dist/__tests__/multi-tenant.test.d.ts.map +1 -0
  8. package/dist/__tests__/multi-tenant.test.js +153 -0
  9. package/dist/__tests__/multi-tenant.test.js.map +1 -0
  10. package/dist/__tests__/schema.test.d.ts +2 -0
  11. package/dist/__tests__/schema.test.d.ts.map +1 -0
  12. package/dist/__tests__/schema.test.js +31 -0
  13. package/dist/__tests__/schema.test.js.map +1 -0
  14. package/dist/auth.d.ts +21 -5
  15. package/dist/auth.d.ts.map +1 -1
  16. package/dist/auth.js +54 -14
  17. package/dist/auth.js.map +1 -1
  18. package/dist/db/dump-schema.d.ts +10 -0
  19. package/dist/db/dump-schema.d.ts.map +1 -0
  20. package/dist/db/dump-schema.js +64 -0
  21. package/dist/db/dump-schema.js.map +1 -0
  22. package/dist/db/index.d.ts +30 -15
  23. package/dist/db/index.d.ts.map +1 -1
  24. package/dist/db/index.js +28 -14
  25. package/dist/db/index.js.map +1 -1
  26. package/dist/db/pg.d.ts +12 -8
  27. package/dist/db/pg.d.ts.map +1 -1
  28. package/dist/db/pg.js +89 -31
  29. package/dist/db/pg.js.map +1 -1
  30. package/dist/db/sqlite.d.ts +12 -8
  31. package/dist/db/sqlite.d.ts.map +1 -1
  32. package/dist/db/sqlite.js +132 -31
  33. package/dist/db/sqlite.js.map +1 -1
  34. package/dist/index.js +2 -2
  35. package/dist/index.js.map +1 -1
  36. package/dist/routes/agents.js +5 -5
  37. package/dist/routes/agents.js.map +1 -1
  38. package/dist/routes/files.js +2 -2
  39. package/dist/routes/files.js.map +1 -1
  40. package/dist/routes/sessions.js +14 -14
  41. package/dist/routes/sessions.js.map +1 -1
  42. package/dist/schemas.d.ts.map +1 -1
  43. package/dist/schemas.js +4 -1
  44. package/dist/schemas.js.map +1 -1
  45. package/package.json +8 -6
package/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # @ash-ai/server
2
+
3
+ The [Ash](https://github.com/ash-ai-org/ash-ai) agent orchestration server — Fastify REST API with SSE streaming, session management, agent registry, and sandbox orchestration.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @ash-ai/server
9
+ ```
10
+
11
+ ## What's included
12
+
13
+ - **REST API** — create sessions, send messages, manage agents
14
+ - **SSE streaming** — real-time message streaming with backpressure
15
+ - **Session management** — lifecycle, persistence (SQLite/Postgres), pause/resume
16
+ - **Agent registry** — deploy agent folders, manage configurations
17
+ - **Sandbox orchestration** — pool management, routing, resource limits
18
+
19
+ ## Quick start
20
+
21
+ ```bash
22
+ export ANTHROPIC_API_KEY=sk-ant-...
23
+ npx @ash-ai/server
24
+ ```
25
+
26
+ The server starts on port 4100 with Swagger UI at `/docs`.
27
+
28
+ ## Documentation
29
+
30
+ See the [Ash README](https://github.com/ash-ai-org/ash-ai) for full documentation.
31
+
32
+ ## License
33
+
34
+ [MIT](https://github.com/ash-ai-org/ash-ai/blob/main/LICENSE)
@@ -40,7 +40,7 @@ describe('API key auth middleware', () => {
40
40
  headers: { authorization: `Basic ${API_KEY}` },
41
41
  });
42
42
  expect(res.statusCode).toBe(401);
43
- expect(res.json().error).toBe('Invalid API key');
43
+ expect(res.json().error).toBe('Invalid Authorization header format');
44
44
  });
45
45
  it('allows requests with correct API key', async () => {
46
46
  const res = await app.inject({
@@ -1 +1 @@
1
- {"version":3,"file":"auth.test.js","sourceRoot":"","sources":["../../src/__tests__/auth.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.test.js","sourceRoot":"","sources":["../../src/__tests__/auth.test.ts"],"names":[],"mappings":"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"}
@@ -44,6 +44,9 @@ describe('file routes', () => {
44
44
  }
45
45
  async function buildApp(coordinator) {
46
46
  const app = Fastify();
47
+ // Simulate auth middleware setting tenantId
48
+ app.decorateRequest('tenantId', '');
49
+ app.addHook('onRequest', async (req) => { req.tenantId = 'default'; });
47
50
  registerSchemas(app);
48
51
  fileRoutes(app, coordinator, dataDir);
49
52
  await app.ready();
@@ -1 +1 @@
1
- {"version":3,"file":"files.test.js","sourceRoot":"","sources":["../../src/__tests__/files.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"files.test.js","sourceRoot":"","sources":["../../src/__tests__/files.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=multi-tenant.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-tenant.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/multi-tenant.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,153 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { mkdtempSync, rmSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { tmpdir } from 'node:os';
5
+ import { randomUUID } from 'node:crypto';
6
+ import { initDb, closeDb, upsertAgent, getAgent, listAgents, deleteAgent, insertSession, getSession, listSessions, insertApiKey, getApiKeyByHash, listApiKeysByTenant, deleteApiKey, } from '../db/index.js';
7
+ import { hashApiKey } from '../auth.js';
8
+ describe('multi-tenant isolation', () => {
9
+ let dataDir;
10
+ beforeEach(async () => {
11
+ dataDir = mkdtempSync(join(tmpdir(), 'ash-test-mt-'));
12
+ await initDb({ dataDir });
13
+ });
14
+ afterEach(async () => {
15
+ await closeDb();
16
+ rmSync(dataDir, { recursive: true, force: true });
17
+ });
18
+ // -- Agent isolation --------------------------------------------------------
19
+ describe('agents', () => {
20
+ it('tenant A cannot see tenant B agents', async () => {
21
+ await upsertAgent('shared-name', '/tmp/a', 'tenant-a');
22
+ await upsertAgent('only-b', '/tmp/b', 'tenant-b');
23
+ const agentsA = await listAgents('tenant-a');
24
+ expect(agentsA).toHaveLength(1);
25
+ expect(agentsA[0].name).toBe('shared-name');
26
+ const agentsB = await listAgents('tenant-b');
27
+ expect(agentsB).toHaveLength(1);
28
+ expect(agentsB[0].name).toBe('only-b');
29
+ });
30
+ it('getAgent filters by tenant', async () => {
31
+ await upsertAgent('my-agent', '/tmp/a', 'tenant-a');
32
+ expect(await getAgent('my-agent', 'tenant-a')).not.toBeNull();
33
+ expect(await getAgent('my-agent', 'tenant-b')).toBeNull();
34
+ });
35
+ it('deleteAgent only affects the correct tenant', async () => {
36
+ await upsertAgent('my-agent', '/tmp/a', 'tenant-a');
37
+ // Tenant B cannot delete tenant A's agent
38
+ expect(await deleteAgent('my-agent', 'tenant-b')).toBe(false);
39
+ expect(await getAgent('my-agent', 'tenant-a')).not.toBeNull();
40
+ // Tenant A can delete their own
41
+ expect(await deleteAgent('my-agent', 'tenant-a')).toBe(true);
42
+ expect(await getAgent('my-agent', 'tenant-a')).toBeNull();
43
+ });
44
+ it('default tenant works when no tenantId passed', async () => {
45
+ await upsertAgent('default-agent', '/tmp/default');
46
+ const agent = await getAgent('default-agent');
47
+ expect(agent).not.toBeNull();
48
+ expect(agent.tenantId).toBe('default');
49
+ const agents = await listAgents();
50
+ expect(agents).toHaveLength(1);
51
+ });
52
+ it('agents have UUID ids', async () => {
53
+ const agent = await upsertAgent('uuid-agent', '/tmp/a', 'tenant-a');
54
+ expect(agent.id).toBeDefined();
55
+ expect(agent.id).toMatch(/^[0-9a-f-]{36}$/);
56
+ });
57
+ it('upsert preserves agent id across updates', async () => {
58
+ const v1 = await upsertAgent('stable-agent', '/tmp/v1', 'tenant-a');
59
+ const v2 = await upsertAgent('stable-agent', '/tmp/v2', 'tenant-a');
60
+ expect(v2.id).toBe(v1.id);
61
+ expect(v2.version).toBe(2);
62
+ expect(v2.path).toBe('/tmp/v2');
63
+ });
64
+ it('same agent name in different tenants gets different ids', async () => {
65
+ const agentA = await upsertAgent('shared-name', '/tmp/a', 'tenant-a');
66
+ const agentB = await upsertAgent('shared-name', '/tmp/b', 'tenant-b');
67
+ expect(agentA.id).not.toBe(agentB.id);
68
+ });
69
+ });
70
+ // -- Session isolation ------------------------------------------------------
71
+ describe('sessions', () => {
72
+ beforeEach(async () => {
73
+ await upsertAgent('agent-a', '/tmp/a', 'tenant-a');
74
+ await upsertAgent('agent-b', '/tmp/b', 'tenant-b');
75
+ });
76
+ it('tenant A cannot see tenant B sessions', async () => {
77
+ await insertSession('s1', 'agent-a', 'sb1', 'tenant-a');
78
+ await insertSession('s2', 'agent-b', 'sb2', 'tenant-b');
79
+ const sessA = await listSessions('tenant-a');
80
+ expect(sessA).toHaveLength(1);
81
+ expect(sessA[0].id).toBe('s1');
82
+ const sessB = await listSessions('tenant-b');
83
+ expect(sessB).toHaveLength(1);
84
+ expect(sessB[0].id).toBe('s2');
85
+ });
86
+ it('getSession returns tenantId for route-level access control', async () => {
87
+ await insertSession('s1', 'agent-a', 'sb1', 'tenant-a');
88
+ const session = await getSession('s1');
89
+ expect(session).not.toBeNull();
90
+ expect(session.tenantId).toBe('tenant-a');
91
+ });
92
+ it('listSessions with agent filter respects tenant', async () => {
93
+ await insertSession('s1', 'agent-a', 'sb1', 'tenant-a');
94
+ await insertSession('s2', 'agent-a', 'sb2', 'tenant-b');
95
+ const sessA = await listSessions('tenant-a', 'agent-a');
96
+ expect(sessA).toHaveLength(1);
97
+ expect(sessA[0].id).toBe('s1');
98
+ });
99
+ it('session includes tenantId in response', async () => {
100
+ const session = await insertSession('s1', 'agent-a', 'sb1', 'tenant-a');
101
+ expect(session.tenantId).toBe('tenant-a');
102
+ });
103
+ });
104
+ // -- API Keys ---------------------------------------------------------------
105
+ describe('api keys', () => {
106
+ it('creates and retrieves API key by hash', async () => {
107
+ const rawKey = 'ash_key_abc123';
108
+ const hash = hashApiKey(rawKey);
109
+ const id = randomUUID();
110
+ const key = await insertApiKey(id, 'tenant-a', hash, 'test key');
111
+ expect(key.tenantId).toBe('tenant-a');
112
+ expect(key.label).toBe('test key');
113
+ const found = await getApiKeyByHash(hash);
114
+ expect(found).not.toBeNull();
115
+ expect(found.tenantId).toBe('tenant-a');
116
+ });
117
+ it('returns null for unknown hash', async () => {
118
+ expect(await getApiKeyByHash('nonexistent')).toBeNull();
119
+ });
120
+ it('lists keys by tenant', async () => {
121
+ const hash1 = hashApiKey('key1');
122
+ const hash2 = hashApiKey('key2');
123
+ await insertApiKey(randomUUID(), 'tenant-a', hash1, 'key 1');
124
+ await insertApiKey(randomUUID(), 'tenant-b', hash2, 'key 2');
125
+ const keysA = await listApiKeysByTenant('tenant-a');
126
+ expect(keysA).toHaveLength(1);
127
+ expect(keysA[0].label).toBe('key 1');
128
+ const keysB = await listApiKeysByTenant('tenant-b');
129
+ expect(keysB).toHaveLength(1);
130
+ });
131
+ it('deletes API key', async () => {
132
+ const id = randomUUID();
133
+ const hash = hashApiKey('deleteme');
134
+ await insertApiKey(id, 'tenant-a', hash, 'deleteable');
135
+ expect(await deleteApiKey(id)).toBe(true);
136
+ expect(await getApiKeyByHash(hash)).toBeNull();
137
+ });
138
+ it('returns false when deleting nonexistent key', async () => {
139
+ expect(await deleteApiKey('nonexistent')).toBe(false);
140
+ });
141
+ });
142
+ // -- Auth integration (hashApiKey) ------------------------------------------
143
+ describe('hashApiKey', () => {
144
+ it('produces consistent SHA-256 hashes', () => {
145
+ const key = 'ash_test_key_xyz';
146
+ expect(hashApiKey(key)).toBe(hashApiKey(key));
147
+ });
148
+ it('different keys produce different hashes', () => {
149
+ expect(hashApiKey('key-a')).not.toBe(hashApiKey('key-b'));
150
+ });
151
+ });
152
+ });
153
+ //# sourceMappingURL=multi-tenant.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-tenant.test.js","sourceRoot":"","sources":["../../src/__tests__/multi-tenant.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=schema.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/schema.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ import { describe, it, expect, afterEach } from 'vitest';
2
+ import { readFileSync, mkdtempSync, rmSync } from 'node:fs';
3
+ import { join, resolve, dirname } from 'node:path';
4
+ import { tmpdir } from 'node:os';
5
+ import { fileURLToPath } from 'node:url';
6
+ import Database from 'better-sqlite3';
7
+ import { SqliteDb } from '../db/sqlite.js';
8
+ import { dumpSchema } from '../db/dump-schema.js';
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ const SCHEMA_PATH = resolve(__dirname, '..', 'db', 'schema.sql');
11
+ describe('schema.sql', () => {
12
+ let tempDir;
13
+ let sqliteDb;
14
+ afterEach(async () => {
15
+ await sqliteDb?.close();
16
+ if (tempDir)
17
+ rmSync(tempDir, { recursive: true, force: true });
18
+ });
19
+ it('matches the checked-in schema.sql (run `pnpm dump-schema` to regenerate)', () => {
20
+ tempDir = mkdtempSync(join(tmpdir(), 'ash-schema-test-'));
21
+ sqliteDb = new SqliteDb(tempDir);
22
+ const raw = new Database(join(tempDir, 'ash.db'), { readonly: true });
23
+ const generated = dumpSchema(raw);
24
+ raw.close();
25
+ const checkedIn = readFileSync(SCHEMA_PATH, 'utf-8');
26
+ // Strip the header comments to compare just the schema body
27
+ const bodyFromFile = checkedIn.replace(/^--.*\n/gm, '').trim();
28
+ expect(generated.trim()).toBe(bodyFromFile);
29
+ });
30
+ });
31
+ //# sourceMappingURL=schema.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.test.js","sourceRoot":"","sources":["../../src/__tests__/schema.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;AAEjE,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,IAAI,OAAe,CAAC;IACpB,IAAI,QAAkB,CAAC;IAEvB,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,QAAQ,EAAE,KAAK,EAAE,CAAC;QACxB,IAAI,OAAO;YAAE,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAC1D,QAAQ,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;QAEjC,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACtE,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAClC,GAAG,CAAC,KAAK,EAAE,CAAC;QAEZ,MAAM,SAAS,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACrD,4DAA4D;QAC5D,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAE/D,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/auth.d.ts CHANGED
@@ -1,10 +1,26 @@
1
1
  import type { FastifyInstance } from 'fastify';
2
+ import type { Db } from './db/index.js';
2
3
  /**
3
- * API key authentication hook.
4
+ * Extend Fastify request with tenantId.
5
+ * After auth runs, every request has a tenantId attached (defaults to 'default').
6
+ */
7
+ declare module 'fastify' {
8
+ interface FastifyRequest {
9
+ tenantId: string;
10
+ }
11
+ }
12
+ /** SHA-256 hash of an API key — used to look up keys without storing the raw value. */
13
+ export declare function hashApiKey(key: string): string;
14
+ /**
15
+ * Multi-tenant authentication hook.
4
16
  *
5
- * If ASH_API_KEY is set, all requests (except /health and /docs) must include
6
- * a matching `Authorization: Bearer <key>` header. If ASH_API_KEY is not set,
7
- * auth is disabled (local dev mode).
17
+ * Resolution order:
18
+ * 1. Public endpoints (/health, /docs) skip auth, tenantId = 'default'
19
+ * 2. Internal endpoints (/api/internal/) skip auth, tenantId = 'default'
20
+ * 3. Bearer token → hash → look up in api_keys table → set tenantId from DB row
21
+ * 4. Bearer token matches ASH_API_KEY env → tenantId = 'default' (backward compat)
22
+ * 5. No auth header + no ASH_API_KEY set → tenantId = 'default' (local dev mode)
23
+ * 6. No match → 401
8
24
  */
9
- export declare function registerAuth(app: FastifyInstance, apiKey: string | undefined): void;
25
+ export declare function registerAuth(app: FastifyInstance, apiKey: string | undefined, db?: Db): void;
10
26
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAyBnF"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AAExC;;;GAGG;AACH,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,QAAQ,EAAE,MAAM,CAAC;KAClB;CACF;AAED,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE,GAAG,IAAI,CA4D5F"}
package/dist/auth.js CHANGED
@@ -1,30 +1,70 @@
1
+ import { createHash } from 'node:crypto';
2
+ /** SHA-256 hash of an API key — used to look up keys without storing the raw value. */
3
+ export function hashApiKey(key) {
4
+ return createHash('sha256').update(key).digest('hex');
5
+ }
1
6
  /**
2
- * API key authentication hook.
7
+ * Multi-tenant authentication hook.
3
8
  *
4
- * If ASH_API_KEY is set, all requests (except /health and /docs) must include
5
- * a matching `Authorization: Bearer <key>` header. If ASH_API_KEY is not set,
6
- * auth is disabled (local dev mode).
9
+ * Resolution order:
10
+ * 1. Public endpoints (/health, /docs) skip auth, tenantId = 'default'
11
+ * 2. Internal endpoints (/api/internal/) skip auth, tenantId = 'default'
12
+ * 3. Bearer token → hash → look up in api_keys table → set tenantId from DB row
13
+ * 4. Bearer token matches ASH_API_KEY env → tenantId = 'default' (backward compat)
14
+ * 5. No auth header + no ASH_API_KEY set → tenantId = 'default' (local dev mode)
15
+ * 6. No match → 401
7
16
  */
8
- export function registerAuth(app, apiKey) {
9
- if (!apiKey) {
10
- app.log.info('ASH_API_KEY not set — auth disabled (local dev mode)');
11
- return;
12
- }
17
+ export function registerAuth(app, apiKey, db) {
18
+ // Decorate request with tenantId so it's always available
19
+ app.decorateRequest('tenantId', 'default');
13
20
  app.addHook('onRequest', async (request, reply) => {
14
- // Health and docs endpoints are always public
21
+ // Public endpoints no auth required
15
22
  if (request.url === '/health' || request.url.startsWith('/docs')) {
23
+ request.tenantId = 'default';
24
+ return;
25
+ }
26
+ // Internal endpoints (runner registration, etc.) — no auth required
27
+ if (request.url.startsWith('/api/internal/')) {
28
+ request.tenantId = 'default';
16
29
  return;
17
30
  }
18
31
  const header = request.headers.authorization;
32
+ // No auth header
19
33
  if (!header) {
34
+ if (!apiKey) {
35
+ // Dev mode: no ASH_API_KEY set, no auth required
36
+ request.tenantId = 'default';
37
+ return;
38
+ }
20
39
  return reply.status(401).send({ error: 'Missing Authorization header', statusCode: 401 });
21
40
  }
22
- // Expect "Bearer <key>"
41
+ // Parse "Bearer <key>"
23
42
  const parts = header.split(' ');
24
- if (parts.length !== 2 || parts[0] !== 'Bearer' || parts[1] !== apiKey) {
25
- return reply.status(401).send({ error: 'Invalid API key', statusCode: 401 });
43
+ if (parts.length !== 2 || parts[0] !== 'Bearer') {
44
+ return reply.status(401).send({ error: 'Invalid Authorization header format', statusCode: 401 });
45
+ }
46
+ const bearerKey = parts[1];
47
+ // Try api_keys table first (multi-tenant path)
48
+ if (db) {
49
+ const keyHash = hashApiKey(bearerKey);
50
+ const apiKeyRecord = await db.getApiKeyByHash(keyHash);
51
+ if (apiKeyRecord) {
52
+ request.tenantId = apiKeyRecord.tenantId;
53
+ return;
54
+ }
26
55
  }
56
+ // Fallback: check against ASH_API_KEY env (single-tenant backward compat)
57
+ if (apiKey && bearerKey === apiKey) {
58
+ request.tenantId = 'default';
59
+ return;
60
+ }
61
+ return reply.status(401).send({ error: 'Invalid API key', statusCode: 401 });
27
62
  });
28
- app.log.info('API key authentication enabled');
63
+ if (!apiKey && !db) {
64
+ app.log.info('ASH_API_KEY not set — auth disabled (local dev mode), all requests use tenant "default"');
65
+ }
66
+ else {
67
+ app.log.info('API key authentication enabled (multi-tenant support active)');
68
+ }
29
69
  }
30
70
  //# sourceMappingURL=auth.js.map
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAoB,EAAE,MAA0B;IAC3E,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;QACrE,OAAO;IACT,CAAC;IAED,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAChD,8CAA8C;QAC9C,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACjE,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5F,CAAC;QAED,wBAAwB;QACxB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;YACvE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Reconstructs the current SQLite schema from PRAGMA introspection.
3
+ *
4
+ * Why not just read sqlite_master? Because ALTER TABLE ADD COLUMN
5
+ * doesn't update the original CREATE TABLE statement stored there.
6
+ * We need PRAGMA table_info to get the actual current columns.
7
+ */
8
+ import type Database from 'better-sqlite3';
9
+ export declare function dumpSchema(db: Database.Database): string;
10
+ //# sourceMappingURL=dump-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dump-schema.d.ts","sourceRoot":"","sources":["../../src/db/dump-schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAiC3C,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,MAAM,CAyExD"}
@@ -0,0 +1,64 @@
1
+ export function dumpSchema(db) {
2
+ const tables = db.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all();
3
+ const parts = [];
4
+ for (const { name } of tables) {
5
+ const columns = db.prepare(`PRAGMA table_info("${name}")`).all();
6
+ // Find single-column UNIQUE constraints (from column-level UNIQUE declarations)
7
+ const indexList = db.prepare(`PRAGMA index_list("${name}")`).all();
8
+ const uniqueCols = new Set();
9
+ for (const idx of indexList) {
10
+ if (idx.origin === 'u') {
11
+ const idxCols = db.prepare(`PRAGMA index_info("${idx.name}")`).all();
12
+ if (idxCols.length === 1) {
13
+ uniqueCols.add(idxCols[0].name);
14
+ }
15
+ }
16
+ }
17
+ // Multi-column unique constraints (table-level)
18
+ const uniqueTableConstraints = [];
19
+ for (const idx of indexList) {
20
+ if (idx.origin === 'u') {
21
+ const idxCols = db.prepare(`PRAGMA index_info("${idx.name}")`).all();
22
+ if (idxCols.length > 1) {
23
+ const colNames = idxCols.sort((a, b) => a.seqno - b.seqno).map((c) => c.name).join(', ');
24
+ uniqueTableConstraints.push(` UNIQUE(${colNames})`);
25
+ }
26
+ }
27
+ }
28
+ // Foreign keys
29
+ const fks = db.prepare(`PRAGMA foreign_key_list("${name}")`).all();
30
+ const fkGroups = new Map();
31
+ for (const fk of fks) {
32
+ if (!fkGroups.has(fk.id))
33
+ fkGroups.set(fk.id, []);
34
+ fkGroups.get(fk.id).push(fk);
35
+ }
36
+ // Build column definitions
37
+ const colDefs = columns.map((col) => {
38
+ let def = ` ${col.name} ${col.type}`;
39
+ if (col.pk)
40
+ def += ' PRIMARY KEY';
41
+ if (col.notnull && !col.pk)
42
+ def += ' NOT NULL';
43
+ if (uniqueCols.has(col.name))
44
+ def += ' UNIQUE';
45
+ if (col.dflt_value !== null)
46
+ def += ` DEFAULT ${col.dflt_value}`;
47
+ return def;
48
+ });
49
+ for (const [, fkCols] of fkGroups) {
50
+ const fromCols = fkCols.map((f) => f.from).join(', ');
51
+ const toCols = fkCols.map((f) => f.to).join(', ');
52
+ colDefs.push(` FOREIGN KEY (${fromCols}) REFERENCES ${fkCols[0].table}(${toCols})`);
53
+ }
54
+ colDefs.push(...uniqueTableConstraints);
55
+ parts.push(`CREATE TABLE ${name} (\n${colDefs.join(',\n')}\n);`);
56
+ }
57
+ // Explicit indexes (skip autoindexes)
58
+ const indexes = db.prepare("SELECT sql FROM sqlite_master WHERE type = 'index' AND sql IS NOT NULL AND name NOT LIKE 'sqlite_%' ORDER BY name").all();
59
+ for (const { sql } of indexes) {
60
+ parts.push(sql + ';');
61
+ }
62
+ return parts.join('\n\n');
63
+ }
64
+ //# sourceMappingURL=dump-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dump-schema.js","sourceRoot":"","sources":["../../src/db/dump-schema.ts"],"names":[],"mappings":"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"}