deepspace 0.30.2 → 0.31.1

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/worker.d.ts CHANGED
@@ -2253,6 +2253,10 @@ declare const BUILD_INJECTED_APP_ID_MIGRATION_ID = "2026-08-build-injected-app-i
2253
2253
  * session has none) instead of crashing on a non-null assertion, and the
2254
2254
  * file states the trust model actions run under. */
2255
2255
  declare const ACTION_ROUTES_BEARER_GUARD_MIGRATION_ID = "2026-08-action-routes-bearer-guard";
2256
+ /** The files proxy identifies a header-less same-origin read (an `<img>`,
2257
+ * `<audio>`, or `<video>` load) by the app-origin session cookie, so private
2258
+ * file URLs render for the signed-in user without tokens or signed URLs. */
2259
+ declare const FILES_SESSION_COOKIE_READS_MIGRATION_ID = "2026-09-files-session-cookie-reads";
2256
2260
  type AppMigrationIdsValidation = {
2257
2261
  valid: true;
2258
2262
  ids: string[];
@@ -2846,7 +2850,8 @@ interface StorageAdmission {
2846
2850
  * POST /api/files/multipart/complete → assemble the parts
2847
2851
  * DELETE /api/files/multipart → abandon a chunked upload
2848
2852
  * GET /api/files → list (prefix + optional user prefix)
2849
- * GET /api/files/:key → download (validated against prefix)
2853
+ * GET /api/files/:key → download (validated against prefix; Range-aware)
2854
+ * HEAD /api/files/:key → the download's headers, no body
2850
2855
  * DELETE /api/files/:key → delete (validated against prefix)
2851
2856
  *
2852
2857
  * ## One transport discipline
@@ -4098,6 +4103,34 @@ interface VerifyOutcome {
4098
4103
  */
4099
4104
  declare function verifyJwt(config: JwtVerifierConfig, token: string | null | undefined): Promise<VerifyOutcome>;
4100
4105
 
4106
+ /**
4107
+ * Session-cookie identity for header-less file reads.
4108
+ *
4109
+ * `<img>`, `<audio>`, `<video>`, and `<a href>` cannot send `Authorization`,
4110
+ * but the browser attaches the app-origin Better Auth session cookie to every
4111
+ * same-origin load. This exchanges that cookie for the same 15-minute JWT the
4112
+ * client already holds and returns only the verified identity.
4113
+ *
4114
+ * Bearer always wins: this applies only when no `Authorization` header is
4115
+ * present, only to GET/HEAD, and only when `Sec-Fetch-Site` is `same-origin`
4116
+ * or `none`. `app.space` is not on the Public Suffix List, so a sibling
4117
+ * `evil.app.space` is same-SITE and `SameSite=Lax` alone would let its
4118
+ * `<img src>` carry the victim's cookie; `Sec-Fetch-Site` cannot be set by
4119
+ * page script. A browser that omits it (Safari before 16.4) and a cross-site
4120
+ * top-level link both get 401 by design.
4121
+ */
4122
+
4123
+ type SessionReadEnv = AuthWorkerEnv & {
4124
+ AUTH_JWT_PUBLIC_KEY: string;
4125
+ AUTH_JWT_ISSUER: string;
4126
+ };
4127
+ /**
4128
+ * Identify a same-origin GET/HEAD by the app-origin session cookie. Returns
4129
+ * `null` — never throws — whenever the request does not qualify or the
4130
+ * exchange fails. Use it only as the fallback after bearer verification.
4131
+ */
4132
+ declare function resolveSessionReadAuth(req: Request, env: SessionReadEnv): Promise<VerifyResult | null>;
4133
+
4101
4134
  declare const AGENT_TOKEN_SCOPE = "agent";
4102
4135
  /** A separate issuer keeps agent credentials invalid at ordinary platform APIs. */
4103
4136
  declare function agentTokenIssuer(issuer: string): string;
@@ -5449,4 +5482,4 @@ declare const MAX_LOG_TEXT_LENGTH: number;
5449
5482
  */
5450
5483
  declare function workerErrorHandler(prefix: string, respond?: (c: Context) => Response): ErrorHandler;
5451
5484
 
5452
- export { ACCOUNT_STORAGE_LIMIT_BYTES, ACTION_ROUTES_BEARER_GUARD_MIGRATION_ID, ACTION_TOOLS_DELETE_WHERE_MIGRATION_ID, AGENT_TOKEN_SCOPE, AGENT_TOOL_REQUEST_BODY_CAP, AGENT_TOOL_RESPONSE_BODY_CAP, AI_CHATS_SCHEMA, AI_MESSAGES_SCHEMA, ALLOWED_BINDING_TYPES, ANONYMOUS_USER_ID_PREFIX, APP_ID_RE, APP_LOG_EVENT_KEYS, APP_NAME_RULES, ASSET_NOT_FOUND_HANDLING_VALUES, AUTO_PROVISIONABLE_TYPES, AUTO_PROVISION_SENTINEL, type ActionContext, type ActionHandler, type ActionResult, type ActionTools, type AgentTargetPolicy, type AgentToolAccessResult, type AgentToolRouteEnv, type AgentToolRouteOptions, type ApiErrorIssue, type ApiWorkerEnv, type AppLogEvent, type AppLogEventKey, type AppLogsResponse, type AppMembership, type AppMigrationIdsValidation, type AppNameResolution, type AppNameValidation, type AssetNotFoundHandling, type AuthWorkerEnv, Awareness, type AwarenessState, type AwarenessStates, BASE_USERS_SCHEMA, BROWSER_PROXY_ROUTES, BUILD_INJECTED_APP_ID_MIGRATION_ID, BUILT_IN_TOOLS, type BaseMessage, BaseRoom, type BindingJsonValue, CHANNELS_SCHEMA, CHANNEL_MEMBERS_SCHEMA, COST_RATES, CanvasRoom, type CanvasShape, type ChatContextConfig, type ChatMessageRow, type ChatRow, type ChatTurn, type ClientMessage, type CollectionSchema, type ColumnDefinition, type ColumnInterpretation, type ComposioToolsOptions, type ConnectionAttachment, type CronContext, type CronExecution, CronRoom, type CronRoomConfig, type CronTask, type CustomBinding, type CustomBindingManifest, DEEPSPACE_AGENT_PROFILES, DEEPSPACE_AI_DEFAULTS, DEEPSPACE_AI_MODELS, DEEPSPACE_MODEL_CATALOG_PROVENANCE, DEFAULT_CONTEXT_CONFIG, DEFAULT_DELETE_WHERE_LIMIT, DEFAULT_DO_MANIFEST, DEFAULT_QUERY_LIMIT, DEPLOYED_APPS_DEFAULTS, type DOBindings, type DOManifest, type DOManifestEntry, type DeepSpaceAIEnv, type DeepSpaceAIModel, type DeepSpaceAIModelId, type DeepSpaceAIOptions, type DeepSpaceAIProvider, type DeepSpaceAgentDiagnosticContext, DeepSpaceAgentModelError, type DeepSpaceAgentProfile, DeepSpaceAgentProfileError, type DeepSpaceAgentProfileId, type DeepSpaceAgentStream, type DeepSpaceAgentStreamOptions, type DeepSpaceAgentSupport, type DeepSpaceAuth, type DeepSpaceAuthConfig, type DeepSpaceDocumentationRouteEnv, type DeepSpaceDocumentationRouteOptions, type DoMigrationDirective, type DoMigrationPlan, type ExistingDOBinding, type GetActionData, type HandlerContext, type Job, type JobContext, JobRoom, type JobRoomConfig, type JobStatus, type JwtClaims, type JwtVerifierConfig, type KnowledgeAddOptions, type KnowledgeAddResult, type KnowledgeClient, type KnowledgeEnv, KnowledgeError, type KnowledgeItem, type KnowledgeListOptions, type KnowledgeListResult, type KnowledgeSearchChunk, type KnowledgeSearchOptions, type KnowledgeSearchResult, type KnowledgeStatus, LOG_LEVELS, type LogLevel, MAX_APP_FILE_BYTES, MAX_BINDING_NAME_LENGTH, MAX_DELETE_WHERE_LIMIT, MAX_DEPLOY_ASSET_FILE_BYTES, MAX_ENV_VAR_BYTES, MAX_LOG_TEXT_LENGTH, MAX_UPLOAD_PARTS, MAX_UPLOAD_REQUEST_BYTES, MESSAGES_SCHEMA, MSG, MSG_AWARENESS, MSG_SYNC, MSG_SYNC_STEP1, MSG_SYNC_STEP2, MSG_SYNC_UPDATE, MSG_YJS_AWARENESS, MSG_YJS_SYNC, type MessageHandlers, type MsgType, type MutateActionData, type NormalizedApiError, PRODUCTION_OFFICIAL_AGENT_ORIGINS, type PermissionContext, type PermissionLevel, type PlatformWorkerEnv, type PrefixResult, type PresencePeer, PresenceRoom, type ProtocolMessage, type ProxyRoute, type QueryActionData, REACTIONS_SCHEMA, READ_RECEIPTS_SCHEMA, RECORD_NOT_FOUND, REGISTRY_INSTANCE, RELEASE_STAMP_PATH, REPO_STORE_LIMIT_BYTES, REQUIRED_COMPATIBILITY_FLAGS, RESERVED_BINDING_NAMES, RESERVED_RUN_WORKER_FIRST, RESOURCE_ID_RE, ROLE_ADMIN, ROLE_ANONYMOUS, ROLE_DEFAULT, RecordRoom, type RecordRoomConfig, RegistryClientError, type ResolvedColumn, type ResolvedDeepSpaceAgentModel, type RolePermissions, type RunMigrationsResult, SDK_RUN_WORKER_FIRST, SECRET_NAME_RE, SECURE_ROOM_BOUNDARIES_MIGRATION_ID, SESSION_COOKIE, STRICT_APP_ID_RE, SYSTEM_ASSIGNED_COLUMNS, SYSTEM_COLLECTIONS, SYSTEM_MAINTAINED_COLUMNS, SYSTEM_MANAGED_COLUMNS, SchemaRegistry, type ScopeContext, type ScopedKnowledgeClient, type ScopedR2Auth, type ScopedR2Config, type ScopedR2Handler, type ScreenshotEnv, type ScreenshotResult, type ServerMessage, type StorageAdmission, type StoredRecord, type Summarizer, type SyncResult, TEST_ACCOUNT_EMAIL_SUFFIX, type TokenDebugInfo, type ToolResult, type ToolSchema, UNDECLARED_ASSET_NOT_FOUND_HANDLING, UPLOAD_PART_BYTES, USERS_COLUMNS, type User, type UserAttachment, type UserToolExecutorEnv, type ValidationError, type VerifiedAuth, type VerifyOutcome, type VerifyResult, type Viewport, WORKER_OWNED_NOT_FOUND_MIGRATION_ID, YjsRoom, agentTokenIssuer, apiWorkerFetch, appendMessage, applyAiToolDefaults, applySlidingWindow, armCronRoom, authWorkerFetch, authenticatedRoomRequest, bindingManifestFromOutputConfig, buildCronContext, buildTableSelect, buildUiParts, callRegistry, canCreate, canDelete, canRead, canUpdate, capToolResultSize, captureScreenshot, checkFieldPermissions, checkUnclaimedOwnerTransition, clientBuild, coerceValue, collectionTableName, columnId, composioTools, computeDoMigration, computeHmacHex, createChat, createDecoder, createDeepSpaceAI, createDeepSpaceAuth, createEncoder, createScopedR2Handler, createUserToolExecutor, dataToColumnValues, decodeJwtPayload, deepSpaceAgentErrorSummary, deleteChatCascade, dispatch, encode, encodeAwarenessMessage, encodeSyncStep1, encodeSyncStep2, encodeUpdate, enqueueJob, epochSeconds, folderFilter, formatBytes, getChat, getDeepSpaceAIModel, getMessageType, getRolePermissions, handleAwarenessMessage, handleSyncMessage, hasContent, isAnonymousUserId, isAssetNotFoundHandling, isAutoProvision, isFilesVerbPath, isOwner, isPlatformReservedPath, isTestAccountClaims, isTestAccountEmail, isTestAccountTier, knowledge, lintSchema, lintSchemaSet, lintSchemas, listDeepSpaceAgentModels, loadMessages, logEventText, loggableError, makeDefaultSummarizer, matchOrigin, meterAi, meterUsage, meterVectorize, mintAppId, mintUlid, noopPermissionContext, normalizeAgentTargetOrigin, normalizeApiError, normalizeKnowledgeFolder, parseQuotaLimit, platformCorsPatterns, platformWorkerFetch, prepareMessagesWithCompaction, priceBindingUsageEvent, readVarUint, readVarUint8Array, registerAgentToolRoutes, registerDeepSpaceDocumentation, registryErrorJson, registryStub, resolveAppMembership, resolveAppName, resolveAppRole, resolveColumn, resolveCompatibilityFlags, resolveDeepSpaceAgentModel, rowToData, runMigrations, serverBuild, storageLimitForTier, storageQuotaMessage, streamDeepSpaceAgent, timingSafeEqualHex, timingSafeEqualStrings, toUint8Array, totalChars, truncateLogText, truncateOldToolResults, turnsToCoreMessages, unwrapToolOutput, updateChat, validateAppMigrationIds, validateAppName, validateBindingManifest, validateDoManifest, verifyAgentToken, verifyJwt, workerErrorHandler, writeVarUint, writeVarUint8Array };
5485
+ export { ACCOUNT_STORAGE_LIMIT_BYTES, ACTION_ROUTES_BEARER_GUARD_MIGRATION_ID, ACTION_TOOLS_DELETE_WHERE_MIGRATION_ID, AGENT_TOKEN_SCOPE, AGENT_TOOL_REQUEST_BODY_CAP, AGENT_TOOL_RESPONSE_BODY_CAP, AI_CHATS_SCHEMA, AI_MESSAGES_SCHEMA, ALLOWED_BINDING_TYPES, ANONYMOUS_USER_ID_PREFIX, APP_ID_RE, APP_LOG_EVENT_KEYS, APP_NAME_RULES, ASSET_NOT_FOUND_HANDLING_VALUES, AUTO_PROVISIONABLE_TYPES, AUTO_PROVISION_SENTINEL, type ActionContext, type ActionHandler, type ActionResult, type ActionTools, type AgentTargetPolicy, type AgentToolAccessResult, type AgentToolRouteEnv, type AgentToolRouteOptions, type ApiErrorIssue, type ApiWorkerEnv, type AppLogEvent, type AppLogEventKey, type AppLogsResponse, type AppMembership, type AppMigrationIdsValidation, type AppNameResolution, type AppNameValidation, type AssetNotFoundHandling, type AuthWorkerEnv, Awareness, type AwarenessState, type AwarenessStates, BASE_USERS_SCHEMA, BROWSER_PROXY_ROUTES, BUILD_INJECTED_APP_ID_MIGRATION_ID, BUILT_IN_TOOLS, type BaseMessage, BaseRoom, type BindingJsonValue, CHANNELS_SCHEMA, CHANNEL_MEMBERS_SCHEMA, COST_RATES, CanvasRoom, type CanvasShape, type ChatContextConfig, type ChatMessageRow, type ChatRow, type ChatTurn, type ClientMessage, type CollectionSchema, type ColumnDefinition, type ColumnInterpretation, type ComposioToolsOptions, type ConnectionAttachment, type CronContext, type CronExecution, CronRoom, type CronRoomConfig, type CronTask, type CustomBinding, type CustomBindingManifest, DEEPSPACE_AGENT_PROFILES, DEEPSPACE_AI_DEFAULTS, DEEPSPACE_AI_MODELS, DEEPSPACE_MODEL_CATALOG_PROVENANCE, DEFAULT_CONTEXT_CONFIG, DEFAULT_DELETE_WHERE_LIMIT, DEFAULT_DO_MANIFEST, DEFAULT_QUERY_LIMIT, DEPLOYED_APPS_DEFAULTS, type DOBindings, type DOManifest, type DOManifestEntry, type DeepSpaceAIEnv, type DeepSpaceAIModel, type DeepSpaceAIModelId, type DeepSpaceAIOptions, type DeepSpaceAIProvider, type DeepSpaceAgentDiagnosticContext, DeepSpaceAgentModelError, type DeepSpaceAgentProfile, DeepSpaceAgentProfileError, type DeepSpaceAgentProfileId, type DeepSpaceAgentStream, type DeepSpaceAgentStreamOptions, type DeepSpaceAgentSupport, type DeepSpaceAuth, type DeepSpaceAuthConfig, type DeepSpaceDocumentationRouteEnv, type DeepSpaceDocumentationRouteOptions, type DoMigrationDirective, type DoMigrationPlan, type ExistingDOBinding, FILES_SESSION_COOKIE_READS_MIGRATION_ID, type GetActionData, type HandlerContext, type Job, type JobContext, JobRoom, type JobRoomConfig, type JobStatus, type JwtClaims, type JwtVerifierConfig, type KnowledgeAddOptions, type KnowledgeAddResult, type KnowledgeClient, type KnowledgeEnv, KnowledgeError, type KnowledgeItem, type KnowledgeListOptions, type KnowledgeListResult, type KnowledgeSearchChunk, type KnowledgeSearchOptions, type KnowledgeSearchResult, type KnowledgeStatus, LOG_LEVELS, type LogLevel, MAX_APP_FILE_BYTES, MAX_BINDING_NAME_LENGTH, MAX_DELETE_WHERE_LIMIT, MAX_DEPLOY_ASSET_FILE_BYTES, MAX_ENV_VAR_BYTES, MAX_LOG_TEXT_LENGTH, MAX_UPLOAD_PARTS, MAX_UPLOAD_REQUEST_BYTES, MESSAGES_SCHEMA, MSG, MSG_AWARENESS, MSG_SYNC, MSG_SYNC_STEP1, MSG_SYNC_STEP2, MSG_SYNC_UPDATE, MSG_YJS_AWARENESS, MSG_YJS_SYNC, type MessageHandlers, type MsgType, type MutateActionData, type NormalizedApiError, PRODUCTION_OFFICIAL_AGENT_ORIGINS, type PermissionContext, type PermissionLevel, type PlatformWorkerEnv, type PrefixResult, type PresencePeer, PresenceRoom, type ProtocolMessage, type ProxyRoute, type QueryActionData, REACTIONS_SCHEMA, READ_RECEIPTS_SCHEMA, RECORD_NOT_FOUND, REGISTRY_INSTANCE, RELEASE_STAMP_PATH, REPO_STORE_LIMIT_BYTES, REQUIRED_COMPATIBILITY_FLAGS, RESERVED_BINDING_NAMES, RESERVED_RUN_WORKER_FIRST, RESOURCE_ID_RE, ROLE_ADMIN, ROLE_ANONYMOUS, ROLE_DEFAULT, RecordRoom, type RecordRoomConfig, RegistryClientError, type ResolvedColumn, type ResolvedDeepSpaceAgentModel, type RolePermissions, type RunMigrationsResult, SDK_RUN_WORKER_FIRST, SECRET_NAME_RE, SECURE_ROOM_BOUNDARIES_MIGRATION_ID, SESSION_COOKIE, STRICT_APP_ID_RE, SYSTEM_ASSIGNED_COLUMNS, SYSTEM_COLLECTIONS, SYSTEM_MAINTAINED_COLUMNS, SYSTEM_MANAGED_COLUMNS, SchemaRegistry, type ScopeContext, type ScopedKnowledgeClient, type ScopedR2Auth, type ScopedR2Config, type ScopedR2Handler, type ScreenshotEnv, type ScreenshotResult, type ServerMessage, type StorageAdmission, type StoredRecord, type Summarizer, type SyncResult, TEST_ACCOUNT_EMAIL_SUFFIX, type TokenDebugInfo, type ToolResult, type ToolSchema, UNDECLARED_ASSET_NOT_FOUND_HANDLING, UPLOAD_PART_BYTES, USERS_COLUMNS, type User, type UserAttachment, type UserToolExecutorEnv, type ValidationError, type VerifiedAuth, type VerifyOutcome, type VerifyResult, type Viewport, WORKER_OWNED_NOT_FOUND_MIGRATION_ID, YjsRoom, agentTokenIssuer, apiWorkerFetch, appendMessage, applyAiToolDefaults, applySlidingWindow, armCronRoom, authWorkerFetch, authenticatedRoomRequest, bindingManifestFromOutputConfig, buildCronContext, buildTableSelect, buildUiParts, callRegistry, canCreate, canDelete, canRead, canUpdate, capToolResultSize, captureScreenshot, checkFieldPermissions, checkUnclaimedOwnerTransition, clientBuild, coerceValue, collectionTableName, columnId, composioTools, computeDoMigration, computeHmacHex, createChat, createDecoder, createDeepSpaceAI, createDeepSpaceAuth, createEncoder, createScopedR2Handler, createUserToolExecutor, dataToColumnValues, decodeJwtPayload, deepSpaceAgentErrorSummary, deleteChatCascade, dispatch, encode, encodeAwarenessMessage, encodeSyncStep1, encodeSyncStep2, encodeUpdate, enqueueJob, epochSeconds, folderFilter, formatBytes, getChat, getDeepSpaceAIModel, getMessageType, getRolePermissions, handleAwarenessMessage, handleSyncMessage, hasContent, isAnonymousUserId, isAssetNotFoundHandling, isAutoProvision, isFilesVerbPath, isOwner, isPlatformReservedPath, isTestAccountClaims, isTestAccountEmail, isTestAccountTier, knowledge, lintSchema, lintSchemaSet, lintSchemas, listDeepSpaceAgentModels, loadMessages, logEventText, loggableError, makeDefaultSummarizer, matchOrigin, meterAi, meterUsage, meterVectorize, mintAppId, mintUlid, noopPermissionContext, normalizeAgentTargetOrigin, normalizeApiError, normalizeKnowledgeFolder, parseQuotaLimit, platformCorsPatterns, platformWorkerFetch, prepareMessagesWithCompaction, priceBindingUsageEvent, readVarUint, readVarUint8Array, registerAgentToolRoutes, registerDeepSpaceDocumentation, registryErrorJson, registryStub, resolveAppMembership, resolveAppName, resolveAppRole, resolveColumn, resolveCompatibilityFlags, resolveDeepSpaceAgentModel, resolveSessionReadAuth, rowToData, runMigrations, serverBuild, storageLimitForTier, storageQuotaMessage, streamDeepSpaceAgent, timingSafeEqualHex, timingSafeEqualStrings, toUint8Array, totalChars, truncateLogText, truncateOldToolResults, turnsToCoreMessages, unwrapToolOutput, updateChat, validateAppMigrationIds, validateAppName, validateBindingManifest, validateDoManifest, verifyAgentToken, verifyJwt, workerErrorHandler, writeVarUint, writeVarUint8Array };
package/dist/worker.js CHANGED
@@ -5794,6 +5794,7 @@ var SECURE_ROOM_BOUNDARIES_MIGRATION_ID = "2026-08-secure-room-boundaries";
5794
5794
  var ACTION_TOOLS_DELETE_WHERE_MIGRATION_ID = "2026-08-action-tools-delete-where";
5795
5795
  var BUILD_INJECTED_APP_ID_MIGRATION_ID = "2026-08-build-injected-app-id";
5796
5796
  var ACTION_ROUTES_BEARER_GUARD_MIGRATION_ID = "2026-08-action-routes-bearer-guard";
5797
+ var FILES_SESSION_COOKIE_READS_MIGRATION_ID = "2026-09-files-session-cookie-reads";
5797
5798
  function validateAppMigrationIds(value) {
5798
5799
  if (!Array.isArray(value)) {
5799
5800
  return { valid: false, reason: "app migrations must be a JSON string array" };
@@ -6780,7 +6781,7 @@ function createScopedR2Handler(config) {
6780
6781
  if (!subpath && request2.method === "GET") {
6781
6782
  return handleList(bucket, prefix, excludedPrefixes, url, scope, auth);
6782
6783
  }
6783
- if (subpath && request2.method === "GET") {
6784
+ if (subpath && (request2.method === "GET" || request2.method === "HEAD")) {
6784
6785
  if (!isKeyWithinScope(subpath, prefix, excludedPrefixes)) {
6785
6786
  return Response.json(
6786
6787
  { error: "Access denied: key outside scope" },
@@ -7387,11 +7388,64 @@ async function handleList(bucket, prefix, excludedPrefixes, url, scope, auth) {
7387
7388
  { headers: CORS_HEADERS4 }
7388
7389
  );
7389
7390
  }
7391
+ function parseByteRange(header, size) {
7392
+ const [, first, last] = /^bytes=(\d*)-(\d*)$/.exec(header.trim()) ?? [];
7393
+ if (first === void 0 || first === "" && last === "") return void 0;
7394
+ const offset = first === "" ? Math.max(0, size - Number(last)) : Number(first);
7395
+ if (offset >= size) return "unsatisfiable";
7396
+ const end = first === "" || last === "" ? size - 1 : Math.min(Number(last), size - 1);
7397
+ return end < offset ? void 0 : { offset, length: end - offset + 1 };
7398
+ }
7390
7399
  async function handleDownload(request2, bucket, key, scope) {
7391
- const object = await bucket.get(key);
7392
- if (!object) {
7400
+ if (request2.method === "HEAD") {
7401
+ const object = await bucket.head(key);
7402
+ if (!object) {
7403
+ return Response.json({ error: "File not found" }, { status: 404, headers: CORS_HEADERS4 });
7404
+ }
7405
+ const headers2 = downloadHeaders(object, key, scope);
7406
+ if (scope === "app" && request2.headers.get("if-none-match") === object.httpEtag) {
7407
+ return new Response(null, { status: 304, headers: headers2 });
7408
+ }
7409
+ headers2.set("Content-Length", String(object.size));
7410
+ return new Response(null, { status: 200, headers: headers2 });
7411
+ }
7412
+ const rangeHeader = request2.headers.get("range");
7413
+ if (rangeHeader === null) {
7414
+ return wholeDownload(request2, await bucket.get(key), key, scope);
7415
+ }
7416
+ const head = await bucket.head(key);
7417
+ if (!head) {
7393
7418
  return Response.json({ error: "File not found" }, { status: 404, headers: CORS_HEADERS4 });
7394
7419
  }
7420
+ if (scope === "app" && request2.headers.get("if-none-match") === head.httpEtag) {
7421
+ return new Response(null, { status: 304, headers: downloadHeaders(head, key, scope) });
7422
+ }
7423
+ const ifRange = request2.headers.get("if-range");
7424
+ if (ifRange !== null && ifRange !== head.httpEtag) {
7425
+ return wholeDownload(request2, await bucket.get(key), key, scope);
7426
+ }
7427
+ const range = parseByteRange(rangeHeader, head.size);
7428
+ if (range === "unsatisfiable") {
7429
+ const headers2 = { ...CORS_HEADERS4, "Content-Range": `bytes */${head.size}` };
7430
+ return new Response(null, { status: 416, headers: headers2 });
7431
+ }
7432
+ if (!range) {
7433
+ return wholeDownload(request2, await bucket.get(key), key, scope);
7434
+ }
7435
+ const conditional = await bucket.get(key, {
7436
+ range,
7437
+ onlyIf: { etagMatches: head.etag }
7438
+ });
7439
+ if (!conditional || !("body" in conditional)) {
7440
+ return wholeDownload(request2, await bucket.get(key), key, scope);
7441
+ }
7442
+ const headers = downloadHeaders(conditional, key, scope);
7443
+ const end = range.offset + range.length - 1;
7444
+ headers.set("Content-Range", `bytes ${range.offset}-${end}/${conditional.size}`);
7445
+ headers.set("Content-Length", String(range.length));
7446
+ return new Response(conditional.body, { status: 206, headers });
7447
+ }
7448
+ function downloadHeaders(object, key, scope) {
7395
7449
  const headers = new Headers();
7396
7450
  const storedType = resolveMimeType(object.httpMetadata?.contentType ?? "");
7397
7451
  const mustDownload = DANGEROUS_MIME_TYPES.has(storedType);
@@ -7409,10 +7463,19 @@ async function handleDownload(request2, bucket, key, scope) {
7409
7463
  contentDisposition(originalName, mustDownload ? "attachment" : "inline")
7410
7464
  );
7411
7465
  if (mustDownload) headers.set("Content-Security-Policy", "sandbox; default-src 'none'");
7466
+ headers.set("Accept-Ranges", "bytes");
7467
+ return headers;
7468
+ }
7469
+ function wholeDownload(request2, object, key, scope) {
7470
+ if (!object) {
7471
+ return Response.json({ error: "File not found" }, { status: 404, headers: CORS_HEADERS4 });
7472
+ }
7473
+ const headers = downloadHeaders(object, key, scope);
7412
7474
  if (scope === "app" && request2.headers.get("if-none-match") === object.httpEtag) {
7413
7475
  return new Response(null, { status: 304, headers });
7414
7476
  }
7415
- return new Response(object.body, { headers });
7477
+ headers.set("Content-Length", String(object.size));
7478
+ return new Response(object.body, { status: 200, headers });
7416
7479
  }
7417
7480
 
7418
7481
  // src/server/utils/proxies.ts
@@ -10061,6 +10124,45 @@ async function verifyJwt(config, token) {
10061
10124
  }
10062
10125
  }
10063
10126
 
10127
+ // src/shared/auth-session.ts
10128
+ var SESSION_COOKIE = "__Secure-better-auth.session_token";
10129
+
10130
+ // src/server/auth/sessionReadAuth.ts
10131
+ var TTL_MS = 5 * 6e4;
10132
+ var sessions = /* @__PURE__ */ new Map();
10133
+ async function exchange(session, env) {
10134
+ try {
10135
+ const res = await authWorkerFetch(env, "/api/auth/token", {
10136
+ method: "POST",
10137
+ headers: { Cookie: `${SESSION_COOKIE}=${session}` },
10138
+ signal: AbortSignal.timeout(1e4)
10139
+ });
10140
+ const { token } = res.ok ? await res.json() : {};
10141
+ if (typeof token !== "string") return null;
10142
+ const config = { publicKey: env.AUTH_JWT_PUBLIC_KEY, issuer: env.AUTH_JWT_ISSUER };
10143
+ return (await verifyJwt(config, token)).result;
10144
+ } catch {
10145
+ return null;
10146
+ }
10147
+ }
10148
+ async function resolveSessionReadAuth(req, env) {
10149
+ const site = req.headers.get("Sec-Fetch-Site");
10150
+ if (req.method !== "GET" && req.method !== "HEAD") return null;
10151
+ if (req.headers.has("Authorization") || site !== "same-origin" && site !== "none") return null;
10152
+ const session = (req.headers.get("Cookie") ?? "").split(";").find((part) => part.trim().startsWith(`${SESSION_COOKIE}=`))?.trim().slice(SESSION_COOKIE.length + 1);
10153
+ if (!session) return null;
10154
+ const now = Date.now();
10155
+ const cached = sessions.get(session);
10156
+ if (cached && cached.expiresAt > now) return cached.promise;
10157
+ if (sessions.size >= 500) sessions.clear();
10158
+ const promise = exchange(session, env).then((result) => {
10159
+ if (!result) sessions.delete(session);
10160
+ return result;
10161
+ });
10162
+ sessions.set(session, { promise, expiresAt: now + TTL_MS });
10163
+ return promise;
10164
+ }
10165
+
10064
10166
  // src/server/auth/agentToken.ts
10065
10167
  var AGENT_TOKEN_SCOPE = "agent";
10066
10168
  function agentTokenIssuer(issuer) {
@@ -10549,9 +10651,6 @@ function normalizeAgentTargetOrigin(value, policy) {
10549
10651
  return !label.includes(".") && validateAppName(label).valid ? url.origin : null;
10550
10652
  }
10551
10653
 
10552
- // src/shared/auth-session.ts
10553
- var SESSION_COOKIE = "__Secure-better-auth.session_token";
10554
-
10555
10654
  // src/shared/api-error.ts
10556
10655
  var SLUG_RE = /^[a-z0-9]+(?:[_.-][a-z0-9]+)*$/;
10557
10656
  var HUMAN_MESSAGES = {
@@ -10647,6 +10746,7 @@ export {
10647
10746
  DEPLOYED_APPS_DEFAULTS,
10648
10747
  DeepSpaceAgentModelError,
10649
10748
  DeepSpaceAgentProfileError,
10749
+ FILES_SESSION_COOKIE_READS_MIGRATION_ID,
10650
10750
  JobRoom,
10651
10751
  KnowledgeError,
10652
10752
  LOG_LEVELS,
@@ -10801,6 +10901,7 @@ export {
10801
10901
  resolveColumn,
10802
10902
  resolveCompatibilityFlags,
10803
10903
  resolveDeepSpaceAgentModel,
10904
+ resolveSessionReadAuth,
10804
10905
  rowToData,
10805
10906
  runMigrations,
10806
10907
  serverBuild,