182 Commits

Author SHA1 Message Date
jfeng 4bf10d7958 Merge pull request #1980 from bowale01/fix/openapi-functions-404-cloud-variant
fix(openapi): add cloud Subhosting 404 variant to function invoke spec
2026-08-19 17:46:17 -07:00
bowale01 51521178e5 fix(openapi): add cloud Subhosting 404 variant to function invoke spec
The RuntimeFunctionNotFound response now documents all three 404 bodies:
- application/json (self-hosted): {error: 'Function not found or not active'}
- application/json (cloud Subhosting): {error: 'Function not found'}
- text/plain (local catch-all): 'Not Found'

Uses examples: (plural) for the two JSON variants so generated clients
can distinguish them. Does not imply Content-Type alone separates all cases.

Closes #1979
2026-08-18 23:18:58 +02:00
Lyu d399655fdc Merge pull request #1928 from bowale01/fix/openapi-functions-404-dual-content-type
fix(openapi): document dual 404 content types for function invoke ope…
2026-08-12 10:30:41 -07:00
bowale01 48ab1f3aba Clarify conditional 404 response variants 2026-08-12 08:28:34 +02:00
Lyu 3f13e97dbe fix(compute): honour the configured default ingress on create
COMPUTE_DEFAULT_INGRESS had no effect on service creation, and neither did the
stored setting that replaces it. The service layer resolved an omitted ingress
to `capabilities.ingressModes[0]` — a static list whose first entry is 'none' —
so the provider's ingressFor() never saw an undefined value to fill in, and the
env var was dead from the day it shipped. Found by setting the new dashboard
default to `port` on a real daemon and watching the container come up private.

The default is now a provider method rather than a position in a list, because
for a single-host driver it is an operator setting that changes while the
process runs; a static list cannot express that. Both the stored row and the
launch call read it, since a row that disagrees with the container is the
failure the capability layer exists to prevent.

Reported in the /api/metadata compute slice too, and the create dialog
preselects it. Without that, the dialog showed 'none' while the server would
have applied 'port' — the setting would look ignored from the one screen that
offers it. Optional in the schema so a client keeps working against a backend
that predates the field.

Also parallelises the compute logs limiter test. 121 sequential supertest
round-trips timed out at 10s on a loaded machine; the memory store increments
synchronously, so concurrent requests still take distinct slots and the same
assertion holds in 60ms.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 16:48:56 -07:00
bowale01 80a9e3563e Merge upstream/main into fix/openapi-functions-404-dual-content-type 2026-08-11 23:57:53 +02:00
bowale01 7b69f65ada Refactor function 404 OpenAPI response 2026-08-11 23:54:23 +02:00
bowale01 40c031574e fix(openapi): document dual 404 content types for function invoke operations
The proxied /functions/{slug} routes forward Deno runtime responses verbatim.
The runtime returns two distinct 404 shapes:
- JSON {error: string} when a valid slug has no active function
- Plain text 'Not Found' when the path fails the runtime's slug regex

Previous spec documented only application/json (referencing ErrorResponse),
so generated clients would throw parsing 'Not Found' as JSON.

Changes:
- GET, POST, PUT, PATCH, DELETE on /functions/{slug}: add dual 404 content
  (application/json + text/plain) with inline schema (not ErrorResponse ref)
- Add missing 404 to PUT, PATCH, DELETE invoke operations

Closes #1926
2026-08-11 23:30:21 +02:00
jfeng ddc462d96b Merge pull request #1922 from Gautam-aman/fix/functions-invoke-404
docs(openapi): document 404 for function invoke methods
2026-08-11 15:11:46 +08:00
Aman Gautam dcd8e4bc0a docs(openapi): document 404 for function invoke methods 2026-08-11 12:36:05 +05:30
Lyu e27b99b813 fix(compute): close the contract and consistency gaps
Four small gaps, all mine, none needing a decision.

The /api/metadata response gained a compute slice but openapi/metadata.yaml never
described it, though it enumerates auth, database, storage, functions, realtime and
deployments. Added with the per-provider capability shape and an example. Worth
recording: there is no openapi/compute.yaml at all, so the build endpoint's absence
from the contract is part of that pre-existing hole rather than something this branch
introduced.

