deepspace 0.4.4 → 0.4.5

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/server.d.ts CHANGED
@@ -2096,49 +2096,6 @@ declare abstract class CronRoom<E = Record<string, unknown>> extends BaseRoom<E>
2096
2096
  protected abstract onTask(taskName: string): void | Promise<void>;
2097
2097
  }
2098
2098
 
2099
- interface SecretMetadata {
2100
- name: string;
2101
- version: number;
2102
- createdAt: string;
2103
- updatedAt: string;
2104
- updatedBy: string | null;
2105
- }
2106
- declare class SecretsRoom<E extends {
2107
- APP_SECRETS_KEY?: string;
2108
- } = {
2109
- APP_SECRETS_KEY?: string;
2110
- }> extends BaseRoom<E> {
2111
- private initialized;
2112
- protected onMessage(_ws: WebSocket, _user: UserAttachment, _message: {
2113
- type: string;
2114
- }): void;
2115
- fetch(request: Request): Promise<Response>;
2116
- protected onRequest(request: Request): Promise<Response>;
2117
- list(): Promise<SecretMetadata[]>;
2118
- pull(): Promise<Record<string, string>>;
2119
- patch(body: {
2120
- set?: Record<string, string>;
2121
- delete?: string[];
2122
- updatedBy?: string;
2123
- }): Promise<{
2124
- version: number;
2125
- secrets: SecretMetadata[];
2126
- }>;
2127
- replace(body: {
2128
- secrets?: Record<string, string>;
2129
- updatedBy?: string;
2130
- }): Promise<{
2131
- version: number;
2132
- secrets: SecretMetadata[];
2133
- }>;
2134
- private transaction;
2135
- private migrateLegacyProductionSecrets;
2136
- private ensureInitialized;
2137
- private requireKey;
2138
- private storeVersion;
2139
- private bumpStoreVersion;
2140
- }
2141
-
2142
2099
  /**
2143
2100
  * JobRoom — Per-app durable background-job execution Durable Object.
2144
2101
  *
@@ -2440,7 +2397,7 @@ declare const ALLOWED_BINDING_TYPES: Set<string>;
2440
2397
  *
2441
2398
  * Includes:
2442
2399
  * - Static-asset + service bindings the platform sets up automatically.
2443
- * - SDK-managed env (auth, identity, owner JWT, app-secret encryption root).
2400
+ * - SDK-managed env (auth, identity, owner JWT).
2444
2401
  * - The auto-attached cost-tracking AE dataset (`USAGE_EVENTS`).
2445
2402
  *
2446
2403
  * DO binding names (RECORD_ROOMS, YJS_ROOMS, etc.) are NOT in this set
@@ -3956,47 +3913,6 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
3956
3913
  }>;
3957
3914
  type DeepSpaceAuth = ReturnType<typeof createDeepSpaceAuth>;
3958
3915
 
3959
- interface SecretsEnv {
3960
- SECRETS_ROOMS?: DurableObjectNamespace;
3961
- APP_SECRETS_KEY?: string;
3962
- APP_SECRETS_LOCAL_FALLBACK?: string;
3963
- }
3964
- interface SecretRefreshResult {
3965
- changed: boolean;
3966
- version: number;
3967
- }
3968
- interface WithFreshSecretsContext {
3969
- secrets: SecretsClient;
3970
- attempt: number;
3971
- refreshed: boolean;
3972
- }
3973
- interface WithFreshSecretsOptions {
3974
- /**
3975
- * By default the operation retries only when a forced refresh observes a
3976
- * changed secret version after an auth-like failure. Set this for idempotent
3977
- * operations that should retry after a successful refresh even when the
3978
- * version is unchanged.
3979
- */
3980
- retryWhenUnchanged?: boolean;
3981
- }
3982
- interface SecretsClient {
3983
- get(name: string): Promise<string | undefined>;
3984
- require(name: string): Promise<string>;
3985
- getMany(names: string[]): Promise<Record<string, string | undefined>>;
3986
- preload(names: string[]): Promise<void>;
3987
- refresh(options?: {
3988
- force?: boolean;
3989
- }): Promise<SecretRefreshResult>;
3990
- checkForUpdates(): Promise<SecretRefreshResult>;
3991
- invalidate(): void;
3992
- withFreshSecrets<T>(operation: (ctx: WithFreshSecretsContext) => Promise<T>, options?: WithFreshSecretsOptions): Promise<T>;
3993
- }
3994
- interface CreateSecretsOptions {
3995
- refreshIntervalMs?: number;
3996
- now?: () => number;
3997
- }
3998
- declare function createSecrets(env: SecretsEnv, options?: CreateSecretsOptions): SecretsClient;
3999
-
4000
3916
  /**
4001
3917
  * Subscription primitives shared between client (useSubscription hook) and
4002
3918
  * server (requireSubscription helper). Pulled into a shared module so the
@@ -4150,4 +4066,4 @@ declare class RefundError extends Error {
4150
4066
  constructor(message: string, status: number);
4151
4067
  }
4152
4068
 
4153
- export { AI_CHATS_SCHEMA, AI_MESSAGES_SCHEMA, ALLOWED_BINDING_TYPES, APP_NAME_RULES, AUTO_PROVISIONABLE_TYPES, AUTO_PROVISION_SENTINEL, type ActionContext, type ActionHandler, type ActionResult, type ActionTools, type ApiWorkerEnv, type AppNameResolution, type AppNameValidation, type AuthWorkerEnv, BASE_USERS_SCHEMA, BUILT_IN_TOOLS, BaseRoom, CHANNELS_SCHEMA, CHANNEL_INVITATIONS_SCHEMA, CHANNEL_MEMBERS_SCHEMA, CONVERSATION_SCHEMAS, COST_RATES, CancelSubscriptionError, type CancelSubscriptionOpts, type CancelSubscriptionResult, CanvasRoom, type CanvasShape, type ChatContextConfig, type ChatMessageRow, type ChatRow, type ChatTurn, type CollectionPermissionSummary, type CollectionSchema, type ColumnDefinition, type ColumnInterpretation, type ComposioToolsOptions, type ConvMemberData, type ConvMessageData, type ConvReactionData, type ConvReadCursorData, type ConvVoteData, type ConversationStateData, type CreateSecretsOptions, type CronContext, type CronExecution, CronRoom, type CronRoomConfig, type CronTask, type CustomBinding, type CustomBindingManifest, DEFAULT_CONTEXT_CONFIG, DEFAULT_DO_MANIFEST, DEFAULT_QUERY_LIMIT, DIRECTORY_SCHEMAS, type DOBindings, type DOManifest, type DOManifestEntry, type DebugApiContext, type DeepSpaceAIEnv, type DeepSpaceAIOptions, type DeepSpaceAuth, type DeepSpaceAuthConfig, type DirectoryCommunityData, type DirectoryConversationData, type DirectoryMembershipData, type DirectoryPostData, type DoMigrationDirective, type DoMigrationPlan, type ExistingDOBinding, GLOBAL_DO_TYPES, GLOBAL_DO_TYPE_NAMES, type GameInput, GameRoom, type GameRoomConfig, type GetActionData, type GlobalDOType, type Job, type JobContext, JobRoom, type JobRoomConfig, type JobStatus, type JwtClaims, type JwtVerifierConfig, MESSAGES_SCHEMA, type MutateActionData, type PermissionAnalysis, type PermissionContext, type PermissionLevel, type PermissionSource, type PlanInfo, type PlatformWorkerEnv, type Player, type PrefixResult, type PresencePeer, PresenceRoom, type QueryActionData, REACTIONS_SCHEMA, READ_RECEIPTS_SCHEMA, RESERVED_BINDING_NAMES, RESERVED_COLLECTION_NAMES, type RecordContext, RecordRoom, type RecordRoomConfig, RefundError, type RefundOpts, type RefundResult, type ResolvedColumn, type ResolvedPermission, type RolePermissions, type RunMigrationsResult, SYSTEM_COLLECTION_SCHEMAS, SYSTEM_MANAGED_COLUMNS, SchemaRegistry, type ScopeContext, type ScopedR2Auth, type ScopedR2Config, type ScopedR2Handler, type ScreenshotEnv, type ScreenshotOptions, type ScreenshotResult, type SecretMetadata, type SecretRefreshResult, type SecretsClient, type SecretsEnv, SecretsRoom, type SharedConnection, type StoredRecord, SubscriptionAuthError, type SubscriptionContext, type SubscriptionRead, SubscriptionRequiredError, type SubscriptionStatus, type Summarizer, type TokenDebugInfo, type ToolResult, type ToolSchema, type ToolsApiContext, USERS_COLUMNS, type User, type UserAttachment, type UserContext, VOTING_SCHEMAS, type ValidationError, type VerifiedAuth, type VerifyOutcome, type VerifyResult, type Viewport, WORKSPACE_SCHEMAS, type WithFreshSecretsContext, type WithFreshSecretsOptions, type YjsContext, YjsRoom, analyzePermissions, apiWorkerFetch, appendMessage, applyAiToolDefaults, applySlidingWindow, authWorkerFetch, bindingManifestFromOutputConfig, broadcastChange, broadcastYjsUpdate, buildCronContext, buildTableSelect, buildUiParts, canCreate, canDelete, canRead, canUpdate, cancelSubscription, capToolResultSize, captureScreenshot, checkFieldPermissions, coerceValue, collectionTableName, columnId, composioTools, computeDoMigration, computeHmacHex, createChat, createDeepSpaceAI, createDeepSpaceAuth, createScopedR2Handler, createSecrets, dataToColumnValues, decodeJwtPayload, deleteChatCascade, deleteRecord, enqueueJob, executeQuery, getAllUsers, getChat, getGlobalDOSchemas, getGlobalDOType, getOrCreateYjsDoc, getRecord, getRolePermissions, getSubscription, getUser, getYjsDocKey, handleApiRequest, handleDelete, handlePut, handleSetRole, handleSubscribe, handleToolsRequest, handleUnsubscribe, handleUserList, handleUserUpdate, handleYjsBinaryMessage, handleYjsJoin, handleYjsLeave, isAutoProvision, isOwner, lintSchema, loadMessages, makeDefaultSummarizer, meterAi, meterUsage, meterVectorize, noopPermissionContext, platformWorkerFetch, prepareMessagesWithCompaction, priceBindingUsageEvent, putRecord, readRecord, recordMatchesSubscription, refundInvoice, registerUser, requireSubscription, resolveAppName, resolveColumn, rowToData, runMigrations, saveYjsDoc, timingSafeEqualHex, totalChars, truncateOldToolResults, turnsToCoreMessages, unwrapToolOutput, updateChat, validateAppName, validateBindingManifest, validateDoManifest, verifyJwt, workspaceAccountsSchema, workspaceContentSharesSchema, workspaceEmailHandlesSchema, workspaceFormResponsesSchema, workspacePeopleSchema, workspaceProjectsSchema, workspaceTagsSchema, workspaceTasksSchema, workspaceTeamMembersSchema, workspaceTeamsSchema, workspaceTransactionsSchema };
4069
+ export { AI_CHATS_SCHEMA, AI_MESSAGES_SCHEMA, ALLOWED_BINDING_TYPES, APP_NAME_RULES, AUTO_PROVISIONABLE_TYPES, AUTO_PROVISION_SENTINEL, type ActionContext, type ActionHandler, type ActionResult, type ActionTools, type ApiWorkerEnv, type AppNameResolution, type AppNameValidation, type AuthWorkerEnv, BASE_USERS_SCHEMA, BUILT_IN_TOOLS, BaseRoom, CHANNELS_SCHEMA, CHANNEL_INVITATIONS_SCHEMA, CHANNEL_MEMBERS_SCHEMA, CONVERSATION_SCHEMAS, COST_RATES, CancelSubscriptionError, type CancelSubscriptionOpts, type CancelSubscriptionResult, CanvasRoom, type CanvasShape, type ChatContextConfig, type ChatMessageRow, type ChatRow, type ChatTurn, type CollectionPermissionSummary, type CollectionSchema, type ColumnDefinition, type ColumnInterpretation, type ComposioToolsOptions, type ConvMemberData, type ConvMessageData, type ConvReactionData, type ConvReadCursorData, type ConvVoteData, type ConversationStateData, type CronContext, type CronExecution, CronRoom, type CronRoomConfig, type CronTask, type CustomBinding, type CustomBindingManifest, DEFAULT_CONTEXT_CONFIG, DEFAULT_DO_MANIFEST, DEFAULT_QUERY_LIMIT, DIRECTORY_SCHEMAS, type DOBindings, type DOManifest, type DOManifestEntry, type DebugApiContext, type DeepSpaceAIEnv, type DeepSpaceAIOptions, type DeepSpaceAuth, type DeepSpaceAuthConfig, type DirectoryCommunityData, type DirectoryConversationData, type DirectoryMembershipData, type DirectoryPostData, type DoMigrationDirective, type DoMigrationPlan, type ExistingDOBinding, GLOBAL_DO_TYPES, GLOBAL_DO_TYPE_NAMES, type GameInput, GameRoom, type GameRoomConfig, type GetActionData, type GlobalDOType, type Job, type JobContext, JobRoom, type JobRoomConfig, type JobStatus, type JwtClaims, type JwtVerifierConfig, MESSAGES_SCHEMA, type MutateActionData, type PermissionAnalysis, type PermissionContext, type PermissionLevel, type PermissionSource, type PlanInfo, type PlatformWorkerEnv, type Player, type PrefixResult, type PresencePeer, PresenceRoom, type QueryActionData, REACTIONS_SCHEMA, READ_RECEIPTS_SCHEMA, RESERVED_BINDING_NAMES, RESERVED_COLLECTION_NAMES, type RecordContext, RecordRoom, type RecordRoomConfig, RefundError, type RefundOpts, type RefundResult, type ResolvedColumn, type ResolvedPermission, type RolePermissions, type RunMigrationsResult, SYSTEM_COLLECTION_SCHEMAS, SYSTEM_MANAGED_COLUMNS, SchemaRegistry, type ScopeContext, type ScopedR2Auth, type ScopedR2Config, type ScopedR2Handler, type ScreenshotEnv, type ScreenshotOptions, type ScreenshotResult, type SharedConnection, type StoredRecord, SubscriptionAuthError, type SubscriptionContext, type SubscriptionRead, SubscriptionRequiredError, type SubscriptionStatus, type Summarizer, type TokenDebugInfo, type ToolResult, type ToolSchema, type ToolsApiContext, USERS_COLUMNS, type User, type UserAttachment, type UserContext, VOTING_SCHEMAS, type ValidationError, type VerifiedAuth, type VerifyOutcome, type VerifyResult, type Viewport, WORKSPACE_SCHEMAS, type YjsContext, YjsRoom, analyzePermissions, apiWorkerFetch, appendMessage, applyAiToolDefaults, applySlidingWindow, authWorkerFetch, bindingManifestFromOutputConfig, broadcastChange, broadcastYjsUpdate, buildCronContext, buildTableSelect, buildUiParts, canCreate, canDelete, canRead, canUpdate, cancelSubscription, capToolResultSize, captureScreenshot, checkFieldPermissions, coerceValue, collectionTableName, columnId, composioTools, computeDoMigration, computeHmacHex, createChat, createDeepSpaceAI, createDeepSpaceAuth, createScopedR2Handler, dataToColumnValues, decodeJwtPayload, deleteChatCascade, deleteRecord, enqueueJob, executeQuery, getAllUsers, getChat, getGlobalDOSchemas, getGlobalDOType, getOrCreateYjsDoc, getRecord, getRolePermissions, getSubscription, getUser, getYjsDocKey, handleApiRequest, handleDelete, handlePut, handleSetRole, handleSubscribe, handleToolsRequest, handleUnsubscribe, handleUserList, handleUserUpdate, handleYjsBinaryMessage, handleYjsJoin, handleYjsLeave, isAutoProvision, isOwner, lintSchema, loadMessages, makeDefaultSummarizer, meterAi, meterUsage, meterVectorize, noopPermissionContext, platformWorkerFetch, prepareMessagesWithCompaction, priceBindingUsageEvent, putRecord, readRecord, recordMatchesSubscription, refundInvoice, registerUser, requireSubscription, resolveAppName, resolveColumn, rowToData, runMigrations, saveYjsDoc, timingSafeEqualHex, totalChars, truncateOldToolResults, turnsToCoreMessages, unwrapToolOutput, updateChat, validateAppName, validateBindingManifest, validateDoManifest, verifyJwt, workspaceAccountsSchema, workspaceContentSharesSchema, workspaceEmailHandlesSchema, workspaceFormResponsesSchema, workspacePeopleSchema, workspaceProjectsSchema, workspaceTagsSchema, workspaceTasksSchema, workspaceTeamMembersSchema, workspaceTeamsSchema, workspaceTransactionsSchema };
package/dist/server.js CHANGED
@@ -3978,13 +3978,13 @@ var YjsRoom = class extends BaseRoom {
3978
3978
  onMessage(ws, user, message) {
3979
3979
  }
3980
3980
  onBinaryMessage(ws, user, data) {
3981
- const bytes2 = new Uint8Array(data);
3982
- const decoder = createDecoder(bytes2);
3981
+ const bytes = new Uint8Array(data);
3982
+ const decoder = createDecoder(bytes);
3983
3983
  const messageType = readVarUint(decoder);
3984
3984
  if (messageType === MSG_SYNC) {
3985
- this.handleSync(ws, decoder, bytes2);
3985
+ this.handleSync(ws, decoder, bytes);
3986
3986
  } else if (messageType === MSG_AWARENESS) {
3987
- this.handleAwareness(ws, decoder, bytes2);
3987
+ this.handleAwareness(ws, decoder, bytes);
3988
3988
  }
3989
3989
  }
3990
3990
  onDisconnect(ws, user) {
@@ -5189,319 +5189,6 @@ function cronMatches(parsed, timezone, date) {
5189
5189
  return parsed.minute.has(minute) && parsed.hour.has(hour) && parsed.dayOfMonth.has(dayOfMonth) && parsed.month.has(month) && parsed.dayOfWeek.has(dayOfWeek);
5190
5190
  }
5191
5191
 
5192
- // src/server/rooms/secrets-room.ts
5193
- var INTERNAL_HEADER = "x-deepspace-internal";
5194
- var INTERNAL_VALUE = "app-secrets";
5195
- var VERSION = "app-secret-v1";
5196
- var NAME_INFO = "deepspace app secret name v1";
5197
- var VALUE_INFO = "deepspace app secret value v1";
5198
- var HMAC_INFO = "deepspace app secret lookup v1";
5199
- var STORE_ID = "default";
5200
- var SecretsRoom = class extends BaseRoom {
5201
- initialized = false;
5202
- onMessage(_ws, _user, _message) {
5203
- }
5204
- async fetch(request) {
5205
- this.ensureInitialized();
5206
- return super.fetch(request);
5207
- }
5208
- async onRequest(request) {
5209
- if (request.headers.get(INTERNAL_HEADER) !== INTERNAL_VALUE) {
5210
- return json({ error: "Not found" }, 404);
5211
- }
5212
- const url = new URL(request.url);
5213
- try {
5214
- if (request.method === "GET" && url.pathname.endsWith("/list")) {
5215
- return json({ version: this.storeVersion(), secrets: await this.list() });
5216
- }
5217
- if (request.method === "GET" && url.pathname.endsWith("/pull")) {
5218
- return json({ version: this.storeVersion(), secrets: await this.pull() });
5219
- }
5220
- if (request.method === "GET" && url.pathname.endsWith("/version")) {
5221
- return json({ version: this.storeVersion() });
5222
- }
5223
- if (request.method === "PATCH" && url.pathname.endsWith("/patch")) {
5224
- const body = await request.json();
5225
- const result = await this.patch(body);
5226
- return json(result);
5227
- }
5228
- if (request.method === "PUT" && url.pathname.endsWith("/replace")) {
5229
- const body = await request.json();
5230
- const result = await this.replace(body);
5231
- return json(result);
5232
- }
5233
- } catch (err) {
5234
- const message = err instanceof Error ? err.message : String(err);
5235
- const status = message.includes("conflict") ? 409 : 500;
5236
- return json({ error: message }, status);
5237
- }
5238
- return json({ error: "Not found" }, 404);
5239
- }
5240
- async list() {
5241
- const rows = this.sql.exec(
5242
- `SELECT name_encrypted, version, updated_by, created_at, updated_at
5243
- FROM app_secrets_store ORDER BY updated_at DESC`
5244
- ).toArray();
5245
- const out = [];
5246
- for (const row of rows) {
5247
- out.push({
5248
- name: await decryptText(this.requireKey(), row.name_encrypted, NAME_INFO),
5249
- version: row.version,
5250
- createdAt: row.created_at,
5251
- updatedAt: row.updated_at,
5252
- updatedBy: row.updated_by
5253
- });
5254
- }
5255
- return out.sort((a, b) => a.name.localeCompare(b.name));
5256
- }
5257
- async pull() {
5258
- const rows = this.sql.exec(
5259
- `SELECT name_hash, name_encrypted, value_encrypted, version, updated_by, created_at, updated_at
5260
- FROM app_secrets_store`
5261
- ).toArray();
5262
- const out = {};
5263
- for (const row of rows) {
5264
- const name = await decryptText(this.requireKey(), row.name_encrypted, NAME_INFO);
5265
- out[name] = await decryptText(this.requireKey(), row.value_encrypted, VALUE_INFO);
5266
- }
5267
- return out;
5268
- }
5269
- async patch(body) {
5270
- const now = (/* @__PURE__ */ new Date()).toISOString();
5271
- const actor = body.updatedBy ?? null;
5272
- const key = this.requireKey();
5273
- const setEntries = Object.entries(body.set ?? {});
5274
- const deleteNames = body.delete ?? [];
5275
- for (const name of [...setEntries.map(([name2]) => name2), ...deleteNames]) {
5276
- validateSecretName(name);
5277
- }
5278
- const writes = [];
5279
- for (const [name, value] of setEntries) {
5280
- const nameHash = await hashName(key, name);
5281
- const existing = this.sql.exec(
5282
- `SELECT version, created_at FROM app_secrets_store WHERE name_hash = ?`,
5283
- nameHash
5284
- ).toArray()[0];
5285
- writes.push({
5286
- nameHash,
5287
- nameEncrypted: await encryptText(key, name, NAME_INFO),
5288
- valueEncrypted: await encryptText(key, value, VALUE_INFO),
5289
- version: (existing?.version ?? 0) + 1,
5290
- createdAt: existing?.created_at ?? now
5291
- });
5292
- }
5293
- const deletes = [];
5294
- for (const name of deleteNames) {
5295
- deletes.push(await hashName(key, name));
5296
- }
5297
- this.transaction(() => {
5298
- for (const write of writes) {
5299
- this.sql.exec(
5300
- `INSERT OR REPLACE INTO app_secrets_store
5301
- (name_hash, name_encrypted, value_encrypted, version, updated_by, created_at, updated_at)
5302
- VALUES (?, ?, ?, ?, ?, ?, ?)`,
5303
- write.nameHash,
5304
- write.nameEncrypted,
5305
- write.valueEncrypted,
5306
- write.version,
5307
- actor,
5308
- write.createdAt,
5309
- now
5310
- );
5311
- }
5312
- for (const nameHash of deletes) {
5313
- this.sql.exec(`DELETE FROM app_secrets_store WHERE name_hash = ?`, nameHash);
5314
- }
5315
- this.bumpStoreVersion(now);
5316
- });
5317
- return { version: this.storeVersion(), secrets: await this.list() };
5318
- }
5319
- async replace(body) {
5320
- const next = body.secrets ?? {};
5321
- for (const name of Object.keys(next)) validateSecretName(name);
5322
- const now = (/* @__PURE__ */ new Date()).toISOString();
5323
- const actor = body.updatedBy ?? null;
5324
- const key = this.requireKey();
5325
- const writes = [];
5326
- for (const [name, value] of Object.entries(next)) {
5327
- writes.push({
5328
- nameHash: await hashName(key, name),
5329
- nameEncrypted: await encryptText(key, name, NAME_INFO),
5330
- valueEncrypted: await encryptText(key, value, VALUE_INFO)
5331
- });
5332
- }
5333
- this.transaction(() => {
5334
- this.sql.exec(`DELETE FROM app_secrets_store`);
5335
- for (const write of writes) {
5336
- this.sql.exec(
5337
- `INSERT INTO app_secrets_store
5338
- (name_hash, name_encrypted, value_encrypted, version, updated_by, created_at, updated_at)
5339
- VALUES (?, ?, ?, 1, ?, ?, ?)`,
5340
- write.nameHash,
5341
- write.nameEncrypted,
5342
- write.valueEncrypted,
5343
- actor,
5344
- now,
5345
- now
5346
- );
5347
- }
5348
- this.bumpStoreVersion(now);
5349
- });
5350
- return { version: this.storeVersion(), secrets: await this.list() };
5351
- }
5352
- transaction(run) {
5353
- this.state.storage.transactionSync(run);
5354
- }
5355
- migrateLegacyProductionSecrets() {
5356
- const legacyExists = this.sql.exec(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'app_secrets'`).toArray().length > 0;
5357
- if (!legacyExists) return;
5358
- const currentCount = this.sql.exec(`SELECT COUNT(*) AS count FROM app_secrets_store`).toArray()[0];
5359
- if ((currentCount?.count ?? 0) > 0) return;
5360
- this.sql.exec(`
5361
- INSERT OR IGNORE INTO app_secrets_store
5362
- (name_hash, name_encrypted, value_encrypted, version, updated_by, created_at, updated_at)
5363
- SELECT name_hash, name_encrypted, value_encrypted, version, updated_by, created_at, updated_at
5364
- FROM app_secrets
5365
- WHERE env = 'production'
5366
- `);
5367
- const legacyVersionExists = this.sql.exec(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'app_secret_env_versions'`).toArray().length > 0;
5368
- const legacyVersion = legacyVersionExists ? this.sql.exec(`SELECT version, updated_at FROM app_secret_env_versions WHERE env = 'production'`).toArray()[0] : void 0;
5369
- if (legacyVersion) {
5370
- this.sql.exec(
5371
- `INSERT OR REPLACE INTO app_secret_store_versions (id, version, updated_at) VALUES (?, ?, ?)`,
5372
- STORE_ID,
5373
- legacyVersion.version,
5374
- legacyVersion.updated_at
5375
- );
5376
- }
5377
- const migratedCount = this.sql.exec(`SELECT COUNT(*) AS count FROM app_secrets_store`).toArray()[0];
5378
- if (!legacyVersion && (migratedCount?.count ?? 0) > 0) {
5379
- this.sql.exec(
5380
- `INSERT OR REPLACE INTO app_secret_store_versions (id, version, updated_at) VALUES (?, ?, ?)`,
5381
- STORE_ID,
5382
- 1,
5383
- (/* @__PURE__ */ new Date()).toISOString()
5384
- );
5385
- }
5386
- }
5387
- ensureInitialized() {
5388
- if (this.initialized) return;
5389
- this.initialized = true;
5390
- this.sql.exec(`
5391
- CREATE TABLE IF NOT EXISTS app_secrets_store (
5392
- name_hash TEXT NOT NULL,
5393
- name_encrypted TEXT NOT NULL,
5394
- value_encrypted TEXT NOT NULL,
5395
- version INTEGER NOT NULL,
5396
- updated_by TEXT,
5397
- created_at TEXT NOT NULL,
5398
- updated_at TEXT NOT NULL,
5399
- PRIMARY KEY (name_hash)
5400
- )
5401
- `);
5402
- this.sql.exec(`
5403
- CREATE TABLE IF NOT EXISTS app_secret_store_versions (
5404
- id TEXT PRIMARY KEY,
5405
- version INTEGER NOT NULL,
5406
- updated_at TEXT NOT NULL
5407
- )
5408
- `);
5409
- this.migrateLegacyProductionSecrets();
5410
- }
5411
- requireKey() {
5412
- if (!this.env.APP_SECRETS_KEY) {
5413
- throw new Error("APP_SECRETS_KEY binding is missing");
5414
- }
5415
- return this.env.APP_SECRETS_KEY;
5416
- }
5417
- storeVersion() {
5418
- const row = this.sql.exec(
5419
- `SELECT version FROM app_secret_store_versions WHERE id = ?`,
5420
- STORE_ID
5421
- ).toArray()[0];
5422
- return row?.version ?? 0;
5423
- }
5424
- bumpStoreVersion(now) {
5425
- const next = this.storeVersion() + 1;
5426
- this.sql.exec(
5427
- `INSERT OR REPLACE INTO app_secret_store_versions (id, version, updated_at) VALUES (?, ?, ?)`,
5428
- STORE_ID,
5429
- next,
5430
- now
5431
- );
5432
- }
5433
- };
5434
- function validateSecretName(name) {
5435
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
5436
- throw new Error(`Invalid secret name "${name}"`);
5437
- }
5438
- }
5439
- function json(body, status = 200) {
5440
- return new Response(JSON.stringify(body), {
5441
- status,
5442
- headers: { "Content-Type": "application/json" }
5443
- });
5444
- }
5445
- async function encryptText(root, plaintext, info) {
5446
- const salt = crypto.getRandomValues(new Uint8Array(16));
5447
- const iv = crypto.getRandomValues(new Uint8Array(12));
5448
- const key = await aesKey(root, salt, info);
5449
- const ciphertext = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, new TextEncoder().encode(plaintext));
5450
- return [VERSION, b64(salt), b64(iv), b64(new Uint8Array(ciphertext))].join(":");
5451
- }
5452
- async function decryptText(root, encoded, info) {
5453
- const [version, saltB64, ivB64, bodyB64] = encoded.split(":");
5454
- if (version !== VERSION || !saltB64 || !ivB64 || !bodyB64) {
5455
- throw new Error("Corrupt app secret ciphertext");
5456
- }
5457
- const key = await aesKey(root, unb64(saltB64), info);
5458
- const plaintext = await crypto.subtle.decrypt(
5459
- { name: "AES-GCM", iv: bytes(unb64(ivB64)) },
5460
- key,
5461
- bytes(unb64(bodyB64))
5462
- );
5463
- return new TextDecoder().decode(plaintext);
5464
- }
5465
- async function hashName(root, name) {
5466
- const key = await hmacKey(root, HMAC_INFO);
5467
- const sig = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(`production:${name}`));
5468
- return Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("");
5469
- }
5470
- async function aesKey(root, salt, info) {
5471
- const base = await crypto.subtle.importKey("raw", new TextEncoder().encode(root), "HKDF", false, ["deriveKey"]);
5472
- return crypto.subtle.deriveKey(
5473
- { name: "HKDF", hash: "SHA-256", salt: bytes(salt), info: new TextEncoder().encode(info) },
5474
- base,
5475
- { name: "AES-GCM", length: 256 },
5476
- false,
5477
- ["encrypt", "decrypt"]
5478
- );
5479
- }
5480
- async function hmacKey(root, info) {
5481
- const base = await crypto.subtle.importKey("raw", new TextEncoder().encode(root), "HKDF", false, ["deriveKey"]);
5482
- return crypto.subtle.deriveKey(
5483
- { name: "HKDF", hash: "SHA-256", salt: bytes(new Uint8Array(16)), info: new TextEncoder().encode(info) },
5484
- base,
5485
- { name: "HMAC", hash: "SHA-256", length: 256 },
5486
- false,
5487
- ["sign"]
5488
- );
5489
- }
5490
- function b64(bytes2) {
5491
- let s = "";
5492
- for (const b of bytes2) s += String.fromCharCode(b);
5493
- return btoa(s);
5494
- }
5495
- function unb64(value) {
5496
- const s = atob(value);
5497
- const out = new Uint8Array(s.length);
5498
- for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i);
5499
- return out;
5500
- }
5501
- function bytes(input) {
5502
- return input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength);
5503
- }
5504
-
5505
5192
  // src/server/rooms/job-room.ts
