@opendatalabs/personal-server-ts-core 0.0.1-canary.00328bf
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/api/index.d.ts +408 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +1257 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/raw-envelope.d.ts +3 -0
- package/dist/api/raw-envelope.d.ts.map +1 -0
- package/dist/api/raw-envelope.js +215 -0
- package/dist/api/raw-envelope.js.map +1 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/request.d.ts +28 -0
- package/dist/auth/request.d.ts.map +1 -0
- package/dist/auth/request.js +106 -0
- package/dist/auth/request.js.map +1 -0
- package/dist/client.d.ts +233 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +243 -0
- package/dist/client.js.map +1 -0
- package/dist/config/defaults.d.ts +12 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +12 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +3 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/paths.d.ts +9 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +14 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/contracts/access-logs.d.ts +8 -0
- package/dist/contracts/access-logs.d.ts.map +1 -0
- package/dist/contracts/access-logs.js +7 -0
- package/dist/contracts/access-logs.js.map +1 -0
- package/dist/contracts/auth-device.d.ts +70 -0
- package/dist/contracts/auth-device.d.ts.map +1 -0
- package/dist/contracts/auth-device.js +163 -0
- package/dist/contracts/auth-device.js.map +1 -0
- package/dist/contracts/binary.d.ts +66 -0
- package/dist/contracts/binary.d.ts.map +1 -0
- package/dist/contracts/binary.js +123 -0
- package/dist/contracts/binary.js.map +1 -0
- package/dist/contracts/config.d.ts +5 -0
- package/dist/contracts/config.d.ts.map +1 -0
- package/dist/contracts/config.js +30 -0
- package/dist/contracts/config.js.map +1 -0
- package/dist/contracts/data.d.ts +165 -0
- package/dist/contracts/data.d.ts.map +1 -0
- package/dist/contracts/data.js +371 -0
- package/dist/contracts/data.js.map +1 -0
- package/dist/contracts/grants.d.ts +45 -0
- package/dist/contracts/grants.d.ts.map +1 -0
- package/dist/contracts/grants.js +177 -0
- package/dist/contracts/grants.js.map +1 -0
- package/dist/contracts/http.d.ts +21 -0
- package/dist/contracts/http.d.ts.map +1 -0
- package/dist/contracts/http.js +49 -0
- package/dist/contracts/http.js.map +1 -0
- package/dist/contracts/index.d.ts +16 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +10 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/oauth.d.ts +38 -0
- package/dist/contracts/oauth.d.ts.map +1 -0
- package/dist/contracts/oauth.js +130 -0
- package/dist/contracts/oauth.js.map +1 -0
- package/dist/contracts/sync.d.ts +10 -0
- package/dist/contracts/sync.d.ts.map +1 -0
- package/dist/contracts/sync.js +35 -0
- package/dist/contracts/sync.js.map +1 -0
- package/dist/derivatives/answer-shape.d.ts +83 -0
- package/dist/derivatives/answer-shape.d.ts.map +1 -0
- package/dist/derivatives/answer-shape.js +320 -0
- package/dist/derivatives/answer-shape.js.map +1 -0
- package/dist/derivatives/api.d.ts +48 -0
- package/dist/derivatives/api.d.ts.map +1 -0
- package/dist/derivatives/api.js +374 -0
- package/dist/derivatives/api.js.map +1 -0
- package/dist/derivatives/compute.d.ts +112 -0
- package/dist/derivatives/compute.d.ts.map +1 -0
- package/dist/derivatives/compute.js +476 -0
- package/dist/derivatives/compute.js.map +1 -0
- package/dist/derivatives/e2ee/aad.d.ts +22 -0
- package/dist/derivatives/e2ee/aad.d.ts.map +1 -0
- package/dist/derivatives/e2ee/aad.js +32 -0
- package/dist/derivatives/e2ee/aad.js.map +1 -0
- package/dist/derivatives/e2ee/attestation.d.ts +134 -0
- package/dist/derivatives/e2ee/attestation.d.ts.map +1 -0
- package/dist/derivatives/e2ee/attestation.js +248 -0
- package/dist/derivatives/e2ee/attestation.js.map +1 -0
- package/dist/derivatives/e2ee/index.d.ts +6 -0
- package/dist/derivatives/e2ee/index.d.ts.map +1 -0
- package/dist/derivatives/e2ee/index.js +6 -0
- package/dist/derivatives/e2ee/index.js.map +1 -0
- package/dist/derivatives/e2ee/jcs.d.ts +17 -0
- package/dist/derivatives/e2ee/jcs.d.ts.map +1 -0
- package/dist/derivatives/e2ee/jcs.js +55 -0
- package/dist/derivatives/e2ee/jcs.js.map +1 -0
- package/dist/derivatives/e2ee/phala.d.ts +62 -0
- package/dist/derivatives/e2ee/phala.d.ts.map +1 -0
- package/dist/derivatives/e2ee/phala.js +168 -0
- package/dist/derivatives/e2ee/phala.js.map +1 -0
- package/dist/derivatives/e2ee/suite.d.ts +56 -0
- package/dist/derivatives/e2ee/suite.d.ts.map +1 -0
- package/dist/derivatives/e2ee/suite.js +164 -0
- package/dist/derivatives/e2ee/suite.js.map +1 -0
- package/dist/derivatives/index.d.ts +11 -0
- package/dist/derivatives/index.d.ts.map +1 -0
- package/dist/derivatives/index.js +11 -0
- package/dist/derivatives/index.js.map +1 -0
- package/dist/derivatives/inference.d.ts +151 -0
- package/dist/derivatives/inference.d.ts.map +1 -0
- package/dist/derivatives/inference.js +262 -0
- package/dist/derivatives/inference.js.map +1 -0
- package/dist/derivatives/prompt.d.ts +99 -0
- package/dist/derivatives/prompt.d.ts.map +1 -0
- package/dist/derivatives/prompt.js +281 -0
- package/dist/derivatives/prompt.js.map +1 -0
- package/dist/derivatives/registration.d.ts +56 -0
- package/dist/derivatives/registration.d.ts.map +1 -0
- package/dist/derivatives/registration.js +187 -0
- package/dist/derivatives/registration.js.map +1 -0
- package/dist/derivatives/scheduler.d.ts +114 -0
- package/dist/derivatives/scheduler.d.ts.map +1 -0
- package/dist/derivatives/scheduler.js +331 -0
- package/dist/derivatives/scheduler.js.map +1 -0
- package/dist/derivatives/store.d.ts +14 -0
- package/dist/derivatives/store.d.ts.map +1 -0
- package/dist/derivatives/store.js +79 -0
- package/dist/derivatives/store.js.map +1 -0
- package/dist/derivatives/types.d.ts +102 -0
- package/dist/derivatives/types.d.ts.map +1 -0
- package/dist/derivatives/types.js +29 -0
- package/dist/derivatives/types.js.map +1 -0
- package/dist/errors/catalog.d.ts +125 -0
- package/dist/errors/catalog.d.ts.map +1 -0
- package/dist/errors/catalog.js +198 -0
- package/dist/errors/catalog.js.map +1 -0
- package/dist/errors/pdpp-catalog.d.ts +36 -0
- package/dist/errors/pdpp-catalog.d.ts.map +1 -0
- package/dist/errors/pdpp-catalog.js +82 -0
- package/dist/errors/pdpp-catalog.js.map +1 -0
- package/dist/grants/index.d.ts +5 -0
- package/dist/grants/index.d.ts.map +1 -0
- package/dist/grants/index.js +6 -0
- package/dist/grants/index.js.map +1 -0
- package/dist/grants/pdpp-binding-store.d.ts +58 -0
- package/dist/grants/pdpp-binding-store.d.ts.map +1 -0
- package/dist/grants/pdpp-binding-store.js +97 -0
- package/dist/grants/pdpp-binding-store.js.map +1 -0
- package/dist/grants/pdpp-binding.d.ts +179 -0
- package/dist/grants/pdpp-binding.d.ts.map +1 -0
- package/dist/grants/pdpp-binding.js +214 -0
- package/dist/grants/pdpp-binding.js.map +1 -0
- package/dist/keys/index.d.ts +3 -0
- package/dist/keys/index.d.ts.map +1 -0
- package/dist/keys/index.js +2 -0
- package/dist/keys/index.js.map +1 -0
- package/dist/keys/public-only-account.d.ts +8 -0
- package/dist/keys/public-only-account.d.ts.map +1 -0
- package/dist/keys/public-only-account.js +21 -0
- package/dist/keys/public-only-account.js.map +1 -0
- package/dist/keys/server-account.d.ts +24 -0
- package/dist/keys/server-account.d.ts.map +1 -0
- package/dist/keys/server-account.js +2 -0
- package/dist/keys/server-account.js.map +1 -0
- package/dist/lineage/attestation.d.ts +42 -0
- package/dist/lineage/attestation.d.ts.map +1 -0
- package/dist/lineage/attestation.js +25 -0
- package/dist/lineage/attestation.js.map +1 -0
- package/dist/lineage/gateway.d.ts +105 -0
- package/dist/lineage/gateway.d.ts.map +1 -0
- package/dist/lineage/gateway.js +242 -0
- package/dist/lineage/gateway.js.map +1 -0
- package/dist/lineage/index.d.ts +5 -0
- package/dist/lineage/index.d.ts.map +1 -0
- package/dist/lineage/index.js +5 -0
- package/dist/lineage/index.js.map +1 -0
- package/dist/lineage/lineage.d.ts +141 -0
- package/dist/lineage/lineage.d.ts.map +1 -0
- package/dist/lineage/lineage.js +255 -0
- package/dist/lineage/lineage.js.map +1 -0
- package/dist/logger/index.d.ts +9 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +5 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logging/access-log.d.ts +23 -0
- package/dist/logging/access-log.d.ts.map +1 -0
- package/dist/logging/access-log.js +2 -0
- package/dist/logging/access-log.js.map +1 -0
- package/dist/logging/access-reader.d.ts +14 -0
- package/dist/logging/access-reader.d.ts.map +1 -0
- package/dist/logging/access-reader.js +2 -0
- package/dist/logging/access-reader.js.map +1 -0
- package/dist/mcp/activity.d.ts +68 -0
- package/dist/mcp/activity.d.ts.map +1 -0
- package/dist/mcp/activity.js +111 -0
- package/dist/mcp/activity.js.map +1 -0
- package/dist/mcp/builder-registration.d.ts +24 -0
- package/dist/mcp/builder-registration.d.ts.map +1 -0
- package/dist/mcp/builder-registration.js +89 -0
- package/dist/mcp/builder-registration.js.map +1 -0
- package/dist/mcp/connection-api.d.ts +201 -0
- package/dist/mcp/connection-api.d.ts.map +1 -0
- package/dist/mcp/connection-api.js +506 -0
- package/dist/mcp/connection-api.js.map +1 -0
- package/dist/mcp/grantee.d.ts +52 -0
- package/dist/mcp/grantee.d.ts.map +1 -0
- package/dist/mcp/grantee.js +91 -0
- package/dist/mcp/grantee.js.map +1 -0
- package/dist/mcp/index.d.ts +12 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +12 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/read-client.d.ts +176 -0
- package/dist/mcp/read-client.d.ts.map +1 -0
- package/dist/mcp/read-client.js +579 -0
- package/dist/mcp/read-client.js.map +1 -0
- package/dist/mcp/resources.d.ts +37 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +114 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/search/index.d.ts +34 -0
- package/dist/mcp/search/index.d.ts.map +1 -0
- package/dist/mcp/search/index.js +156 -0
- package/dist/mcp/search/index.js.map +1 -0
- package/dist/mcp/server.d.ts +72 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +447 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/session.d.ts +160 -0
- package/dist/mcp/session.d.ts.map +1 -0
- package/dist/mcp/session.js +243 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/mcp/store.d.ts +13 -0
- package/dist/mcp/store.d.ts.map +1 -0
- package/dist/mcp/store.js +119 -0
- package/dist/mcp/store.js.map +1 -0
- package/dist/mcp/token-expiry.d.ts +38 -0
- package/dist/mcp/token-expiry.d.ts.map +1 -0
- package/dist/mcp/token-expiry.js +55 -0
- package/dist/mcp/token-expiry.js.map +1 -0
- package/dist/mcp/tools.d.ts +95 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +1381 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/types.d.ts +135 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +24 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/payment/index.d.ts +2 -0
- package/dist/payment/index.d.ts.map +1 -0
- package/dist/payment/index.js +2 -0
- package/dist/payment/index.js.map +1 -0
- package/dist/payment/x402.d.ts +155 -0
- package/dist/payment/x402.d.ts.map +1 -0
- package/dist/payment/x402.js +402 -0
- package/dist/payment/x402.js.map +1 -0
- package/dist/pdpp/approval.d.ts +182 -0
- package/dist/pdpp/approval.d.ts.map +1 -0
- package/dist/pdpp/approval.js +337 -0
- package/dist/pdpp/approval.js.map +1 -0
- package/dist/pdpp/client-identity.d.ts +88 -0
- package/dist/pdpp/client-identity.d.ts.map +1 -0
- package/dist/pdpp/client-identity.js +183 -0
- package/dist/pdpp/client-identity.js.map +1 -0
- package/dist/pdpp/client-metadata.d.ts +95 -0
- package/dist/pdpp/client-metadata.d.ts.map +1 -0
- package/dist/pdpp/client-metadata.js +96 -0
- package/dist/pdpp/client-metadata.js.map +1 -0
- package/dist/pdpp/declaration.d.ts +118 -0
- package/dist/pdpp/declaration.d.ts.map +1 -0
- package/dist/pdpp/declaration.js +549 -0
- package/dist/pdpp/declaration.js.map +1 -0
- package/dist/pdpp/index.d.ts +35 -0
- package/dist/pdpp/index.d.ts.map +1 -0
- package/dist/pdpp/index.js +22 -0
- package/dist/pdpp/index.js.map +1 -0
- package/dist/pdpp/issuance.d.ts +91 -0
- package/dist/pdpp/issuance.d.ts.map +1 -0
- package/dist/pdpp/issuance.js +124 -0
- package/dist/pdpp/issuance.js.map +1 -0
- package/dist/pdpp/pkce.d.ts +53 -0
- package/dist/pdpp/pkce.d.ts.map +1 -0
- package/dist/pdpp/pkce.js +109 -0
- package/dist/pdpp/pkce.js.map +1 -0
- package/dist/pdpp/redirect.d.ts +60 -0
- package/dist/pdpp/redirect.d.ts.map +1 -0
- package/dist/pdpp/redirect.js +125 -0
- package/dist/pdpp/redirect.js.map +1 -0
- package/dist/pdpp/resolve.d.ts +53 -0
- package/dist/pdpp/resolve.d.ts.map +1 -0
- package/dist/pdpp/resolve.js +218 -0
- package/dist/pdpp/resolve.js.map +1 -0
- package/dist/pdpp/review.d.ts +155 -0
- package/dist/pdpp/review.d.ts.map +1 -0
- package/dist/pdpp/review.js +142 -0
- package/dist/pdpp/review.js.map +1 -0
- package/dist/pdpp/selection.d.ts +43 -0
- package/dist/pdpp/selection.d.ts.map +1 -0
- package/dist/pdpp/selection.js +211 -0
- package/dist/pdpp/selection.js.map +1 -0
- package/dist/pdpp/store.d.ts +204 -0
- package/dist/pdpp/store.d.ts.map +1 -0
- package/dist/pdpp/store.js +501 -0
- package/dist/pdpp/store.js.map +1 -0
- package/dist/pdpp/tokens.d.ts +149 -0
- package/dist/pdpp/tokens.d.ts.map +1 -0
- package/dist/pdpp/tokens.js +387 -0
- package/dist/pdpp/tokens.js.map +1 -0
- package/dist/pdpp/types.d.ts +258 -0
- package/dist/pdpp/types.d.ts.map +1 -0
- package/dist/pdpp/types.js +40 -0
- package/dist/pdpp/types.js.map +1 -0
- package/dist/pdpp-version.d.ts +28 -0
- package/dist/pdpp-version.d.ts.map +1 -0
- package/dist/pdpp-version.js +28 -0
- package/dist/pdpp-version.js.map +1 -0
- package/dist/policy/data-read.d.ts +56 -0
- package/dist/policy/data-read.d.ts.map +1 -0
- package/dist/policy/data-read.js +176 -0
- package/dist/policy/data-read.js.map +1 -0
- package/dist/policy/data-write.d.ts +69 -0
- package/dist/policy/data-write.d.ts.map +1 -0
- package/dist/policy/data-write.js +131 -0
- package/dist/policy/data-write.js.map +1 -0
- package/dist/policy/index.d.ts +4 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +4 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/signed-artifacts.d.ts +17 -0
- package/dist/policy/signed-artifacts.d.ts.map +1 -0
- package/dist/policy/signed-artifacts.js +110 -0
- package/dist/policy/signed-artifacts.js.map +1 -0
- package/dist/ports/index.d.ts +243 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +7 -0
- package/dist/ports/index.js.map +1 -0
- package/dist/ports/pdpp-auth.d.ts +103 -0
- package/dist/ports/pdpp-auth.d.ts.map +1 -0
- package/dist/ports/pdpp-auth.js +37 -0
- package/dist/ports/pdpp-auth.js.map +1 -0
- package/dist/ports/pdpp-auth.test-utils.d.ts +9 -0
- package/dist/ports/pdpp-auth.test-utils.d.ts.map +1 -0
- package/dist/ports/pdpp-auth.test-utils.js +18 -0
- package/dist/ports/pdpp-auth.test-utils.js.map +1 -0
- package/dist/schemas/server-config.d.ts +190 -0
- package/dist/schemas/server-config.d.ts.map +1 -0
- package/dist/schemas/server-config.js +282 -0
- package/dist/schemas/server-config.js.map +1 -0
- package/dist/signing/index.d.ts +3 -0
- package/dist/signing/index.d.ts.map +1 -0
- package/dist/signing/index.js +3 -0
- package/dist/signing/index.js.map +1 -0
- package/dist/signing/request-signer.d.ts +20 -0
- package/dist/signing/request-signer.d.ts.map +1 -0
- package/dist/signing/request-signer.js +23 -0
- package/dist/signing/request-signer.js.map +1 -0
- package/dist/signing/signer.d.ts +40 -0
- package/dist/signing/signer.d.ts.map +1 -0
- package/dist/signing/signer.js +56 -0
- package/dist/signing/signer.js.map +1 -0
- package/dist/storage/adapters/index.d.ts +4 -0
- package/dist/storage/adapters/index.d.ts.map +1 -0
- package/dist/storage/adapters/index.js +3 -0
- package/dist/storage/adapters/index.js.map +1 -0
- package/dist/storage/adapters/interface.d.ts +57 -0
- package/dist/storage/adapters/interface.d.ts.map +1 -0
- package/dist/storage/adapters/interface.js +2 -0
- package/dist/storage/adapters/interface.js.map +1 -0
- package/dist/storage/adapters/sdk.d.ts +23 -0
- package/dist/storage/adapters/sdk.d.ts.map +1 -0
- package/dist/storage/adapters/sdk.js +73 -0
- package/dist/storage/adapters/sdk.js.map +1 -0
- package/dist/storage/adapters/vana.d.ts +12 -0
- package/dist/storage/adapters/vana.d.ts.map +1 -0
- package/dist/storage/adapters/vana.js +111 -0
- package/dist/storage/adapters/vana.js.map +1 -0
- package/dist/storage/blocks/build.d.ts +20 -0
- package/dist/storage/blocks/build.d.ts.map +1 -0
- package/dist/storage/blocks/build.js +378 -0
- package/dist/storage/blocks/build.js.map +1 -0
- package/dist/storage/blocks/cursor.d.ts +33 -0
- package/dist/storage/blocks/cursor.d.ts.map +1 -0
- package/dist/storage/blocks/cursor.js +142 -0
- package/dist/storage/blocks/cursor.js.map +1 -0
- package/dist/storage/blocks/errors.d.ts +6 -0
- package/dist/storage/blocks/errors.d.ts.map +1 -0
- package/dist/storage/blocks/errors.js +9 -0
- package/dist/storage/blocks/errors.js.map +1 -0
- package/dist/storage/blocks/index.d.ts +6 -0
- package/dist/storage/blocks/index.d.ts.map +1 -0
- package/dist/storage/blocks/index.js +5 -0
- package/dist/storage/blocks/index.js.map +1 -0
- package/dist/storage/blocks/select.d.ts +29 -0
- package/dist/storage/blocks/select.d.ts.map +1 -0
- package/dist/storage/blocks/select.js +120 -0
- package/dist/storage/blocks/select.js.map +1 -0
- package/dist/storage/blocks/types.d.ts +56 -0
- package/dist/storage/blocks/types.d.ts.map +1 -0
- package/dist/storage/blocks/types.js +2 -0
- package/dist/storage/blocks/types.js.map +1 -0
- package/dist/storage/hierarchy/index.d.ts +3 -0
- package/dist/storage/hierarchy/index.d.ts.map +1 -0
- package/dist/storage/hierarchy/index.js +2 -0
- package/dist/storage/hierarchy/index.js.map +1 -0
- package/dist/storage/hierarchy/manager.d.ts +9 -0
- package/dist/storage/hierarchy/manager.d.ts.map +1 -0
- package/dist/storage/hierarchy/manager.js +2 -0
- package/dist/storage/hierarchy/manager.js.map +1 -0
- package/dist/storage/hierarchy/paths.d.ts +11 -0
- package/dist/storage/hierarchy/paths.d.ts.map +1 -0
- package/dist/storage/hierarchy/paths.js +43 -0
- package/dist/storage/hierarchy/paths.js.map +1 -0
- package/dist/storage/index/index.d.ts +3 -0
- package/dist/storage/index/index.d.ts.map +1 -0
- package/dist/storage/index/index.js +2 -0
- package/dist/storage/index/index.js.map +1 -0
- package/dist/storage/index/manager.d.ts +63 -0
- package/dist/storage/index/manager.d.ts.map +1 -0
- package/dist/storage/index/manager.js +2 -0
- package/dist/storage/index/manager.js.map +1 -0
- package/dist/storage/index/schema.d.ts +2 -0
- package/dist/storage/index/schema.d.ts.map +1 -0
- package/dist/storage/index/schema.js +2 -0
- package/dist/storage/index/schema.js.map +1 -0
- package/dist/storage/index/types.d.ts +37 -0
- package/dist/storage/index/types.d.ts.map +1 -0
- package/dist/storage/index/types.js +2 -0
- package/dist/storage/index/types.js.map +1 -0
- package/dist/storage/pdpp-records/cursor.d.ts +27 -0
- package/dist/storage/pdpp-records/cursor.d.ts.map +1 -0
- package/dist/storage/pdpp-records/cursor.js +49 -0
- package/dist/storage/pdpp-records/cursor.js.map +1 -0
- package/dist/storage/pdpp-records/enforcement.d.ts +37 -0
- package/dist/storage/pdpp-records/enforcement.d.ts.map +1 -0
- package/dist/storage/pdpp-records/enforcement.js +79 -0
- package/dist/storage/pdpp-records/enforcement.js.map +1 -0
- package/dist/storage/pdpp-records/index.d.ts +8 -0
- package/dist/storage/pdpp-records/index.d.ts.map +1 -0
- package/dist/storage/pdpp-records/index.js +8 -0
- package/dist/storage/pdpp-records/index.js.map +1 -0
- package/dist/storage/pdpp-records/interface.d.ts +49 -0
- package/dist/storage/pdpp-records/interface.d.ts.map +1 -0
- package/dist/storage/pdpp-records/interface.js +2 -0
- package/dist/storage/pdpp-records/interface.js.map +1 -0
- package/dist/storage/pdpp-records/memory-store.d.ts +9 -0
- package/dist/storage/pdpp-records/memory-store.d.ts.map +1 -0
- package/dist/storage/pdpp-records/memory-store.js +0 -0
- package/dist/storage/pdpp-records/memory-store.js.map +1 -0
- package/dist/storage/pdpp-records/record-key.d.ts +52 -0
- package/dist/storage/pdpp-records/record-key.d.ts.map +1 -0
- package/dist/storage/pdpp-records/record-key.js +97 -0
- package/dist/storage/pdpp-records/record-key.js.map +1 -0
- package/dist/storage/pdpp-records/stream-declaration.d.ts +43 -0
- package/dist/storage/pdpp-records/stream-declaration.d.ts.map +1 -0
- package/dist/storage/pdpp-records/stream-declaration.js +17 -0
- package/dist/storage/pdpp-records/stream-declaration.js.map +1 -0
- package/dist/storage/pdpp-records/types.d.ts +93 -0
- package/dist/storage/pdpp-records/types.d.ts.map +1 -0
- package/dist/storage/pdpp-records/types.js +17 -0
- package/dist/storage/pdpp-records/types.js.map +1 -0
- package/dist/storage/preview.d.ts +12 -0
- package/dist/storage/preview.d.ts.map +1 -0
- package/dist/storage/preview.js +239 -0
- package/dist/storage/preview.js.map +1 -0
- package/dist/sync/cursor.d.ts +10 -0
- package/dist/sync/cursor.d.ts.map +1 -0
- package/dist/sync/cursor.js +2 -0
- package/dist/sync/cursor.js.map +1 -0
- package/dist/sync/data-point-feed.d.ts +35 -0
- package/dist/sync/data-point-feed.d.ts.map +1 -0
- package/dist/sync/data-point-feed.js +122 -0
- package/dist/sync/data-point-feed.js.map +1 -0
- package/dist/sync/data-point-id.d.ts +7 -0
- package/dist/sync/data-point-id.d.ts.map +1 -0
- package/dist/sync/data-point-id.js +16 -0
- package/dist/sync/data-point-id.js.map +1 -0
- package/dist/sync/delete-data-port.d.ts +50 -0
- package/dist/sync/delete-data-port.d.ts.map +1 -0
- package/dist/sync/delete-data-port.js +244 -0
- package/dist/sync/delete-data-port.js.map +1 -0
- package/dist/sync/engine/sync-manager.d.ts +58 -0
- package/dist/sync/engine/sync-manager.d.ts.map +1 -0
- package/dist/sync/engine/sync-manager.js +285 -0
- package/dist/sync/engine/sync-manager.js.map +1 -0
- package/dist/sync/index.d.ts +15 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +14 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/issues.d.ts +55 -0
- package/dist/sync/issues.d.ts.map +1 -0
- package/dist/sync/issues.js +168 -0
- package/dist/sync/issues.js.map +1 -0
- package/dist/sync/pdpp-import.d.ts +192 -0
- package/dist/sync/pdpp-import.d.ts.map +1 -0
- package/dist/sync/pdpp-import.js +422 -0
- package/dist/sync/pdpp-import.js.map +1 -0
- package/dist/sync/pending-blob-deletions.d.ts +29 -0
- package/dist/sync/pending-blob-deletions.d.ts.map +1 -0
- package/dist/sync/pending-blob-deletions.js +116 -0
- package/dist/sync/pending-blob-deletions.js.map +1 -0
- package/dist/sync/retry-memory.d.ts +33 -0
- package/dist/sync/retry-memory.d.ts.map +1 -0
- package/dist/sync/retry-memory.js +68 -0
- package/dist/sync/retry-memory.js.map +1 -0
- package/dist/sync/scope-deletions.d.ts +155 -0
- package/dist/sync/scope-deletions.d.ts.map +1 -0
- package/dist/sync/scope-deletions.js +225 -0
- package/dist/sync/scope-deletions.js.map +1 -0
- package/dist/sync/tombstone.d.ts +27 -0
- package/dist/sync/tombstone.d.ts.map +1 -0
- package/dist/sync/tombstone.js +28 -0
- package/dist/sync/tombstone.js.map +1 -0
- package/dist/sync/types.d.ts +27 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/sync/types.js +2 -0
- package/dist/sync/types.js.map +1 -0
- package/dist/sync/workers/delete.d.ts +163 -0
- package/dist/sync/workers/delete.d.ts.map +1 -0
- package/dist/sync/workers/delete.js +474 -0
- package/dist/sync/workers/delete.js.map +1 -0
- package/dist/sync/workers/download.d.ts +159 -0
- package/dist/sync/workers/download.d.ts.map +1 -0
- package/dist/sync/workers/download.js +731 -0
- package/dist/sync/workers/download.js.map +1 -0
- package/dist/sync/workers/upload.d.ts +98 -0
- package/dist/sync/workers/upload.d.ts.map +1 -0
- package/dist/sync/workers/upload.js +412 -0
- package/dist/sync/workers/upload.js.map +1 -0
- package/dist/test-utils/e2ee-fixtures.d.ts +94 -0
- package/dist/test-utils/e2ee-fixtures.d.ts.map +1 -0
- package/dist/test-utils/e2ee-fixtures.js +116 -0
- package/dist/test-utils/e2ee-fixtures.js.map +1 -0
- package/dist/test-utils/e2ee-gateway.d.ts +61 -0
- package/dist/test-utils/e2ee-gateway.d.ts.map +1 -0
- package/dist/test-utils/e2ee-gateway.js +248 -0
- package/dist/test-utils/e2ee-gateway.js.map +1 -0
- package/dist/test-utils/index.d.ts +5 -0
- package/dist/test-utils/index.d.ts.map +1 -0
- package/dist/test-utils/index.js +5 -0
- package/dist/test-utils/index.js.map +1 -0
- package/dist/test-utils/memory-storage.d.ts +12 -0
- package/dist/test-utils/memory-storage.d.ts.map +1 -0
- package/dist/test-utils/memory-storage.js +146 -0
- package/dist/test-utils/memory-storage.js.map +1 -0
- package/dist/test-utils/wallet.d.ts +47 -0
- package/dist/test-utils/wallet.d.ts.map +1 -0
- package/dist/test-utils/wallet.js +98 -0
- package/dist/test-utils/wallet.js.map +1 -0
- package/dist/write/attribution.d.ts +185 -0
- package/dist/write/attribution.d.ts.map +1 -0
- package/dist/write/attribution.js +450 -0
- package/dist/write/attribution.js.map +1 -0
- package/dist/write/authorize.d.ts +77 -0
- package/dist/write/authorize.d.ts.map +1 -0
- package/dist/write/authorize.js +109 -0
- package/dist/write/authorize.js.map +1 -0
- package/dist/write/index.d.ts +5 -0
- package/dist/write/index.d.ts.map +1 -0
- package/dist/write/index.js +5 -0
- package/dist/write/index.js.map +1 -0
- package/dist/write/route.d.ts +61 -0
- package/dist/write/route.d.ts.map +1 -0
- package/dist/write/route.js +132 -0
- package/dist/write/route.js.map +1 -0
- package/dist/write/session.d.ts +96 -0
- package/dist/write/session.d.ts.map +1 -0
- package/dist/write/session.js +136 -0
- package/dist/write/session.js.map +1 -0
- package/package.json +175 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authorization sessions and authenticated owner approval.
|
|
3
|
+
*
|
|
4
|
+
* This is the module that decides whether a consent decision is real. The
|
|
5
|
+
* threat it exists to stop is an approval that looks right — correct session,
|
|
6
|
+
* correct review digest, arriving from the first-party consent UI — but that
|
|
7
|
+
* no authenticated owner actually made.
|
|
8
|
+
*
|
|
9
|
+
* The rule: **affiliation is not authentication.** The AS does not accept an
|
|
10
|
+
* approval because it came from an allowlisted origin, a first-party console,
|
|
11
|
+
* a shared UI/server secret, or a signed assertion from the consent broker
|
|
12
|
+
* saying "the owner agreed". Each of those authenticates a *channel* or
|
|
13
|
+
* delegates the decision to a browser-reachable component; compromise it and
|
|
14
|
+
* it mints approvals for any subject. Instead, the owner authenticates to the
|
|
15
|
+
* PS itself, and the resulting owner token — resolved through the same token
|
|
16
|
+
* service the RS uses — is what authorizes the decision. The consent UI
|
|
17
|
+
* forwards that token; it can never substitute for it.
|
|
18
|
+
*
|
|
19
|
+
* Two independent checks must both pass, and neither implies the other:
|
|
20
|
+
*
|
|
21
|
+
* 1. The caller presents an active token with `pdpp_token_kind: "owner"`
|
|
22
|
+
* whose `subject_id` equals the session's subject. Possession of the
|
|
23
|
+
* session id is not authority over it.
|
|
24
|
+
* 2. The presented `review_digest` matches a re-derivation over what is
|
|
25
|
+
* about to be issued (§7 staleness). Authenticating the owner does not
|
|
26
|
+
* excuse approving something other than what they reviewed.
|
|
27
|
+
*/
|
|
28
|
+
import { randomBytes } from "node:crypto";
|
|
29
|
+
import { buildConsentReview, } from "./review.js";
|
|
30
|
+
import { issueGrant } from "./issuance.js";
|
|
31
|
+
import { resolveSelection } from "./resolve.js";
|
|
32
|
+
/** How long an owner has to act on a consent screen before it goes stale. */
|
|
33
|
+
export const REVIEW_SESSION_TTL_SECONDS = 10 * 60;
|
|
34
|
+
/**
|
|
35
|
+
* In-memory pending-session store. Sessions are short-lived and pre-decision,
|
|
36
|
+
* so they hold no issued authority — losing them on restart costs an owner a
|
|
37
|
+
* re-click, not a grant. Issued grants and tokens go to SQLite, where
|
|
38
|
+
* durability actually matters.
|
|
39
|
+
*/
|
|
40
|
+
export class AuthorizationSessionStore {
|
|
41
|
+
sessions = new Map();
|
|
42
|
+
create(input) {
|
|
43
|
+
const now = input.now ?? new Date();
|
|
44
|
+
const session = {
|
|
45
|
+
session_id: `as_${randomBytes(16).toString("hex")}`,
|
|
46
|
+
subject_id: input.subjectId,
|
|
47
|
+
request: input.request,
|
|
48
|
+
snapshot: input.snapshot,
|
|
49
|
+
requester: input.requester,
|
|
50
|
+
redirect_uri: input.redirectUri,
|
|
51
|
+
...(input.stateParam && { state_param: input.stateParam }),
|
|
52
|
+
...(input.codeChallenge && { code_challenge: input.codeChallenge }),
|
|
53
|
+
...(input.codeChallengeMethod && {
|
|
54
|
+
code_challenge_method: input.codeChallengeMethod,
|
|
55
|
+
}),
|
|
56
|
+
expires_at: new Date(now.getTime() + REVIEW_SESSION_TTL_SECONDS * 1000).toISOString(),
|
|
57
|
+
status: "pending",
|
|
58
|
+
...(input.grantExpiresAt && { grant_expires_at: input.grantExpiresAt }),
|
|
59
|
+
...(input.streamDescriptions && {
|
|
60
|
+
stream_descriptions: input.streamDescriptions,
|
|
61
|
+
}),
|
|
62
|
+
};
|
|
63
|
+
this.sessions.set(session.session_id, session);
|
|
64
|
+
return session;
|
|
65
|
+
}
|
|
66
|
+
get(sessionId) {
|
|
67
|
+
return this.sessions.get(sessionId) ?? null;
|
|
68
|
+
}
|
|
69
|
+
setStatus(sessionId, status) {
|
|
70
|
+
const session = this.sessions.get(sessionId);
|
|
71
|
+
if (session)
|
|
72
|
+
session.status = status;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Authenticate the caller as the owner of a session.
|
|
77
|
+
*
|
|
78
|
+
* Returns the session only when the token is an active *owner* token for that
|
|
79
|
+
* exact subject. Every failure collapses to `session_not_found` rather than a
|
|
80
|
+
* distinguishable "wrong owner" — otherwise a caller holding any valid owner
|
|
81
|
+
* token could probe session ids to learn which ones exist and whose they are.
|
|
82
|
+
*/
|
|
83
|
+
function authenticateOwner(sessions, tokens, sessionId, ownerToken, now) {
|
|
84
|
+
if (!ownerToken) {
|
|
85
|
+
return {
|
|
86
|
+
ok: false,
|
|
87
|
+
failure: {
|
|
88
|
+
code: "unauthorized",
|
|
89
|
+
message: "an authenticated owner session is required to decide an authorization",
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const context = tokens.resolveToken(ownerToken, now);
|
|
94
|
+
// A client token must never approve a grant — that would let the requesting
|
|
95
|
+
// application authorize itself.
|
|
96
|
+
if (!context.active || context.tokenKind !== "owner" || !context.subjectId) {
|
|
97
|
+
return {
|
|
98
|
+
ok: false,
|
|
99
|
+
failure: {
|
|
100
|
+
code: "unauthorized",
|
|
101
|
+
message: "owner token is missing, inactive, or not an owner token",
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const session = sessions.get(sessionId);
|
|
106
|
+
if (!session) {
|
|
107
|
+
return {
|
|
108
|
+
ok: false,
|
|
109
|
+
failure: {
|
|
110
|
+
code: "session_not_found",
|
|
111
|
+
message: "authorization session not found",
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// The binding that matters: this owner must be *this session's* owner.
|
|
116
|
+
if (session.subject_id !== context.subjectId) {
|
|
117
|
+
return {
|
|
118
|
+
ok: false,
|
|
119
|
+
failure: {
|
|
120
|
+
code: "session_not_found",
|
|
121
|
+
message: "authorization session not found",
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (Date.parse(session.expires_at) <= now.getTime()) {
|
|
126
|
+
return {
|
|
127
|
+
ok: false,
|
|
128
|
+
failure: {
|
|
129
|
+
code: "session_not_found",
|
|
130
|
+
message: "authorization session has expired",
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return { ok: true, session };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Overlay the owner's explicit instance picks onto the inventory.
|
|
138
|
+
*
|
|
139
|
+
* A pick narrows the eligible set for that stream to exactly what the owner
|
|
140
|
+
* chose — it never widens it. Intersecting with the real inventory is what
|
|
141
|
+
* stops a caller from "choosing" a handle the owner has not connected, so an
|
|
142
|
+
* owner choice cannot become an escalation path.
|
|
143
|
+
*/
|
|
144
|
+
function withInstanceChoices(inventory, choices) {
|
|
145
|
+
if (!choices)
|
|
146
|
+
return inventory;
|
|
147
|
+
return {
|
|
148
|
+
eligibleFor(streamName) {
|
|
149
|
+
const eligible = inventory.eligibleFor(streamName);
|
|
150
|
+
const chosen = choices[streamName];
|
|
151
|
+
if (!chosen || chosen.length === 0)
|
|
152
|
+
return eligible;
|
|
153
|
+
return chosen.filter((handle) => eligible.includes(handle));
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Find every stream that needs an owner choice, rather than stopping at the
|
|
159
|
+
* first. A UI that asked about one stream at a time would make the owner
|
|
160
|
+
* approve a moving target across several round trips.
|
|
161
|
+
*/
|
|
162
|
+
function pendingInstanceChoices(session, inventory) {
|
|
163
|
+
const choices = [];
|
|
164
|
+
const streams = session.request.streams ?? [];
|
|
165
|
+
const wildcard = streams.find((s) => s.name === "*");
|
|
166
|
+
const names = wildcard
|
|
167
|
+
? session.snapshot.streams.map((s) => s.name)
|
|
168
|
+
: streams.map((s) => s.name);
|
|
169
|
+
for (const name of names) {
|
|
170
|
+
const requested = wildcard ?? streams.find((s) => s.name === name);
|
|
171
|
+
// An explicitly named handle set is already a decision; no choice needed.
|
|
172
|
+
if (requested?.instance_ids && requested.instance_ids.length > 0)
|
|
173
|
+
continue;
|
|
174
|
+
const eligible = inventory.eligibleFor(name);
|
|
175
|
+
if (eligible.length > 1) {
|
|
176
|
+
choices.push({ stream: name, candidates: eligible });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return choices;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Build the review an authenticated owner sees.
|
|
183
|
+
*
|
|
184
|
+
* Resolution runs here against current inventory, so the digest the owner is
|
|
185
|
+
* handed reflects the world as it is right now. If it changes before they
|
|
186
|
+
* approve, `approveAuthorization` will re-derive a different digest and reject.
|
|
187
|
+
*/
|
|
188
|
+
export function fetchReview(input) {
|
|
189
|
+
const now = input.now ?? new Date();
|
|
190
|
+
const auth = authenticateOwner(input.sessions, input.tokens, input.sessionId, input.ownerToken, now);
|
|
191
|
+
if (!auth.ok)
|
|
192
|
+
return auth;
|
|
193
|
+
const { session } = auth;
|
|
194
|
+
if (session.status !== "pending") {
|
|
195
|
+
return {
|
|
196
|
+
ok: false,
|
|
197
|
+
failure: {
|
|
198
|
+
code: "access_denied",
|
|
199
|
+
message: "authorization session is already decided",
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const inventory = withInstanceChoices(input.inventory, input.instanceChoices);
|
|
204
|
+
// Surface outstanding choices before attempting resolution: an unresolvable
|
|
205
|
+
// instance is a consent step, not an error the owner can do nothing about.
|
|
206
|
+
const choices = pendingInstanceChoices(session, inventory);
|
|
207
|
+
if (choices.length > 0) {
|
|
208
|
+
return {
|
|
209
|
+
ok: true,
|
|
210
|
+
result: {
|
|
211
|
+
session_id: session.session_id,
|
|
212
|
+
instance_choice_required: choices,
|
|
213
|
+
expires_at: session.expires_at,
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
const resolution = resolveSelection(session.request, session.snapshot, inventory);
|
|
218
|
+
if (!resolution.ok) {
|
|
219
|
+
return {
|
|
220
|
+
ok: false,
|
|
221
|
+
failure: {
|
|
222
|
+
code: "invalid_request",
|
|
223
|
+
message: resolution.failure.message,
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
const review = buildConsentReview({
|
|
228
|
+
subjectId: session.subject_id,
|
|
229
|
+
request: session.request,
|
|
230
|
+
snapshot: session.snapshot,
|
|
231
|
+
resolvedStreams: resolution.streams,
|
|
232
|
+
requester: session.requester,
|
|
233
|
+
expiresAt: session.grant_expires_at,
|
|
234
|
+
streamDescriptions: session.stream_descriptions,
|
|
235
|
+
});
|
|
236
|
+
return {
|
|
237
|
+
ok: true,
|
|
238
|
+
result: {
|
|
239
|
+
session_id: session.session_id,
|
|
240
|
+
review,
|
|
241
|
+
expires_at: session.expires_at,
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Approve an authorization: authenticate the owner, then issue.
|
|
247
|
+
*
|
|
248
|
+
* Order is deliberate. Authentication runs before anything else, so an
|
|
249
|
+
* unauthenticated caller cannot learn from the error whether their digest was
|
|
250
|
+
* fresh — a spoofed approval with a perfectly valid digest gets the same
|
|
251
|
+
* `unauthorized` as one with a garbage digest.
|
|
252
|
+
*/
|
|
253
|
+
export function approveAuthorization(input) {
|
|
254
|
+
const now = input.now ?? new Date();
|
|
255
|
+
const auth = authenticateOwner(input.sessions, input.tokens, input.sessionId, input.ownerToken, now);
|
|
256
|
+
if (!auth.ok)
|
|
257
|
+
return auth;
|
|
258
|
+
const { session } = auth;
|
|
259
|
+
if (session.status !== "pending") {
|
|
260
|
+
return {
|
|
261
|
+
ok: false,
|
|
262
|
+
failure: {
|
|
263
|
+
code: "access_denied",
|
|
264
|
+
message: "authorization session is already decided",
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
if (!input.reviewDigest) {
|
|
269
|
+
return {
|
|
270
|
+
ok: false,
|
|
271
|
+
failure: {
|
|
272
|
+
code: "invalid_request",
|
|
273
|
+
message: "review_digest is required",
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
const issuance = issueGrant({
|
|
278
|
+
subjectId: session.subject_id,
|
|
279
|
+
request: session.request,
|
|
280
|
+
snapshot: session.snapshot,
|
|
281
|
+
inventory: withInstanceChoices(input.inventory, input.instanceChoices),
|
|
282
|
+
requester: session.requester,
|
|
283
|
+
approvedReviewDigest: input.reviewDigest,
|
|
284
|
+
explicitAiTrainingConsent: input.explicitAiTrainingConsent,
|
|
285
|
+
expiresAt: session.grant_expires_at,
|
|
286
|
+
streamDescriptions: session.stream_descriptions,
|
|
287
|
+
now,
|
|
288
|
+
});
|
|
289
|
+
if (!issuance.ok) {
|
|
290
|
+
// `resolution_failed` at APPROVAL time is staleness, not a bad request.
|
|
291
|
+
// The selection already resolved once — that is how the owner got a review
|
|
292
|
+
// to approve. If it no longer resolves, the world changed underneath them:
|
|
293
|
+
// most commonly a second instance was connected while the consent screen
|
|
294
|
+
// was open, which under §6 means the AS can no longer auto-resolve and the
|
|
295
|
+
// owner has a new choice to make.
|
|
296
|
+
//
|
|
297
|
+
// The distinction is load-bearing for the consent UI: `stale_review` routes
|
|
298
|
+
// to re-fetch and re-render, so the owner sees the new choice and decides
|
|
299
|
+
// again; `invalid_request` routes to "report a bug" and strands them. The
|
|
300
|
+
// canonical §6 drift case must land on the first.
|
|
301
|
+
const code = issuance.failure.code === "stale_approval" ||
|
|
302
|
+
issuance.failure.code === "resolution_failed"
|
|
303
|
+
? "stale_review"
|
|
304
|
+
: issuance.failure.code === "ai_training_consent_required"
|
|
305
|
+
? "ai_training_consent_required"
|
|
306
|
+
: "invalid_request";
|
|
307
|
+
return { ok: false, failure: { code, message: issuance.failure.message } };
|
|
308
|
+
}
|
|
309
|
+
input.sessions.setStatus(session.session_id, "approved");
|
|
310
|
+
return {
|
|
311
|
+
ok: true,
|
|
312
|
+
grant: issuance.grant,
|
|
313
|
+
consentEvidence: issuance.consentEvidence,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Deny an authorization. Terminal, and retains no consent evidence — there is
|
|
318
|
+
* nothing the owner consented to, so there is nothing to hold evidence of.
|
|
319
|
+
*/
|
|
320
|
+
export function denyAuthorization(input) {
|
|
321
|
+
const now = input.now ?? new Date();
|
|
322
|
+
const auth = authenticateOwner(input.sessions, input.tokens, input.sessionId, input.ownerToken, now);
|
|
323
|
+
if (!auth.ok)
|
|
324
|
+
return auth;
|
|
325
|
+
if (auth.session.status !== "pending") {
|
|
326
|
+
return {
|
|
327
|
+
ok: false,
|
|
328
|
+
failure: {
|
|
329
|
+
code: "access_denied",
|
|
330
|
+
message: "authorization session is already decided",
|
|
331
|
+
},
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
input.sessions.setStatus(auth.session.session_id, "denied");
|
|
335
|
+
return { ok: true };
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=approval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval.js","sourceRoot":"","sources":["../../src/pdpp/approval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EACL,kBAAkB,GAGnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAwB,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAA0B,MAAM,cAAc,CAAC;AAIxE,6EAA6E;AAC7E,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,GAAG,EAAE,CAAC;AAyClD;;;;;GAKG;AACH,MAAM,OAAO,yBAAyB;IACnB,QAAQ,GAAG,IAAI,GAAG,EAAgC,CAAC;IAEpE,MAAM,CAAC,KAYN;QACC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;QACpC,MAAM,OAAO,GAAyB;YACpC,UAAU,EAAE,MAAM,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;YACnD,UAAU,EAAE,KAAK,CAAC,SAAS;YAC3B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,YAAY,EAAE,KAAK,CAAC,WAAW;YAC/B,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;YAC1D,GAAG,CAAC,KAAK,CAAC,aAAa,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC;YACnE,GAAG,CAAC,KAAK,CAAC,mBAAmB,IAAI;gBAC/B,qBAAqB,EAAE,KAAK,CAAC,mBAAmB;aACjD,CAAC;YACF,UAAU,EAAE,IAAI,IAAI,CAClB,GAAG,CAAC,OAAO,EAAE,GAAG,0BAA0B,GAAG,IAAI,CAClD,CAAC,WAAW,EAAE;YACf,MAAM,EAAE,SAAS;YACjB,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,gBAAgB,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC;YACvE,GAAG,CAAC,KAAK,CAAC,kBAAkB,IAAI;gBAC9B,mBAAmB,EAAE,KAAK,CAAC,kBAAkB;aAC9C,CAAC;SACH,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,GAAG,CAAC,SAAiB;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;IAC9C,CAAC;IAED,SAAS,CAAC,SAAiB,EAAE,MAAoB;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,OAAO;YAAE,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;IACvC,CAAC;CACF;AAED;;;;;;;GAOG;AACH,SAAS,iBAAiB,CACxB,QAAmC,EACnC,MAAwB,EACxB,SAAiB,EACjB,UAA8B,EAC9B,GAAS;IAIT,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,cAAc;gBACpB,OAAO,EACL,uEAAuE;aAC1E;SACF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACrD,4EAA4E;IAC5E,gCAAgC;IAChC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAC3E,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,cAAc;gBACpB,OAAO,EAAE,yDAAyD;aACnE;SACF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,iCAAiC;aAC3C;SACF,CAAC;IACJ,CAAC;IAED,uEAAuE;IACvE,IAAI,OAAO,CAAC,UAAU,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;QAC7C,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,iCAAiC;aAC3C;SACF,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;QACpD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,mCAAmC;aAC7C;SACF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC/B,CAAC;AA6BD;;;;;;;GAOG;AACH,SAAS,mBAAmB,CAC1B,SAA4B,EAC5B,OAA6C;IAE7C,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,OAAO;QACL,WAAW,CAAC,UAAkB;YAC5B,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;YACnC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,QAAQ,CAAC;YACpD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9D,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAC7B,OAA6B,EAC7B,SAA4B;IAE5B,MAAM,OAAO,GAAqB,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;IAErD,MAAM,KAAK,GAAG,QAAQ;QACpB,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7C,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACnE,0EAA0E;QAC1E,IAAI,SAAS,EAAE,YAAY,IAAI,SAAS,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC3E,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,KAS3B;IAGC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,iBAAiB,CAC5B,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,UAAU,EAChB,GAAG,CACJ,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACzB,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,0CAA0C;aACpD;SACF,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IAE9E,4EAA4E;IAC5E,2EAA2E;IAC3E,MAAM,OAAO,GAAG,sBAAsB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC3D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,EAAE,EAAE,IAAI;YACR,MAAM,EAAE;gBACN,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,wBAAwB,EAAE,OAAO;gBACjC,UAAU,EAAE,OAAO,CAAC,UAAU;aAC/B;SACF,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,gBAAgB,CACjC,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,QAAQ,EAChB,SAAS,CACV,CAAC;IACF,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;QACnB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,OAAO;aACpC;SACF,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC;QAChC,SAAS,EAAE,OAAO,CAAC,UAAU;QAC7B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,eAAe,EAAE,UAAU,CAAC,OAAO;QACnC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,gBAAgB;QACnC,kBAAkB,EAAE,OAAO,CAAC,mBAAmB;KAChD,CAAC,CAAC;IAEH,OAAO;QACL,EAAE,EAAE,IAAI;QACR,MAAM,EAAE;YACN,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,MAAM;YACN,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAgBpC;IACC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IAEpC,MAAM,IAAI,GAAG,iBAAiB,CAC5B,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,UAAU,EAChB,GAAG,CACJ,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACzB,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,0CAA0C;aACpD;SACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QACxB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,2BAA2B;aACrC;SACF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC;QAC1B,SAAS,EAAE,OAAO,CAAC,UAAU;QAC7B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,SAAS,EAAE,mBAAmB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,eAAe,CAAC;QACtE,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,oBAAoB,EAAE,KAAK,CAAC,YAAY;QACxC,yBAAyB,EAAE,KAAK,CAAC,yBAAyB;QAC1D,SAAS,EAAE,OAAO,CAAC,gBAAgB;QACnC,kBAAkB,EAAE,OAAO,CAAC,mBAAmB;QAC/C,GAAG;KACJ,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,wEAAwE;QACxE,2EAA2E;QAC3E,2EAA2E;QAC3E,yEAAyE;QACzE,2EAA2E;QAC3E,kCAAkC;QAClC,EAAE;QACF,4EAA4E;QAC5E,0EAA0E;QAC1E,0EAA0E;QAC1E,kDAAkD;QAClD,MAAM,IAAI,GACR,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,gBAAgB;YAC1C,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,mBAAmB;YAC3C,CAAC,CAAC,cAAc;YAChB,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,8BAA8B;gBACxD,CAAC,CAAC,8BAA8B;gBAChC,CAAC,CAAC,iBAAiB,CAAC;QAC1B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACzD,OAAO;QACL,EAAE,EAAE,IAAI;QACR,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,eAAe,EAAE,QAAQ,CAAC,eAAe;KAC1C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAMjC;IACC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,iBAAiB,CAC5B,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,UAAU,EAChB,GAAG,CACJ,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAE1B,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,0CAA0C;aACpD;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC5D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolving a URL-hosted client identity, under a bounded fetch policy.
|
|
3
|
+
*
|
|
4
|
+
* §6 says a conforming AS MUST NOT reject a valid client ID metadata document
|
|
5
|
+
* solely because the client is not preregistered, and MUST accept a valid
|
|
6
|
+
* URL-hosted client identity unless local policy denies authorization. Before
|
|
7
|
+
* this, the AS validated `redirect_uri` only against a config-supplied
|
|
8
|
+
* registration, so an unregistered-but-valid client was refused for the one
|
|
9
|
+
* reason the spec names as insufficient.
|
|
10
|
+
*
|
|
11
|
+
* ── Why this is not just "fetch the client_id" ──────────────────────────────
|
|
12
|
+
*
|
|
13
|
+
* The AS is being handed a URL by an untrusted caller and asked to fetch it.
|
|
14
|
+
* That is a server-side request forgery primitive: without bounds, a client_id
|
|
15
|
+
* of `http://169.254.169.254/...` turns the AS into a proxy for whatever the
|
|
16
|
+
* deployment can reach. So this reuses `checkDeclarationUrl`, the same guard
|
|
17
|
+
* the declaration retrieval path already applies — https-only, no private or
|
|
18
|
+
* loopback literals, and the deployment's host allowlist unless it has
|
|
19
|
+
* explicitly opted into any HTTPS host.
|
|
20
|
+
*
|
|
21
|
+
* The response is size-capped and redirect-bounded for the same reason: an
|
|
22
|
+
* unbounded body is a memory exhaustion vector, and unbounded redirects defeat
|
|
23
|
+
* the host check by hopping somewhere it would have refused.
|
|
24
|
+
*
|
|
25
|
+
* ── Registration still wins ────────────────────────────────────────────────
|
|
26
|
+
*
|
|
27
|
+
* A locally registered client is resolved from config without any fetch at
|
|
28
|
+
* all. This path exists only for clients the deployment has NOT registered,
|
|
29
|
+
* and a deployment that wants registration-only behavior gets it by leaving
|
|
30
|
+
* the fetcher unset — in which case nothing here runs and the previous
|
|
31
|
+
* behavior is preserved exactly.
|
|
32
|
+
*/
|
|
33
|
+
import { type DeclarationTrustPolicy } from "./declaration.js";
|
|
34
|
+
import { type ClientIdMetadataDocument } from "./client-metadata.js";
|
|
35
|
+
import type { RegisteredRedirectPolicy } from "./redirect.js";
|
|
36
|
+
/** Bodies larger than this are refused rather than buffered. */
|
|
37
|
+
export declare const MAX_CLIENT_DOCUMENT_BYTES: number;
|
|
38
|
+
export type ClientIdentityFailureCode = "untrusted_client_url" | "fetch_failed" | "invalid_document" | "client_id_mismatch" | "too_large";
|
|
39
|
+
export interface ClientIdentityFailure {
|
|
40
|
+
code: ClientIdentityFailureCode;
|
|
41
|
+
message: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Retrieves a client ID metadata document. Injected so the deployment owns
|
|
45
|
+
* the transport, and so that leaving it unset disables this path entirely.
|
|
46
|
+
*/
|
|
47
|
+
export type ClientDocumentFetcher = (url: string) => Promise<{
|
|
48
|
+
status: number;
|
|
49
|
+
body: string;
|
|
50
|
+
finalUrl: string;
|
|
51
|
+
} | null>;
|
|
52
|
+
export interface ResolveClientIdentityOptions {
|
|
53
|
+
clientId: string;
|
|
54
|
+
fetcher: ClientDocumentFetcher;
|
|
55
|
+
/** Reuses the declaration trust policy; same bounds, same allowlist. */
|
|
56
|
+
policy: DeclarationTrustPolicy;
|
|
57
|
+
}
|
|
58
|
+
export type ClientIdentityResult = {
|
|
59
|
+
ok: true;
|
|
60
|
+
policy: RegisteredRedirectPolicy;
|
|
61
|
+
verifiedDomain: string;
|
|
62
|
+
/**
|
|
63
|
+
* The validated document itself, so the caller can resolve the requester
|
|
64
|
+
* identity from it.
|
|
65
|
+
*
|
|
66
|
+
* Returning this is what keeps redirect trust and displayed identity in
|
|
67
|
+
* agreement. The document is what earned the client its redirect
|
|
68
|
+
* admission; if the AS then rendered the client's inline
|
|
69
|
+
* `client_display` instead, the owner could be shown a name the verified
|
|
70
|
+
* domain never asserted. §6 ranks validated binding metadata above
|
|
71
|
+
* inline metadata, and the caller can only honor that ranking if it is
|
|
72
|
+
* handed the metadata.
|
|
73
|
+
*/
|
|
74
|
+
document: ClientIdMetadataDocument;
|
|
75
|
+
} | {
|
|
76
|
+
ok: false;
|
|
77
|
+
failure: ClientIdentityFailure;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Resolve a `client_id` URL into a redirect policy the AS can enforce.
|
|
81
|
+
*
|
|
82
|
+
* Returns the same `RegisteredRedirectPolicy` shape a config registration
|
|
83
|
+
* produces, so the caller's redirect validation is unchanged — a URL-hosted
|
|
84
|
+
* client is subject to exactly the same exact-match redirect rule as a
|
|
85
|
+
* registered one, rather than a looser path.
|
|
86
|
+
*/
|
|
87
|
+
export declare function resolveUrlHostedClientIdentity(options: ResolveClientIdentityOptions): Promise<ClientIdentityResult>;
|
|
88
|
+
//# sourceMappingURL=client-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-identity.d.ts","sourceRoot":"","sources":["../../src/pdpp/client-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE9D,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,QAAY,CAAC;AAEnD,MAAM,MAAM,yBAAyB,GACjC,sBAAsB,GACtB,cAAc,GACd,kBAAkB,GAClB,oBAAoB,GACpB,WAAW,CAAC;AAEhB,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,GAAG,EAAE,MAAM,KACR,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAAC;AAExE,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,wEAAwE;IACxE,MAAM,EAAE,sBAAsB,CAAC;CAChC;AAED,MAAM,MAAM,oBAAoB,GAC5B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,wBAAwB,CAAC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;OAWG;IACH,QAAQ,EAAE,wBAAwB,CAAC;CACpC,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAElD;;;;;;;GAOG;AACH,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,oBAAoB,CAAC,CA0J/B"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolving a URL-hosted client identity, under a bounded fetch policy.
|
|
3
|
+
*
|
|
4
|
+
* §6 says a conforming AS MUST NOT reject a valid client ID metadata document
|
|
5
|
+
* solely because the client is not preregistered, and MUST accept a valid
|
|
6
|
+
* URL-hosted client identity unless local policy denies authorization. Before
|
|
7
|
+
* this, the AS validated `redirect_uri` only against a config-supplied
|
|
8
|
+
* registration, so an unregistered-but-valid client was refused for the one
|
|
9
|
+
* reason the spec names as insufficient.
|
|
10
|
+
*
|
|
11
|
+
* ── Why this is not just "fetch the client_id" ──────────────────────────────
|
|
12
|
+
*
|
|
13
|
+
* The AS is being handed a URL by an untrusted caller and asked to fetch it.
|
|
14
|
+
* That is a server-side request forgery primitive: without bounds, a client_id
|
|
15
|
+
* of `http://169.254.169.254/...` turns the AS into a proxy for whatever the
|
|
16
|
+
* deployment can reach. So this reuses `checkDeclarationUrl`, the same guard
|
|
17
|
+
* the declaration retrieval path already applies — https-only, no private or
|
|
18
|
+
* loopback literals, and the deployment's host allowlist unless it has
|
|
19
|
+
* explicitly opted into any HTTPS host.
|
|
20
|
+
*
|
|
21
|
+
* The response is size-capped and redirect-bounded for the same reason: an
|
|
22
|
+
* unbounded body is a memory exhaustion vector, and unbounded redirects defeat
|
|
23
|
+
* the host check by hopping somewhere it would have refused.
|
|
24
|
+
*
|
|
25
|
+
* ── Registration still wins ────────────────────────────────────────────────
|
|
26
|
+
*
|
|
27
|
+
* A locally registered client is resolved from config without any fetch at
|
|
28
|
+
* all. This path exists only for clients the deployment has NOT registered,
|
|
29
|
+
* and a deployment that wants registration-only behavior gets it by leaving
|
|
30
|
+
* the fetcher unset — in which case nothing here runs and the previous
|
|
31
|
+
* behavior is preserved exactly.
|
|
32
|
+
*/
|
|
33
|
+
import { checkDeclarationUrl, } from "./declaration.js";
|
|
34
|
+
import { verifyClientIdDocument, } from "./client-metadata.js";
|
|
35
|
+
/** Bodies larger than this are refused rather than buffered. */
|
|
36
|
+
export const MAX_CLIENT_DOCUMENT_BYTES = 64 * 1024;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve a `client_id` URL into a redirect policy the AS can enforce.
|
|
39
|
+
*
|
|
40
|
+
* Returns the same `RegisteredRedirectPolicy` shape a config registration
|
|
41
|
+
* produces, so the caller's redirect validation is unchanged — a URL-hosted
|
|
42
|
+
* client is subject to exactly the same exact-match redirect rule as a
|
|
43
|
+
* registered one, rather than a looser path.
|
|
44
|
+
*/
|
|
45
|
+
export async function resolveUrlHostedClientIdentity(options) {
|
|
46
|
+
const { clientId, fetcher, policy } = options;
|
|
47
|
+
// A non-URL client_id is not a URL-hosted identity. Not an error here —
|
|
48
|
+
// the caller falls back to registration-only behavior.
|
|
49
|
+
let parsed;
|
|
50
|
+
try {
|
|
51
|
+
parsed = new URL(clientId);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return {
|
|
55
|
+
ok: false,
|
|
56
|
+
failure: {
|
|
57
|
+
code: "untrusted_client_url",
|
|
58
|
+
message: "client_id is not a URL-hosted identity",
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// The SSRF gate, before any network call.
|
|
63
|
+
const urlProblem = checkDeclarationUrl(parsed.toString(), policy);
|
|
64
|
+
if (urlProblem) {
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
failure: {
|
|
68
|
+
code: "untrusted_client_url",
|
|
69
|
+
message: urlProblem.message,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
let retrieved;
|
|
74
|
+
try {
|
|
75
|
+
retrieved = await fetcher(parsed.toString());
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
return {
|
|
79
|
+
ok: false,
|
|
80
|
+
failure: {
|
|
81
|
+
code: "fetch_failed",
|
|
82
|
+
message: err instanceof Error ? err.message : String(err),
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (!retrieved || retrieved.status !== 200) {
|
|
87
|
+
return {
|
|
88
|
+
ok: false,
|
|
89
|
+
failure: {
|
|
90
|
+
code: "fetch_failed",
|
|
91
|
+
message: `client_id document returned ${retrieved?.status ?? "no response"}`,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (retrieved.body.length > MAX_CLIENT_DOCUMENT_BYTES) {
|
|
96
|
+
return {
|
|
97
|
+
ok: false,
|
|
98
|
+
failure: {
|
|
99
|
+
code: "too_large",
|
|
100
|
+
message: `client_id document exceeds ${MAX_CLIENT_DOCUMENT_BYTES} bytes`,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// A redirect may not escape the gate: re-check where we actually landed.
|
|
105
|
+
const finalProblem = checkDeclarationUrl(retrieved.finalUrl, policy);
|
|
106
|
+
if (finalProblem) {
|
|
107
|
+
return {
|
|
108
|
+
ok: false,
|
|
109
|
+
failure: {
|
|
110
|
+
code: "untrusted_client_url",
|
|
111
|
+
message: `client_id document redirected to an untrusted location: ${finalProblem.message}`,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
let document;
|
|
116
|
+
try {
|
|
117
|
+
document = JSON.parse(retrieved.body);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return {
|
|
121
|
+
ok: false,
|
|
122
|
+
failure: {
|
|
123
|
+
code: "invalid_document",
|
|
124
|
+
message: "client_id document is not valid JSON",
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (!Array.isArray(document.redirect_uris)) {
|
|
129
|
+
return {
|
|
130
|
+
ok: false,
|
|
131
|
+
failure: {
|
|
132
|
+
code: "invalid_document",
|
|
133
|
+
message: "client_id document declares no redirect_uris",
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// A document that declares no usable name gets none, rather than an empty
|
|
138
|
+
// one. `resolveRequesterIdentity` falls back through inline metadata to the
|
|
139
|
+
// client_id itself, so an absent name must be absent -- a `{ name: "" }`
|
|
140
|
+
// would outrank the inline display and render a blank requester.
|
|
141
|
+
const documentName = typeof document.client_name === "string" && document.client_name.length > 0
|
|
142
|
+
? document.client_name
|
|
143
|
+
: undefined;
|
|
144
|
+
// The identity check: the document must assert the URL it came from.
|
|
145
|
+
// Without this, any host could publish a document claiming to be someone
|
|
146
|
+
// else's client_id.
|
|
147
|
+
const candidate = {
|
|
148
|
+
client_id: String(document.client_id ?? ""),
|
|
149
|
+
...(documentName && { display: { name: documentName } }),
|
|
150
|
+
https: true,
|
|
151
|
+
retrieved_from: retrieved.finalUrl,
|
|
152
|
+
};
|
|
153
|
+
const verified = verifyClientIdDocument(candidate);
|
|
154
|
+
if (!verified) {
|
|
155
|
+
return {
|
|
156
|
+
ok: false,
|
|
157
|
+
failure: {
|
|
158
|
+
code: "client_id_mismatch",
|
|
159
|
+
message: "client_id document does not assert the URL it was retrieved from",
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
const redirectUris = document.redirect_uris.filter((uri) => typeof uri === "string" && uri.length > 0);
|
|
164
|
+
if (redirectUris.length === 0) {
|
|
165
|
+
return {
|
|
166
|
+
ok: false,
|
|
167
|
+
failure: {
|
|
168
|
+
code: "invalid_document",
|
|
169
|
+
message: "client_id document declares no usable redirect_uris",
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
ok: true,
|
|
175
|
+
policy: { client_id: clientId, redirect_uris: redirectUris },
|
|
176
|
+
verifiedDomain: verified.verifiedDomain,
|
|
177
|
+
// The same document that earned redirect admission, so the caller can
|
|
178
|
+
// resolve the displayed requester identity from it rather than from the
|
|
179
|
+
// client's inline assertion.
|
|
180
|
+
document: candidate,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=client-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-identity.js","sourceRoot":"","sources":["../../src/pdpp/client-identity.ts"],"names":[],"mappings":"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"}
|