The markdown metadata export omitted compute for the same reason. It now renders a
Compute section, spelled out as what a client should stop offering (regions no,
scale-to-zero no) rather than dumping the capability object, and stays absent when no
driver is configured -- absence is how a client detects that compute is off.

listMachines passed a bare name to Docker's name filter, which is an unanchored regex
over container names, so `api` also matched `api-v2`. Now anchored (allowing for the
leading slash Docker puts on container names) with an exact-match filter behind it,
since reporting a sibling service's container as this service's instance is how the
wrong container gets stopped. No caller today; this was a trap waiting for one.

The ingress docblock I added earlier landed between protocol's docblock and protocol
itself, so the Edge-protocol comment documented ingress and protocol was left
undocumented. Reordered. updateServiceSchema was already correct.

All four verified: the openapi YAML is parsed and asserted against the schema shape,
and the other three have tests that fail when the fix is reverted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 19:35:58 -07:00
Aman Gautam a5f9579a54 docs(openapi): align cloud authorization example 2026-08-04 22:37:01 +05:30
Aman Gautam 39becd2207 docs(openapi): document cloud backend authentication 2026-08-04 22:21:31 +05:30
Aman Gautam 77ade997a9 docs(openapi): document cloud backend authentication 2026-08-04 18:23:28 +05:30
Aman Gautam f024a24f6a docs(openapi): clarify usage stats response semantics 2026-08-04 18:14:46 +05:30
Aman Gautam e06e149049 docs(openapi): add usage API specification 2026-08-04 18:03:34 +05:30
jfeng 2bde9f2756 Merge pull request #1831 from ayaangazali/fix/schedules-delete-404
fix(schedules): return 404 instead of 500 when deleting a missing schedule
2026-08-02 18:44:00 -07:00
ayaangazali cce6f26810 fix(schedules): return 404 instead of 500 when deleting a missing schedule
schedules.delete_job() signals a missing row the same way it signals a real
failure, by returning success = false. deleteSchedule mapped every false
result to a 500 DATABASE_INTERNAL_ERROR, so deleting a schedule that does not
exist, or deleting the same schedule twice, reported a server error even
though nothing was wrong on the server.

GET and PATCH on the same id already return 404 SCHEDULE_NOT_FOUND, so this
also makes the three id routes agree. Check for the schedule first, mirroring
updateSchedule, and leave genuine delete_job failures as 500.

Also document the 404 on DELETE /api/schedules/{id} in openapi/schedules.yaml,
which listed it for GET and PATCH but not for DELETE.
2026-07-31 23:59:43 -07:00
Lyu ff770dbf93 Merge pull request #1828 from InsForge/codex/dashboard-sse-events
Move dashboard internal events from Socket.IO to SSE
2026-07-31 16:05:16 -07:00
Lyu 0c3c649c15 refactor: drop the dashboard SSE rate limiter
The endpoint is admin-gated, per-project, and the client reconnects with
exponential backoff, so the limiter guarded against a load profile the
endpoint cannot realistically see.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 15:55:31 -07:00
Lyu 7b6e76a008 fix: broad records fallback for unparseable table names in dashboard events
Also document the data field as optional in the dashboard OpenAPI spec.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 15:48:44 -07:00
Lyu 6cc7ba255c refactor: use verifyAdmin for the SSE endpoint and drop dead realtime code
- replace verifyProjectAdminJwt with the standard verifyAdmin middleware
  (accepting API keys like every other admin endpoint) and delete the
  dedicated middleware and its test
- remove the never-published 'realtime' dashboard event resource from the
  shared schema and the client invalidation mapping
- stop joining sockets to role:/user: rooms; nothing has broadcast to them
  since dashboard events left Socket.IO

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 15:09:18 -07:00
Lyu 1aff0df477 fix: address second-round review on dashboard SSE hardening
- rate-limit SSE connection attempts (30/min per IP) per API guidelines
- parse table references defensively and isolate the event handler so a
  malformed producer name cannot reject the stream read loop