5506
5193
  var RUNNING_STALE_MS = 16 * 60 * 1e3;
5507
5194
  var DEFAULT_RETENTION_MS = 24 * 60 * 60 * 1e3;
@@ -6119,7 +5806,6 @@ var RESERVED_BINDING_NAMES = /* @__PURE__ */ new Set([
6119
5806
  "AUTH_WORKER_URL",
6120
5807
  "APP_IDENTITY_TOKEN",
6121
5808
  "APP_OWNER_JWT",
6122
- "APP_SECRETS_KEY",
6123
5809
  "USAGE_EVENTS"
6124
5810
  ]);
6125
5811
  function validateBindingManifest(manifest) {
@@ -6956,8 +6642,8 @@ import { importSPKI, jwtVerify } from "jose";
6956
6642
 
6957
6643
  // src/server/auth/utils.ts
6958
6644
  var BASE64_URL_REGEX = /^[A-Za-z0-9-_]+$/;
6959
- function bufferToHex(bytes2) {
6960
- const view = bytes2 instanceof Uint8Array ? bytes2 : new Uint8Array(bytes2);
6645
+ function bufferToHex(bytes) {
6646
+ const view = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
6961
6647
  let hex = "";
6962
6648
  for (const byte of view) {
6963
6649
  hex += byte.toString(16).padStart(2, "0");
@@ -6980,9 +6666,9 @@ function decodeJwtPayload(token) {
6980
6666
  if (!BASE64_URL_REGEX.test(payloadSegment)) return void 0;
6981
6667
  try {
6982
6668
  const normalized = payloadSegment.replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(payloadSegment.length / 4) * 4, "=");
6983
- const bytes2 = base64ToUint8Array(normalized);
6984
- const json2 = new TextDecoder().decode(bytes2);
6985
- const payload = JSON.parse(json2);
6669
+ const bytes = base64ToUint8Array(normalized);
6670
+ const json = new TextDecoder().decode(bytes);
6671
+ const payload = JSON.parse(json);
6986
6672
  return {
6987
6673
  iss: payload.iss ?? null,
6988
6674
  aud: payload.aud ?? null,
@@ -7206,176 +6892,6 @@ async function generateAppleClientSecret(apple) {
7206
6892
  return token;
7207
6893
  }
7208
6894
 
7209
- // src/server/secrets.ts
7210
- var DEFAULT_REFRESH_INTERVAL_MS = 24 * 60 * 60 * 1e3;
7211
- function createSecrets(env, options = {}) {
7212
- const refreshIntervalMs = options.refreshIntervalMs ?? DEFAULT_REFRESH_INTERVAL_MS;
7213
- const now = options.now ?? (() => Date.now());
7214
- const cache = /* @__PURE__ */ new Map();
7215
- let loadedAll = null;
7216
- let loadedVersion = 0;
7217
- let lastCheckedAt = 0;
7218
- function stub() {
7219
- if (!env.SECRETS_ROOMS) throw new Error("SECRETS_ROOMS binding is missing");
7220
- if (!env.APP_SECRETS_KEY) throw new Error("APP_SECRETS_KEY binding is missing");
7221
- const id = env.SECRETS_ROOMS.idFromName("app-secrets");
7222
- return env.SECRETS_ROOMS.get(id);
7223
- }
7224
- async function fetchJson(path) {
7225
- const res = await stub().fetch(`https://app-secrets/${path}`, {
7226
- headers: { "x-deepspace-internal": "app-secrets" }
7227
- });
7228
- const body = await res.json().catch(() => ({}));
7229
- if (!res.ok) throw new Error(body.error ?? `App secrets unavailable (${res.status})`);
7230
- return body;
7231
- }
7232
- async function pullAll() {
7233
- const body = await fetchJson("pull");
7234
- const version = typeof body.version === "number" ? body.version : 0;
7235
- cache.clear();
7236
- for (const [name, value] of Object.entries(body.secrets ?? {})) {
7237
- cache.set(name, value);
7238
- }
7239
- loadedVersion = version;
7240
- lastCheckedAt = now();
7241
- return version;
7242
- }
7243
- async function loadAll() {
7244
- await pullAll();
7245
- }
7246
- async function ensureLoaded() {
7247
- if (!loadedAll) {
7248
- loadedAll = loadAll().catch((err) => {
7249
- loadedAll = null;
7250
- throw err;
7251
- });
7252
- }
7253
- await loadedAll;
7254
- }
7255
- async function maybeCheckForUpdates() {
7256
- if (!loadedAll) return;
7257
- if (refreshIntervalMs < 0) return;
7258
- if (now() - lastCheckedAt < refreshIntervalMs) return;
7259
- try {
7260
- await client.checkForUpdates();
7261
- } catch {
7262
- }
7263
- }
7264
- function localDevValue(name) {
7265
- const value = env[name];
7266
- return env.APP_SECRETS_LOCAL_FALLBACK === "true" && typeof value === "string" ? value : void 0;
7267
- }
7268
- const client = {
7269
- async get(name) {
7270
- const local = localDevValue(name);
7271
- if (local !== void 0) return local;
7272
- if (!cache.has(name)) await ensureLoaded();
7273
- else await maybeCheckForUpdates();
7274
- return cache.get(name);
7275
- },
7276
- async require(name) {
7277
- const value = await this.get(name);
7278
- if (value === void 0) throw new Error(`Missing app secret "${name}"`);
7279
- return value;
7280
- },
7281
- async getMany(names) {
7282
- const out = {};
7283
- for (const name of names) out[name] = await this.get(name);
7284
- return out;
7285
- },
7286
- async preload(names) {
7287
- if (env.APP_SECRETS_LOCAL_FALLBACK === "true") {
7288
- const missing = [];
7289
- for (const name of names) {
7290
- const local = localDevValue(name);
7291
- if (local !== void 0) cache.set(name, local);
7292
- else missing.push(name);
7293
- }
7294
- if (missing.length === 0) {
7295
- await maybeCheckForUpdates();
7296
- return;
7297
- }
7298
- }
7299
- await ensureLoaded();
7300
- await maybeCheckForUpdates();
7301
- },
7302
- async refresh(refreshOptions = {}) {
7303
- if (refreshOptions.force || !loadedAll) {
7304
- const previous = loadedVersion;
7305
- const version = await pullAll();
7306
- loadedAll = Promise.resolve();
7307
- return { changed: version !== previous, version };
7308
- }
7309
- return this.checkForUpdates();
7310
- },
7311
- async checkForUpdates() {
7312
- await ensureLoaded();
7313
- const body = await fetchJson("version");
7314
- const version = typeof body.version === "number" ? body.version : 0;
7315
- lastCheckedAt = now();
7316
- if (version === loadedVersion) return { changed: false, version };
7317
- const pulledVersion = await pullAll();
7318
- return { changed: true, version: pulledVersion };
7319
- },
7320
- invalidate() {
7321
- cache.clear();
7322
- loadedAll = null;
7323
- loadedVersion = 0;
7324
- lastCheckedAt = 0;
7325
- },
7326
- async withFreshSecrets(operation, retryOptions = {}) {
7327
- let first;
7328
- try {
7329
- first = await operation({ secrets: client, attempt: 1, refreshed: false });
7330
- } catch (err) {
7331
- if (!shouldRefreshOnError(err)) throw err;
7332
- const refresh = await refreshAfterFailure(err);
7333
- if (!refresh.changed && !retryOptions.retryWhenUnchanged) throw err;
7334
- return operation({ secrets: client, attempt: 2, refreshed: refresh.changed });
7335
- }
7336
- if (first instanceof Response && shouldRefreshOnStatus(first.status)) {
7337
- const refresh = await refreshAfterFailure(first);
7338
- if (refresh.changed || retryOptions.retryWhenUnchanged) {
7339
- return operation({ secrets: client, attempt: 2, refreshed: refresh.changed });
7340
- }
7341
- }
7342
- return first;
7343
- }
7344
- };
7345
- async function refreshAfterFailure(original) {
7346
- try {
7347
- return await client.refresh({ force: true });
7348
- } catch (err) {
7349
- const originalMessage = describeFailure(original);
7350
- const refreshMessage = err instanceof Error ? err.message : String(err);
7351
- throw new Error(`Secret refresh failed after API failure (${originalMessage}): ${refreshMessage}`);
7352
- }
7353
- }
7354
- return client;
7355
- }
7356
- function shouldRefreshOnError(error) {
7357
- const status = statusFromError(error);
7358
- return status !== void 0 && shouldRefreshOnStatus(status);
7359
- }
7360
- function shouldRefreshOnStatus(status) {
7361
- return status === 401 || status === 403;
7362
- }
7363
- function statusFromError(error) {
7364
- if (!error || typeof error !== "object") return void 0;
7365
- const record = error;
7366
- if (typeof record.status === "number") return record.status;
7367
- if (typeof record.statusCode === "number") return record.statusCode;
7368
- if (typeof record.response?.status === "number") return record.response.status;
7369
- return void 0;
7370
- }
7371
- function describeFailure(value) {
7372
- if (value instanceof Response) return `HTTP ${value.status}`;
7373
- if (value instanceof Error) return value.message;
7374
- const status = statusFromError(value);
7375
- if (status) return `HTTP ${status}`;
7376
- return String(value);
7377
- }
7378
-
7379
6895
  // src/shared/subscription.ts
7380
6896
  var ENTITLED_STATUSES = /* @__PURE__ */ new Set([
7381
6897
  "active",
@@ -7557,7 +7073,6 @@ export {
7557
7073
  SYSTEM_COLLECTION_SCHEMAS,
7558
7074
  SYSTEM_MANAGED_COLUMNS,
7559
7075
  SchemaRegistry,
7560
- SecretsRoom,
7561
7076
  SubscriptionAuthError,
7562
7077
  SubscriptionRequiredError,
7563
7078
  USERS_COLUMNS,
@@ -7594,7 +7109,6 @@ export {
7594
7109
  createDeepSpaceAI,
7595
7110
  createDeepSpaceAuth,
7596
7111
  createScopedR2Handler,
7597
- createSecrets,
7598
7112
  dataToColumnValues,
7599
7113
  decodeJwtPayload,
7600
7114
  deleteChatCascade,