@syncular/server-hono 0.0.1-60
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/api-key-auth.d.ts +49 -0
- package/dist/api-key-auth.d.ts.map +1 -0
- package/dist/api-key-auth.js +110 -0
- package/dist/api-key-auth.js.map +1 -0
- package/dist/blobs.d.ts +69 -0
- package/dist/blobs.d.ts.map +1 -0
- package/dist/blobs.js +383 -0
- package/dist/blobs.js.map +1 -0
- package/dist/console/index.d.ts +8 -0
- package/dist/console/index.d.ts.map +1 -0
- package/dist/console/index.js +7 -0
- package/dist/console/index.js.map +1 -0
- package/dist/console/routes.d.ts +106 -0
- package/dist/console/routes.d.ts.map +1 -0
- package/dist/console/routes.js +1612 -0
- package/dist/console/routes.js.map +1 -0
- package/dist/console/schemas.d.ts +308 -0
- package/dist/console/schemas.d.ts.map +1 -0
- package/dist/console/schemas.js +201 -0
- package/dist/console/schemas.js.map +1 -0
- package/dist/create-server.d.ts +78 -0
- package/dist/create-server.d.ts.map +1 -0
- package/dist/create-server.js +99 -0
- package/dist/create-server.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/openapi.d.ts +45 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +59 -0
- package/dist/openapi.js.map +1 -0
- package/dist/proxy/connection-manager.d.ts +78 -0
- package/dist/proxy/connection-manager.d.ts.map +1 -0
- package/dist/proxy/connection-manager.js +251 -0
- package/dist/proxy/connection-manager.js.map +1 -0
- package/dist/proxy/index.d.ts +8 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/index.js +8 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/proxy/routes.d.ts +74 -0
- package/dist/proxy/routes.d.ts.map +1 -0
- package/dist/proxy/routes.js +147 -0
- package/dist/proxy/routes.js.map +1 -0
- package/dist/rate-limit.d.ts +101 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +186 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/routes.d.ts +126 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +788 -0
- package/dist/routes.js.map +1 -0
- package/dist/ws.d.ts +230 -0
- package/dist/ws.d.ts.map +1 -0
- package/dist/ws.js +601 -0
- package/dist/ws.js.map +1 -0
- package/package.json +73 -0
- package/src/__tests__/create-server.test.ts +187 -0
- package/src/__tests__/pull-chunk-storage.test.ts +189 -0
- package/src/__tests__/rate-limit.test.ts +78 -0
- package/src/__tests__/realtime-bridge.test.ts +131 -0
- package/src/__tests__/ws-connection-manager.test.ts +176 -0
- package/src/api-key-auth.ts +179 -0
- package/src/blobs.ts +534 -0
- package/src/console/index.ts +17 -0
- package/src/console/routes.ts +2155 -0
- package/src/console/schemas.ts +299 -0
- package/src/create-server.ts +180 -0
- package/src/index.ts +42 -0
- package/src/openapi.ts +74 -0
- package/src/proxy/connection-manager.ts +340 -0
- package/src/proxy/index.ts +8 -0
- package/src/proxy/routes.ts +223 -0
- package/src/rate-limit.ts +321 -0
- package/src/routes.ts +1186 -0
- package/src/ws.ts +789 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server-hono - API Key Authentication Helper
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for validating API keys in relay/proxy routes.
|
|
5
|
+
*/
|
|
6
|
+
import type { ServerSyncDialect } from '@syncular/server';
|
|
7
|
+
import type { Context } from 'hono';
|
|
8
|
+
import { type Kysely } from 'kysely';
|
|
9
|
+
import { type ApiKeyType } from './console/schemas';
|
|
10
|
+
interface SyncApiKeysTable {
|
|
11
|
+
key_id: string;
|
|
12
|
+
key_hash: string;
|
|
13
|
+
key_prefix: string;
|
|
14
|
+
name: string;
|
|
15
|
+
key_type: string;
|
|
16
|
+
scope_keys: unknown | null;
|
|
17
|
+
actor_id: string | null;
|
|
18
|
+
created_at: string;
|
|
19
|
+
expires_at: string | null;
|
|
20
|
+
last_used_at: string | null;
|
|
21
|
+
revoked_at: string | null;
|
|
22
|
+
}
|
|
23
|
+
type ApiKeyDb = {
|
|
24
|
+
sync_api_keys: SyncApiKeysTable;
|
|
25
|
+
};
|
|
26
|
+
interface ValidateApiKeyResult {
|
|
27
|
+
keyId: string;
|
|
28
|
+
keyType: ApiKeyType;
|
|
29
|
+
actorId: string | null;
|
|
30
|
+
scopeKeys: string[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Validates an API key from Authorization header.
|
|
34
|
+
* Updates last_used_at on successful validation.
|
|
35
|
+
*/
|
|
36
|
+
export declare function validateApiKey<DB extends ApiKeyDb>(db: Kysely<DB>, dialect: ServerSyncDialect, authHeader: string | undefined): Promise<ValidateApiKeyResult | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Creates an authenticator for relay/proxy routes.
|
|
39
|
+
* Returns actorId from the API key if valid and allowed.
|
|
40
|
+
*/
|
|
41
|
+
export declare function createApiKeyAuthenticator<DB extends ApiKeyDb>(db: Kysely<DB>, dialect: ServerSyncDialect, allowedTypes: ApiKeyType[]): (c: Context) => Promise<{
|
|
42
|
+
actorId: string;
|
|
43
|
+
} | null>;
|
|
44
|
+
/**
|
|
45
|
+
* Middleware that validates API key and attaches result to context.
|
|
46
|
+
*/
|
|
47
|
+
export declare function apiKeyAuthMiddleware<DB extends ApiKeyDb>(db: Kysely<DB>, dialect: ServerSyncDialect, allowedTypes: ApiKeyType[]): (c: Context<any, any, {}>, next: () => Promise<void>) => Promise<Response | undefined>;
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=api-key-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key-auth.d.ts","sourceRoot":"","sources":["../src/api-key-auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,KAAK,MAAM,EAAO,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,mBAAmB,CAAC;AAEtE,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,KAAK,QAAQ,GAAG;IACd,aAAa,EAAE,gBAAgB,CAAC;CACjC,CAAC;AAEF,UAAU,oBAAoB;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,EAAE,SAAS,QAAQ,EACtD,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAkEtC;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,EAAE,SAAS,QAAQ,EAC3D,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,OAAO,EAAE,iBAAiB,EAC1B,YAAY,EAAE,UAAU,EAAE,GACzB,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAmBrD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,SAAS,QAAQ,EACtD,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,OAAO,EAAE,iBAAiB,EAC1B,YAAY,EAAE,UAAU,EAAE,0FAsB3B"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server-hono - API Key Authentication Helper
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for validating API keys in relay/proxy routes.
|
|
5
|
+
*/
|
|
6
|
+
import { sql } from 'kysely';
|
|
7
|
+
import { ApiKeyTypeSchema } from './console/schemas';
|
|
8
|
+
/**
|
|
9
|
+
* Validates an API key from Authorization header.
|
|
10
|
+
* Updates last_used_at on successful validation.
|
|
11
|
+
*/
|
|
12
|
+
export async function validateApiKey(db, dialect, authHeader) {
|
|
13
|
+
if (!authHeader?.startsWith('Bearer ')) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const secretKey = authHeader.slice(7);
|
|
17
|
+
if (!secretKey || !secretKey.startsWith('sk_')) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
// Hash the provided key
|
|
21
|
+
const keyHash = await hashApiKey(secretKey);
|
|
22
|
+
// Look up key by hash
|
|
23
|
+
const rowResult = await sql `
|
|
24
|
+
select key_id, key_type, actor_id, scope_keys, expires_at, revoked_at
|
|
25
|
+
from ${sql.table('sync_api_keys')}
|
|
26
|
+
where key_hash = ${keyHash}
|
|
27
|
+
limit 1
|
|
28
|
+
`.execute(db);
|
|
29
|
+
const row = rowResult.rows[0];
|
|
30
|
+
if (!row) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const parsedKeyType = ApiKeyTypeSchema.safeParse(row.key_type);
|
|
34
|
+
if (!parsedKeyType.success)
|
|
35
|
+
return null;
|
|
36
|
+
// Check if revoked
|
|
37
|
+
if (row.revoked_at) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
// Check if expired
|
|
41
|
+
if (row.expires_at) {
|
|
42
|
+
const expiresAt = new Date(row.expires_at);
|
|
43
|
+
if (expiresAt < new Date()) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Update last_used_at
|
|
48
|
+
const now = new Date().toISOString();
|
|
49
|
+
await sql `
|
|
50
|
+
update ${sql.table('sync_api_keys')}
|
|
51
|
+
set last_used_at = ${now}
|
|
52
|
+
where key_id = ${row.key_id}
|
|
53
|
+
`.execute(db);
|
|
54
|
+
// Parse scopes
|
|
55
|
+
const scopeKeys = dialect.dbToArray(row.scope_keys);
|
|
56
|
+
return {
|
|
57
|
+
keyId: row.key_id,
|
|
58
|
+
keyType: parsedKeyType.data,
|
|
59
|
+
actorId: row.actor_id,
|
|
60
|
+
scopeKeys,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Creates an authenticator for relay/proxy routes.
|
|
65
|
+
* Returns actorId from the API key if valid and allowed.
|
|
66
|
+
*/
|
|
67
|
+
export function createApiKeyAuthenticator(db, dialect, allowedTypes) {
|
|
68
|
+
return async (c) => {
|
|
69
|
+
const authHeader = c.req.header('Authorization');
|
|
70
|
+
const result = await validateApiKey(db, dialect, authHeader);
|
|
71
|
+
if (!result) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
// Check if key type is allowed
|
|
75
|
+
if (!allowedTypes.includes(result.keyType)) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
// Return actorId (use key's actorId if set, otherwise use a default)
|
|
79
|
+
return {
|
|
80
|
+
actorId: result.actorId ?? `api-key:${result.keyId}`,
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Middleware that validates API key and attaches result to context.
|
|
86
|
+
*/
|
|
87
|
+
export function apiKeyAuthMiddleware(db, dialect, allowedTypes) {
|
|
88
|
+
return async (c, next) => {
|
|
89
|
+
const authHeader = c.req.header('Authorization');
|
|
90
|
+
const result = await validateApiKey(db, dialect, authHeader);
|
|
91
|
+
if (!result) {
|
|
92
|
+
return c.json({ error: 'UNAUTHENTICATED' }, 401);
|
|
93
|
+
}
|
|
94
|
+
if (!allowedTypes.includes(result.keyType)) {
|
|
95
|
+
return c.json({ error: 'FORBIDDEN', message: 'Invalid key type' }, 403);
|
|
96
|
+
}
|
|
97
|
+
// Attach to context for downstream handlers
|
|
98
|
+
c.set('apiKey', result);
|
|
99
|
+
await next();
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// Hash function (same as in routes.ts)
|
|
103
|
+
async function hashApiKey(secretKey) {
|
|
104
|
+
const encoder = new TextEncoder();
|
|
105
|
+
const data = encoder.encode(secretKey);
|
|
106
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
107
|
+
const hashArray = new Uint8Array(hashBuffer);
|
|
108
|
+
return Array.from(hashArray, (b) => b.toString(16).padStart(2, '0')).join('');
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=api-key-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key-auth.js","sourceRoot":"","sources":["../src/api-key-auth.ts"],"names":[],"mappings":"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"}
|
package/dist/blobs.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server-hono - Blob routes for media/binary handling
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - POST /blobs/upload - Initiate a blob upload (get presigned URL)
|
|
6
|
+
* - POST /blobs/:hash/complete - Complete a blob upload
|
|
7
|
+
* - GET /blobs/:hash/url - Get a presigned download URL
|
|
8
|
+
* - PUT /blobs/:hash/upload - Direct upload (for database adapter)
|
|
9
|
+
* - GET /blobs/:hash/download - Direct download (for database adapter)
|
|
10
|
+
*/
|
|
11
|
+
import type { BlobManager } from '@syncular/server';
|
|
12
|
+
import { type BlobTokenSigner, type SyncBlobsDb } from '@syncular/server';
|
|
13
|
+
import type { Context } from 'hono';
|
|
14
|
+
import { Hono } from 'hono';
|
|
15
|
+
import type { Kysely } from 'kysely';
|
|
16
|
+
interface BlobAuthResult {
|
|
17
|
+
actorId: string;
|
|
18
|
+
}
|
|
19
|
+
export interface CreateBlobRoutesOptions<DB extends SyncBlobsDb = SyncBlobsDb> {
|
|
20
|
+
/** Blob manager instance */
|
|
21
|
+
blobManager: BlobManager;
|
|
22
|
+
/** Authentication function */
|
|
23
|
+
authenticate: (c: Context) => Promise<BlobAuthResult | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Token signer for database adapter direct uploads/downloads.
|
|
26
|
+
* Required if using the database blob storage adapter.
|
|
27
|
+
*/
|
|
28
|
+
tokenSigner?: BlobTokenSigner;
|
|
29
|
+
/**
|
|
30
|
+
* Database instance for direct blob storage.
|
|
31
|
+
* Required if using the database blob storage adapter.
|
|
32
|
+
*/
|
|
33
|
+
db?: Kysely<DB>;
|
|
34
|
+
/**
|
|
35
|
+
* Optional: Check if actor can access a blob.
|
|
36
|
+
* By default, any authenticated actor can access any completed blob.
|
|
37
|
+
* Provide this to implement scope-based access control.
|
|
38
|
+
*/
|
|
39
|
+
canAccessBlob?: (args: {
|
|
40
|
+
actorId: string;
|
|
41
|
+
hash: string;
|
|
42
|
+
}) => Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Maximum upload size in bytes.
|
|
45
|
+
* Default: 100MB (104857600)
|
|
46
|
+
*/
|
|
47
|
+
maxUploadSize?: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Create blob routes for Hono.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const blobRoutes = createBlobRoutes({
|
|
55
|
+
* blobManager,
|
|
56
|
+
* authenticate: async (c) => {
|
|
57
|
+
* const token = c.req.header('Authorization')?.replace('Bearer ', '');
|
|
58
|
+
* if (!token) return null;
|
|
59
|
+
* const user = await verifyToken(token);
|
|
60
|
+
* return user ? { actorId: user.id } : null;
|
|
61
|
+
* },
|
|
62
|
+
* });
|
|
63
|
+
*
|
|
64
|
+
* app.route('/api/sync', blobRoutes);
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function createBlobRoutes<DB extends SyncBlobsDb>(options: CreateBlobRoutesOptions<DB>): Hono;
|
|
68
|
+
export {};
|
|
69
|
+
//# sourceMappingURL=blobs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blobs.d.ts","sourceRoot":"","sources":["../src/blobs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,OAAO,KAAK,EACV,WAAW,EAGZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,WAAW,EAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGrC,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB,CAAC,EAAE,SAAS,WAAW,GAAG,WAAW;IAC3E,4BAA4B;IAC5B,WAAW,EAAE,WAAW,CAAC;IACzB,8BAA8B;IAC9B,YAAY,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC7D;;;OAGG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IAChB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9E;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAUD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,WAAW,EACrD,OAAO,EAAE,uBAAuB,CAAC,EAAE,CAAC,GACnC,IAAI,CAwZN"}
|
package/dist/blobs.js
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server-hono - Blob routes for media/binary handling
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - POST /blobs/upload - Initiate a blob upload (get presigned URL)
|
|
6
|
+
* - POST /blobs/:hash/complete - Complete a blob upload
|
|
7
|
+
* - GET /blobs/:hash/url - Get a presigned download URL
|
|
8
|
+
* - PUT /blobs/:hash/upload - Direct upload (for database adapter)
|
|
9
|
+
* - GET /blobs/:hash/download - Direct download (for database adapter)
|
|
10
|
+
*/
|
|
11
|
+
import { BlobUploadCompleteResponseSchema, BlobUploadInitRequestSchema, BlobUploadInitResponseSchema, ErrorResponseSchema, parseBlobHash, } from '@syncular/core';
|
|
12
|
+
import { readBlobFromDatabase, storeBlobInDatabase, } from '@syncular/server';
|
|
13
|
+
import { Hono } from 'hono';
|
|
14
|
+
import { describeRoute, resolver, validator as zValidator } from 'hono-openapi';
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
const hashParamsSchema = z.object({
|
|
17
|
+
hash: z.string().min(1),
|
|
18
|
+
});
|
|
19
|
+
const tokenQuerySchema = z.object({
|
|
20
|
+
token: z.string().min(1),
|
|
21
|
+
});
|
|
22
|
+
/**
|
|
23
|
+
* Create blob routes for Hono.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const blobRoutes = createBlobRoutes({
|
|
28
|
+
* blobManager,
|
|
29
|
+
* authenticate: async (c) => {
|
|
30
|
+
* const token = c.req.header('Authorization')?.replace('Bearer ', '');
|
|
31
|
+
* if (!token) return null;
|
|
32
|
+
* const user = await verifyToken(token);
|
|
33
|
+
* return user ? { actorId: user.id } : null;
|
|
34
|
+
* },
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* app.route('/api/sync', blobRoutes);
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function createBlobRoutes(options) {
|
|
41
|
+
const { blobManager, authenticate, tokenSigner, db, canAccessBlob, maxUploadSize = 100 * 1024 * 1024, // 100MB
|
|
42
|
+
} = options;
|
|
43
|
+
const routes = new Hono();
|
|
44
|
+
// -------------------------------------------------------------------------
|
|
45
|
+
// POST /blobs/upload - Initiate upload
|
|
46
|
+
// -------------------------------------------------------------------------
|
|
47
|
+
routes.post('/blobs/upload', describeRoute({
|
|
48
|
+
tags: ['blobs'],
|
|
49
|
+
summary: 'Initiate blob upload',
|
|
50
|
+
description: 'Initiates a blob upload and returns a presigned URL for uploading',
|
|
51
|
+
responses: {
|
|
52
|
+
200: {
|
|
53
|
+
description: 'Upload initiated (or blob already exists)',
|
|
54
|
+
content: {
|
|
55
|
+
'application/json': {
|
|
56
|
+
schema: resolver(BlobUploadInitResponseSchema),
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
400: {
|
|
61
|
+
description: 'Invalid request',
|
|
62
|
+
content: {
|
|
63
|
+
'application/json': { schema: resolver(ErrorResponseSchema) },
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
401: {
|
|
67
|
+
description: 'Unauthenticated',
|
|
68
|
+
content: {
|
|
69
|
+
'application/json': { schema: resolver(ErrorResponseSchema) },
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
}), zValidator('json', BlobUploadInitRequestSchema), async (c) => {
|
|
74
|
+
const auth = await authenticate(c);
|
|
75
|
+
if (!auth)
|
|
76
|
+
return c.json({ error: 'UNAUTHENTICATED' }, 401);
|
|
77
|
+
const body = c.req.valid('json');
|
|
78
|
+
// Validate size
|
|
79
|
+
if (body.size > maxUploadSize) {
|
|
80
|
+
return c.json({
|
|
81
|
+
error: 'BLOB_TOO_LARGE',
|
|
82
|
+
message: `Maximum upload size is ${maxUploadSize} bytes`,
|
|
83
|
+
}, 400);
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const result = await blobManager.initiateUpload({
|
|
87
|
+
hash: body.hash,
|
|
88
|
+
size: body.size,
|
|
89
|
+
mimeType: body.mimeType,
|
|
90
|
+
actorId: auth.actorId,
|
|
91
|
+
});
|
|
92
|
+
return c.json(result, 200);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
if (isBlobValidationError(err)) {
|
|
96
|
+
return c.json({ error: 'INVALID_REQUEST', message: err.message }, 400);
|
|
97
|
+
}
|
|
98
|
+
throw err;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
// -------------------------------------------------------------------------
|
|
102
|
+
// POST /blobs/:hash/complete - Complete upload
|
|
103
|
+
// -------------------------------------------------------------------------
|
|
104
|
+
routes.post('/blobs/:hash/complete', describeRoute({
|
|
105
|
+
tags: ['blobs'],
|
|
106
|
+
summary: 'Complete blob upload',
|
|
107
|
+
description: 'Marks a blob upload as complete after the client has uploaded to the presigned URL',
|
|
108
|
+
responses: {
|
|
109
|
+
200: {
|
|
110
|
+
description: 'Upload completed',
|
|
111
|
+
content: {
|
|
112
|
+
'application/json': {
|
|
113
|
+
schema: resolver(BlobUploadCompleteResponseSchema),
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
400: {
|
|
118
|
+
description: 'Invalid request or upload failed',
|
|
119
|
+
content: {
|
|
120
|
+
'application/json': { schema: resolver(ErrorResponseSchema) },
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
401: {
|
|
124
|
+
description: 'Unauthenticated',
|
|
125
|
+
content: {
|
|
126
|
+
'application/json': { schema: resolver(ErrorResponseSchema) },
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
}), zValidator('param', hashParamsSchema), async (c) => {
|
|
131
|
+
const auth = await authenticate(c);
|
|
132
|
+
if (!auth)
|
|
133
|
+
return c.json({ error: 'UNAUTHENTICATED' }, 401);
|
|
134
|
+
const { hash } = c.req.valid('param');
|
|
135
|
+
// Validate hash format
|
|
136
|
+
if (!parseBlobHash(hash)) {
|
|
137
|
+
return c.json({ error: 'INVALID_REQUEST', message: 'Invalid blob hash format' }, 400);
|
|
138
|
+
}
|
|
139
|
+
const result = await blobManager.completeUpload(hash);
|
|
140
|
+
if (!result.ok) {
|
|
141
|
+
return c.json({ error: 'UPLOAD_FAILED', message: result.error }, 400);
|
|
142
|
+
}
|
|
143
|
+
return c.json(result, 200);
|
|
144
|
+
});
|
|
145
|
+
// -------------------------------------------------------------------------
|
|
146
|
+
// GET /blobs/:hash/url - Get download URL
|
|
147
|
+
// -------------------------------------------------------------------------
|
|
148
|
+
routes.get('/blobs/:hash/url', describeRoute({
|
|
149
|
+
tags: ['blobs'],
|
|
150
|
+
summary: 'Get blob download URL',
|
|
151
|
+
description: 'Returns a presigned URL for downloading a blob',
|
|
152
|
+
responses: {
|
|
153
|
+
200: {
|
|
154
|
+
description: 'Download URL',
|
|
155
|
+
content: {
|
|
156
|
+
'application/json': {
|
|
157
|
+
schema: resolver(z.object({
|
|
158
|
+
url: z.string().url(),
|
|
159
|
+
expiresAt: z.string(),
|
|
160
|
+
metadata: z.object({
|
|
161
|
+
hash: z.string(),
|
|
162
|
+
size: z.number(),
|
|
163
|
+
mimeType: z.string(),
|
|
164
|
+
createdAt: z.string(),
|
|
165
|
+
uploadComplete: z.boolean(),
|
|
166
|
+
}),
|
|
167
|
+
})),
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
401: {
|
|
172
|
+
description: 'Unauthenticated',
|
|
173
|
+
content: {
|
|
174
|
+
'application/json': { schema: resolver(ErrorResponseSchema) },
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
403: {
|
|
178
|
+
description: 'Forbidden',
|
|
179
|
+
content: {
|
|
180
|
+
'application/json': { schema: resolver(ErrorResponseSchema) },
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
404: {
|
|
184
|
+
description: 'Not found',
|
|
185
|
+
content: {
|
|
186
|
+
'application/json': { schema: resolver(ErrorResponseSchema) },
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
}), zValidator('param', hashParamsSchema), async (c) => {
|
|
191
|
+
const auth = await authenticate(c);
|
|
192
|
+
if (!auth)
|
|
193
|
+
return c.json({ error: 'UNAUTHENTICATED' }, 401);
|
|
194
|
+
const { hash } = c.req.valid('param');
|
|
195
|
+
// Validate hash format
|
|
196
|
+
if (!parseBlobHash(hash)) {
|
|
197
|
+
return c.json({ error: 'NOT_FOUND' }, 404);
|
|
198
|
+
}
|
|
199
|
+
// Check access if canAccessBlob is provided
|
|
200
|
+
if (canAccessBlob) {
|
|
201
|
+
const canAccess = await canAccessBlob({ actorId: auth.actorId, hash });
|
|
202
|
+
if (!canAccess) {
|
|
203
|
+
return c.json({ error: 'FORBIDDEN' }, 403);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
const result = await blobManager.getDownloadUrl({
|
|
208
|
+
hash,
|
|
209
|
+
actorId: auth.actorId,
|
|
210
|
+
});
|
|
211
|
+
return c.json(result, 200);
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
if (isBlobNotFoundError(err)) {
|
|
215
|
+
return c.json({ error: 'NOT_FOUND' }, 404);
|
|
216
|
+
}
|
|
217
|
+
throw err;
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
// -------------------------------------------------------------------------
|
|
221
|
+
// PUT /blobs/:hash/upload - Direct upload (database adapter)
|
|
222
|
+
// -------------------------------------------------------------------------
|
|
223
|
+
if (tokenSigner && db) {
|
|
224
|
+
routes.put('/blobs/:hash/upload', describeRoute({
|
|
225
|
+
tags: ['blobs'],
|
|
226
|
+
summary: 'Direct blob upload',
|
|
227
|
+
description: 'Direct upload endpoint for database storage adapter. Requires a signed token.',
|
|
228
|
+
responses: {
|
|
229
|
+
200: {
|
|
230
|
+
description: 'Upload successful',
|
|
231
|
+
},
|
|
232
|
+
400: {
|
|
233
|
+
description: 'Invalid request',
|
|
234
|
+
content: {
|
|
235
|
+
'application/json': { schema: resolver(ErrorResponseSchema) },
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
401: {
|
|
239
|
+
description: 'Invalid or expired token',
|
|
240
|
+
content: {
|
|
241
|
+
'application/json': { schema: resolver(ErrorResponseSchema) },
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
}), zValidator('param', hashParamsSchema), zValidator('query', tokenQuerySchema), async (c) => {
|
|
246
|
+
const { hash } = c.req.valid('param');
|
|
247
|
+
const { token } = c.req.valid('query');
|
|
248
|
+
// Verify token
|
|
249
|
+
const payload = await tokenSigner.verify(token);
|
|
250
|
+
if (!payload || payload.action !== 'upload' || payload.hash !== hash) {
|
|
251
|
+
return c.json({ error: 'INVALID_TOKEN' }, 401);
|
|
252
|
+
}
|
|
253
|
+
// Get upload metadata
|
|
254
|
+
const metadata = await blobManager.getMetadata(hash);
|
|
255
|
+
// Read body
|
|
256
|
+
const body = await c.req.arrayBuffer();
|
|
257
|
+
const bodyBytes = new Uint8Array(body);
|
|
258
|
+
// Verify size
|
|
259
|
+
const expectedSize = metadata?.size;
|
|
260
|
+
if (expectedSize !== undefined && bodyBytes.length !== expectedSize) {
|
|
261
|
+
return c.json({
|
|
262
|
+
error: 'SIZE_MISMATCH',
|
|
263
|
+
message: `Expected ${expectedSize} bytes, got ${bodyBytes.length}`,
|
|
264
|
+
}, 400);
|
|
265
|
+
}
|
|
266
|
+
// Verify hash
|
|
267
|
+
const computedHash = await computeSha256Hash(bodyBytes);
|
|
268
|
+
const expectedHex = parseBlobHash(hash);
|
|
269
|
+
if (computedHash !== expectedHex) {
|
|
270
|
+
return c.json({
|
|
271
|
+
error: 'HASH_MISMATCH',
|
|
272
|
+
message: 'Content hash does not match',
|
|
273
|
+
}, 400);
|
|
274
|
+
}
|
|
275
|
+
// Store via the blob adapter (R2, database, etc.)
|
|
276
|
+
const mimeType = c.req.header('Content-Type') ??
|
|
277
|
+
metadata?.mimeType ??
|
|
278
|
+
'application/octet-stream';
|
|
279
|
+
if (blobManager.adapter.put) {
|
|
280
|
+
await blobManager.adapter.put(hash, bodyBytes, { mimeType });
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
await storeBlobInDatabase(db, {
|
|
284
|
+
hash,
|
|
285
|
+
size: bodyBytes.length,
|
|
286
|
+
mimeType,
|
|
287
|
+
body: bodyBytes,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
return c.text('OK', 200);
|
|
291
|
+
});
|
|
292
|
+
// -------------------------------------------------------------------------
|
|
293
|
+
// GET /blobs/:hash/download - Direct download (database adapter)
|
|
294
|
+
// -------------------------------------------------------------------------
|
|
295
|
+
routes.get('/blobs/:hash/download', describeRoute({
|
|
296
|
+
tags: ['blobs'],
|
|
297
|
+
summary: 'Direct blob download',
|
|
298
|
+
description: 'Direct download endpoint for database storage adapter. Requires a signed token.',
|
|
299
|
+
responses: {
|
|
300
|
+
200: {
|
|
301
|
+
description: 'Blob content',
|
|
302
|
+
},
|
|
303
|
+
401: {
|
|
304
|
+
description: 'Invalid or expired token',
|
|
305
|
+
content: {
|
|
306
|
+
'application/json': { schema: resolver(ErrorResponseSchema) },
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
404: {
|
|
310
|
+
description: 'Not found',
|
|
311
|
+
content: {
|
|
312
|
+
'application/json': { schema: resolver(ErrorResponseSchema) },
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
}), zValidator('param', hashParamsSchema), zValidator('query', tokenQuerySchema), async (c) => {
|
|
317
|
+
const { hash } = c.req.valid('param');
|
|
318
|
+
const { token } = c.req.valid('query');
|
|
319
|
+
// Verify token
|
|
320
|
+
const payload = await tokenSigner.verify(token);
|
|
321
|
+
if (!payload ||
|
|
322
|
+
payload.action !== 'download' ||
|
|
323
|
+
payload.hash !== hash) {
|
|
324
|
+
return c.json({ error: 'INVALID_TOKEN' }, 401);
|
|
325
|
+
}
|
|
326
|
+
// Read via the blob adapter (R2, database, etc.)
|
|
327
|
+
if (blobManager.adapter.get) {
|
|
328
|
+
const data = await blobManager.adapter.get(hash);
|
|
329
|
+
if (!data) {
|
|
330
|
+
return c.json({ error: 'NOT_FOUND' }, 404);
|
|
331
|
+
}
|
|
332
|
+
const meta = blobManager.adapter.getMetadata
|
|
333
|
+
? await blobManager.adapter.getMetadata(hash)
|
|
334
|
+
: null;
|
|
335
|
+
return new Response(data, {
|
|
336
|
+
status: 200,
|
|
337
|
+
headers: {
|
|
338
|
+
'Content-Type': meta?.mimeType ?? 'application/octet-stream',
|
|
339
|
+
'Content-Length': String(data.length),
|
|
340
|
+
'Cache-Control': 'private, max-age=31536000, immutable',
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
// Fallback: read from database directly
|
|
345
|
+
const blob = await readBlobFromDatabase(db, hash);
|
|
346
|
+
if (!blob) {
|
|
347
|
+
return c.json({ error: 'NOT_FOUND' }, 404);
|
|
348
|
+
}
|
|
349
|
+
return new Response(blob.body, {
|
|
350
|
+
status: 200,
|
|
351
|
+
headers: {
|
|
352
|
+
'Content-Type': blob.mimeType,
|
|
353
|
+
'Content-Length': String(blob.size),
|
|
354
|
+
'Cache-Control': 'private, max-age=31536000, immutable',
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
return routes;
|
|
360
|
+
}
|
|
361
|
+
// ============================================================================
|
|
362
|
+
// Helpers
|
|
363
|
+
// ============================================================================
|
|
364
|
+
function isBlobValidationError(err) {
|
|
365
|
+
return (typeof err === 'object' &&
|
|
366
|
+
err !== null &&
|
|
367
|
+
err.name === 'BlobValidationError');
|
|
368
|
+
}
|
|
369
|
+
function isBlobNotFoundError(err) {
|
|
370
|
+
return (typeof err === 'object' &&
|
|
371
|
+
err !== null &&
|
|
372
|
+
err.name === 'BlobNotFoundError');
|
|
373
|
+
}
|
|
374
|
+
async function computeSha256Hash(data) {
|
|
375
|
+
// Create a new ArrayBuffer copy to satisfy TypeScript's strict typing
|
|
376
|
+
const buffer = new Uint8Array(data).buffer;
|
|
377
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
|
|
378
|
+
const hashArray = new Uint8Array(hashBuffer);
|
|
379
|
+
return Array.from(hashArray)
|
|
380
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
381
|
+
.join('');
|
|
382
|
+
}
|
|
383
|
+
//# sourceMappingURL=blobs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blobs.js","sourceRoot":"","sources":["../src/blobs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server-hono - Console API
|
|
3
|
+
*
|
|
4
|
+
* Provides monitoring and operations endpoints for the @syncular dashboard.
|
|
5
|
+
*/
|
|
6
|
+
export type { ConsoleAuthResult, ConsoleEventEmitter, CreateConsoleRoutesOptions, } from './routes';
|
|
7
|
+
export { createConsoleEventEmitter, createConsoleRoutes, createTokenAuthenticator, } from './routes';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/console/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,UAAU,CAAC"}
|