- release the stream reader when the read loop exits abnormally
- cancel the response body before throwing on non-ok stream responses
- document GET /api/dashboard/events in the OpenAPI specs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 14:59:47 -07:00
Aman Gautam 93bced8e16 docs(storage): align DownloadStrategy schema with runtime behavior 2026-08-01 00:46:30 +05:30
Aman Gautam b1ee79c74e docs(storage): align download strategy with proxy mode behavior 2026-08-01 00:34:14 +05:30
Aman Gautam 1d044ad067 docs(storage): document S3 proxy mode upload and download strategies 2026-08-01 00:23:30 +05:30
Carmen Dou 685efe3d47 Merge pull request #1732 from Gautam-aman/docs/schedules-openapi
Add OpenAPI specification for schedules API
2026-07-30 17:40:34 -07:00
Wayne Hsu 4c10f5c498 fix(auth): address native Apple review feedback 2026-07-30 18:16:25 +01:00
Wayne Hsu 0e4c0877e6 feat(auth): add native Apple ID token sign-in 2026-07-30 15:48:54 +01:00
Lyu 91d60fc85c Merge pull request #1798 from InsForge/codex/ins-521-email-otp-auth
feat(auth): add email OTP sign-in
2026-07-27 15:25:28 -07:00
Lyu 9f3317e9e6 fix(auth): harden email OTP sign-in per review
Security
- Add an otp_type discriminator to auth.email_otps and scope numeric-code
  verification to NUMERIC_CODE rows, so a wrong 6-digit guess can no longer
  consume a live magic-link (HASH_TOKEN) reset/verify token for the same
  (email, purpose).
- Case-insensitive user lookup in signInWithOTP so a mixed-case OAuth email
  no longer creates a duplicate lowercased account.
- Re-sanitize non-AppError failures in the OTP verify paths (no raw infra
  error messages in 500 responses).

Refactor
- AuthOTPService.consumeNumericOTP owns the OTP transaction: it persists the
  attempt counter on failure, commits caller work + consumption together, and
  rolls back on caller error. signInWithOTP, verifyEmailWithCode and
  exchangeCodeForToken route through it; remove the dead verifyEmailOTPWithCode.
- Resolve disableSignup via AuthConfigService; STRING_AGG(DISTINCT) providers
  and drop the user_id reassignment in the email provider upsert; reuse
  EMAIL_TEMPLATE_TYPES in the cloud provider.

Schema / contract / docs
- Session preprocess treats null/undefined method as the legacy password flow;
  shared six-digit code schema; trim name before the length check.
- Add request-otp to the OpenAPI email-template enum; document the
  unverified-account password-clearing behavior in the four REST guides.

Tests updated/added across the OTP service, route, schema, and migration suites.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 11:41:19 -07:00
Lyu 3fdffe2718 fix(storage): resolve bucket visibility before opening the proxy stream
Addresses second-round review: an isBucketPublic DB failure between
getObjectStream and the close-handler registration would leak the open
S3 socket. Also sync the remaining AWS_REGION-only mentions in the
storage OpenAPI spec with the S3_REGION fallback, and add the
credential-override and proxy-mode notes to the README storage section.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 17:05:52 -07:00
Lyu 2b5c4505d6 refactor(auth): unify session login methods 2026-07-24 12:48:44 -07:00
Lyu 77418fdc0c fix(storage): address review feedback
- Replace error-message string matching with a typed ObjectNotFoundError
  for missing blobs; the S3 gateway GetObject handler now also maps it
  to NoSuchKey instead of a 500.
- Set Cache-Control: private, no-store on proxied private-bucket bytes.
- Pin MinIO/mc/RustFS image tags in the overlays and test rig.
- Defer the dashboard gateway-config fetch until the dialog is open.
- Document the `available` field and S3_REGION fallback in the storage
  OpenAPI spec; sync the security-guide env example; use S3_BUCKET in
  the RustFS test rig instructions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 12:44:56 -07:00
