@canopy-io/node 0.7.1 → 0.8.0
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/CHANGELOG.md +16 -0
- package/README.md +56 -14
- package/dist/index.cjs +88 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +99 -22
- package/dist/index.d.ts +99 -22
- package/dist/index.js +87 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -550,7 +550,7 @@ interface paths {
|
|
|
550
550
|
put?: never;
|
|
551
551
|
/**
|
|
552
552
|
* Set an identity's password (admin)
|
|
553
|
-
* @description Sets an identity's password directly (server-to-server admin), primarily for migrating users off a legacy store without the user present. Reuses the argon2id + HaveIBeenPwned path, so a breached password returns `400`;
|
|
553
|
+
* @description Sets an identity's password directly (server-to-server admin), primarily for migrating users off a legacy store without the user present. Reuses the argon2id + HaveIBeenPwned path, so a breached password returns `400`; any active failed-login lockout is cleared, and the identity's active sessions are revoked so a rotated credential can't keep a stale session alive. Returns `204 No Content`; returns `404` when the identity has no membership in this Environment.
|
|
554
554
|
*/
|
|
555
555
|
post: operations["ApiIdentitiesController_setIdentityPassword"];
|
|
556
556
|
delete?: never;
|
|
@@ -588,7 +588,7 @@ interface paths {
|
|
|
588
588
|
};
|
|
589
589
|
/**
|
|
590
590
|
* List an identity's active sessions (admin)
|
|
591
|
-
* @description Lists an identity's active sessions (server-to-server admin): the rows a customer reads to confirm from its own side that a sign-out took, or to show a person where they are signed in. Each row is a session's current refresh token, so `id` changes on every refresh. Returns `404` when the identity has no membership in this Environment.
|
|
591
|
+
* @description Lists an identity's active sessions in the caller's Environment (server-to-server admin): the rows a customer reads to confirm from its own side that a sign-out took, or to show a person where they are signed in. Each row is a session's current refresh token, so `id` changes on every refresh. Sessions the identity holds in its other Environments are not listed. Returns `404` when the identity has no membership in this Environment.
|
|
592
592
|
*/
|
|
593
593
|
get: operations["ApiIdentitiesController_listIdentitySessions"];
|
|
594
594
|
put?: never;
|
|
@@ -611,7 +611,7 @@ interface paths {
|
|
|
611
611
|
post?: never;
|
|
612
612
|
/**
|
|
613
613
|
* Revoke one of an identity's sessions (admin)
|
|
614
|
-
* @description Revokes one of an identity's sessions (server-to-server admin) by marking its refresh token revoked, so the next refresh from that device returns `401` while every other session carries on. Audited as `identity.session.revoked`, the same row the person's own per-session sign-out writes. Returns `204 No Content`; returns `404` when the identity has no membership in this Environment, or when the session is not the identity's or is already revoked.
|
|
614
|
+
* @description Revokes one of an identity's sessions in the caller's Environment (server-to-server admin) by marking its refresh token revoked, so the next refresh from that device returns `401` while every other session carries on. Audited as `identity.session.revoked`, the same row the person's own per-session sign-out writes. Returns `204 No Content`; returns `404` when the identity has no membership in this Environment, or when the session is not the identity's, belongs to another Environment, or is already revoked.
|
|
615
615
|
*/
|
|
616
616
|
delete: operations["ApiIdentitiesController_revokeIdentitySession"];
|
|
617
617
|
options?: never;
|
|
@@ -630,7 +630,7 @@ interface paths {
|
|
|
630
630
|
put?: never;
|
|
631
631
|
/**
|
|
632
632
|
* Revoke all of an identity's sessions (admin)
|
|
633
|
-
* @description Revokes all of an identity's sessions (server-to-server admin) by marking every active refresh token revoked, so the next refresh on any device returns `401` and the user must sign in again. In-flight access tokens remain valid until their short TTL lapses. Idempotent — revoking when no tokens are active is a no-op. Audits twice: `identity.sessions.admin_revoked` for the identity's own security log, and `session.all_revoked`, the subscribable webhook event, so a revoke made here reaches subscribers exactly as one made from the Console does. Returns `204 No Content`; returns `404` when the identity has no membership in this Environment.
|
|
633
|
+
* @description Revokes all of an identity's sessions in the caller's Environment (server-to-server admin) by marking every active refresh token it holds there revoked, so the next refresh on any device returns `401` and the user must sign in again. Sessions in the identity's other Environments are left alone; the Console's account route is the one that signs a person out everywhere. In-flight access tokens remain valid until their short TTL lapses. Idempotent — revoking when no tokens are active is a no-op. Audits twice: `identity.sessions.admin_revoked` for the identity's own security log, and `session.all_revoked`, the subscribable webhook event, so a revoke made here reaches subscribers exactly as one made from the Console does. Returns `204 No Content`; returns `404` when the identity has no membership in this Environment.
|
|
634
634
|
*/
|
|
635
635
|
post: operations["ApiIdentitiesController_revokeIdentitySessions"];
|
|
636
636
|
delete?: never;
|
|
@@ -892,7 +892,7 @@ interface paths {
|
|
|
892
892
|
};
|
|
893
893
|
/**
|
|
894
894
|
* List hierarchy (scoped tree)
|
|
895
|
-
* @description Returns the caller's accessible hierarchy as a nested tree for the current Environment, each node annotated with `access_state`, `can_access`, and `can_manage`. `user` principals (dashboard) see the full tree; API-key principals see only the subtree their `access_mode`/scopes grant — `full_access` unlocks everything, while scoped keys see nodes reachable via `hierarchy.view`. The response also includes a `scope` block listing `accessible_node_ids`, `scope_root_node_ids`, and `entry_node_ids`.
|
|
895
|
+
* @description Returns the caller's accessible hierarchy as a nested tree for the current Environment, each node annotated with `access_state`, `can_access`, and `can_manage`. `user` principals (dashboard), which need the Console capability covering `hierarchy.view`, see the full tree; API-key principals see only the subtree their `access_mode`/scopes grant — `full_access` unlocks everything, while scoped keys see nodes reachable via `hierarchy.view`. The response also includes a `scope` block listing `accessible_node_ids`, `scope_root_node_ids`, and `entry_node_ids`.
|
|
896
896
|
*/
|
|
897
897
|
get: operations["ApiNodesController_listNodes"];
|
|
898
898
|
put?: never;
|
|
@@ -2362,7 +2362,7 @@ interface paths {
|
|
|
2362
2362
|
put?: never;
|
|
2363
2363
|
/**
|
|
2364
2364
|
* Create a new API key
|
|
2365
|
-
* @description Issues a new API key in the active Application, scoped to the current Environment. The full `cnpy_`-prefixed secret is returned in the `key` field of the response and is not recoverable afterward, only a masked `key_preview` and metadata persist; the one exception is a retry carrying the same `Idempotency-Key` within 24 hours, which replays this response. `access_mode: "scoped"` requires a non-empty `scopes` array and enforces it on every authorization check; `access_mode: "full_access"` forbids `scopes` and bypasses RBAC entirely within the Application. Pass `expires_at` (ISO 8601) for an expiring key or omit it for none. Supports `Idempotency-Key` for safe retries, emits an `api_key.created` event, and is limited to 20 requests a minute per caller. A scope the platform does not offer is refused with `400`.
|
|
2365
|
+
* @description Issues a new API key in the active Application, scoped to the current Environment. The full `cnpy_`-prefixed secret is returned in the `key` field of the response and is not recoverable afterward, only a masked `key_preview` and metadata persist; the one exception is a retry carrying the same `Idempotency-Key` within 24 hours, which replays this response. `access_mode: "scoped"` requires a non-empty `scopes` array and enforces it on every authorization check; `access_mode: "full_access"` forbids `scopes` and bypasses RBAC entirely within the Application. Pass `expires_at` (ISO 8601) for an expiring key or omit it for none. Supports `Idempotency-Key` for safe retries, emits an `api_key.created` event, and is limited to 20 requests a minute per caller. A scope the platform does not offer is refused with `400`. A scoped API key can create only scoped keys whose scopes it holds itself; asking for more is refused with `403`.
|
|
2366
2366
|
*/
|
|
2367
2367
|
post: operations["ApiApiKeysController_create"];
|
|
2368
2368
|
delete?: never;
|
|
@@ -3963,7 +3963,7 @@ interface components {
|
|
|
3963
3963
|
/** Format: date-time */
|
|
3964
3964
|
created_at: string;
|
|
3965
3965
|
/**
|
|
3966
|
-
* @description The issuer this client's tokens name, which a relying party configures: `https://<custom auth domain>` while the Environment has an active one, else the
|
|
3966
|
+
* @description The issuer this client's tokens name, which a relying party configures: `https://<custom auth domain>` while the Environment has an active one, else the Environment's own, `<platform origin>/environments/<environment_id>`. Its discovery document is at `<issuer>/.well-known/openid-configuration`.
|
|
3967
3967
|
* @example https://auth.yourapp.com
|
|
3968
3968
|
*/
|
|
3969
3969
|
issuer: string;
|
|
@@ -4000,7 +4000,7 @@ interface components {
|
|
|
4000
4000
|
/** Format: date-time */
|
|
4001
4001
|
created_at: string;
|
|
4002
4002
|
/**
|
|
4003
|
-
* @description The issuer this client's tokens name, which a relying party configures: `https://<custom auth domain>` while the Environment has an active one, else the
|
|
4003
|
+
* @description The issuer this client's tokens name, which a relying party configures: `https://<custom auth domain>` while the Environment has an active one, else the Environment's own, `<platform origin>/environments/<environment_id>`. Its discovery document is at `<issuer>/.well-known/openid-configuration`.
|
|
4004
4004
|
* @example https://auth.yourapp.com
|
|
4005
4005
|
*/
|
|
4006
4006
|
issuer: string;
|
|
@@ -4013,6 +4013,7 @@ interface components {
|
|
|
4013
4013
|
};
|
|
4014
4014
|
UpdateOAuthClientDto: {
|
|
4015
4015
|
name?: string;
|
|
4016
|
+
/** @description Replaces the registered redirect URIs. At least one is required, as at creation: a client with none could never complete a sign-in. */
|
|
4016
4017
|
redirect_uris?: string[];
|
|
4017
4018
|
/** @description Where this client may send someone after RP-initiated logout. Matched exactly. An empty array removes every destination, which leaves logout working with nowhere to return to. */
|
|
4018
4019
|
post_logout_redirect_uris?: string[];
|
|
@@ -4053,12 +4054,12 @@ interface components {
|
|
|
4053
4054
|
/** @description API key description */
|
|
4054
4055
|
description?: string;
|
|
4055
4056
|
/**
|
|
4056
|
-
* @description Required. `scoped` enforces the `scopes` array on every authorization check (deny if the requested permission isn't listed). `full_access` bypasses RBAC entirely within the key's Application — every permission is granted. Pick `scoped` whenever possible; `full_access` should be a deliberate choice (use cases: bootstrap automation, trusted backend services that legitimately need App-wide access). `scoped` requires a non-empty `scopes` array; `full_access` forbids `scopes`.
|
|
4057
|
+
* @description Required. `scoped` enforces the `scopes` array on every authorization check (deny if the requested permission isn't listed). `full_access` bypasses RBAC entirely within the key's Application — every permission is granted. Pick `scoped` whenever possible; `full_access` should be a deliberate choice (use cases: bootstrap automation, trusted backend services that legitimately need App-wide access). `scoped` requires a non-empty `scopes` array; `full_access` forbids `scopes`. A scoped API key can create only scoped keys whose scopes it holds itself.
|
|
4057
4058
|
* @enum {string}
|
|
4058
4059
|
*/
|
|
4059
4060
|
access_mode: "scoped" | "full_access";
|
|
4060
4061
|
/** @description Permission scopes this key is authorized for, each one the platform offers (`GET .../api-keys/scopes`). Required and must be non-empty when `access_mode` is `scoped`. Must be omitted when `access_mode` is `full_access`. */
|
|
4061
|
-
scopes?: ("hierarchy.view" | "hierarchy.manage" | "rbac.view_roles" | "rbac.manage_roles" | "rbac.view_assignments" | "rbac.manage_assignments" | "permissions.evaluate" | "identity.view" | "identity.manage" | "api_key.view" | "api_key.manage" | "webhook.view" | "webhook.manage" | "oauth_client.view" | "oauth_client.manage")[];
|
|
4062
|
+
scopes?: ("hierarchy.view" | "hierarchy.manage" | "rbac.view_roles" | "rbac.manage_roles" | "rbac.view_assignments" | "rbac.manage_assignments" | "permissions.evaluate" | "identity.view" | "identity.manage" | "api_key.view" | "api_key.manage" | "webhook.view" | "webhook.manage" | "oauth_client.view" | "oauth_client.manage" | "branding.view" | "branding.manage")[];
|
|
4062
4063
|
/** @description Expiration date (ISO 8601). Omit for no expiration. */
|
|
4063
4064
|
expires_at?: string;
|
|
4064
4065
|
};
|
|
@@ -7682,7 +7683,7 @@ interface operations {
|
|
|
7682
7683
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
7683
7684
|
};
|
|
7684
7685
|
};
|
|
7685
|
-
/** @description The identity is not found, or the session does not belong to it or is already revoked */
|
|
7686
|
+
/** @description The identity is not found, or the session does not belong to it, belongs to another Environment, or is already revoked */
|
|
7686
7687
|
404: {
|
|
7687
7688
|
headers: {
|
|
7688
7689
|
[name: string]: unknown;
|
|
@@ -7693,7 +7694,7 @@ interface operations {
|
|
|
7693
7694
|
* "error": {
|
|
7694
7695
|
* "statusCode": 404,
|
|
7695
7696
|
* "code": null,
|
|
7696
|
-
* "message": "The identity is not found, or the session does not belong to it or is already revoked",
|
|
7697
|
+
* "message": "The identity is not found, or the session does not belong to it, belongs to another Environment, or is already revoked",
|
|
7697
7698
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
7698
7699
|
* "path": "/api/v1/identities/{id}/sessions/{sessionId}",
|
|
7699
7700
|
* "method": "DELETE"
|
|
@@ -13246,6 +13247,27 @@ interface operations {
|
|
|
13246
13247
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
13247
13248
|
};
|
|
13248
13249
|
};
|
|
13250
|
+
/** @description The caller is an organization administrator and the member also belongs to another organization in the Environment; the second factor is held once per identity, so only the application's administrators may reset it (`organization.member_mfa_shared`) */
|
|
13251
|
+
409: {
|
|
13252
|
+
headers: {
|
|
13253
|
+
[name: string]: unknown;
|
|
13254
|
+
};
|
|
13255
|
+
content: {
|
|
13256
|
+
/**
|
|
13257
|
+
* @example {
|
|
13258
|
+
* "error": {
|
|
13259
|
+
* "statusCode": 409,
|
|
13260
|
+
* "code": null,
|
|
13261
|
+
* "message": "The caller is an organization administrator and the member also belongs to another organization in the Environment; the second factor is held once per identity, so only the application's administrators may reset it (`organization.member_mfa_shared`)",
|
|
13262
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
13263
|
+
* "path": "/api/v1/organizations/{id}/members/{identityId}/mfa/reset",
|
|
13264
|
+
* "method": "POST"
|
|
13265
|
+
* }
|
|
13266
|
+
* }
|
|
13267
|
+
*/
|
|
13268
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
13269
|
+
};
|
|
13270
|
+
};
|
|
13249
13271
|
};
|
|
13250
13272
|
};
|
|
13251
13273
|
ApiOrganizationsController_listInvites: {
|
|
@@ -19166,7 +19188,7 @@ interface operations {
|
|
|
19166
19188
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
19167
19189
|
};
|
|
19168
19190
|
};
|
|
19169
|
-
/** @description
|
|
19191
|
+
/** @description The bearer token is not an admin or platform token, or the caller lacks the permission this operation checks: a scoped API key without that scope, an admin without the Account capability that covers it, or, for a node-scoped check, a node outside this Environment */
|
|
19170
19192
|
403: {
|
|
19171
19193
|
headers: {
|
|
19172
19194
|
[name: string]: unknown;
|
|
@@ -19177,7 +19199,7 @@ interface operations {
|
|
|
19177
19199
|
* "error": {
|
|
19178
19200
|
* "statusCode": 403,
|
|
19179
19201
|
* "code": null,
|
|
19180
|
-
* "message": "
|
|
19202
|
+
* "message": "The bearer token is not an admin or platform token, or the caller lacks the permission this operation checks: a scoped API key without that scope, an admin without the Account capability that covers it, or, for a node-scoped check, a node outside this Environment",
|
|
19181
19203
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
19182
19204
|
* "path": "/api/v1/branding",
|
|
19183
19205
|
* "method": "GET"
|
|
@@ -19255,7 +19277,7 @@ interface operations {
|
|
|
19255
19277
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
19256
19278
|
};
|
|
19257
19279
|
};
|
|
19258
|
-
/** @description
|
|
19280
|
+
/** @description The bearer token is not an admin or platform token, or the caller lacks the permission this operation checks: a scoped API key without that scope, an admin without the Account capability that covers it, or, for a node-scoped check, a node outside this Environment */
|
|
19259
19281
|
403: {
|
|
19260
19282
|
headers: {
|
|
19261
19283
|
[name: string]: unknown;
|
|
@@ -19266,7 +19288,7 @@ interface operations {
|
|
|
19266
19288
|
* "error": {
|
|
19267
19289
|
* "statusCode": 403,
|
|
19268
19290
|
* "code": null,
|
|
19269
|
-
* "message": "
|
|
19291
|
+
* "message": "The bearer token is not an admin or platform token, or the caller lacks the permission this operation checks: a scoped API key without that scope, an admin without the Account capability that covers it, or, for a node-scoped check, a node outside this Environment",
|
|
19270
19292
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
19271
19293
|
* "path": "/api/v1/branding",
|
|
19272
19294
|
* "method": "GET"
|
|
@@ -20882,7 +20904,7 @@ interface operations {
|
|
|
20882
20904
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
20883
20905
|
};
|
|
20884
20906
|
};
|
|
20885
|
-
/** @description The
|
|
20907
|
+
/** @description The caller lacks `api_key.manage` (a scoped API key without that scope, or an admin without the Account capability that covers it), or is a scoped API key asking for more than it holds: `full_access`, or a scope outside its own (`api_key.access_exceeds_caller`) */
|
|
20886
20908
|
403: {
|
|
20887
20909
|
headers: {
|
|
20888
20910
|
[name: string]: unknown;
|
|
@@ -20893,10 +20915,10 @@ interface operations {
|
|
|
20893
20915
|
* "error": {
|
|
20894
20916
|
* "statusCode": 403,
|
|
20895
20917
|
* "code": null,
|
|
20896
|
-
* "message": "The
|
|
20918
|
+
* "message": "The caller lacks `api_key.manage` (a scoped API key without that scope, or an admin without the Account capability that covers it), or is a scoped API key asking for more than it holds: `full_access`, or a scope outside its own (`api_key.access_exceeds_caller`)",
|
|
20897
20919
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
20898
20920
|
* "path": "/api/v1/api-keys",
|
|
20899
|
-
* "method": "
|
|
20921
|
+
* "method": "POST"
|
|
20900
20922
|
* }
|
|
20901
20923
|
* }
|
|
20902
20924
|
*/
|
|
@@ -21942,8 +21964,9 @@ declare class CanopyConnectionError extends Error {
|
|
|
21942
21964
|
* whole point of verifying a signature rather than calling an endpoint.
|
|
21943
21965
|
*
|
|
21944
21966
|
* Branch on `code`; it follows the same dot-notation contract as the API's own
|
|
21945
|
-
* codes. Every one
|
|
21946
|
-
*
|
|
21967
|
+
* codes. Every one but `token.jwks_unavailable` means the same thing to an
|
|
21968
|
+
* HTTP caller, 401; that one means the keys could not be read, so the token may
|
|
21969
|
+
* be good and the answer is 503. {@link tokenErrorStatus} maps them.
|
|
21947
21970
|
*/
|
|
21948
21971
|
declare class CanopyTokenError extends Error {
|
|
21949
21972
|
readonly name = "CanopyTokenError";
|
|
@@ -21960,6 +21983,8 @@ declare class CanopyTokenError extends Error {
|
|
|
21960
21983
|
* - `token.audience_mismatch` — `aud` does not include the configured audience
|
|
21961
21984
|
* - `token.audience_unverified` — token has an `aud` but none was configured
|
|
21962
21985
|
* - `token.preauth_not_allowed` — a pre-auth token, which grants no access
|
|
21986
|
+
* - `token.type_not_allowed` — a principal type the verifier does not accept
|
|
21987
|
+
* (see `allowedTypes`)
|
|
21963
21988
|
*/
|
|
21964
21989
|
readonly code: string;
|
|
21965
21990
|
constructor(code: string, message: string, options?: {
|
|
@@ -21991,6 +22016,44 @@ declare function isCanopyError(error: unknown): error is CanopyError;
|
|
|
21991
22016
|
declare function isCanopyConnectionError(error: unknown): error is CanopyConnectionError;
|
|
21992
22017
|
declare function isCanopyTokenError(error: unknown): error is CanopyTokenError;
|
|
21993
22018
|
|
|
22019
|
+
/**
|
|
22020
|
+
* The HTTP answer a failure should become, for code that verifies tokens or
|
|
22021
|
+
* authorizes requests outside the NestJS guards (Express, Fastify, a worker).
|
|
22022
|
+
* The guards use the same mapping, so every integration answers alike.
|
|
22023
|
+
*/
|
|
22024
|
+
interface FailureStatus {
|
|
22025
|
+
status: number;
|
|
22026
|
+
/** A message safe to send to the caller; the detail stays on the error. */
|
|
22027
|
+
message: string;
|
|
22028
|
+
}
|
|
22029
|
+
/**
|
|
22030
|
+
* The answer for a failed {@link TokenVerifier.verify}: `401` when the token is
|
|
22031
|
+
* at fault, `503` when the signing keys could not be read and the token may be
|
|
22032
|
+
* perfectly good.
|
|
22033
|
+
*
|
|
22034
|
+
* The difference matters. A client reads `401` as "your token is stale",
|
|
22035
|
+
* discards a valid one and asks for another, which aims a refresh storm at an
|
|
22036
|
+
* issuer that is already down, and an outage that only emits 4xx is invisible
|
|
22037
|
+
* to anything watching for 5xx.
|
|
22038
|
+
*
|
|
22039
|
+
* Anything that is not a token error is returned as `500`: it is a bug, not a
|
|
22040
|
+
* verdict on the token.
|
|
22041
|
+
*/
|
|
22042
|
+
declare function tokenErrorStatus(error: unknown): FailureStatus;
|
|
22043
|
+
/**
|
|
22044
|
+
* The answer for a failed authorization check ({@link LocalAuthorizer.evaluate}
|
|
22045
|
+
* or a {@link Canopy} call that decides access). Every branch denies; they say
|
|
22046
|
+
* different things so an incident is diagnosable:
|
|
22047
|
+
*
|
|
22048
|
+
* - `500` when the authorizer cannot see far enough to decide (a credential
|
|
22049
|
+
* that cannot read the hierarchy), when Canopy rejected our own credential,
|
|
22050
|
+
* when the endpoint is not served (an SDK newer than the API), or on a 4xx
|
|
22051
|
+
* nobody anticipated. No retry fixes these.
|
|
22052
|
+
* - `503` when Canopy did not answer, or answered 429 or 5xx.
|
|
22053
|
+
* - `403` when Canopy answered that the identity is not in this Environment.
|
|
22054
|
+
*/
|
|
22055
|
+
declare function authorizationErrorStatus(error: unknown): FailureStatus;
|
|
22056
|
+
|
|
21994
22057
|
interface TokenVerifierOptions {
|
|
21995
22058
|
/**
|
|
21996
22059
|
* The Environment whose tokens are accepted. Every Environment is its own
|
|
@@ -22048,6 +22111,16 @@ interface TokenVerifierOptions {
|
|
|
22048
22111
|
* request path, so an unbounded read there is an unbounded request.
|
|
22049
22112
|
*/
|
|
22050
22113
|
jwksTimeoutMs?: number;
|
|
22114
|
+
/**
|
|
22115
|
+
* The principal types accepted, matched against the `type` claim. Defaults to
|
|
22116
|
+
* `["identity"]`: the people who sign in to your application.
|
|
22117
|
+
*
|
|
22118
|
+
* Canopy also signs tokens for its own administrators (`user`), its staff
|
|
22119
|
+
* (`platform`) and, for some flows, API keys (`api_key`), all with the same
|
|
22120
|
+
* keys and issuer. A backend that serves your end users should accept none
|
|
22121
|
+
* of them, so they are refused unless you name them here.
|
|
22122
|
+
*/
|
|
22123
|
+
allowedTypes?: ReadonlyArray<CanopyTokenClaims["type"]>;
|
|
22051
22124
|
/** Injectable for tests and for runtimes with a non-global fetch. */
|
|
22052
22125
|
fetch?: typeof globalThis.fetch;
|
|
22053
22126
|
}
|
|
@@ -22138,11 +22211,14 @@ declare class TokenVerifier {
|
|
|
22138
22211
|
private readonly jwksTimeoutMs;
|
|
22139
22212
|
private readonly clockToleranceSec;
|
|
22140
22213
|
private readonly allowPreAuthTokens;
|
|
22214
|
+
private readonly allowedTypes;
|
|
22141
22215
|
private readonly fetchImpl;
|
|
22142
22216
|
/** Imported keys by `kid`, so a repeat verification skips the import cost. */
|
|
22143
22217
|
private keys;
|
|
22144
22218
|
private keysFetchedAt;
|
|
22145
22219
|
private lastFetchAttemptAt;
|
|
22220
|
+
/** Whether the latest read of the key set failed, for an unknown `kid`. */
|
|
22221
|
+
private lastFetchFailed;
|
|
22146
22222
|
/** In-flight fetch, so a burst of requests triggers one call, not N. */
|
|
22147
22223
|
private inFlight;
|
|
22148
22224
|
constructor(options?: TokenVerifierOptions);
|
|
@@ -22186,6 +22262,7 @@ declare class TokenVerifier {
|
|
|
22186
22262
|
private shouldRefresh;
|
|
22187
22263
|
private refreshKeys;
|
|
22188
22264
|
private fetchKeys;
|
|
22265
|
+
private readKeys;
|
|
22189
22266
|
}
|
|
22190
22267
|
|
|
22191
22268
|
/**
|
|
@@ -22232,4 +22309,4 @@ type WebhookEventData<Name extends WebhookEventName> = WebhookEvent<Name>["data"
|
|
|
22232
22309
|
*/
|
|
22233
22310
|
declare function isWebhookEvent<Name extends WebhookEventName>(delivery: WebhookDelivery, name: Name): delivery is WebhookEvent<Name>;
|
|
22234
22311
|
|
|
22235
|
-
export { type AssignmentItem, Assignments, type CallOptions, Canopy, CanopyAuthorizerError, CanopyClient, type CanopyClientOptions, CanopyConnectionError, CanopyError, type CanopyErrorBody, type CanopyOrgContext, type CanopyTokenClaims, CanopyTokenError, type Collection, type ConcurrencyOptions, type ConditionalResult, type CursorPagination, Identities, type IdentityAssignmentItem, type IdentityItem, type IdentitySessionItem, type LocalAuthorizationQuery, LocalAuthorizer, type LocalAuthorizerOptions, type LocalAuthorizerStats, MAX_TTL_MS, type OffsetPagination, type OperationId, type OrganizationInviteItem, type OrganizationItem, type OrganizationMemberItem, Organizations, type PageFetcher, type PageParams, type PaginateOptions, type Pagination, Paginator, type PartialSuccess, type PermissionItem, Permissions, type QueryParams, type RequestBody, type RequestOptions, type ResponseBody, type RoleItem, Roles, type Schema, TokenVerifier, type TokenVerifierOptions, type WebhookDelivery, type WebhookEvent, type WebhookEventData, type WebhookEventName, type components, isCanopyAuthorizerError, isCanopyConnectionError, isCanopyError, isCanopyTokenError, isCursorPagination, isWebhookEvent, type operations, orgContext, paginate, type paths, withConcurrency };
|
|
22312
|
+
export { type AssignmentItem, Assignments, type CallOptions, Canopy, CanopyAuthorizerError, CanopyClient, type CanopyClientOptions, CanopyConnectionError, CanopyError, type CanopyErrorBody, type CanopyOrgContext, type CanopyTokenClaims, CanopyTokenError, type Collection, type ConcurrencyOptions, type ConditionalResult, type CursorPagination, type FailureStatus, Identities, type IdentityAssignmentItem, type IdentityItem, type IdentitySessionItem, type LocalAuthorizationQuery, LocalAuthorizer, type LocalAuthorizerOptions, type LocalAuthorizerStats, MAX_TTL_MS, type OffsetPagination, type OperationId, type OrganizationInviteItem, type OrganizationItem, type OrganizationMemberItem, Organizations, type PageFetcher, type PageParams, type PaginateOptions, type Pagination, Paginator, type PartialSuccess, type PermissionItem, Permissions, type QueryParams, type RequestBody, type RequestOptions, type ResponseBody, type RoleItem, Roles, type Schema, TokenVerifier, type TokenVerifierOptions, type WebhookDelivery, type WebhookEvent, type WebhookEventData, type WebhookEventName, authorizationErrorStatus, type components, isCanopyAuthorizerError, isCanopyConnectionError, isCanopyError, isCanopyTokenError, isCursorPagination, isWebhookEvent, type operations, orgContext, paginate, type paths, tokenErrorStatus, withConcurrency };
|