@cauthyhq/node 1.0.0 → 1.1.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 +43 -0
- package/README.md +4 -0
- package/dist/{cauthy-ClP5orP4.d.mts → cauthy-Bn-i7cKD.d.mts} +24 -1
- package/dist/{cauthy-B6Sm3T8M.d.ts → cauthy-Wy-YDGrM.d.ts} +24 -1
- package/dist/express.d.mts +1 -1
- package/dist/express.d.ts +1 -1
- package/dist/fastify.d.mts +1 -1
- package/dist/fastify.d.ts +1 -1
- package/dist/hono.d.mts +1 -1
- package/dist/hono.d.ts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +18 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +18 -7
- package/dist/index.mjs.map +1 -1
- package/dist/mcp.js.map +1 -1
- package/dist/mcp.mjs.map +1 -1
- package/dist/next.d.mts +1 -1
- package/dist/next.d.ts +1 -1
- package/dist/testing.d.mts +13 -1
- package/dist/testing.d.ts +13 -1
- package/dist/testing.js +93 -5
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +91 -4
- package/dist/testing.mjs.map +1 -1
- package/package.json +8 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.1.0 — security release
|
|
4
|
+
|
|
5
|
+
Cauthy now marks the tokens a machine holds, and names the client a person's token was issued through. This release makes `verifyToken` use those marks. Refusing a machine's token where a person is expected is a fix, not a break, so it ships as a minor version: upgrade.
|
|
6
|
+
|
|
7
|
+
### Security
|
|
8
|
+
|
|
9
|
+
- **A client's own token no longer passes as a person's.** A `client_credentials` token carries `token_use: "client"` and the client's public `client_id`. `verifyToken`, `createTokenVerifier`, `auth.verifyToken` and `auth.tokenVerifier` now refuse it with the reason `client_token` (rule R13 of the spec's `verification/rules.md`), by the claim's presence, whatever its value. In 1.0 such a token was accepted as a person whose `userId` was the client's id.
|
|
10
|
+
- **By contract, a person's token issued through another client is refused** with `wrong_client` (rule R15): `auth.verifyToken` and `auth.tokenVerifier` check the token's `azp` against the link's sign-in client. A token with no `azp` passes. A call that names another `clientId` in contract mode is a `CauthyConfigError`.
|
|
11
|
+
- `token_use` and `azp`, when present, must be strings (`invalid_claim` otherwise, rule R8).
|
|
12
|
+
|
|
13
|
+
### Backends that serve machines
|
|
14
|
+
|
|
15
|
+
If an endpoint is called by machines with a `client_credentials` token, pass `allowClientTokens: true` to the verifier that guards it:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
const verifyMachine = auth.tokenVerifier({ allowClientTokens: true })
|
|
19
|
+
const who = await verifyMachine(request)
|
|
20
|
+
who.clientId // the client's public id; who.userId is its internal id
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Without it those calls get `client_token` (answer 401) after the upgrade.
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- `TokenIdentity.authorizedParty`: the token's `azp`, the client a person's token was issued through; absent when none was named.
|
|
28
|
+
- `TokenIdentity.clientId`: the token's `client_id` (a client's own token, with `allowClientTokens`; an AI agent's).
|
|
29
|
+
- `VerifyTokenOptions.allowClientTokens` (default `false`) and `VerifyTokenOptions.clientId` (default none; by contract, the link's sign-in client).
|
|
30
|
+
- `TokenRefusal` gains `client_token` and `wrong_client`.
|
|
31
|
+
|
|
32
|
+
### Notes
|
|
33
|
+
|
|
34
|
+
- Cauthy now answers its JWKS with `max-age=300` and publishes a key at least that long before it signs with it. Nothing changes here: the keys are kept for the answer's `max-age` and fetched again on an unknown `kid`.
|
|
35
|
+
- A session that began through a client renews only through it. The SDK already renews with the `clientId` it signed in with, and sends that `clientId` on its own screens' calls: keep one `clientId` per deployment.
|
|
36
|
+
|
|
37
|
+
### Development
|
|
38
|
+
|
|
39
|
+
- vitest 4.1.12, fastify 5.12.8 (tests), and postcss 8.5.32 and esbuild 0.28.2 by override: every open advisory was in development dependencies only. `npm audit` reports none.
|
|
40
|
+
|
|
41
|
+
## 1.0.0
|
|
42
|
+
|
|
43
|
+
First release: the server half of `cauthy-auth` 0.42 (see the README, "Moving from cauthy-auth").
|
package/README.md
CHANGED
|
@@ -91,6 +91,7 @@ import { auth } from './auth'
|
|
|
91
91
|
// issuer the instance's own (CAUTHY_ISSUER, or the contract)
|
|
92
92
|
// tenantId by contract, the link's tenant_id; otherwise the `tenantId` option or CAUTHY_TENANT_ID
|
|
93
93
|
// audience the `audience` option or CAUTHY_AUDIENCE: your Cauthy's JWT_AUDIENCE (Cauthy has no default for it)
|
|
94
|
+
// clientId by contract, the link's sign-in client: a person's token issued through another is refused (wrong_client)
|
|
94
95
|
const verify = auth.tokenVerifier() // throws CauthyConfigError now if one is missing
|
|
95
96
|
const who = await verify(request) // or: await auth.verifyToken(request)
|
|
96
97
|
```
|
|
@@ -106,6 +107,8 @@ const verify = createTokenVerifier({ issuer: 'https://id.example.com', audience:
|
|
|
106
107
|
|
|
107
108
|
- **The audience and the workspace are required.** Without them a token issued for another application or workspace would be accepted.
|
|
108
109
|
- A system's own token (`sys` claim, whatever its value) and a guest's token (`anon: true`) are refused where a person is expected. Pass `allowSystem` or `allowAnonymous` for an endpoint that takes them.
|
|
110
|
+
- A client's own token (a `client_credentials` grant: `token_use: "client"`, whatever the value) is refused with `client_token` where a person is expected. A backend that serves machines too passes `allowClientTokens: true`; the identity then carries `clientId`, the client's public id (its `userId` is the client's internal id).
|
|
111
|
+
- `authorizedParty` is the token's `azp`: the client a person's token was issued through, absent when none was named. With `clientId` (by contract, always the link's sign-in client), a token whose `azp` names another client is refused with `wrong_client`; a token with no `azp` passes.
|
|
109
112
|
- Clock tolerance is 30 seconds (`leeway`, 0 to 60). A token over 8192 bytes, with a repeated JSON name, a fractional date or a wrongly typed claim is refused.
|
|
110
113
|
- Keys are fetched from `<issuer>/.well-known/jwks.json` with no redirect, within 5 seconds, at most 64 KiB, and kept for the answer's `max-age`.
|
|
111
114
|
|
|
@@ -171,6 +174,7 @@ It refuses to start when any `CAUTHY_*` variable of the standard mode is also se
|
|
|
171
174
|
CI runs the auth-bff conformance suite at level `strict` against `examples/acme-crm` on an in-memory Cauthy, and the spec's token vectors against `verifyToken`:
|
|
172
175
|
|
|
173
176
|
SPEC_DIR=../cauthy-sdk-spec LEVEL=strict npm run conformance
|
|
177
|
+
SPEC_DIR=../cauthy-sdk-spec LEVEL=switches npm run conformance # also the dashboard switches, on the in-memory Cauthy
|
|
174
178
|
SPEC_DIR=../cauthy-sdk-spec npm run vectors
|
|
175
179
|
|
|
176
180
|
## Security
|
|
@@ -832,13 +832,20 @@ interface TokenIdentity {
|
|
|
832
832
|
system?: string;
|
|
833
833
|
/** Set when the token is a guest's (only with `allowAnonymous`). */
|
|
834
834
|
anonymous?: true;
|
|
835
|
+
/** The client a person's token was issued through (`azp`); absent when none was named. */
|
|
836
|
+
authorizedParty?: string;
|
|
837
|
+
/**
|
|
838
|
+
* The token's `client_id`: on a client's own token (only with
|
|
839
|
+
* `allowClientTokens`), the client's public id; on an AI agent's, the agent's.
|
|
840
|
+
*/
|
|
841
|
+
clientId?: string;
|
|
835
842
|
/** UTC, ISO 8601. */
|
|
836
843
|
expiresAt: string;
|
|
837
844
|
/** The token as it arrived, to pass on. */
|
|
838
845
|
token: string;
|
|
839
846
|
}
|
|
840
847
|
/** Why a token was refused: the closed list of verification/rules.md, and `no_token` when none was given. */
|
|
841
|
-
type TokenRefusal = 'no_token' | 'too_large' | 'malformed' | 'alg_not_allowed' | 'unsupported_header' | 'missing_kid' | 'unknown_kid' | 'weak_key' | 'bad_signature' | 'missing_claim' | 'invalid_claim' | 'wrong_issuer' | 'wrong_audience' | 'expired' | 'not_yet_valid' | 'issued_in_future' | 'wrong_tenant' | 'system_token' | 'anonymous_token';
|
|
848
|
+
type TokenRefusal = 'no_token' | 'too_large' | 'malformed' | 'alg_not_allowed' | 'unsupported_header' | 'missing_kid' | 'unknown_kid' | 'weak_key' | 'bad_signature' | 'missing_claim' | 'invalid_claim' | 'wrong_issuer' | 'wrong_audience' | 'expired' | 'not_yet_valid' | 'issued_in_future' | 'wrong_tenant' | 'system_token' | 'client_token' | 'anonymous_token' | 'wrong_client';
|
|
842
849
|
/**
|
|
843
850
|
* Cauthy's keys could not be fetched (or are not a key set): the token may be
|
|
844
851
|
* good, and the application cannot tell. Answer 503, not 401. It is not a
|
|
@@ -880,6 +887,20 @@ interface VerifyTokenOptions {
|
|
|
880
887
|
allowSystem?: boolean;
|
|
881
888
|
/** Accept a guest's token (`anon: true`). Default: false (rule R14). */
|
|
882
889
|
allowAnonymous?: boolean;
|
|
890
|
+
/**
|
|
891
|
+
* Accept a client's own token (a `token_use` claim, from a
|
|
892
|
+
* `client_credentials` grant) too: for a backend that serves machines as
|
|
893
|
+
* well as people. Default: false, so a machine never passes as a person
|
|
894
|
+
* (rule R13). The identity then carries `clientId`.
|
|
895
|
+
*/
|
|
896
|
+
allowClientTokens?: boolean;
|
|
897
|
+
/**
|
|
898
|
+
* The client this backend signs people in through. When set, a person's
|
|
899
|
+
* token issued through another client (an `azp` naming another) is refused
|
|
900
|
+
* with `wrong_client` (rule R15); a token with no `azp` passes. In contract
|
|
901
|
+
* mode it is the link's sign-in client. Default: none, and `azp` is not checked.
|
|
902
|
+
*/
|
|
903
|
+
clientId?: string;
|
|
883
904
|
}
|
|
884
905
|
/**
|
|
885
906
|
* Cauthy's published keys (K1 to K5 of verification/rules.md): fetched with a
|
|
@@ -990,6 +1011,8 @@ interface Cauthy {
|
|
|
990
1011
|
* an API of this application: `verifyToken` with this instance's issuer, its
|
|
991
1012
|
* workspace (by contract, the link's `tenant_id`; otherwise `tenantId` or
|
|
992
1013
|
* `CAUTHY_TENANT_ID`) and its audience (`audience` or `CAUTHY_AUDIENCE`).
|
|
1014
|
+
* By contract it also refuses a person's token issued through another
|
|
1015
|
+
* client than the link's (`wrong_client`).
|
|
993
1016
|
*/
|
|
994
1017
|
verifyToken(from: string | Request | Headers, options?: Partial<VerifyTokenOptions>): Promise<TokenIdentity>;
|
|
995
1018
|
/** The same, built once: throws `CauthyConfigError` now if the audience or the workspace is missing. */
|
|
@@ -832,13 +832,20 @@ interface TokenIdentity {
|
|
|
832
832
|
system?: string;
|
|
833
833
|
/** Set when the token is a guest's (only with `allowAnonymous`). */
|
|
834
834
|
anonymous?: true;
|
|
835
|
+
/** The client a person's token was issued through (`azp`); absent when none was named. */
|
|
836
|
+
authorizedParty?: string;
|
|
837
|
+
/**
|
|
838
|
+
* The token's `client_id`: on a client's own token (only with
|
|
839
|
+
* `allowClientTokens`), the client's public id; on an AI agent's, the agent's.
|
|
840
|
+
*/
|
|
841
|
+
clientId?: string;
|
|
835
842
|
/** UTC, ISO 8601. */
|
|
836
843
|
expiresAt: string;
|
|
837
844
|
/** The token as it arrived, to pass on. */
|
|
838
845
|
token: string;
|
|
839
846
|
}
|
|
840
847
|
/** Why a token was refused: the closed list of verification/rules.md, and `no_token` when none was given. */
|
|
841
|
-
type TokenRefusal = 'no_token' | 'too_large' | 'malformed' | 'alg_not_allowed' | 'unsupported_header' | 'missing_kid' | 'unknown_kid' | 'weak_key' | 'bad_signature' | 'missing_claim' | 'invalid_claim' | 'wrong_issuer' | 'wrong_audience' | 'expired' | 'not_yet_valid' | 'issued_in_future' | 'wrong_tenant' | 'system_token' | 'anonymous_token';
|
|
848
|
+
type TokenRefusal = 'no_token' | 'too_large' | 'malformed' | 'alg_not_allowed' | 'unsupported_header' | 'missing_kid' | 'unknown_kid' | 'weak_key' | 'bad_signature' | 'missing_claim' | 'invalid_claim' | 'wrong_issuer' | 'wrong_audience' | 'expired' | 'not_yet_valid' | 'issued_in_future' | 'wrong_tenant' | 'system_token' | 'client_token' | 'anonymous_token' | 'wrong_client';
|
|
842
849
|
/**
|
|
843
850
|
* Cauthy's keys could not be fetched (or are not a key set): the token may be
|
|
844
851
|
* good, and the application cannot tell. Answer 503, not 401. It is not a
|
|
@@ -880,6 +887,20 @@ interface VerifyTokenOptions {
|
|
|
880
887
|
allowSystem?: boolean;
|
|
881
888
|
/** Accept a guest's token (`anon: true`). Default: false (rule R14). */
|
|
882
889
|
allowAnonymous?: boolean;
|
|
890
|
+
/**
|
|
891
|
+
* Accept a client's own token (a `token_use` claim, from a
|
|
892
|
+
* `client_credentials` grant) too: for a backend that serves machines as
|
|
893
|
+
* well as people. Default: false, so a machine never passes as a person
|
|
894
|
+
* (rule R13). The identity then carries `clientId`.
|
|
895
|
+
*/
|
|
896
|
+
allowClientTokens?: boolean;
|
|
897
|
+
/**
|
|
898
|
+
* The client this backend signs people in through. When set, a person's
|
|
899
|
+
* token issued through another client (an `azp` naming another) is refused
|
|
900
|
+
* with `wrong_client` (rule R15); a token with no `azp` passes. In contract
|
|
901
|
+
* mode it is the link's sign-in client. Default: none, and `azp` is not checked.
|
|
902
|
+
*/
|
|
903
|
+
clientId?: string;
|
|
883
904
|
}
|
|
884
905
|
/**
|
|
885
906
|
* Cauthy's published keys (K1 to K5 of verification/rules.md): fetched with a
|
|
@@ -990,6 +1011,8 @@ interface Cauthy {
|
|
|
990
1011
|
* an API of this application: `verifyToken` with this instance's issuer, its
|
|
991
1012
|
* workspace (by contract, the link's `tenant_id`; otherwise `tenantId` or
|
|
992
1013
|
* `CAUTHY_TENANT_ID`) and its audience (`audience` or `CAUTHY_AUDIENCE`).
|
|
1014
|
+
* By contract it also refuses a person's token issued through another
|
|
1015
|
+
* client than the link's (`wrong_client`).
|
|
993
1016
|
*/
|
|
994
1017
|
verifyToken(from: string | Request | Headers, options?: Partial<VerifyTokenOptions>): Promise<TokenIdentity>;
|
|
995
1018
|
/** The same, built once: throws `CauthyConfigError` now if the audience or the workspace is missing. */
|
package/dist/express.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
import { S as Session, C as Cauthy } from './cauthy-
|
|
2
|
+
import { S as Session, C as Cauthy } from './cauthy-Bn-i7cKD.mjs';
|
|
3
3
|
import './keys-D5k0omTb.mjs';
|
|
4
4
|
import 'jose';
|
|
5
5
|
import './theme.mjs';
|
package/dist/express.d.ts
CHANGED
package/dist/fastify.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FastifyReply, FastifyPluginAsync, FastifyInstance } from 'fastify';
|
|
2
|
-
import { S as Session, C as Cauthy } from './cauthy-
|
|
2
|
+
import { S as Session, C as Cauthy } from './cauthy-Bn-i7cKD.mjs';
|
|
3
3
|
import './keys-D5k0omTb.mjs';
|
|
4
4
|
import 'jose';
|
|
5
5
|
import './theme.mjs';
|
package/dist/fastify.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FastifyReply, FastifyPluginAsync, FastifyInstance } from 'fastify';
|
|
2
|
-
import { S as Session, C as Cauthy } from './cauthy-
|
|
2
|
+
import { S as Session, C as Cauthy } from './cauthy-Wy-YDGrM.js';
|
|
3
3
|
import './keys-D5k0omTb.js';
|
|
4
4
|
import 'jose';
|
|
5
5
|
import './theme.js';
|
package/dist/hono.d.mts
CHANGED
package/dist/hono.d.ts
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AttributeType, a as CatalogResource, C as Cauthy, b as CauthyApiError, c as CauthyConfigError, d as CauthyEvent, e as CauthyOptions, f as CauthyPact, g as CauthySystem, h as CauthyTokenError, i as CauthyUnavailableError, j as CauthyWebhookError, k as CheckOf, l as CheckQuestion, m as CheckResult, n as CheckRule, o as ConditionalPermission, p as ContractOptions, J as JsonValue, M as MountTarget, N as NewMember, O as Organization, q as OrganizationMember, r as OrganizationRef, P as PactItem, s as PactStatus, t as PermissionOf, u as Permitted, v as Policy, w as PolicyDefinition, x as PolicyPermission, y as PolicyRole, z as PublicSession, B as PushPolicyOptions, R as ReplayStore, D as Resolved, E as ResolvedContract, F as RoleOf, G as STANDARD_VARIABLES, S as Session, H as SessionOrganization, I as SessionStatus, K as SessionUser, L as SystemKey, Q as SystemOptions, T as SystemPolicy, U as TokenIdentity, V as TokenRefusal, W as VerifyTokenOptions, X as VerifyWebhookOptions, Y as can, Z as createCauthy, _ as createSystem, $ as createTokenVerifier, a0 as definePolicy, a1 as failClosed, a2 as memoryReplayStore, a3 as policySource, a4 as pullCatalog, a5 as pullPolicy, a6 as pushCatalog, a7 as pushPolicy, a8 as readContract, a9 as remoteKeys, aa as verifyToken, ab as verifyWebhook } from './cauthy-
|
|
1
|
+
export { A as AttributeType, a as CatalogResource, C as Cauthy, b as CauthyApiError, c as CauthyConfigError, d as CauthyEvent, e as CauthyOptions, f as CauthyPact, g as CauthySystem, h as CauthyTokenError, i as CauthyUnavailableError, j as CauthyWebhookError, k as CheckOf, l as CheckQuestion, m as CheckResult, n as CheckRule, o as ConditionalPermission, p as ContractOptions, J as JsonValue, M as MountTarget, N as NewMember, O as Organization, q as OrganizationMember, r as OrganizationRef, P as PactItem, s as PactStatus, t as PermissionOf, u as Permitted, v as Policy, w as PolicyDefinition, x as PolicyPermission, y as PolicyRole, z as PublicSession, B as PushPolicyOptions, R as ReplayStore, D as Resolved, E as ResolvedContract, F as RoleOf, G as STANDARD_VARIABLES, S as Session, H as SessionOrganization, I as SessionStatus, K as SessionUser, L as SystemKey, Q as SystemOptions, T as SystemPolicy, U as TokenIdentity, V as TokenRefusal, W as VerifyTokenOptions, X as VerifyWebhookOptions, Y as can, Z as createCauthy, _ as createSystem, $ as createTokenVerifier, a0 as definePolicy, a1 as failClosed, a2 as memoryReplayStore, a3 as policySource, a4 as pullCatalog, a5 as pullPolicy, a6 as pushCatalog, a7 as pushPolicy, a8 as readContract, a9 as remoteKeys, aa as verifyToken, ab as verifyWebhook } from './cauthy-Bn-i7cKD.mjs';
|
|
2
2
|
export { K as KeyStore, P as PactKeys, S as StoredKey } from './keys-D5k0omTb.mjs';
|
|
3
3
|
export { CauthyTheme, ImportedTheme, PushThemeOptions, StackmythThemeOptions, StackmythTokens, ThemeFont, ThemeTexts, pushTheme, themeFromStackmyth, tokensFromStackmyth } from './theme.mjs';
|
|
4
4
|
import 'jose';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AttributeType, a as CatalogResource, C as Cauthy, b as CauthyApiError, c as CauthyConfigError, d as CauthyEvent, e as CauthyOptions, f as CauthyPact, g as CauthySystem, h as CauthyTokenError, i as CauthyUnavailableError, j as CauthyWebhookError, k as CheckOf, l as CheckQuestion, m as CheckResult, n as CheckRule, o as ConditionalPermission, p as ContractOptions, J as JsonValue, M as MountTarget, N as NewMember, O as Organization, q as OrganizationMember, r as OrganizationRef, P as PactItem, s as PactStatus, t as PermissionOf, u as Permitted, v as Policy, w as PolicyDefinition, x as PolicyPermission, y as PolicyRole, z as PublicSession, B as PushPolicyOptions, R as ReplayStore, D as Resolved, E as ResolvedContract, F as RoleOf, G as STANDARD_VARIABLES, S as Session, H as SessionOrganization, I as SessionStatus, K as SessionUser, L as SystemKey, Q as SystemOptions, T as SystemPolicy, U as TokenIdentity, V as TokenRefusal, W as VerifyTokenOptions, X as VerifyWebhookOptions, Y as can, Z as createCauthy, _ as createSystem, $ as createTokenVerifier, a0 as definePolicy, a1 as failClosed, a2 as memoryReplayStore, a3 as policySource, a4 as pullCatalog, a5 as pullPolicy, a6 as pushCatalog, a7 as pushPolicy, a8 as readContract, a9 as remoteKeys, aa as verifyToken, ab as verifyWebhook } from './cauthy-
|
|
1
|
+
export { A as AttributeType, a as CatalogResource, C as Cauthy, b as CauthyApiError, c as CauthyConfigError, d as CauthyEvent, e as CauthyOptions, f as CauthyPact, g as CauthySystem, h as CauthyTokenError, i as CauthyUnavailableError, j as CauthyWebhookError, k as CheckOf, l as CheckQuestion, m as CheckResult, n as CheckRule, o as ConditionalPermission, p as ContractOptions, J as JsonValue, M as MountTarget, N as NewMember, O as Organization, q as OrganizationMember, r as OrganizationRef, P as PactItem, s as PactStatus, t as PermissionOf, u as Permitted, v as Policy, w as PolicyDefinition, x as PolicyPermission, y as PolicyRole, z as PublicSession, B as PushPolicyOptions, R as ReplayStore, D as Resolved, E as ResolvedContract, F as RoleOf, G as STANDARD_VARIABLES, S as Session, H as SessionOrganization, I as SessionStatus, K as SessionUser, L as SystemKey, Q as SystemOptions, T as SystemPolicy, U as TokenIdentity, V as TokenRefusal, W as VerifyTokenOptions, X as VerifyWebhookOptions, Y as can, Z as createCauthy, _ as createSystem, $ as createTokenVerifier, a0 as definePolicy, a1 as failClosed, a2 as memoryReplayStore, a3 as policySource, a4 as pullCatalog, a5 as pullPolicy, a6 as pushCatalog, a7 as pushPolicy, a8 as readContract, a9 as remoteKeys, aa as verifyToken, ab as verifyWebhook } from './cauthy-Wy-YDGrM.js';
|
|
2
2
|
export { K as KeyStore, P as PactKeys, S as StoredKey } from './keys-D5k0omTb.js';
|
|
3
3
|
export { CauthyTheme, ImportedTheme, PushThemeOptions, StackmythThemeOptions, StackmythTokens, ThemeFont, ThemeTexts, pushTheme, themeFromStackmyth, tokensFromStackmyth } from './theme.js';
|
|
4
4
|
import 'jose';
|
package/dist/index.js
CHANGED
|
@@ -1808,6 +1808,7 @@ function createTokenVerifier(options = {}) {
|
|
|
1808
1808
|
if (claims.roles !== void 0 && claims.roles !== null && !(Array.isArray(claims.roles) && claims.roles.every((r) => typeof r === "string"))) bad("roles");
|
|
1809
1809
|
if (claims.email !== void 0 && typeof claims.email !== "string") bad("email");
|
|
1810
1810
|
for (const name of ["email_verified", "anon"]) if (claims[name] !== void 0 && typeof claims[name] !== "boolean") bad(name);
|
|
1811
|
+
for (const name of ["token_use", "azp"]) if (claims[name] !== void 0 && typeof claims[name] !== "string") bad(name);
|
|
1811
1812
|
if (!issuers.includes(claims.iss)) throw new CauthyTokenError("wrong_issuer");
|
|
1812
1813
|
if (!(Array.isArray(aud) ? aud.includes(audience) : aud === audience)) throw new CauthyTokenError("wrong_audience");
|
|
1813
1814
|
const now = (options.now ?? /* @__PURE__ */ new Date()).getTime() / 1e3;
|
|
@@ -1816,7 +1817,9 @@ function createTokenVerifier(options = {}) {
|
|
|
1816
1817
|
if (now < claims.iat - leeway) throw new CauthyTokenError("issued_in_future");
|
|
1817
1818
|
if (claims.tid !== tenant) throw new CauthyTokenError("wrong_tenant");
|
|
1818
1819
|
if ("sys" in claims && !options.allowSystem) throw new CauthyTokenError("system_token");
|
|
1820
|
+
if ("token_use" in claims && !options.allowClientTokens) throw new CauthyTokenError("client_token");
|
|
1819
1821
|
if (claims.anon === true && !options.allowAnonymous) throw new CauthyTokenError("anonymous_token");
|
|
1822
|
+
if (options.clientId && typeof claims.azp === "string" && claims.azp !== "" && claims.azp !== options.clientId) throw new CauthyTokenError("wrong_client");
|
|
1820
1823
|
return {
|
|
1821
1824
|
userId: claims.sub,
|
|
1822
1825
|
tenantId: claims.tid,
|
|
@@ -1825,6 +1828,8 @@ function createTokenVerifier(options = {}) {
|
|
|
1825
1828
|
roles: Array.isArray(claims.roles) ? claims.roles : [],
|
|
1826
1829
|
...typeof claims.sys === "string" && claims.sys !== "" ? { system: claims.sys } : {},
|
|
1827
1830
|
...claims.anon === true ? { anonymous: true } : {},
|
|
1831
|
+
...typeof claims.azp === "string" && claims.azp !== "" ? { authorizedParty: claims.azp } : {},
|
|
1832
|
+
...typeof claims.client_id === "string" && claims.client_id !== "" ? { clientId: claims.client_id } : {},
|
|
1828
1833
|
expiresAt: new Date(claims.exp * 1e3).toISOString(),
|
|
1829
1834
|
token
|
|
1830
1835
|
};
|
|
@@ -3324,13 +3329,19 @@ function createCauthy(given = {}) {
|
|
|
3324
3329
|
return { response: redirect(to) };
|
|
3325
3330
|
}
|
|
3326
3331
|
const replay = given.webhookReplay ?? memoryReplayStore();
|
|
3327
|
-
const tokenVerifier = (o = {}) =>
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3332
|
+
const tokenVerifier = (o = {}) => {
|
|
3333
|
+
if (contract && o.clientId !== void 0 && o.clientId !== contract.clientId) {
|
|
3334
|
+
throw new CauthyConfigError(`clientId is the contract's (${contract.clientId}): remove it from the call`);
|
|
3335
|
+
}
|
|
3336
|
+
return createTokenVerifier({
|
|
3337
|
+
issuer,
|
|
3338
|
+
tenantId: contract?.tenantId ?? given.tenantId,
|
|
3339
|
+
audience: given.audience,
|
|
3340
|
+
fetch: given.fetch,
|
|
3341
|
+
...contract ? { clientId: contract.clientId } : {},
|
|
3342
|
+
...o
|
|
3343
|
+
});
|
|
3344
|
+
};
|
|
3334
3345
|
const webhook = (request, o = {}) => verifyWebhook(request, { issuer, url: o.url ?? `${originOf(request)}${new URL(request.url).pathname}`, jwks: o.jwks, now: o.now, replay });
|
|
3335
3346
|
const pact = contract && ownKeys ? {
|
|
3336
3347
|
contract,
|