Lyu 8e6cb85240 fix(auth): consume disabled-signup OTPs 2026-07-24 12:12:03 -07:00
Lyu f11718478f Merge pull request #1778 from bowale01/fix/openapi-add-apikey-scheme
fix(openapi): add apiKey security scheme to email, functions, and logs specs
2026-07-22 10:46:47 -07:00
Lyu 5eabbfef5b fix email verification review issues 2026-07-21 15:13:07 -07:00
Lyu 2b0923242f fix email verification provider safeguards 2026-07-21 12:15:17 -07:00
bowale01 6ed3a852aa fix: update email endpoint description to reflect apiKey auth
Description now states that either user authentication or admin API key is accepted.
2026-07-21 20:29:42 +02:00
bowale01 f3a94c94a2 fix(openapi): add apiKey security scheme to email, functions, and logs specs
The handlers for these endpoints accept admin API keys (x-api-key header)
via verifyUser/verifyAdmin middleware, but the specs only declared bearerAuth.
This aligns them with the other 10 specs that already declare both schemes.

- email.yaml: add apiKey to 1 operation (POST /api/email/send-raw)
- functions.yaml: add apiKey to 5 admin operations
- logs.yaml: add apiKey to 3 admin operations

Closes #1757
2026-07-21 20:00:56 +02:00
Aman Gautam e9f32c151e docs(openapi): address review feedback 2026-07-21 11:11:26 +05:30
Lyu 6ac3c191b3 Merge pull request #1760 from InsForge/claude/storage-put-method-a4e808
feat(storage): use standard PUT replacement semantics
2026-07-20 19:20:35 -07:00
Lyu 69e51a1c30 refactor(storage): drop autoKey, restore dashboard rename, align confirm status
Following the move to standard S3 PUT semantics (create-or-replace, no
server-side rename), tighten the surface:

- Remove the autoKey upload-strategy flag from shared-schemas, the route,
  and getUploadStrategy. It duplicated the existing POST /objects
  server-key path and isn't an S3 concept; the SDK's uploadAuto mints the
  key client-side instead. generateObjectKey stays for POST /objects.
- Restore the dashboard's friendly auto-rename, which the S3-semantics
  rework had dropped (leaving duplicate uploads to silently overwrite).
  Since PUT no longer 409s, the dashboard now proactively lists and picks
  the next free "name (N).ext" before uploading, reserving keys chosen
  earlier in the same batch. Client-only; the API never renames.
- confirm-upload returns 200 (was 201) to match the direct PUT route:
  both finalize a create-or-replace and neither reads back to distinguish
  create vs replace.
- Update OpenAPI and all REST/TypeScript doc locales accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 16:35:21 -07:00
Lyu 210ffd8770 fix(storage): use standard PUT replacement semantics 2026-07-20 15:35:12 -07:00
Lyu 4bb04d6008 fix(storage): preserve confirm upload errors 2026-07-20 14:50:18 -07:00
Lyu 8abf15206b refactor(storage): keep review fixes minimal 2026-07-20 14:22:46 -07:00
Lyu 862df46ffc fix(storage): stage presigned uploads before confirm 2026-07-20 13:54:33 -07:00
Lyu c71146bccf fix: harden model gateway usage refresh 2026-07-20 12:43:33 -07:00
Lyu 6412adf6c0 fix: address model gateway usage review 2026-07-20 12:07:49 -07:00
Lyu d11717ef63 fix(storage): address PR review — self-contained upsert URLs, race-free confirms, OpenAPI
- Direct upload-strategy uploadUrl now carries ?upsert=true when upsert
  was requested, so the strategy contract is self-contained for clients
  that redeem the URL verbatim (the SDK appended the flag itself, which
  masked the gap).
- confirmUpload's upsert path is a single INSERT ... ON CONFLICT DO
  UPDATE, so concurrent upsert confirms can no longer race into a 409;
  ownership stays out of the SET clause, matching putObject.
- Dashboard auto-rename retries feed rejected candidates back into the
  next-key computation, so retries always advance even when the capped
  substring listing misses the conflicting key.
- putObject upsert comment now pins why no rowCount check is needed
  (the conflict arm raises 42501, mapped to 403), plus a unit test
  driving a 42501 through putObject({ upsert: true }) → 403 with no
  provider write.
- upload-strategy and confirm-upload bodies are validated with the
  shared zod schemas (consistent 400s; size: 0 is now accepted on
  confirm since the provider size check is authoritative).
- openapi/storage.yaml documents the new contract: PUT upsert query
  param with 200/403/409, upload-strategy upsert/autoKey fields, and
  the confirm-upload upsert field.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 11:50:42 -07:00