Skip to content

feat: add CORS management to bucket provisioner plugin#963

Merged
pyramation merged 10 commits intomainfrom
devin/1775257329-cors-allowed-origins
Apr 4, 2026
Merged

feat: add CORS management to bucket provisioner plugin#963
pyramation merged 10 commits intomainfrom
devin/1775257329-cors-allowed-origins

Conversation

@pyramation
Copy link
Copy Markdown
Contributor

@pyramation pyramation commented Apr 3, 2026

Summary

Adds CORS management to the graphile-bucket-provisioner-plugin and @constructive-io/bucket-provisioner packages.

Plugin changes (graphile-bucket-provisioner-plugin):

  • CORS update hook — wraps update* mutations on @storageBuckets-tagged tables to detect allowed_origins changes and call updateCors() on the S3 bucket
  • 3-tier CORS resolution: bucket-level allowed_originsstorage_module-level allowed_origins → plugin config allowedOrigins
  • Wildcard CORS (['*']) for CDN/public bucket deployments
  • Reads allowed_origins from both the bucket row and storage_module table
  • provisionBucket explicit mutation now passes bucket-level allowed_origins through the hierarchy
  • README updated to document CORS features, update hook, and 3-tier resolution

Library changes (@constructive-io/bucket-provisioner):

  • provision() now accepts optional allowedOrigins per-call override (falls back to provisioner default)
  • New updateCors() method for CORS-only updates without full re-provisioning
  • New UpdateCorsOptions type exported

Test coverage: 54 plugin tests (8 new CORS tests) + 84 bucket-provisioner tests passing.

Updates since last revision

  • Preset integrationBucketProvisionerPreset is now wired into ConstructivePreset in graphile-settings, following the same lazy-init pattern as presigned-url-resolver.ts
  • New bucket-provisioner-resolver.ts — reads CDN config via getEnvOptions() (merges pgpmDefaults → config file → env vars), caches on first call
  • Schema snapshot updatedprovisionBucket mutation, ProvisionBucketInput, and ProvisionBucketPayload now appear in the GraphQL SDL snapshot
  • JSDoc examples updatedpreset.ts and index.ts examples now show getEnvOptions() pattern instead of raw process.env

Review & Testing Checklist for Human

  • Update mutation input shape — The update hook extracts allowed_origins from bucketInput directly (not from a patch sub-object). Verify this matches how PostGraphile v5 actually structures update* mutation inputs. If PG5 uses { nodeId, patch: { allowed_origins } }, the detection at 'allowed_origins' in bucketInput will miss it. This is the highest-risk item.
  • Bucket key extraction on update — The update path reads bucketInput?.key to look up the bucket row post-update. Confirm this is where PG5 puts the row identifier in update mutation args. If PG5 uses nodeId instead, the CORS update will silently skip with a warning.
  • Preset wiring CDN configbucket-provisioner-resolver.ts reads cdn from getEnvOptions() and destructures awsAccessKey, awsSecretKey, etc. Verify these fields are always populated by pgpmDefaults so the resolver doesn't throw on first call in environments without explicit CDN env vars.
  • Verify CORS hierarchy in real DB scenario — Unit tests mock the DB queries; confirm the allowed_origins column is actually returned by the SQL queries against real storage_module and buckets tables (depends on companion PR constructive-db#756).

Suggested test plan: Deploy with a test database that has the allowed_origins columns (from constructive-db#756), create a bucket with specific allowed_origins, and verify the S3 bucket gets the correct CORS config. Then update allowed_origins and confirm the S3 CORS is re-applied. Also verify that provisionBucket mutation appears in the schema when running against ConstructivePreset.

Notes

Link to Devin session: https://app.devin.ai/sessions/4c882ba2dfbf4045adf85fb83cde6f77
Requested by: @pyramation

pyramation and others added 3 commits April 3, 2026 11:50
…kets on bucket table mutations

- PostGraphile v5 plugin with two provisioning pathways:
  1. Auto-provisioning hook on create mutations tagged with @storagebuckets
  2. Explicit provisionBucket GraphQL mutation for manual/retry provisioning
- Reads per-database endpoint/provider/publicUrlPrefix overrides from storage_module table
- Lazy S3 config resolution (function-based, cached after first call)
- Graceful error handling (provisioning failures logged, never fail the mutation)
- Custom bucket naming via prefix or resolveBucketName function
- 46 passing tests covering plugin structure, mutation callback, auto-provisioning hook,
  connection config resolution, error handling, and bucket name resolution
- Added to CI test matrix
…ner-plugin' into devin/1775257329-cors-allowed-origins
- Add per-call allowedOrigins override to BucketProvisioner.provision()
- Add updateCors() method for CORS-only updates on existing buckets
- Export UpdateCorsOptions type from bucket-provisioner package
- Update graphile plugin with 3-tier CORS resolution hierarchy:
  bucket-level > storage_module-level > plugin config
- Wrap update* mutations on @storagebuckets tables to detect
  allowed_origins changes and re-apply CORS rules
- Read allowed_origins from bucket row in provisionBucket mutation
- Support wildcard CORS (['*']) for CDN/public buckets
- Add 8 new tests for CORS hierarchy, update hooks, error handling
- All 54 plugin tests + 84 bucket-provisioner tests passing
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

…Options

- Add bucket-provisioner-resolver.ts in graphile-settings (lazy init via getEnvOptions, same pattern as presigned-url-resolver.ts)
- Wire BucketProvisionerPreset into constructive-preset.ts with lazy connection getter
- Update JSDoc examples in bucket-provisioner-plugin to show getEnvOptions pattern instead of raw process.env
- Export getBucketProvisionerConnection from graphile-settings index
@pyramation pyramation merged commit 2f72710 into main Apr 4, 2026
49 checks passed
@pyramation pyramation deleted the devin/1775257329-cors-allowed-origins branch April 4, 2026 02:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant