@selvajs/platform 0.21.0-beta.2 → 1.0.0-beta.4
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/README.md +10 -7
- package/dist/access/index.d.ts +1 -2
- package/dist/access/index.js +1 -2
- package/dist/access/rules.d.ts +11 -12
- package/dist/access/rules.js +27 -23
- package/dist/apiTokens/index.d.ts +2 -3
- package/dist/apiTokens/index.js +2 -3
- package/dist/apiTokens/interface.d.ts +0 -1
- package/dist/apiTokens/interface.js +0 -1
- package/dist/apiTokens/scope.d.ts +3 -2
- package/dist/apiTokens/scope.js +9 -5
- package/dist/apiTokens/types.d.ts +7 -2
- package/dist/apiTokens/types.js +10 -5
- package/dist/auth/index.d.ts +0 -1
- package/dist/auth/index.js +0 -1
- package/dist/auth/interface.d.ts +4 -23
- package/dist/auth/interface.js +0 -1
- package/dist/auth/types.d.ts +4 -2
- package/dist/auth/types.js +0 -1
- package/dist/bindings/index.d.ts +0 -1
- package/dist/bindings/index.js +0 -1
- package/dist/bindings/interface.d.ts +0 -1
- package/dist/bindings/interface.js +0 -1
- package/dist/computeServer/index.d.ts +1 -7
- package/dist/computeServer/index.js +2 -8
- package/dist/computeServer/interface.d.ts +9 -6
- package/dist/computeServer/interface.js +0 -1
- package/dist/computeServer/public.d.ts +6 -0
- package/dist/computeServer/public.js +2 -0
- package/dist/computeServer/secrets.d.ts +12 -6
- package/dist/computeServer/secrets.js +35 -15
- package/dist/computeServer/types.d.ts +5 -2
- package/dist/computeServer/types.js +4 -1
- package/dist/computeServer/utils.d.ts +17 -6
- package/dist/computeServer/utils.js +31 -21
- package/dist/config.d.ts +1 -2
- package/dist/config.js +0 -1
- package/dist/context.d.ts +12 -1
- package/dist/context.js +51 -2
- package/dist/data/index.d.ts +0 -1
- package/dist/data/index.js +0 -1
- package/dist/data/interface.d.ts +0 -1
- package/dist/data/interface.js +0 -1
- package/dist/definitions/index.d.ts +2 -3
- package/dist/definitions/index.js +2 -3
- package/dist/definitions/interface.d.ts +0 -1
- package/dist/definitions/interface.js +0 -1
- package/dist/definitions/paths.d.ts +0 -1
- package/dist/definitions/paths.js +1 -12
- package/dist/definitions/schemas.d.ts +2 -21
- package/dist/definitions/schemas.js +10 -19
- package/dist/definitions/types.d.ts +12 -4
- package/dist/definitions/types.js +1 -3
- package/dist/errors/interface.d.ts +1 -2
- package/dist/errors/interface.js +0 -1
- package/dist/errors.d.ts +8 -1
- package/dist/errors.js +11 -1
- package/dist/events/audit.d.ts +1 -2
- package/dist/events/audit.js +0 -1
- package/dist/events/index.d.ts +0 -1
- package/dist/events/index.js +0 -1
- package/dist/events/interface.d.ts +0 -1
- package/dist/events/interface.js +0 -1
- package/dist/index.d.ts +18 -61
- package/dist/index.js +18 -24
- package/dist/invites/index.d.ts +0 -1
- package/dist/invites/index.js +0 -1
- package/dist/invites/interface.d.ts +5 -6
- package/dist/invites/interface.js +0 -1
- package/dist/invites/types.d.ts +0 -1
- package/dist/invites/types.js +0 -1
- package/dist/logging/interface.d.ts +0 -1
- package/dist/logging/interface.js +0 -1
- package/dist/metrics/interface.d.ts +0 -1
- package/dist/metrics/interface.js +0 -1
- package/dist/notifications/index.d.ts +0 -1
- package/dist/notifications/index.js +0 -1
- package/dist/notifications/interface.d.ts +1 -3
- package/dist/notifications/interface.js +1 -3
- package/dist/notifications/types.d.ts +0 -1
- package/dist/notifications/types.js +0 -1
- package/dist/organizations/index.d.ts +2 -3
- package/dist/organizations/index.js +1 -2
- package/dist/organizations/interface.d.ts +3 -5
- package/dist/organizations/interface.js +0 -1
- package/dist/organizations/paths.d.ts +1 -6
- package/dist/organizations/paths.js +2 -20
- package/dist/organizations/schemas.d.ts +5 -7
- package/dist/organizations/schemas.js +20 -13
- package/dist/organizations/types.d.ts +0 -1
- package/dist/organizations/types.js +0 -1
- package/dist/pagination.d.ts +11 -3
- package/dist/pagination.js +15 -1
- package/dist/permissions/index.d.ts +2 -2
- package/dist/permissions/index.js +2 -2
- package/dist/permissions/interface.d.ts +4 -4
- package/dist/permissions/interface.js +0 -1
- package/dist/permissions/types.d.ts +0 -1
- package/dist/permissions/types.js +0 -1
- package/dist/platformProjects/index.d.ts +1 -3
- package/dist/platformProjects/index.js +1 -2
- package/dist/platformProjects/interface.d.ts +0 -1
- package/dist/platformProjects/interface.js +0 -1
- package/dist/platformProjects/schemas.d.ts +0 -1
- package/dist/platformProjects/schemas.js +0 -1
- package/dist/platformProjects/types.d.ts +3 -2
- package/dist/platformProjects/types.js +0 -1
- package/dist/projects/index.d.ts +0 -1
- package/dist/projects/index.js +0 -1
- package/dist/projects/interface.d.ts +0 -1
- package/dist/projects/interface.js +0 -1
- package/dist/projects/schemas.d.ts +0 -1
- package/dist/projects/schemas.js +0 -1
- package/dist/projects/types.d.ts +0 -1
- package/dist/projects/types.js +0 -1
- package/dist/shareLinks/index.d.ts +0 -1
- package/dist/shareLinks/index.js +0 -1
- package/dist/shareLinks/interface.d.ts +6 -3
- package/dist/shareLinks/interface.js +0 -1
- package/dist/shareLinks/schemas.d.ts +0 -1
- package/dist/shareLinks/schemas.js +4 -2
- package/dist/shareLinks/types.d.ts +0 -1
- package/dist/shareLinks/types.js +0 -1
- package/dist/solveCache/interface.d.ts +2 -3
- package/dist/solveCache/interface.js +0 -1
- package/dist/storage/assetClasses.d.ts +4 -8
- package/dist/storage/assetClasses.js +6 -21
- package/dist/storage/cacheBust.d.ts +0 -1
- package/dist/storage/cacheBust.js +5 -3
- package/dist/storage/image.d.ts +8 -5
- package/dist/storage/image.js +74 -12
- package/dist/storage/index.d.ts +2 -4
- package/dist/storage/index.js +2 -3
- package/dist/storage/interface.d.ts +11 -3
- package/dist/storage/interface.js +0 -1
- package/dist/storage/safeKey.d.ts +7 -0
- package/dist/storage/safeKey.js +12 -0
- package/dist/testing/index.d.ts +5 -2
- package/dist/testing/index.js +3 -2
- package/dist/testing/suites/apiTokenStoreSuite.d.ts +0 -1
- package/dist/testing/suites/apiTokenStoreSuite.js +0 -1
- package/dist/testing/suites/auditQuerySuite.d.ts +18 -0
- package/dist/testing/suites/auditQuerySuite.js +73 -0
- package/dist/testing/suites/authProviderSuite.d.ts +14 -3
- package/dist/testing/suites/authProviderSuite.js +57 -32
- package/dist/testing/suites/computeServerStoreSuite.d.ts +1 -2
- package/dist/testing/suites/computeServerStoreSuite.js +68 -4
- package/dist/testing/suites/definitionStoreSuite.d.ts +2 -1
- package/dist/testing/suites/definitionStoreSuite.js +48 -16
- package/dist/testing/suites/emailLinkAuthSuite.d.ts +2 -5
- package/dist/testing/suites/emailLinkAuthSuite.js +1 -9
- package/dist/testing/suites/eventSinkSuite.d.ts +0 -1
- package/dist/testing/suites/eventSinkSuite.js +9 -1
- package/dist/testing/suites/helpers.d.ts +5 -1
- package/dist/testing/suites/helpers.js +7 -1
- package/dist/testing/suites/inviteStoreSuite.d.ts +0 -1
- package/dist/testing/suites/inviteStoreSuite.js +17 -7
- package/dist/testing/suites/oauthAuthSuite.d.ts +18 -0
- package/dist/testing/suites/oauthAuthSuite.js +26 -0
- package/dist/testing/suites/orgStoreSuite.d.ts +5 -1
- package/dist/testing/suites/orgStoreSuite.js +26 -7
- package/dist/testing/suites/platformPermissionStoreSuite.d.ts +0 -5
- package/dist/testing/suites/platformPermissionStoreSuite.js +12 -63
- package/dist/testing/suites/platformProjectGrantStoreSuite.d.ts +0 -1
- package/dist/testing/suites/platformProjectGrantStoreSuite.js +0 -5
- package/dist/testing/suites/projectStoreSuite.d.ts +5 -1
- package/dist/testing/suites/projectStoreSuite.js +6 -6
- package/dist/testing/suites/shareLinkStoreSuite.d.ts +2 -1
- package/dist/testing/suites/shareLinkStoreSuite.js +22 -25
- package/dist/testing/suites/solveMetricSinkSuite.d.ts +0 -1
- package/dist/testing/suites/solveMetricSinkSuite.js +2 -2
- package/dist/testing/suites/storageProviderSuite.d.ts +0 -1
- package/dist/testing/suites/storageProviderSuite.js +15 -10
- package/dist/testing/suites/userProfileStoreSuite.d.ts +1 -2
- package/dist/testing/suites/userProfileStoreSuite.js +42 -7
- package/dist/userProfile/index.d.ts +2 -2
- package/dist/userProfile/index.js +2 -2
- package/dist/userProfile/interface.d.ts +5 -6
- package/dist/userProfile/interface.js +0 -1
- package/dist/userProfile/types.d.ts +2 -1
- package/dist/userProfile/types.js +2 -1
- package/dist/utils/audit.d.ts +0 -1
- package/dist/utils/audit.js +0 -1
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.js +0 -1
- package/package.json +7 -6
- package/dist/access/index.d.ts.map +0 -1
- package/dist/access/index.js.map +0 -1
- package/dist/access/rules.d.ts.map +0 -1
- package/dist/access/rules.js.map +0 -1
- package/dist/apiTokens/index.d.ts.map +0 -1
- package/dist/apiTokens/index.js.map +0 -1
- package/dist/apiTokens/interface.d.ts.map +0 -1
- package/dist/apiTokens/interface.js.map +0 -1
- package/dist/apiTokens/scope.d.ts.map +0 -1
- package/dist/apiTokens/scope.js.map +0 -1
- package/dist/apiTokens/types.d.ts.map +0 -1
- package/dist/apiTokens/types.js.map +0 -1
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/interface.d.ts.map +0 -1
- package/dist/auth/interface.js.map +0 -1
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/bindings/index.d.ts.map +0 -1
- package/dist/bindings/index.js.map +0 -1
- package/dist/bindings/interface.d.ts.map +0 -1
- package/dist/bindings/interface.js.map +0 -1
- package/dist/computeServer/index.d.ts.map +0 -1
- package/dist/computeServer/index.js.map +0 -1
- package/dist/computeServer/interface.d.ts.map +0 -1
- package/dist/computeServer/interface.js.map +0 -1
- package/dist/computeServer/secrets.d.ts.map +0 -1
- package/dist/computeServer/secrets.js.map +0 -1
- package/dist/computeServer/types.d.ts.map +0 -1
- package/dist/computeServer/types.js.map +0 -1
- package/dist/computeServer/utils.d.ts.map +0 -1
- package/dist/computeServer/utils.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js.map +0 -1
- package/dist/data/index.d.ts.map +0 -1
- package/dist/data/index.js.map +0 -1
- package/dist/data/interface.d.ts.map +0 -1
- package/dist/data/interface.js.map +0 -1
- package/dist/definitions/index.d.ts.map +0 -1
- package/dist/definitions/index.js.map +0 -1
- package/dist/definitions/interface.d.ts.map +0 -1
- package/dist/definitions/interface.js.map +0 -1
- package/dist/definitions/paths.d.ts.map +0 -1
- package/dist/definitions/paths.js.map +0 -1
- package/dist/definitions/schemas.d.ts.map +0 -1
- package/dist/definitions/schemas.js.map +0 -1
- package/dist/definitions/types.d.ts.map +0 -1
- package/dist/definitions/types.js.map +0 -1
- package/dist/errors/interface.d.ts.map +0 -1
- package/dist/errors/interface.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/events/audit.d.ts.map +0 -1
- package/dist/events/audit.js.map +0 -1
- package/dist/events/index.d.ts.map +0 -1
- package/dist/events/index.js.map +0 -1
- package/dist/events/interface.d.ts.map +0 -1
- package/dist/events/interface.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/invites/index.d.ts.map +0 -1
- package/dist/invites/index.js.map +0 -1
- package/dist/invites/interface.d.ts.map +0 -1
- package/dist/invites/interface.js.map +0 -1
- package/dist/invites/types.d.ts.map +0 -1
- package/dist/invites/types.js.map +0 -1
- package/dist/logging/interface.d.ts.map +0 -1
- package/dist/logging/interface.js.map +0 -1
- package/dist/metrics/interface.d.ts.map +0 -1
- package/dist/metrics/interface.js.map +0 -1
- package/dist/notifications/index.d.ts.map +0 -1
- package/dist/notifications/index.js.map +0 -1
- package/dist/notifications/interface.d.ts.map +0 -1
- package/dist/notifications/interface.js.map +0 -1
- package/dist/notifications/types.d.ts.map +0 -1
- package/dist/notifications/types.js.map +0 -1
- package/dist/organizations/index.d.ts.map +0 -1
- package/dist/organizations/index.js.map +0 -1
- package/dist/organizations/interface.d.ts.map +0 -1
- package/dist/organizations/interface.js.map +0 -1
- package/dist/organizations/paths.d.ts.map +0 -1
- package/dist/organizations/paths.js.map +0 -1
- package/dist/organizations/schemas.d.ts.map +0 -1
- package/dist/organizations/schemas.js.map +0 -1
- package/dist/organizations/types.d.ts.map +0 -1
- package/dist/organizations/types.js.map +0 -1
- package/dist/pagination.d.ts.map +0 -1
- package/dist/pagination.js.map +0 -1
- package/dist/permissions/index.d.ts.map +0 -1
- package/dist/permissions/index.js.map +0 -1
- package/dist/permissions/interface.d.ts.map +0 -1
- package/dist/permissions/interface.js.map +0 -1
- package/dist/permissions/types.d.ts.map +0 -1
- package/dist/permissions/types.js.map +0 -1
- package/dist/platformProjects/index.d.ts.map +0 -1
- package/dist/platformProjects/index.js.map +0 -1
- package/dist/platformProjects/interface.d.ts.map +0 -1
- package/dist/platformProjects/interface.js.map +0 -1
- package/dist/platformProjects/schemas.d.ts.map +0 -1
- package/dist/platformProjects/schemas.js.map +0 -1
- package/dist/platformProjects/types.d.ts.map +0 -1
- package/dist/platformProjects/types.js.map +0 -1
- package/dist/projects/index.d.ts.map +0 -1
- package/dist/projects/index.js.map +0 -1
- package/dist/projects/interface.d.ts.map +0 -1
- package/dist/projects/interface.js.map +0 -1
- package/dist/projects/schemas.d.ts.map +0 -1
- package/dist/projects/schemas.js.map +0 -1
- package/dist/projects/types.d.ts.map +0 -1
- package/dist/projects/types.js.map +0 -1
- package/dist/shareLinks/index.d.ts.map +0 -1
- package/dist/shareLinks/index.js.map +0 -1
- package/dist/shareLinks/interface.d.ts.map +0 -1
- package/dist/shareLinks/interface.js.map +0 -1
- package/dist/shareLinks/schemas.d.ts.map +0 -1
- package/dist/shareLinks/schemas.js.map +0 -1
- package/dist/shareLinks/types.d.ts.map +0 -1
- package/dist/shareLinks/types.js.map +0 -1
- package/dist/solveCache/interface.d.ts.map +0 -1
- package/dist/solveCache/interface.js.map +0 -1
- package/dist/storage/assetClasses.d.ts.map +0 -1
- package/dist/storage/assetClasses.js.map +0 -1
- package/dist/storage/cacheBust.d.ts.map +0 -1
- package/dist/storage/cacheBust.js.map +0 -1
- package/dist/storage/image.d.ts.map +0 -1
- package/dist/storage/image.js.map +0 -1
- package/dist/storage/index.d.ts.map +0 -1
- package/dist/storage/index.js.map +0 -1
- package/dist/storage/interface.d.ts.map +0 -1
- package/dist/storage/interface.js.map +0 -1
- package/dist/testing/index.d.ts.map +0 -1
- package/dist/testing/index.js.map +0 -1
- package/dist/testing/suites/apiTokenStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/apiTokenStoreSuite.js.map +0 -1
- package/dist/testing/suites/authProviderSuite.d.ts.map +0 -1
- package/dist/testing/suites/authProviderSuite.js.map +0 -1
- package/dist/testing/suites/computeServerStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/computeServerStoreSuite.js.map +0 -1
- package/dist/testing/suites/definitionStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/definitionStoreSuite.js.map +0 -1
- package/dist/testing/suites/emailLinkAuthSuite.d.ts.map +0 -1
- package/dist/testing/suites/emailLinkAuthSuite.js.map +0 -1
- package/dist/testing/suites/eventSinkSuite.d.ts.map +0 -1
- package/dist/testing/suites/eventSinkSuite.js.map +0 -1
- package/dist/testing/suites/helpers.d.ts.map +0 -1
- package/dist/testing/suites/helpers.js.map +0 -1
- package/dist/testing/suites/inviteStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/inviteStoreSuite.js.map +0 -1
- package/dist/testing/suites/orgStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/orgStoreSuite.js.map +0 -1
- package/dist/testing/suites/platformPermissionStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/platformPermissionStoreSuite.js.map +0 -1
- package/dist/testing/suites/platformProjectGrantStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/platformProjectGrantStoreSuite.js.map +0 -1
- package/dist/testing/suites/projectStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/projectStoreSuite.js.map +0 -1
- package/dist/testing/suites/shareLinkStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/shareLinkStoreSuite.js.map +0 -1
- package/dist/testing/suites/solveMetricSinkSuite.d.ts.map +0 -1
- package/dist/testing/suites/solveMetricSinkSuite.js.map +0 -1
- package/dist/testing/suites/storageProviderSuite.d.ts.map +0 -1
- package/dist/testing/suites/storageProviderSuite.js.map +0 -1
- package/dist/testing/suites/userProfileStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/userProfileStoreSuite.js.map +0 -1
- package/dist/userProfile/index.d.ts.map +0 -1
- package/dist/userProfile/index.js.map +0 -1
- package/dist/userProfile/interface.d.ts.map +0 -1
- package/dist/userProfile/interface.js.map +0 -1
- package/dist/userProfile/types.d.ts.map +0 -1
- package/dist/userProfile/types.js.map +0 -1
- package/dist/utils/audit.d.ts.map +0 -1
- package/dist/utils/audit.js.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @selvajs/platform
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Selva's contract with its backends: the interfaces, plus the logic every adapter shares (access rules, API-token scopes, at-rest secret encryption, Zod request schemas, slugs, the image transcoder) and vitest conformance suites. No dependency on a specific database, storage or auth service. Concrete adapters live in their own packages: `@selvajs/local-provider`, `@selvajs/supabase-provider`, `@selvajs/header-auth-provider`.
|
|
4
4
|
|
|
5
5
|
This README is the contract. Read it before writing an adapter.
|
|
6
6
|
|
|
@@ -20,6 +20,7 @@ This README is the contract. Read it before writing an adapter.
|
|
|
20
20
|
| `IShareLinkStore` | Per-definition anonymous-access tokens. | Yes — every method. |
|
|
21
21
|
| `IInviteStore` | Pending org-membership invitations. | Yes — every method. |
|
|
22
22
|
| `IComputeServerStore` | Global + per-org compute-server config. | No — not tenant-scoped. |
|
|
23
|
+
| `IApiTokenStore` | API tokens and their revocation. | Yes — every method. |
|
|
23
24
|
| `IStorageProvider` | Path-based blob storage. Authorization is the caller's responsibility. | No — callers pass already-authorized paths. |
|
|
24
25
|
|
|
25
26
|
`IDataProvider` composes every store, plus optional `auditQuery` / `events` hooks, an optional `verifySchemaVersion` handshake (for adapters whose schema migrates out-of-band), and the `ensureUser` / `onUserDeleted` lifecycle methods. An adapter typically implements one class per store and aggregates them.
|
|
@@ -49,12 +50,12 @@ Providers are two-phase: a metadata store (`IDataProvider`) and a blob store (`I
|
|
|
49
50
|
|
|
50
51
|
List queries filter `'pending'` and `'archived'` by default (`DefinitionListOptions.includePending` / `includeArchived` opt in). If step 2 fails, the record stays `'pending'` and is invisible to consumers.
|
|
51
52
|
|
|
52
|
-
**Delete —
|
|
53
|
+
**Delete — metadata-first:**
|
|
53
54
|
|
|
54
|
-
1. `
|
|
55
|
-
2. `
|
|
55
|
+
1. `data.delete(guid)`, which hides the record at once.
|
|
56
|
+
2. `storage.deletePrefix(prefix)`.
|
|
56
57
|
|
|
57
|
-
If step 2 fails,
|
|
58
|
+
If step 2 fails, the blobs are orphans no reader can reach. The reverse order would leave a live record with its blobs gone.
|
|
58
59
|
|
|
59
60
|
---
|
|
60
61
|
|
|
@@ -84,7 +85,7 @@ The Selva app normally picks bundled providers from `SELVA_AUTH_PROVIDER` / `SEL
|
|
|
84
85
|
|
|
85
86
|
## Testing your adapter
|
|
86
87
|
|
|
87
|
-
`@selvajs/platform/testing` ships a conformance suite per store. Adapters import it and run it against their own instance — passing means the adapter
|
|
88
|
+
`@selvajs/platform/testing` ships a conformance suite per store. Adapters import it and run it against their own instance — passing means the adapter honours the contract the bundled providers do.
|
|
88
89
|
|
|
89
90
|
```ts
|
|
90
91
|
import { runDefinitionStoreConformance } from '@selvajs/platform/testing';
|
|
@@ -96,7 +97,9 @@ runDefinitionStoreConformance({
|
|
|
96
97
|
});
|
|
97
98
|
```
|
|
98
99
|
|
|
99
|
-
A suite exists per store, plus auth, email-link auth, storage, event sink
|
|
100
|
+
A suite exists per store, plus auth, email-link auth, storage, event sink and solve-metric sink. `runAuthProviderConformance` wraps `runAuthCoreConformance` and `runPasswordAuthConformance`, so a provider without passwords can run the core alone or pass `passwordless`. New cases go behind an option, so an upgrade doesn't turn a third-party adapter red. The suites cover `ctx` scoping, `pending` filtering, `includePending` opt-in, `ProviderError` shapes, and the races a store exists to prevent, such as the share-link solve cap. They don't cover performance.
|
|
101
|
+
|
|
102
|
+
`sharp` is an optional peer dependency. An adapter that calls `transcodeImageIfNeeded` has to install it.
|
|
100
103
|
|
|
101
104
|
---
|
|
102
105
|
|
package/dist/access/index.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
export type { ProjectAccessInput, DefinitionAccessInput, VisibilityChangeInput, ReclaimAccessInput, CreateProjectAccessInput, OrgOwnerAuthorityInput, OwnerRemovalInput, OwnerRemovalCheck } from './rules.js';
|
|
2
|
-
export { canView, canSolve, canEdit, canManage, canEditProjectSettings, canChangeVisibilityToPublic, canEditDefinition, canReclaim, canCreateProject, canChangeOrgRole, checkOwnerRemoval, withAdminBypass } from './rules.js';
|
|
3
|
-
//# sourceMappingURL=index.d.ts.map
|
|
2
|
+
export { canView, canSolve, canEdit, canCreateDefinition, canManage, canEditProjectSettings, canChangeVisibilityToPublic, canEditDefinition, canReclaim, canCreateProject, canChangeOrgRole, checkOwnerRemoval, withAdminBypass } from './rules.js';
|
package/dist/access/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export { canView, canSolve, canEdit, canManage, canEditProjectSettings, canChangeVisibilityToPublic, canEditDefinition, canReclaim, canCreateProject, canChangeOrgRole, checkOwnerRemoval, withAdminBypass } from './rules.js';
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export { canView, canSolve, canEdit, canCreateDefinition, canManage, canEditProjectSettings, canChangeVisibilityToPublic, canEditDefinition, canReclaim, canCreateProject, canChangeOrgRole, checkOwnerRemoval, withAdminBypass } from './rules.js';
|
package/dist/access/rules.d.ts
CHANGED
|
@@ -50,6 +50,12 @@ export declare function canSolve(input: ProjectAccessInput): boolean;
|
|
|
50
50
|
* All other visibilities: project owner/editor.
|
|
51
51
|
*/
|
|
52
52
|
export declare function canEdit(input: ProjectAccessInput): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Adding a new definition. Commons projects (`autoJoinOnUpload`) take uploads
|
|
55
|
+
* from anyone who can {@link canView} them, and the uploader owns what they
|
|
56
|
+
* upload; everywhere else it needs {@link canEdit}.
|
|
57
|
+
*/
|
|
58
|
+
export declare function canCreateDefinition(input: ProjectAccessInput): boolean;
|
|
53
59
|
/** Platform projects: `instance_admin` only. All other visibilities: project owner. */
|
|
54
60
|
export declare function canManage(input: ProjectAccessInput): boolean;
|
|
55
61
|
/** Platform projects: `instance_admin` only. All other visibilities: project owner. */
|
|
@@ -125,18 +131,12 @@ export interface OrgOwnerAuthorityInput {
|
|
|
125
131
|
role: OrgRole;
|
|
126
132
|
}
|
|
127
133
|
/**
|
|
128
|
-
* Whether the actor may hand out or take away org `owner`/`admin` standing
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* existing member's role, and removing an owner — and all three had written it
|
|
132
|
-
* out longhand. Two of them had drifted by the time the access audit found
|
|
133
|
-
* them: the invite route let an admin mint an `owner` invite for themselves,
|
|
134
|
-
* and DELETE let an admin remove an owner that PATCH would not let them demote.
|
|
135
|
-
* They are one rule, so they read it from one place.
|
|
134
|
+
* Whether the actor may hand out or take away org `owner`/`admin` standing.
|
|
135
|
+
* Inviting someone as owner/admin, changing a member's role and removing an owner
|
|
136
|
+
* are one rule, so all three read it here.
|
|
136
137
|
*
|
|
137
|
-
* Reads the actor's **membership row**. `Organization.ownerId` is a separate
|
|
138
|
-
*
|
|
139
|
-
* is not authority for this decision.
|
|
138
|
+
* Reads the actor's **membership row**. `Organization.ownerId` is a separate field
|
|
139
|
+
* that can disagree with it and is not authority for this decision.
|
|
140
140
|
*/
|
|
141
141
|
export declare function canChangeOrgRole(input: OrgOwnerAuthorityInput): boolean;
|
|
142
142
|
/**
|
|
@@ -157,4 +157,3 @@ export interface OwnerRemovalInput {
|
|
|
157
157
|
confirmed: boolean;
|
|
158
158
|
}
|
|
159
159
|
export declare function checkOwnerRemoval(input: OwnerRemovalInput): OwnerRemovalCheck;
|
|
160
|
-
//# sourceMappingURL=rules.d.ts.map
|
package/dist/access/rules.js
CHANGED
|
@@ -33,10 +33,12 @@ export function canView(input) {
|
|
|
33
33
|
return platformGrants.some((g) => (g.granteeType === 'user' && g.granteeId === userId) ||
|
|
34
34
|
(g.granteeType === 'org' && g.granteeId === actingOrgId));
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
// A project member sees the project at any visibility. Leaving the org ends the
|
|
37
|
+
// membership, so this only widens access for someone who reclaimed from outside.
|
|
38
|
+
if (member !== null)
|
|
39
|
+
return true;
|
|
38
40
|
if (project.visibility === 'org')
|
|
39
|
-
return orgMember !== null;
|
|
41
|
+
return orgMember !== null && actingOrgId === project.orgId;
|
|
40
42
|
if (project.visibility === 'public')
|
|
41
43
|
return allowCrossOrgPublic ? true : orgMember !== null;
|
|
42
44
|
return false;
|
|
@@ -69,16 +71,28 @@ export function canSolve(input) {
|
|
|
69
71
|
*/
|
|
70
72
|
export function canEdit(input) {
|
|
71
73
|
const { member, project, enablePlatformProjects, platformPermissions } = input;
|
|
72
|
-
if (project
|
|
74
|
+
if (!project)
|
|
75
|
+
return false;
|
|
76
|
+
if (project.visibility === 'platform') {
|
|
73
77
|
if (!enablePlatformProjects)
|
|
74
78
|
return false;
|
|
75
79
|
return isInstanceAdmin(platformPermissions);
|
|
76
80
|
}
|
|
77
81
|
return member?.role === 'owner' || member?.role === 'editor';
|
|
78
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Adding a new definition. Commons projects (`autoJoinOnUpload`) take uploads
|
|
85
|
+
* from anyone who can {@link canView} them, and the uploader owns what they
|
|
86
|
+
* upload; everywhere else it needs {@link canEdit}.
|
|
87
|
+
*/
|
|
88
|
+
export function canCreateDefinition(input) {
|
|
89
|
+
return (input.project?.autoJoinOnUpload === true && canView(input)) || canEdit(input);
|
|
90
|
+
}
|
|
79
91
|
/** Platform projects: `instance_admin` only. All other visibilities: project owner. */
|
|
80
92
|
export function canManage(input) {
|
|
81
|
-
if (input.project
|
|
93
|
+
if (!input.project)
|
|
94
|
+
return false;
|
|
95
|
+
if (input.project.visibility === 'platform') {
|
|
82
96
|
if (!input.enablePlatformProjects)
|
|
83
97
|
return false;
|
|
84
98
|
return isInstanceAdmin(input.platformPermissions);
|
|
@@ -87,12 +101,7 @@ export function canManage(input) {
|
|
|
87
101
|
}
|
|
88
102
|
/** Platform projects: `instance_admin` only. All other visibilities: project owner. */
|
|
89
103
|
export function canEditProjectSettings(input) {
|
|
90
|
-
|
|
91
|
-
if (!input.enablePlatformProjects)
|
|
92
|
-
return false;
|
|
93
|
-
return isInstanceAdmin(input.platformPermissions);
|
|
94
|
-
}
|
|
95
|
-
return input.member?.role === 'owner';
|
|
104
|
+
return canManage(input);
|
|
96
105
|
}
|
|
97
106
|
/**
|
|
98
107
|
* Authorization to flip a project to `public`. The `ALLOW_CROSS_ORG_PUBLIC`
|
|
@@ -113,6 +122,8 @@ export function canEditDefinition(input) {
|
|
|
113
122
|
const { project, definition, member, orgMember, userId, platformPermissions, enablePlatformProjects } = input;
|
|
114
123
|
if (!project || !definition)
|
|
115
124
|
return false;
|
|
125
|
+
if (definition.projectId !== project.id)
|
|
126
|
+
return false;
|
|
116
127
|
if (project.visibility === 'platform') {
|
|
117
128
|
if (!enablePlatformProjects)
|
|
118
129
|
return false;
|
|
@@ -166,18 +177,12 @@ export function canCreateProject(input) {
|
|
|
166
177
|
return false;
|
|
167
178
|
}
|
|
168
179
|
/**
|
|
169
|
-
* Whether the actor may hand out or take away org `owner`/`admin` standing
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
* existing member's role, and removing an owner — and all three had written it
|
|
173
|
-
* out longhand. Two of them had drifted by the time the access audit found
|
|
174
|
-
* them: the invite route let an admin mint an `owner` invite for themselves,
|
|
175
|
-
* and DELETE let an admin remove an owner that PATCH would not let them demote.
|
|
176
|
-
* They are one rule, so they read it from one place.
|
|
180
|
+
* Whether the actor may hand out or take away org `owner`/`admin` standing.
|
|
181
|
+
* Inviting someone as owner/admin, changing a member's role and removing an owner
|
|
182
|
+
* are one rule, so all three read it here.
|
|
177
183
|
*
|
|
178
|
-
* Reads the actor's **membership row**. `Organization.ownerId` is a separate
|
|
179
|
-
*
|
|
180
|
-
* is not authority for this decision.
|
|
184
|
+
* Reads the actor's **membership row**. `Organization.ownerId` is a separate field
|
|
185
|
+
* that can disagree with it and is not authority for this decision.
|
|
181
186
|
*/
|
|
182
187
|
export function canChangeOrgRole(input) {
|
|
183
188
|
if (input.role === 'member')
|
|
@@ -194,4 +199,3 @@ export function checkOwnerRemoval(input) {
|
|
|
194
199
|
return 'needs_confirm';
|
|
195
200
|
return 'ok';
|
|
196
201
|
}
|
|
197
|
-
//# sourceMappingURL=rules.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export type { ApiScope, ApiScopeAction, ApiScopeResource, ApiToken, ApiTokenSummary, ApiTokenRevokeReason, ApiTokenLifetimeDays } from './types.js';
|
|
2
|
-
export { ApiScopeActionSchema, ApiScopeStringSchema,
|
|
2
|
+
export { ApiScopeActionSchema, ApiScopeStringSchema, API_TOKEN_LIFETIME_DAYS, parseApiScope, formatApiScope, describeApiScope } from './types.js';
|
|
3
3
|
export type { IApiTokenStore } from './interface.js';
|
|
4
4
|
export type { ScopeTarget } from './scope.js';
|
|
5
|
-
export { scopeAllows, narrowApiTokenContext, outsideTokenOrg } from './scope.js';
|
|
6
|
-
//# sourceMappingURL=index.d.ts.map
|
|
5
|
+
export { scopeAllows, apiScopeActionCovers, narrowApiTokenContext, outsideTokenOrg } from './scope.js';
|
package/dist/apiTokens/index.js
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export { ApiScopeActionSchema, ApiScopeStringSchema,
|
|
2
|
-
export { scopeAllows, narrowApiTokenContext, outsideTokenOrg } from './scope.js';
|
|
3
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export { ApiScopeActionSchema, ApiScopeStringSchema, API_TOKEN_LIFETIME_DAYS, parseApiScope, formatApiScope, describeApiScope } from './types.js';
|
|
2
|
+
export { scopeAllows, apiScopeActionCovers, narrowApiTokenContext, outsideTokenOrg } from './scope.js';
|
|
@@ -14,6 +14,8 @@ export interface ScopeTarget {
|
|
|
14
14
|
* checked elsewhere.
|
|
15
15
|
*/
|
|
16
16
|
export declare function scopeAllows(ctx: RequestContext, action: ApiScopeAction, target?: ScopeTarget): boolean;
|
|
17
|
+
/** Does a scope granting `granted` allow `wanted`? */
|
|
18
|
+
export declare function apiScopeActionCovers(granted: ApiScopeAction, wanted: ApiScopeAction): boolean;
|
|
17
19
|
/**
|
|
18
20
|
* Narrow the owner's live context to what the token grants. Only removes
|
|
19
21
|
* rights:
|
|
@@ -24,7 +26,7 @@ export declare function scopeAllows(ctx: RequestContext, action: ApiScopeAction,
|
|
|
24
26
|
*
|
|
25
27
|
* Scopes this version can't parse are dropped, so they grant nothing.
|
|
26
28
|
*/
|
|
27
|
-
export declare function narrowApiTokenContext(ctx: RequestContext, token: Pick<ApiToken, 'id' | 'orgId' | 'scopes'>): RequestContext;
|
|
29
|
+
export declare function narrowApiTokenContext(ctx: RequestContext, token: Pick<ApiToken, 'id' | 'orgId' | 'scopes' | 'expiresAt'>): RequestContext;
|
|
28
30
|
/**
|
|
29
31
|
* True when an API-token request reaches for something owned by an org other
|
|
30
32
|
* than the token's. A token is bound to one org, so that resource doesn't
|
|
@@ -32,4 +34,3 @@ export declare function narrowApiTokenContext(ctx: RequestContext, token: Pick<A
|
|
|
32
34
|
* not found. Session requests are never outside.
|
|
33
35
|
*/
|
|
34
36
|
export declare function outsideTokenOrg(ctx: RequestContext, orgId: string): boolean;
|
|
35
|
-
//# sourceMappingURL=scope.d.ts.map
|
package/dist/apiTokens/scope.js
CHANGED
|
@@ -12,10 +12,11 @@ export function scopeAllows(ctx, action, target) {
|
|
|
12
12
|
const api = ctx.apiScope;
|
|
13
13
|
if (!api)
|
|
14
14
|
return true;
|
|
15
|
-
return api.scopes.some((s) =>
|
|
15
|
+
return api.scopes.some((s) => apiScopeActionCovers(s.action, action) && resourceCovers(s, ctx, target));
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
/** Does a scope granting `granted` allow `wanted`? */
|
|
18
|
+
export function apiScopeActionCovers(granted, wanted) {
|
|
19
|
+
return granted === wanted || wanted === 'read' || (granted === 'write' && wanted === 'upload');
|
|
19
20
|
}
|
|
20
21
|
function resourceCovers(scope, ctx, target) {
|
|
21
22
|
const { resource } = scope;
|
|
@@ -45,7 +46,11 @@ export function narrowApiTokenContext(ctx, token) {
|
|
|
45
46
|
throw new ProviderError('API token context must act in the token’s org', 500);
|
|
46
47
|
}
|
|
47
48
|
const scopes = token.scopes.map(parseApiScope).filter((s) => s !== null);
|
|
48
|
-
return {
|
|
49
|
+
return {
|
|
50
|
+
...ctx,
|
|
51
|
+
platformPermissions: [],
|
|
52
|
+
apiScope: { tokenId: token.id, scopes, expiresAt: token.expiresAt }
|
|
53
|
+
};
|
|
49
54
|
}
|
|
50
55
|
/**
|
|
51
56
|
* True when an API-token request reaches for something owned by an org other
|
|
@@ -56,4 +61,3 @@ export function narrowApiTokenContext(ctx, token) {
|
|
|
56
61
|
export function outsideTokenOrg(ctx, orgId) {
|
|
57
62
|
return ctx.apiScope !== undefined && orgId !== ctx.actingOrgId;
|
|
58
63
|
}
|
|
59
|
-
//# sourceMappingURL=scope.js.map
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* `write`, `solve` and `upload` each include `read`, and `write` includes
|
|
4
|
+
* `upload`. `upload` covers only creating definitions, uploading versions,
|
|
5
|
+
* checking a file's schema before upload and making a version live: it can't
|
|
6
|
+
* edit metadata, delete or share.
|
|
7
|
+
*/
|
|
3
8
|
export declare const ApiScopeActionSchema: z.ZodEnum<{
|
|
4
9
|
read: "read";
|
|
5
10
|
write: "write";
|
|
6
11
|
solve: "solve";
|
|
12
|
+
upload: "upload";
|
|
7
13
|
}>;
|
|
8
14
|
export type ApiScopeAction = z.infer<typeof ApiScopeActionSchema>;
|
|
9
15
|
/**
|
|
@@ -76,4 +82,3 @@ export declare const API_TOKEN_LIFETIME_DAYS: readonly [30, 90, 180];
|
|
|
76
82
|
export type ApiTokenLifetimeDays = (typeof API_TOKEN_LIFETIME_DAYS)[number];
|
|
77
83
|
/** "Read and change everything in the org". Names no ids, so it suits an email. */
|
|
78
84
|
export declare function describeApiScope(value: string): string;
|
|
79
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/apiTokens/types.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
/**
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* `write`, `solve` and `upload` each include `read`, and `write` includes
|
|
4
|
+
* `upload`. `upload` covers only creating definitions, uploading versions,
|
|
5
|
+
* checking a file's schema before upload and making a version live: it can't
|
|
6
|
+
* edit metadata, delete or share.
|
|
7
|
+
*/
|
|
8
|
+
export const ApiScopeActionSchema = z.enum(['read', 'write', 'solve', 'upload']);
|
|
4
9
|
// Ids are uuids or guids in practice; the charset only has to keep `:` out so
|
|
5
10
|
// the string form stays unambiguous.
|
|
6
|
-
const SCOPE_PATTERN = /^(read|write|solve):(all|(org|project|definition):([A-Za-z0-9_-]{1,128}))$/;
|
|
11
|
+
const SCOPE_PATTERN = /^(read|write|solve|upload):(all|(org|project|definition):([A-Za-z0-9_-]{1,128}))$/;
|
|
7
12
|
/** `read:all`, `write:org:<id>`, `solve:project:<id>`, `read:definition:<guid>`. */
|
|
8
13
|
export function parseApiScope(value) {
|
|
9
14
|
const m = SCOPE_PATTERN.exec(value);
|
|
@@ -37,7 +42,8 @@ export const API_TOKEN_LIFETIME_DAYS = [30, 90, 180];
|
|
|
37
42
|
const ACTION_WORDS = {
|
|
38
43
|
read: 'Read',
|
|
39
44
|
write: 'Read and change',
|
|
40
|
-
solve: 'Read and run solves on'
|
|
45
|
+
solve: 'Read and run solves on',
|
|
46
|
+
upload: 'Read and upload definitions to'
|
|
41
47
|
};
|
|
42
48
|
/** "Read and change everything in the org". Names no ids, so it suits an email. */
|
|
43
49
|
export function describeApiScope(value) {
|
|
@@ -51,4 +57,3 @@ export function describeApiScope(value) {
|
|
|
51
57
|
: 'everything in the org';
|
|
52
58
|
return `${ACTION_WORDS[scope.action]} ${what}`;
|
|
53
59
|
}
|
|
54
|
-
//# sourceMappingURL=types.js.map
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
export type { AuthUser, UserManagementResult, LoginResult } from './types.js';
|
|
2
2
|
export type { IAuthProvider, IOAuthAuth, ISessionRefresh, IPasswordAuth, IEmailLinkAuth, IProxyAuth, IDelegatedSession, DelegatedSessionStatus } from './interface.js';
|
|
3
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/auth/index.js
CHANGED
package/dist/auth/interface.d.ts
CHANGED
|
@@ -30,9 +30,8 @@ export interface IPasswordAuth {
|
|
|
30
30
|
* `getOAuthAuthorizationUrl` and 303s to the result.
|
|
31
31
|
* 2. IdP redirects back to `/auth/{provider}/callback?code=...` → server
|
|
32
32
|
* calls `exchangeOAuthCode` to mint the session pair.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* without bouncing the user.
|
|
33
|
+
*
|
|
34
|
+
* Keeping the session alive afterwards is `ISessionRefresh`'s job.
|
|
36
35
|
*
|
|
37
36
|
* Each method returns `null` rather than throwing on irrecoverable
|
|
38
37
|
* credential failures, so the route layer can pick the right HTTP shape
|
|
@@ -64,23 +63,6 @@ export interface IOAuthAuth {
|
|
|
64
63
|
sessionToken: string;
|
|
65
64
|
refreshToken: string;
|
|
66
65
|
} | null>;
|
|
67
|
-
/**
|
|
68
|
-
* Swap a refresh token for a fresh access/refresh pair. Returns null on
|
|
69
|
-
* irrecoverable failure (revoked, expired, signed by a different secret);
|
|
70
|
-
* the session-refresh middleware treats null as "force re-login" by
|
|
71
|
-
* clearing the refresh cookie.
|
|
72
|
-
*
|
|
73
|
-
* @deprecated Session refresh is session lifecycle, not OAuth — a consumer
|
|
74
|
-
* that brokers no OAuth still needs it (refreshing a password session, or
|
|
75
|
-
* revoking on logout). Moved to `IAuthProvider.sessionRefresh`
|
|
76
|
-
* (`ISessionRefresh`). This member delegates for one release and will be
|
|
77
|
-
* removed in the next minor; migrate callers to
|
|
78
|
-
* `auth.sessionRefresh?.refreshSession(...)`.
|
|
79
|
-
*/
|
|
80
|
-
refreshSession(refreshToken: string): Promise<{
|
|
81
|
-
sessionToken: string;
|
|
82
|
-
refreshToken: string;
|
|
83
|
-
} | null>;
|
|
84
66
|
}
|
|
85
67
|
/**
|
|
86
68
|
* Optional session-lifecycle surface: refresh an expiring session, revoke one
|
|
@@ -245,8 +227,8 @@ export interface IDelegatedSession {
|
|
|
245
227
|
*/
|
|
246
228
|
status(): Promise<DelegatedSessionStatus>;
|
|
247
229
|
/**
|
|
248
|
-
* A session token acting as `userId` inside `orgId`, valid for
|
|
249
|
-
*
|
|
230
|
+
* A session token acting as `userId` inside `orgId`, valid for `ttlSeconds`
|
|
231
|
+
* (default 60 s). It carries no instance-admin rights, whatever the user holds: those
|
|
250
232
|
* never ride on a bearer key. Throws if `status` isn't ok.
|
|
251
233
|
*/
|
|
252
234
|
mint(userId: string, opts: {
|
|
@@ -327,4 +309,3 @@ export interface IAuthProvider {
|
|
|
327
309
|
*/
|
|
328
310
|
touchLastLogin?(id: string): Promise<void>;
|
|
329
311
|
}
|
|
330
|
-
//# sourceMappingURL=interface.d.ts.map
|
package/dist/auth/interface.js
CHANGED
package/dist/auth/types.d.ts
CHANGED
|
@@ -21,7 +21,10 @@ export interface AuthUser {
|
|
|
21
21
|
* - `last_admin` — refused; would leave zero `instance_admin` users
|
|
22
22
|
*/
|
|
23
23
|
export type UserManagementResult = 'ok' | 'not_found' | 'not_supported' | 'last_admin';
|
|
24
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* `success` includes the session token the provider minted. `rate_limited` is for
|
|
26
|
+
* providers that throttle logins; no bundled provider returns it.
|
|
27
|
+
*/
|
|
25
28
|
export type LoginResult = {
|
|
26
29
|
kind: 'success';
|
|
27
30
|
user: AuthUser;
|
|
@@ -30,4 +33,3 @@ export type LoginResult = {
|
|
|
30
33
|
kind: 'failed';
|
|
31
34
|
reason?: 'invalid_credentials' | 'disabled' | 'rate_limited';
|
|
32
35
|
};
|
|
33
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/auth/types.js
CHANGED
package/dist/bindings/index.d.ts
CHANGED
package/dist/bindings/index.js
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
export { isPlatformServer, isOrgServer } from './types.js';
|
|
3
|
-
export type { IComputeServerStore, GetConfigOptions } from './interface.js';
|
|
1
|
+
export * from './public.js';
|
|
4
2
|
export { isEncryptedSecret, encryptSecret, decryptSecret, decodeSecretKey } from './secrets.js';
|
|
5
|
-
export type { SecretVerificationReport, SecretVerificationFailure, SecretVerificationFailureReason } from './secrets.js';
|
|
6
|
-
export type { ResolveOptions } from './utils.js';
|
|
7
|
-
export { serversVisibleTo, defaultServerIdFor, resolveServerForOrg, findServerById, platformServers, orgServersFor, scopeConfigToOrg } from './utils.js';
|
|
8
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
//
|
|
3
|
-
// re-exported from the root barrel, which client `.svelte` code imports and
|
|
4
|
-
// where a browser bundle can't resolve `node:crypto`. Import these from
|
|
5
|
-
// `@selvajs/platform/computeServer` in server code. The report TYPES are erased
|
|
6
|
-
// at build, so they also stay re-exported from the root barrel for convenience.
|
|
1
|
+
export * from './public.js';
|
|
2
|
+
// Server-only: import these from `@selvajs/platform/computeServer`.
|
|
7
3
|
export { isEncryptedSecret, encryptSecret, decryptSecret, decodeSecretKey } from './secrets.js';
|
|
8
|
-
export { serversVisibleTo, defaultServerIdFor, resolveServerForOrg, findServerById, platformServers, orgServersFor, scopeConfigToOrg } from './utils.js';
|
|
9
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -28,10 +28,9 @@ export interface GetConfigOptions {
|
|
|
28
28
|
*
|
|
29
29
|
* Org-facing surfaces must pass this. Without it the store hands back every
|
|
30
30
|
* platform server and every *other* org's private servers, leaving each
|
|
31
|
-
* caller to re-apply a filter it can silently forget
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* deliberately; they act instance-wide.
|
|
31
|
+
* caller to re-apply a filter it can silently forget. Admin surfaces, boot
|
|
32
|
+
* health and the save-diff handlers omit it deliberately; they act
|
|
33
|
+
* instance-wide.
|
|
35
34
|
*/
|
|
36
35
|
scopeToOrgId?: string;
|
|
37
36
|
}
|
|
@@ -53,6 +52,10 @@ export interface IComputeServerStore {
|
|
|
53
52
|
* authenticated under the current `SELVA_AT_REST_KEY` (the solve fails
|
|
54
53
|
* later at Rhino.Compute rather than here).
|
|
55
54
|
*
|
|
55
|
+
* A plaintext key at rest is adapter-defined: local throws, because it never
|
|
56
|
+
* writes one, and Supabase warns and returns it, because rows can predate
|
|
57
|
+
* encryption. Both report it through `verifySecrets`.
|
|
58
|
+
*
|
|
56
59
|
* The narrow path onto the solve hot path: resolve a server from the
|
|
57
60
|
* key-free config, then fetch that one key.
|
|
58
61
|
*/
|
|
@@ -61,7 +64,8 @@ export interface IComputeServerStore {
|
|
|
61
64
|
savePlatformServers(ctx: RequestContext, servers: ComputeServerConfig[], defaultServerId: string | undefined): Promise<void>;
|
|
62
65
|
/**
|
|
63
66
|
* Replaces the org-private server set for `orgId` and (optionally) updates
|
|
64
|
-
* `orgDefaults[orgId]`. Platform rows are left untouched
|
|
67
|
+
* `orgDefaults[orgId]`. Platform rows are left untouched, and any non-org entry
|
|
68
|
+
* in `servers` is ignored.
|
|
65
69
|
*
|
|
66
70
|
* `defaultServerId: null` clears the org's override; `undefined` leaves
|
|
67
71
|
* the existing value alone.
|
|
@@ -90,4 +94,3 @@ export interface IComputeServerStore {
|
|
|
90
94
|
*/
|
|
91
95
|
verifySecrets?(): Promise<SecretVerificationReport>;
|
|
92
96
|
}
|
|
93
|
-
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { ComputeServerConfig, ComputeConfig, PlatformComputeServer, OrgComputeServer } from './types.js';
|
|
2
|
+
export { COMPUTE_RETRY_MAX, COMPUTE_TIMEOUT_DEFAULT_MS, COMPUTE_TIMEOUT_MAX_MS, COMPUTE_TIMEOUT_MIN_MS, isPlatformServer, isOrgServer } from './types.js';
|
|
3
|
+
export type { IComputeServerStore, GetConfigOptions } from './interface.js';
|
|
4
|
+
export type { ResolveOptions } from './utils.js';
|
|
5
|
+
export { serversVisibleTo, defaultServerIdFor, clampRetryCount, clampTimeoutMs, pickServer, resolveServerForOrg, findServerById, platformServers, scopeConfigToOrg } from './utils.js';
|
|
6
|
+
export type { SecretVerificationReport, SecretVerificationFailure, SecretVerificationFailureReason } from './secrets.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { COMPUTE_RETRY_MAX, COMPUTE_TIMEOUT_DEFAULT_MS, COMPUTE_TIMEOUT_MAX_MS, COMPUTE_TIMEOUT_MIN_MS, isPlatformServer, isOrgServer } from './types.js';
|
|
2
|
+
export { serversVisibleTo, defaultServerIdFor, clampRetryCount, clampTimeoutMs, pickServer, resolveServerForOrg, findServerById, platformServers, scopeConfigToOrg } from './utils.js';
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
export declare function isEncryptedSecret(value: string): boolean;
|
|
1
2
|
/**
|
|
2
3
|
* AES-256-GCM envelope for at-rest secrets (e.g. compute API keys).
|
|
3
4
|
*
|
|
4
|
-
* Wire format: `enc:
|
|
5
|
-
*
|
|
5
|
+
* Wire format: `enc:v2:<base64(iv|tag|ciphertext)>`. `v2` authenticates the
|
|
6
|
+
* record the secret belongs to as AAD, so ciphertext copied onto another record
|
|
7
|
+
* fails to decrypt instead of handing the plaintext to that record's URL.
|
|
8
|
+
* `enc:v1:` envelopes have no AAD and still read: a store rewrites them as `v2`
|
|
9
|
+
* on its next save.
|
|
6
10
|
*
|
|
7
11
|
* Defends against backup leaks, accidental file/DB sharing, and read-only
|
|
8
12
|
* storage access — not against an attacker who also has the master key
|
|
@@ -11,10 +15,13 @@
|
|
|
11
15
|
*
|
|
12
16
|
* Pure `node:crypto`, no fs or DB coupling, so the local and Supabase
|
|
13
17
|
* compute-server stores share this one implementation.
|
|
18
|
+
*
|
|
19
|
+
* Pass `aad` to bind the secret to its record. {@link decryptSecret} then needs the
|
|
20
|
+
* same value.
|
|
14
21
|
*/
|
|
15
|
-
export declare function
|
|
16
|
-
|
|
17
|
-
export declare function decryptSecret(envelope: string, key: Buffer): string;
|
|
22
|
+
export declare function encryptSecret(plaintext: string, key: Buffer, aad?: string): string;
|
|
23
|
+
/** `aad` is ignored for an `enc:v1:` envelope and required for an `enc:v2:` one. */
|
|
24
|
+
export declare function decryptSecret(envelope: string, key: Buffer, aad?: string): string;
|
|
18
25
|
/**
|
|
19
26
|
* Decodes a `SELVA_AT_REST_KEY` env var into a 32-byte buffer (64-char hex or
|
|
20
27
|
* base64, with or without padding). Throws on anything else so a
|
|
@@ -46,4 +53,3 @@ export interface SecretVerificationReport {
|
|
|
46
53
|
/** True if at least one row holds an unencrypted apiKey at rest. */
|
|
47
54
|
plaintextFound: boolean;
|
|
48
55
|
}
|
|
49
|
-
//# sourceMappingURL=secrets.d.ts.map
|