@owlmeans/oidc 0.1.18-rc.5 → 0.1.18-rc.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,33 +1,34 @@
1
1
  # @owlmeans/oidc
2
2
 
3
- Shared OIDC protocol abstractions — guard/gate aliases, models, and module declarations used by both server and browser OIDC packages.
3
+ Shared OIDC protocol abstractions — guard/gate aliases, models, and immutable protocol declarations used by both server and browser OIDC packages.
4
4
 
5
5
  ## Overview
6
6
 
7
- - `OIDC_GATE` — gate alias to compose with `gate(...)` inside `guard(...)` declarations
7
+ - `OIDC_GATE` — gate alias to put in a protocol's `gate` option
8
8
  - `OIDC_GUARD`, `WRAPPED_OIDC`, `OIDC_FLOW`, `OIDC_AUTHEN_MODULE`, `OIDC_WRAPPED_TOKEN` — shared aliases
9
9
  - `OidcGuard`, `WithSharedConfig`, `OidcProviderConfig` — shared types
10
- - Module declarations for the OIDC dispatcher (`/authenticate/oidc/init`, `/authenticate/oidc/process`)
10
+ - Entrypoint declarations for the OIDC dispatcher (`/authenticate/oidc/init`, `/authenticate/oidc/process`)
11
11
 
12
12
  ## Installation
13
13
 
14
14
  ```bash
15
- bun add @owlmeans/oidc
15
+ bun add @owlmeans/oidc@^0.1.18-rc.51
16
16
  ```
17
17
 
18
18
  ## Usage
19
19
 
20
- Compose `OIDC_GATE` into a guard on a module:
20
+ Compose `OIDC_GATE` into a protocol declaration:
21
21
 
22
22
  ```typescript
23
- import { module, guard, gate } from '@owlmeans/module'
23
+ import { contract, protocol, typed } from '@owlmeans/entrypoint'
24
24
  import { route } from '@owlmeans/route'
25
25
  import { DEFAULT_GUARD } from '@owlmeans/auth-common'
26
26
  import { OIDC_GATE } from '@owlmeans/oidc'
27
27
 
28
- module(
28
+ protocol(
29
29
  route(manager.back.account.base, '/account'),
30
- guard(DEFAULT_GUARD, gate(OIDC_GATE, [`my-service-account-{entity}`]))
30
+ contract(typed<Account>()),
31
+ { guards: DEFAULT_GUARD, gate: { alias: OIDC_GATE, params: [`my-service-account-{entity}`] } },
31
32
  )
32
33
  ```
33
34
 
@@ -56,7 +57,7 @@ import { OIDC_GUARD } from '@owlmeans/oidc'
56
57
  - `WRAPPED_OIDC` — `'wrapped-oidc-authz'`
57
58
  - `OIDC_AUTHEN_MODULE` — `'iam-oidc-authen'`
58
59
  - `OIDC_WRAPPED_TOKEN` — `'oidc-wrapped-token'`
59
- - `DISPATCHER_OIDC`, `DISPATCHER_OIDC_INIT` — auth dispatcher module aliases
60
+ - `DISPATCHER_OIDC`, `DISPATCHER_OIDC_INIT` — auth dispatcher entrypoint aliases
60
61
  - `INTERACTION`, `INTERACTION_PATH` — interaction route aliases
61
62
  - `OIDC_GUARD_CACHE` — guard cache resource alias
62
63
 
@@ -73,9 +74,11 @@ import { OIDC_GUARD } from '@owlmeans/oidc'
73
74
  - `GOOGLE_CLIENT_AUTH` identifies the browser Google auth plugin registered by `@owlmeans/web-oidc-rp/auth/plugins`.
74
75
  - `OIDC_GATE` is for OIDC-backed authorization. Apps that only use Google/OIDC for login and authorize against local identity records should define their own product gate alias.
75
76
 
76
- ### `modules`
77
+ ### `oidcProtocols`
77
78
 
78
- Array of dispatcher module declarations: `POST /authenticate/oidc/init` and `POST /authenticate/oidc/process`.
79
+ Immutable dispatcher declaration tree: `POST /authenticate/oidc/init` and
80
+ `POST /authenticate/oidc/process`. The relying-party packages bind these exact protocol objects
81
+ locally; do not recreate them or consume an alias-addressed compatibility list.
79
82
 
80
83
  ## Related Packages
81
84
 
@@ -92,7 +95,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
92
95
  your project's skill store (`.agents/skills/`):
93
96
 
94
97
  ```sh
95
- npx @owlmeans/agent-skills
98
+ npx @owlmeans/agent-skills@^0.1.18-rc.45
96
99
  ```
97
100
 
98
101
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/oidc",
4
- "version": "0.1.18-rc.0",
5
- "generatedAt": "2026-08-16T22:20:50.507Z",
4
+ "version": "0.1.18-rc.51",
5
+ "generatedAt": "2026-10-01T23:27:48.732Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oidc
3
- description: How to use @owlmeans/oidc — shared OIDC protocol abstractions including OIDC_GATE constant used in module gate() declarations. Auto-invoked when importing OIDC types/constants or wiring OIDC into a guard().
3
+ description: How to use @owlmeans/oidc — the OIDC names both sides share — the OIDC_GATE alias, the guard, the requested-scope contract, provider descriptors, the dispatcher entrypoints, the organizations scope and switch protocols, and the error query params. Auto-invoked when importing OIDC types or constants, wiring OIDC into a protocol gate, or declaring an identity provider in configuration.
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,60 +8,134 @@ user-invocable: false
8
8
  # @owlmeans/oidc
9
9
 
10
10
  **Layer:** Core
11
- **Install:** `"@owlmeans/oidc": "^0.1.18-rc.0"` in `dependencies`
11
+ **Install:** `"@owlmeans/oidc": "^0.1.18-rc.51"` in `dependencies`
12
+
13
+ The shared half of the OIDC stack: no transport, no library. It owns the names, the shapes and the
14
+ guard that the server relying party (`@owlmeans/server-oidc-rp`), the browser relying party
15
+ (`@owlmeans/web-oidc-rp`) and the embedded provider (`@owlmeans/server-oidc-provider`) must agree on.
12
16
 
13
17
  ## Key Exports
14
18
 
15
19
  | Export | Description |
16
20
  |--------|-------------|
17
- | `OIDC_GATE` | Gate alias to pass to `gate(...)` inside `guard(...)` |
18
- | `GOOGLE_CLIENT_AUTH` | Client auth plugin type for Google OAuth |
19
- | `GOOGLE_SERVICE` | Provider service key for Google (`'google'`) |
21
+ | `OIDC_GATE` | Gate alias to pass in a protocol's `gate` option |
22
+ | `OIDC_GUARD` | The guard's alias |
23
+ | `OIDC_GUARD_CACHE` | A resource-alias constant nothing reads — the guard has no cache lookup, so registering a resource under it changes no behaviour |
24
+ | `makeOidcGuard(opts?)` / `appendOidcGuard(context, opts?)` | The wrapped-token guard, and its registration. The target-specific packages wrap these |
25
+ | `withOidcGuard(protocolTree, coguards?)` | Returns a decorated immutable protocol tree, prepending `OIDC_GUARD` to selected guarded declarations (default `DEFAULT_GUARD`) |
26
+ | `oidcProtocols` | Shared declarations: the sign-in pair `init` (`POST /authenticate/oidc/init`) and `authenticate` (`POST /authenticate/oidc/process`), and the organization switch `organizations` (`GET /authenticate/oidc/organizations`) and `organization` (`POST /authenticate/oidc/organization`, body `{ entitySlug }`), both guarded by `OIDC_GUARD` |
27
+ | `DISPATCHER_OIDC_INIT`, `DISPATCHER_OIDC`, `DISPATCHER_OIDC_ORGANIZATIONS`, `DISPATCHER_OIDC_ORGANIZATION` | Their aliases |
28
+ | `OIDC_WRAPPED_TOKEN`, `WRAPPED_OIDC` | The authorization-header scheme for an OIDC-wrapped token, and the service alias that refreshes one |
29
+ | `OIDC_CLIENT_AUTH`, `GOOGLE_CLIENT_AUTH` | Authentication plugin types — the generic OIDC one and the Google one |
30
+ | `GOOGLE_SERVICE` | Provider service value for Google (`'google'`) |
20
31
  | `OIDC_RP_BASE_SCOPES` / `OIDC_RP_BASE_SCOPE` | The scopes every OwlMeans RP requests, as array / space-delimited string |
21
- | `EMAIL_SCOPE`, `PERMISSIONS_SCOPE`, `PERMISSIONS_CLAIM` | Standard email scope; the integrated-IAM grant scope and its claim |
22
- | `OIDC_ERROR_QUERY`, `OIDC_ERROR_DESCRIPTION_QUERY` | Redirect-URI params an authorization server sets on failure |
23
- | `INTERACTION`, `INTERACTION_PATH`, `INTERACTION_UID` | Interaction screen entrypoint alias, path, and its uid path param |
24
- | `OidcProviderDescriptor` | Shared provider config shape, including service, endpoints, redirect URI, and optional default flag |
25
- | `OidcGuard` types | Guard payload shapes |
26
- | Modules | Shared OIDC module declarations |
27
- | Models | Token/profile shapes |
32
+ | `EMAIL_SCOPE`, `PERMISSIONS_SCOPE`, `PERMISSIONS_CLAIM` | The standard email scope; the integrated-IAM grant scope and the claim it produces |
33
+ | `ORGANIZATIONS_SCOPE`, `ORGANIZATIONS_CLAIM` | `'organizations'` — the tenanted-client scope and the claim carrying `OidcOrganizationClaim[]` |
34
+ | `ORGANIZATION_REFUSAL`, `ORGANIZATION_OWNER_REFUSAL` | `AuthForbidden` reasons: not one of the subject's organizations; the action needs its owner |
35
+ | `IAM_API_METADATA` | `'owlmeans_iam_api'` — the discovery-document field naming the provider's runtime IAM API |
36
+ | `OIDC_CODE_QUERY`, `OIDC_ERROR_QUERY`, `OIDC_ERROR_DESCRIPTION_QUERY` | Redirect-URI params an authorization server sets on success and on failure |
37
+ | `INTERACTION`, `INTERACTION_PATH`, `INTERACTION_UID` | Interaction screen alias, path, and the uid path param the path must declare |
38
+ | `PROVIDER_INTERACTION`, `OIDC_AUTHEN_MODULE`, `OIDC_FLOW` | The provider-side interaction alias, the IAM authentication entrypoint alias, and the flow name |
39
+ | `DEFAULT_PATH`, `DEFAULT_FRONT` | `'oidc'` and `'oidc-client'` — the provider's default base path and the default front service alias |
40
+ | `OidcProviderDescriptor` | One identity provider as configuration: `clientId`, `secret?`, `discoveryUrl?`, `service?`/`basePath?`, `redirectUri?`, `extraScopes?`, `entityId?`, `idOverride?`, the three endpoint overrides `authEndpoint?`/`tokenEndpoint?`/`userinfoEndpoint?`, plus the presentation fields below |
41
+ | `OidcProviderConfig` | A descriptor plus `internal?` (machine use only) and `apiClientId?` (the admin client) |
42
+ | `OidcSharedConfig` / `WithSharedConfig` | `cfg.oidc`: `providers`, `restrictedProviders`, `clientCookie.interaction` |
43
+ | `OidcIamConfig` | `{ iamMode?: 'keycloak' \| 'integrated' }` — the IAM-mode seam, kept here to avoid a cycle with `@owlmeans/iam` |
44
+ | `OidcGuard`, `OidcGuardOptions` | The guard service type, and `{ coguards, cache?, tokenService? }` — only `coguards` (its **first** entry, default `DEFAULT_GUARD`) and `tokenService` are read; `cache` is declared and never used |
45
+ | `OIDCAuthInitParams`, `OIDCClientAuthPayload`, `OIDCTokenUpdate`, `CommonTokenSetParams` | The dispatcher wire shapes; init's `entitySlug?` is the organization the person asks to act in |
46
+ | `OIDCAuthInitParamsSchema`, `OIDCClientAuthPayloadSchema`, `OIDCTokenUpdateSchema`, `ProviderProfileDetailsSchema`, `OidcOrganizationSwitchSchema` | Their AJV schemas — closed: the server's AJV strips an undeclared field silently, so every field a caller sends is declared |
47
+ | `OidcOrganizationClaim` | `{ entitySlug, entityKey, title?, owner, groups?, home? }` — one organization of the subject as the provider claims it; `entityKey` is the frozen IAM key and never leaves a server |
48
+ | `OidcPermissionSetClaim` | `PermissionSet` + `entitySlug?` — a set bound to that organization |
49
+ | `OidcOrganizationItem`, `OidcOrganizationList`, `OidcOrganizationSwitch` | The switch's wire shapes: `{ entitySlug, title?, owner, groups?, home?, acting }` items (no key), the `{ items }` list, the `{ entitySlug }` body |
50
+ | `WrappedOIDCUpdate` | `AuthToken` + `entity?: ResolvedEntity` — what `WrappedOIDCService.update` answers |
51
+ | `ProviderProfileDetails`, `OidcUserDetails`, `OidcProviderSettings` | What an identity provider reports about a subject |
52
+ | `WrappedOIDCService` | The `AuthorizationService` that keeps a wrapped token fresh; `update` answers a `WrappedOIDCUpdate` |
28
53
 
29
54
  ## Usage
30
55
 
31
56
  ```typescript
32
- import { entrypoint, guard, gate } from '@owlmeans/entrypoint'
57
+ import { contract, protocol, typed } from '@owlmeans/entrypoint'
33
58
  import { route } from '@owlmeans/route'
34
59
  import { DEFAULT_GUARD } from '@owlmeans/auth-common'
35
60
  import { OIDC_GATE } from '@owlmeans/oidc'
36
61
 
37
- entrypoint(
38
- route(manager.back.account.base, '/account'),
39
- guard(DEFAULT_GUARD, gate(OIDC_GATE, [`my-service-account-{entity}`]))
62
+ protocol(
63
+ route(accountAlias, '/account'),
64
+ contract(typed<Account>()),
65
+ { guards: DEFAULT_GUARD, gate: { alias: OIDC_GATE, params: ['my-service-account--read'] } },
40
66
  )
41
67
  ```
42
68
 
43
- The actual OIDC verification happens in `@owlmeans/server-oidc-rp` (server) and `@owlmeans/web-oidc-rp` (browser). The `oidc` package gives both sides a shared name to refer to.
69
+ The verification itself happens in `@owlmeans/server-oidc-rp` (server) and `@owlmeans/web-oidc-rp`
70
+ (browser); this package gives both sides one name to refer to. `OIDC_GATE` is for OIDC/UMA-style
71
+ authorization. A product that authenticates over OIDC but authorizes against its own identity
72
+ resources declares its own gate alias instead.
44
73
 
45
74
  ## Scope names are a cross-package contract
46
75
 
47
76
  `OIDC_RP_BASE_SCOPES` is the one definition of what an OwlMeans relying party asks an authorization
48
- server for. Two sides must agree on it and both read it from here:
77
+ server for, and two sides read it from here:
49
78
 
50
79
  - the **RP** builds its request from it (`requestedScope()` in `@owlmeans/server-oidc-rp`);
51
80
  - whoever **registers the client** must allow at least these scopes — an authorization server
52
- rejects the entire request with `invalid_scope` when a requested scope is one it supports but
53
- the client is not allowed to use (see `@owlmeans/iam-integrated`'s `INTEGRATED_CLIENT_SCOPES`).
81
+ rejects the entire request with `invalid_scope` when a requested scope is one it supports but the
82
+ client is not allowed to use.
54
83
 
55
- Never hardcode a scope string on either side; adding one to `OIDC_RP_BASE_SCOPES` must widen every
84
+ Never hardcode a scope string on either side. Adding one to `OIDC_RP_BASE_SCOPES` must widen every
56
85
  client allowlist derived from it in the same change.
57
86
 
58
- ## Product-Viable Usage Notes
87
+ ## Organizations of a tenanted client
88
+
89
+ A client that asks for `ORGANIZATIONS_SCOPE` gets two claims from the integrated provider: the
90
+ `organizations` claim (`OidcOrganizationClaim[]`) and the FULL `permissions` claim, in which a set
91
+ bound to an organization carries `entitySlug`. A client that never asks gets the flattened claim of
92
+ the one organization it acts in and no `organizations` claim — so the scope is what turns tenancy
93
+ on, and an old client is untouched by it.
94
+
95
+ Only the relying party's server sees the claims. The browser token carries the acting
96
+ organization's `entitySlug`, `groups` and its sets with the binding stripped; `entityKey` and the
97
+ bound sets of other organizations never leave the server (`@owlmeans/server-oidc-rp`).
98
+
99
+ The guard attaches `updated.entity` to the request whenever the wrapping service answers one. A
100
+ relying party of a tenanted client has no organization registry of its own, so this is the only
101
+ way `req.entity` gets set there; `attachEntity` (`@owlmeans/auth-common`) keeps it only while its
102
+ `slug` is exactly the token's.
103
+
104
+ The switch is two protocols guarded by `OIDC_GUARD` alone — they act on the session the wrapped
105
+ token names, after the guard has validated it against the provider. There is no per-request
106
+ organization selector: the server's AJV strips unknown query keys, and the session, not the
107
+ request, decides which organization a request acts in.
108
+
109
+ ## Provider descriptors
110
+
111
+ `cfg.oidc.providers` is the list. `discoveryUrl` is the canonical form — the fully-qualified issuer,
112
+ used verbatim; `service` + `basePath` is the legacy fallback that reassembles the issuer from a
113
+ registered service host, and it forces the relying party to know the provider's URL layout.
114
+
115
+ Presentation lives on the descriptor too, because a browser never talks to the issuer directly and
116
+ has no discovery document to read a name out of: `label` (the human-readable name), `icon` (an icon
117
+ registry **name**, never markup), `order` (ascending; absent sorts after the default) and `hidden`
118
+ (registered but never offered). `internal: true` means machine use and is never offered either.
119
+
120
+ `def` marks the default provider, and **both sides read it**. On the server, `getDefault()` in
121
+ `@owlmeans/server-oidc-rp` returns the `clientId` of the first provider carrying the flag, and the
122
+ init handler resolves the OIDC client from that value before it looks at `entityId` at all — so `def`
123
+ in a server config decides which provider the browser-starts-server-finishes flow runs against. In
124
+ the browser it drives presentation as well: `@owlmeans/web-oidc-rp` gives the flagged provider a
125
+ login method of `order` 20 (unless the descriptor sets its own) and renders it with primary emphasis.
126
+
127
+ `restrictedProviders` narrows what an application may use: `false` forbids identity-provider sign-in
128
+ outright, `true` allows only the default one, and an array is an allowlist matched against a
129
+ provider's `entityId ?? service ?? clientId`.
59
130
 
60
- - Provider config is stored in `cfg.oidc.providers`; viable config registers both an internal admin provider and a Google provider with `service: GOOGLE_SERVICE`.
61
- - `GOOGLE_SERVICE` is the provider service value `'google'`. Keep it stable so browser plugins, backend provider lookup, and identity credentials derive the same login-service key.
62
- - `GOOGLE_CLIENT_AUTH` names the browser authentication plugin registered by `@owlmeans/web-oidc-rp/auth/plugins`.
63
- - `OIDC_GATE` is for OIDC/UMA-style authorization gates. Do not use it for downstream products that authenticate with OIDC/Google but authorize against local identity resources; those products should declare their own gate alias.
131
+ `authEndpoint`, `tokenEndpoint` and `userinfoEndpoint` name a provider's endpoints outright, for a
132
+ provider reached without discovery. The shipped reader of all three is the Google sign-in plugin in
133
+ `@owlmeans/server-oidc-rp`, which falls back to Google's own endpoints when they are absent; a
134
+ descriptor that carries a `discoveryUrl` gets its endpoints from the discovery document instead and
135
+ these fields do nothing.
64
136
 
65
137
  ## Depends On
66
138
 
67
- - `@owlmeans/entrypoint`, `@owlmeans/route`, `@owlmeans/auth`
139
+ - `@owlmeans/entrypoint`, `@owlmeans/route`, `@owlmeans/auth`, `@owlmeans/auth-common`,
140
+ `@owlmeans/basic-envelope`, `@owlmeans/config`, `@owlmeans/context`, `@owlmeans/resource`
141
+ - `ajv` (peer) — the schemas above are `JSONSchemaType` declarations
@@ -1,13 +1,15 @@
1
1
  ---
2
2
  name: oidc-versions
3
3
  description: How to manage and upgrade the four OIDC/OAuth third-party dependencies used by OwlMeans OIDC packages. Covers exact-pin policy, official doc anchors, breaking-change checklists for each lib, the OwlMeans isolation principle, and the verification flow across common and downstream repos. Auto-invoked when touching oidc-provider, openid-client, jose, or oidc-client-ts version strings in package.json files.
4
- allowed-tools: Bash(npm view *) Bash(grep *) Bash(bun *)
4
+ allowed-tools: Bash(npm view *), Bash(grep *), Bash(bun *)
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
7
7
 
8
8
  # OIDC / OAuth dependency version management — OwlMeans Common
9
9
 
10
- This skill is the sibling of [[versions]] (internal `@owlmeans/*` version sync) and [[shadcn-versions]] (UI lib bumps). Use it whenever upgrading the upstream OIDC/OAuth libraries, and cross-read it before touching any OIDC package implementation.
10
+ The sibling of [[versions]] (internal `@owlmeans/*` version sync) and [[shadcn-versions]] (UI lib
11
+ bumps). Use it whenever upgrading the upstream OIDC/OAuth libraries, and cross-read it before
12
+ touching any OIDC package implementation.
11
13
 
12
14
  ## The four libraries and their owning packages
13
15
 
@@ -18,9 +20,12 @@ This skill is the sibling of [[versions]] (internal `@owlmeans/*` version sync)
18
20
  | `openid-client` | `@owlmeans/server-oidc-rp` | **exact** | `6.8.4` |
19
21
  | `oidc-client-ts` | `@owlmeans/web-oidc-rp`, `@owlmeans/mui-oidc-rp` | **exact** | `3.5.0` |
20
22
 
21
- `@types/oidc-provider` is a dev dep of `server-oidc-provider` and must track the oidc-provider major: `9.5.0` (v9 ships no bundled types).
23
+ `@types/oidc-provider` is a dev dependency of `@owlmeans/server-oidc-provider` and must track the
24
+ oidc-provider major: `9.5.0` (v9 ships no bundled types).
22
25
 
23
- All four are authored by panva or authts and follow semantic versioning. **Exact pins** are the project policy — every bump is deliberate and reviewed.
26
+ All four are authored by panva or authts and follow semantic versioning. **Exact pins** are the
27
+ policy — no caret, no range — so that every bump is a deliberate, reviewed change. The pinned value
28
+ lives in each owning package's `dependencies`; nothing else may declare one of these libraries.
24
29
 
25
30
  ## Checking installed vs latest
26
31
 
@@ -43,91 +48,114 @@ Consult these before every bump — especially for same-major minors that might
43
48
 
44
49
  ## Breaking-change checklist per library
45
50
 
46
- ### oidc-provider (v9.x — current)
47
-
48
- Migrated from v8 in this project. Key differences to keep in mind:
49
-
50
- - **Provider is a Koa app instance.** `oidc.use()` middleware registered after `api.server.use(base, oidc.callback())` is *downstream* of the Koa router — `await next()` inside such middleware does **not** run after a matched route completes. Move any post-response header manipulation (e.g. CSP rewrites) to a **Fastify `onSend` hook** scoped to the OIDC base path instead.
51
- - **`enableHttpPostMethods`** defaults to `false` (authorization/logout endpoints no longer accept POST by default). Set `enableHttpPostMethods: true` in the Provider config if the interaction flow POSTs.
52
- - **DPoP is on by default.** `features.dPoP.enabled` is `true` without explicit config. Disable if the OIDC clients don't send DPoP proofs.
53
- - **Cookie `sameSite` defaults to `lax`** (was `none`). Review if the interaction UI lives on a different subdomain.
54
- - **JWK `kid` must be unique.** No two keys in `jwks.keys` can share the same `kid`. Generate or assign a deterministic unique `kid` when building the JWKS.
55
- - **`provider.Account` getter removed.** Use `findAccount` callback; do not read `oidc.Account`.
56
- - **Node 22+ required.**
57
- - **ESM-only** (was already ESM in v8).
58
- - HTTP requests now use the **global `fetch()`** (not `got`). `httpOptions` is replaced with a `fetch` config option that mirrors the fetch API.
59
- - **`@types/oidc-provider`** must be `9.x` (`^9.5.0` or exact); the v8 types are incompatible.
60
-
61
- ### jose (v6.x — current)
62
-
63
- Migrated from v5 in this project:
64
-
65
- - **WebCrypto is the only crypto backend.** `importPKCS8`, `importSPKI`, `importJWK`, `generateKeyPair` now return `CryptoKey` (not `KeyObject`).
66
- - **`extractable` must be set when you need to call `exportJWK` on an imported key.** In v5 Node `KeyObject` was always extractable. In v6 the `CryptoKey` default is `extractable: false`. The fix:
51
+ ### oidc-provider v9
52
+
53
+ - **The provider is a Koa app instance**, and `Provider#use(fn)` splices `fn` **ahead of** the
54
+ provider's own router in the Koa chain, so such a middleware runs before routing and resumes
55
+ normally after `await next()`. Header corrections for an OwlMeans server nonetheless belong in a
56
+ middleware registered on the API server **before** `oidc.callback()`, writing to the raw response
57
+ where `@fastify/helmet` has already put its defaults. They must never be a Fastify `onSend` hook:
58
+ `oidc.callback()` ends the response outside Fastify's reply lifecycle, so `onSend` never fires for
59
+ a route the provider answers.
60
+ - **`enableHttpPostMethods` is `false`.** Turning it on requires `cookies.long.sameSite: 'none'` in
61
+ the same configuration; otherwise the constructor throws `TypeError: HTTP POST Method support
62
+ requires that cookies.long.sameSite is set to none`.
63
+ - **DPoP is on.** `features.dPoP.enabled` is `true` with no configuration. Disable it when the
64
+ clients send no DPoP proofs.
65
+ - **Cookie `sameSite` is `lax`** for both `cookies.long` and `cookies.short`. Review it when the
66
+ interaction UI lives on a different subdomain.
67
+ - **JWK `kid` must be unique.** No two keys in `jwks.keys` may share one.
68
+ - **There is no `provider.Account` getter.** Accounts come from the `findAccount` callback.
69
+ - **ESM-only**, and outbound HTTP goes through the `fetch` configuration option — a function
70
+ mirroring the fetch API, defaulting to `globalThis.fetch`. There is no `httpOptions`.
71
+ - **`@types/oidc-provider` must track the major** (`9.5.0`); v9 ships no bundled types.
72
+
73
+ ### jose v6
74
+
75
+ - **WebCrypto is the only crypto backend.** `importPKCS8`, `importSPKI` and `importX509` resolve to a
76
+ `CryptoKey`; `importJWK` resolves to a `CryptoKey` for every key type except `oct`, which yields a
77
+ `Uint8Array`. `KeyObject` survives only as an exported type.
78
+ - **`extractable` defaults to `false` for a private key** and `true` for everything else, so an
79
+ imported private key cannot be exported unless the import asked for it:
67
80
  ```typescript
68
- // ✅ v6 — must pass { extractable: true }
69
81
  const key = await jose.importPKCS8(pkcs8String, 'RS256', { extractable: true })
70
82
  const jwk = await jose.exportJWK(key) // works
71
83
  ```
72
- - **`decodeJwt` unchanged** — still `decodeJwt(jwt): JWTPayload`.
73
- - **Subpath exports removed.** All exports are from the root `'jose'` entry; e.g. `'jose/jwt/verify'` no longer works.
74
- - **CJS `require()` requires Node's `require(esm)` support** (Node 22+, or use dynamic `import()`).
75
-
76
- ### openid-client (v6.x — no migration needed from v6.1)
84
+ - `decodeJwt(jwt): JWTPayload`.
85
+ - Both the root entry and the subpath entries (`jose/jwt/verify`, `jose/key/import`, `jose/errors`, …)
86
+ are exported. Prefer the root entry — an `import * as jose from 'jose'` is what the OwlMeans
87
+ packages use, and a subpath import buys nothing under a bundler.
88
+ - **CJS `require()` needs Node's `require(esm)` support**; use dynamic `import()` otherwise.
77
89
 
78
- v6 introduced a **functional API** (replacing the class-based v5 API). OwlMeans already targets v6 (migrated earlier). Key API surface used:
90
+ ### openid-client v6
79
91
 
80
- - `client.discovery(issuerUrl, clientId, secret, authMethod, options)` — returns a `Configuration` object.
81
- - `client.buildAuthorizationUrl(config, params)` — returns a `URL`.
82
- - `client.authorizationCodeGrant(config, url, checks)` — returns `TokenEndpointResponse`.
83
- - `client.clientCredentialsGrant(config)` / `client.refreshTokenGrant(config, refreshToken)`.
84
- - `client.tokenIntrospection(config, token)`.
85
- - `client.allowInsecureRequests` — passed in the `execute` array option of `discovery` when behind HTTP (dev/internal).
92
+ A functional API — there is no client class. The surface OwlMeans uses:
86
93
 
87
- Breaking changes within v6.x are documented in the CHANGELOG; check before bumping patch/minor versions.
94
+ - `discovery(issuerUrl, clientId, metadata?, clientAuthentication?, options?)` → `Configuration`.
95
+ `metadata` accepts the client secret as a bare string. `clientAuthentication` is a `ClientAuth`
96
+ function (`ClientSecretPost(secret)`, `ClientSecretBasic(secret)`, …) and defaults to
97
+ `ClientSecretPost` when a secret is present — passing `undefined` takes that default.
98
+ - `buildAuthorizationUrl(config, params)` → `URL`.
99
+ - `authorizationCodeGrant(config, url, checks)` → `TokenEndpointResponse`.
100
+ - `clientCredentialsGrant(config)` / `refreshTokenGrant(config, refreshToken)`.
101
+ - `tokenIntrospection(config, token)`.
102
+ - `allowInsecureRequests` — passed inside the `execute` array of `discovery`'s options to permit
103
+ plain HTTP for an internal or development issuer.
88
104
 
89
- ### oidc-client-ts (v3.x — no migration from v3.1)
105
+ ### oidc-client-ts v3
90
106
 
91
- Current pin is `3.5.0`. OwlMeans only uses `UserManager` (browser-side, currently a stub). Check the CHANGELOG for breaking changes to `UserManager` constructor or `signinRedirect` between minor versions.
107
+ Only `UserManager` is referenced, in the incomplete fully-browser-side path; the production flow is a
108
+ server-side token exchange. Check the CHANGELOG for changes to the `UserManager` constructor or
109
+ `signinRedirect` before bumping a minor.
92
110
 
93
111
  ## OwlMeans isolation principle
94
112
 
95
- **No upstream OIDC library type may appear in a package's public `index.ts` exports.** Define OwlMeans-owned interfaces and map at the service boundary.
96
-
97
- Canonical example — `@owlmeans/server-oidc-rp` public types:
98
- - `OidcTokenSet` — OwlMeans-owned shape for `access_token`, `refresh_token`, `id_token`, etc.
99
- - `OidcGrantChecks` — owned shape for PKCE checks.
100
- - `OidcServerMetadata` — owned shape for issuer/endpoint metadata.
101
- - `OidcIntrospectionResponse` — owned shape for token introspection.
102
- - `OidcClientDescriptor` — **opaque branded type** (consumers receive and pass it back; never read its internal structure).
103
-
104
- The implementation in `src/service.ts` imports and uses the upstream types internally, mapping to/from the owned types at method boundaries. This means a future library swap is confined to a single file.
113
+ **No upstream OIDC library NAME may appear in a package's public `index.ts` exports.** Declare
114
+ OwlMeans-owned types and map at the service boundary, so a consumer never imports from
115
+ `openid-client` or `oidc-provider` to type a variable this stack handed it.
116
+
117
+ The public types of `@owlmeans/server-oidc-rp` are the canonical example:
118
+
119
+ - `OidcTokenSet` / `OidcTokenSetParameters` — declared shapes for `access_token`, `refresh_token`,
120
+ `id_token`, `token_type`, `expires_in`, `scope`, with and without the `claims()` helper.
121
+ - `OidcGrantChecks` — the declared shape for PKCE checks.
122
+ - `OidcIntrospectionResponse` — the declared shape for token introspection.
123
+ - `OidcServerMetadata` and `OidcClientDescriptor` — deliberate aliases onto the upstream metadata and
124
+ configuration objects, exported under owned names. `OidcClientDescriptor` is **opaque**: consumers
125
+ receive it and pass it back, and never read its internals.
126
+
127
+ What the principle guarantees is the **exported name**: a consumer types every value this stack hands
128
+ it without importing `openid-client` or `oidc-provider`. It does not confine upstream imports to one
129
+ file, and reading it that way misleads. In `@owlmeans/server-oidc-rp` the type module imports
130
+ `Configuration`, `ServerMetadata`, `TokenEndpointResponse` and `TokenEndpointResponseHelpers` from
131
+ `openid-client` in order to alias them under the owned names; the service module imports the
132
+ functional API; and `jose`'s `decodeJwt` is imported directly by the token wrapper, the `oidc-client`
133
+ auth plugin and the exchange handler. A library swap touches each of those — the owned names are what
134
+ keep it from reaching any consumer.
105
135
 
106
136
  See [[server-oidc-rp]] for the full public surface.
107
137
 
108
138
  ## Performing a bump
109
139
 
110
- 1. **Read the CHANGELOG** for the target version (link above). Enumerate every breaking change against the checklist above.
140
+ 1. **Read the CHANGELOG** for the target version (link above). Enumerate every breaking change
141
+ against the checklist above.
111
142
  2. Update the version string in **each owning package's `package.json`** — exact pins only, no caret.
112
- 3. Update `@types/oidc-provider` if bumping `oidc-provider` across a major.
113
- 4. **Run `bun install`** in the monorepo root to update the lockfile.
114
- 5. **Fix any code changes** using the checklist (particularly the `extractable` gotcha for jose and the CSP/debug middleware placement for oidc-provider).
115
- 6. Build affected packages: `bun run build` (or `tsc -b`) per package.
116
- 7. Run unit tests: `bun test ./tests` per package.
143
+ 3. Update `@types/oidc-provider` when bumping `oidc-provider` across a major.
144
+ 4. Reinstall so the lockfile is regenerated.
145
+ 5. **Fix the code** using the checklist — particularly the jose `extractable` argument and the
146
+ placement of the header-correcting middleware for oidc-provider.
147
+ 6. Build every affected package, then run its unit tests.
117
148
 
118
149
  ## Downstream verification
119
150
 
120
- Downstream repos that link `@owlmeans/*` packages as local workspace entries (bun hoisted linker) pick up the rebuilt outputs automatically. After rebuilding the affected packages, verify each downstream:
121
-
122
- ```bash
123
- # per repo: viable, viable-agent, internal
124
- cd <your-project-root>
125
- bun install # refresh transitive third-party versions
126
- bun run build # or per-workspace build command
127
- bun test # or per-workspace test command
128
- ```
151
+ A project that links these packages as local workspace entries picks up the rebuilt outputs
152
+ automatically, but its own transitive copies of the four libraries do not move on their own. After
153
+ rebuilding, in every consuming project: reinstall, build, and run the tests.
129
154
 
130
- Check `overrides` in each repo's root `package.json` — remove stale pins of oidc-provider/jose/openid-client/oidc-client-ts if present.
155
+ Then check `overrides` (or the equivalent resolution field) in each consuming project's root
156
+ manifest and remove any stale pin of `oidc-provider`, `jose`, `openid-client` or `oidc-client-ts` —
157
+ an override outranks the exact pin the owning package declares, so a forgotten one silently keeps the
158
+ old version installed.
131
159
 
132
160
  ## Cross-references
133
161
 
package/build/consts.d.ts CHANGED
@@ -14,6 +14,10 @@ export declare const OIDC_GUARD = "guard:oidc";
14
14
  export declare const OIDC_GUARD_CACHE = "resource:oidc-guard:cache";
15
15
  export declare const DISPATCHER_OIDC_INIT = "dispatcher:oidc:init";
16
16
  export declare const DISPATCHER_OIDC = "dispatcher:oidc:authenticate";
17
+ /** Lists the organizations the session's subject belongs to. */
18
+ export declare const DISPATCHER_OIDC_ORGANIZATIONS = "dispatcher:oidc:organizations";
19
+ /** Switches the organization the session acts in. */
20
+ export declare const DISPATCHER_OIDC_ORGANIZATION = "dispatcher:oidc:organization";
17
21
  export declare const OIDC_CODE_QUERY = "code";
18
22
  /**
19
23
  * Query params an authorization server sets on the redirect URI when the request failed
@@ -42,4 +46,18 @@ export declare const OIDC_RP_BASE_SCOPES: string[];
42
46
  export declare const OIDC_RP_BASE_SCOPE: string;
43
47
  /** Token/userinfo claim carrying the subject's PermissionSet[] for the requesting client. */
44
48
  export declare const PERMISSIONS_CLAIM = "permissions";
49
+ /**
50
+ * OIDC scope of a tenanted client: the provider answers it with the subject's organizations and
51
+ * the full permission claim, bound sets included. A client that never asks for it gets the
52
+ * flattened claim of the one organization it acts in, exactly as before the scope existed.
53
+ */
54
+ export declare const ORGANIZATIONS_SCOPE = "organizations";
55
+ /** Token/userinfo claim carrying the subject's `OidcOrganizationClaim[]`. */
56
+ export declare const ORGANIZATIONS_CLAIM = "organizations";
57
+ /** `AuthForbidden` reason: the organization named is not one the subject belongs to. */
58
+ export declare const ORGANIZATION_REFUSAL = "organization";
59
+ /** `AuthForbidden` reason: the action needs the organization's owner. */
60
+ export declare const ORGANIZATION_OWNER_REFUSAL = "organization:owner";
61
+ /** Discovery-document field carrying the base URL of the provider's runtime IAM API. */
62
+ export declare const IAM_API_METADATA = "owlmeans_iam_api";
45
63
  //# sourceMappingURL=consts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,SAAS,CAAA;AAElC,eAAO,MAAM,aAAa,gBAAgB,CAAA;AAE1C,6FAA6F;AAC7F,eAAO,MAAM,eAAe,QAAQ,CAAA;AAEpC,eAAO,MAAM,gBAAgB,sBAA4C,CAAA;AAEzE,eAAO,MAAM,WAAW,qBAAqB,CAAA;AAE7C,eAAO,MAAM,SAAS,SAAS,CAAA;AAE/B,eAAO,MAAM,kBAAkB,oBAAoB,CAAA;AAEnD,eAAO,MAAM,oBAAoB,4BAA4B,CAAA;AAE7D,eAAO,MAAM,gBAAgB,gBAAgB,CAAA;AAE7C,eAAO,MAAM,kBAAkB,iBAAiB,CAAA;AAGhD,eAAO,MAAM,cAAc,WAAW,CAAA;AAEtC,eAAO,MAAM,UAAU,eAAe,CAAA;AAEtC,eAAO,MAAM,gBAAgB,8BAA8B,CAAA;AAE3D,eAAO,MAAM,oBAAoB,yBAAyB,CAAA;AAE1D,eAAO,MAAM,eAAe,iCAAiC,CAAA;AAE7D,eAAO,MAAM,eAAe,SAAS,CAAA;AAErC;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,UAAU,CAAA;AAEvC,eAAO,MAAM,4BAA4B,sBAAsB,CAAA;AAE/D,eAAO,MAAM,kBAAkB,uBAAuB,CAAA;AAEtD,eAAO,MAAM,YAAY,uBAAuB,CAAA;AAEhD,eAAO,MAAM,SAAS,cAAc,CAAA;AAEpC,+EAA+E;AAC/E,eAAO,MAAM,WAAW,UAAU,CAAA;AAElC,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,gBAAgB,CAAA;AAE9C;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,UAAqC,CAAA;AAErE,4FAA4F;AAC5F,eAAO,MAAM,kBAAkB,QAAgC,CAAA;AAE/D,6FAA6F;AAC7F,eAAO,MAAM,iBAAiB,gBAAgB,CAAA"}
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,SAAS,CAAA;AAElC,eAAO,MAAM,aAAa,gBAAgB,CAAA;AAE1C,6FAA6F;AAC7F,eAAO,MAAM,eAAe,QAAQ,CAAA;AAEpC,eAAO,MAAM,gBAAgB,sBAA4C,CAAA;AAEzE,eAAO,MAAM,WAAW,qBAAqB,CAAA;AAE7C,eAAO,MAAM,SAAS,SAAS,CAAA;AAE/B,eAAO,MAAM,kBAAkB,oBAAoB,CAAA;AAEnD,eAAO,MAAM,oBAAoB,4BAA4B,CAAA;AAE7D,eAAO,MAAM,gBAAgB,gBAAgB,CAAA;AAE7C,eAAO,MAAM,kBAAkB,iBAAiB,CAAA;AAGhD,eAAO,MAAM,cAAc,WAAW,CAAA;AAEtC,eAAO,MAAM,UAAU,eAAe,CAAA;AAEtC,eAAO,MAAM,gBAAgB,8BAA8B,CAAA;AAE3D,eAAO,MAAM,oBAAoB,yBAAyB,CAAA;AAE1D,eAAO,MAAM,eAAe,iCAAiC,CAAA;AAE7D,gEAAgE;AAChE,eAAO,MAAM,6BAA6B,kCAAkC,CAAA;AAE5E,qDAAqD;AACrD,eAAO,MAAM,4BAA4B,iCAAiC,CAAA;AAE1E,eAAO,MAAM,eAAe,SAAS,CAAA;AAErC;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,UAAU,CAAA;AAEvC,eAAO,MAAM,4BAA4B,sBAAsB,CAAA;AAE/D,eAAO,MAAM,kBAAkB,uBAAuB,CAAA;AAEtD,eAAO,MAAM,YAAY,uBAAuB,CAAA;AAEhD,eAAO,MAAM,SAAS,cAAc,CAAA;AAEpC,+EAA+E;AAC/E,eAAO,MAAM,WAAW,UAAU,CAAA;AAElC,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,gBAAgB,CAAA;AAE9C;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,UAAqC,CAAA;AAErE,4FAA4F;AAC5F,eAAO,MAAM,kBAAkB,QAAgC,CAAA;AAE/D,6FAA6F;AAC7F,eAAO,MAAM,iBAAiB,gBAAgB,CAAA;AAE9C;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,kBAAkB,CAAA;AAElD,6EAA6E;AAC7E,eAAO,MAAM,mBAAmB,kBAAkB,CAAA;AAElD,wFAAwF;AACxF,eAAO,MAAM,oBAAoB,iBAAiB,CAAA;AAElD,yEAAyE;AACzE,eAAO,MAAM,0BAA0B,uBAAuB,CAAA;AAE9D,wFAAwF;AACxF,eAAO,MAAM,gBAAgB,qBAAqB,CAAA"}
package/build/consts.js CHANGED
@@ -16,6 +16,10 @@ export const OIDC_GUARD = 'guard:oidc';
16
16
  export const OIDC_GUARD_CACHE = 'resource:oidc-guard:cache';
17
17
  export const DISPATCHER_OIDC_INIT = 'dispatcher:oidc:init';
18
18
  export const DISPATCHER_OIDC = 'dispatcher:oidc:authenticate';
19
+ /** Lists the organizations the session's subject belongs to. */
20
+ export const DISPATCHER_OIDC_ORGANIZATIONS = 'dispatcher:oidc:organizations';
21
+ /** Switches the organization the session acts in. */
22
+ export const DISPATCHER_OIDC_ORGANIZATION = 'dispatcher:oidc:organization';
19
23
  export const OIDC_CODE_QUERY = 'code';
20
24
  /**
21
25
  * Query params an authorization server sets on the redirect URI when the request failed
@@ -44,4 +48,18 @@ export const OIDC_RP_BASE_SCOPES = ['openid', 'profile', EMAIL_SCOPE];
44
48
  export const OIDC_RP_BASE_SCOPE = OIDC_RP_BASE_SCOPES.join(' ');
45
49
  /** Token/userinfo claim carrying the subject's PermissionSet[] for the requesting client. */
46
50
  export const PERMISSIONS_CLAIM = 'permissions';
51
+ /**
52
+ * OIDC scope of a tenanted client: the provider answers it with the subject's organizations and
53
+ * the full permission claim, bound sets included. A client that never asks for it gets the
54
+ * flattened claim of the one organization it acts in, exactly as before the scope existed.
55
+ */
56
+ export const ORGANIZATIONS_SCOPE = 'organizations';
57
+ /** Token/userinfo claim carrying the subject's `OidcOrganizationClaim[]`. */
58
+ export const ORGANIZATIONS_CLAIM = 'organizations';
59
+ /** `AuthForbidden` reason: the organization named is not one the subject belongs to. */
60
+ export const ORGANIZATION_REFUSAL = 'organization';
61
+ /** `AuthForbidden` reason: the action needs the organization's owner. */
62
+ export const ORGANIZATION_OWNER_REFUSAL = 'organization:owner';
63
+ /** Discovery-document field carrying the base URL of the provider's runtime IAM API. */
64
+ export const IAM_API_METADATA = 'owlmeans_iam_api';
47
65
  //# sourceMappingURL=consts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAEvC,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAA;AAElC,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAA;AAE1C,6FAA6F;AAC7F,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAA;AAEpC,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,KAAK,GAAG,eAAe,EAAE,CAAA;AAEzE,MAAM,CAAC,MAAM,WAAW,GAAG,kBAAkB,CAAA;AAE7C,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAA;AAE/B,MAAM,CAAC,MAAM,kBAAkB,GAAG,iBAAiB,CAAA;AAEnD,MAAM,CAAC,MAAM,oBAAoB,GAAG,yBAAyB,CAAA;AAE7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAA;AAE7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAA;AAEhD,2GAA2G;AAC3G,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAA;AAEtC,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAA;AAEtC,MAAM,CAAC,MAAM,gBAAgB,GAAG,2BAA2B,CAAA;AAE3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAA;AAE1D,MAAM,CAAC,MAAM,eAAe,GAAG,8BAA8B,CAAA;AAE7D,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAA;AAErC;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAA;AAEvC,MAAM,CAAC,MAAM,4BAA4B,GAAG,mBAAmB,CAAA;AAE/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAA;AAEtD,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAA;AAEhD,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAA;AAEpC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAA;AAElC,mFAAmF;AACnF,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAA;AAE9C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;AAErE,4FAA4F;AAC5F,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAE/D,6FAA6F;AAC7F,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAA"}
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAEvC,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAA;AAElC,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAA;AAE1C,6FAA6F;AAC7F,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAA;AAEpC,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,KAAK,GAAG,eAAe,EAAE,CAAA;AAEzE,MAAM,CAAC,MAAM,WAAW,GAAG,kBAAkB,CAAA;AAE7C,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAA;AAE/B,MAAM,CAAC,MAAM,kBAAkB,GAAG,iBAAiB,CAAA;AAEnD,MAAM,CAAC,MAAM,oBAAoB,GAAG,yBAAyB,CAAA;AAE7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAA;AAE7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAA;AAEhD,2GAA2G;AAC3G,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAA;AAEtC,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAA;AAEtC,MAAM,CAAC,MAAM,gBAAgB,GAAG,2BAA2B,CAAA;AAE3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAA;AAE1D,MAAM,CAAC,MAAM,eAAe,GAAG,8BAA8B,CAAA;AAE7D,gEAAgE;AAChE,MAAM,CAAC,MAAM,6BAA6B,GAAG,+BAA+B,CAAA;AAE5E,qDAAqD;AACrD,MAAM,CAAC,MAAM,4BAA4B,GAAG,8BAA8B,CAAA;AAE1E,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAA;AAErC;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAA;AAEvC,MAAM,CAAC,MAAM,4BAA4B,GAAG,mBAAmB,CAAA;AAE/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAA;AAEtD,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAA;AAEhD,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAA;AAEpC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAA;AAElC,mFAAmF;AACnF,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAA;AAE9C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;AAErE,4FAA4F;AAC5F,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAE/D,6FAA6F;AAC7F,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAA;AAE9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAA;AAElD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAA;AAElD,wFAAwF;AACxF,MAAM,CAAC,MAAM,oBAAoB,GAAG,cAAc,CAAA;AAElD,yEAAyE;AACzE,MAAM,CAAC,MAAM,0BAA0B,GAAG,oBAAoB,CAAA;AAE9D,wFAAwF;AACxF,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAA"}
@@ -0,0 +1,16 @@
1
+ import type { AuthToken } from '@owlmeans/auth';
2
+ import type { OidcOrganizationList } from './types.js';
3
+ /** Shared OIDC browser-to-server protocols, bound by the relying-party packages. */
4
+ export declare const oidcProtocols: {
5
+ init: import("@owlmeans/entrypoint").EntrypointProtocol<{
6
+ body: import("./types.js").OIDCAuthInitParams;
7
+ }, any>;
8
+ authenticate: import("@owlmeans/entrypoint").EntrypointProtocol<{
9
+ body: import("./types.js").OIDCClientAuthPayload;
10
+ }, any>;
11
+ organizations: import("@owlmeans/entrypoint").EntrypointProtocol<{}, OidcOrganizationList>;
12
+ organization: import("@owlmeans/entrypoint").EntrypointProtocol<{
13
+ body: import("./types.js").OidcOrganizationSwitch;
14
+ }, AuthToken>;
15
+ };
16
+ //# sourceMappingURL=entrypoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoints.d.ts","sourceRoot":"","sources":["../src/entrypoints.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAK/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAEtD,oFAAoF;AACpF,eAAO,MAAM,aAAa;IACxB,IAAI;;;IAIJ,YAAY;;;IAOZ,aAAa;IAKb,YAAY;;;CAKb,CAAA"}
@@ -0,0 +1,15 @@
1
+ import { contract, protocol, typed } from '@owlmeans/entrypoint';
2
+ import { route, RouteMethod, backend } from '@owlmeans/route';
3
+ import { DISPATCHER_OIDC, DISPATCHER_OIDC_INIT, DISPATCHER_OIDC_ORGANIZATION, DISPATCHER_OIDC_ORGANIZATIONS, OIDC_GUARD, } from './consts.js';
4
+ import { OIDCAuthInitParamsSchema, OIDCClientAuthPayloadSchema, OidcOrganizationSwitchSchema } from './models.js';
5
+ /** Shared OIDC browser-to-server protocols, bound by the relying-party packages. */
6
+ export const oidcProtocols = {
7
+ init: protocol(route(DISPATCHER_OIDC_INIT, '/authenticate/oidc/init', backend(null, RouteMethod.POST)), contract.request({ body: typed(OIDCAuthInitParamsSchema) }, typed())),
8
+ authenticate: protocol(route(DISPATCHER_OIDC, '/authenticate/oidc/process', backend(null, RouteMethod.POST)), contract.request({ body: typed(OIDCClientAuthPayloadSchema) }, typed())),
9
+ // The organization switch acts on the session the wrapped token names, so only that token's own
10
+ // guard can reach it — and it runs after the guard has refreshed the session against the
11
+ // provider, so the list it answers from is the provider's current one.
12
+ organizations: protocol(route(DISPATCHER_OIDC_ORGANIZATIONS, '/authenticate/oidc/organizations', backend(null, RouteMethod.GET)), contract(typed()), { guards: OIDC_GUARD }),
13
+ organization: protocol(route(DISPATCHER_OIDC_ORGANIZATION, '/authenticate/oidc/organization', backend(null, RouteMethod.POST)), contract.request({ body: typed(OidcOrganizationSwitchSchema) }, typed()), { guards: OIDC_GUARD }),
14
+ };
15
+ //# sourceMappingURL=entrypoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoints.js","sourceRoot":"","sources":["../src/entrypoints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAE7D,OAAO,EACL,eAAe,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,6BAA6B,EAAE,UAAU,GAC/G,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAA;AAGjH,oFAAoF;AACpF,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,QAAQ,CACZ,KAAK,CAAC,oBAAoB,EAAE,yBAAyB,EAAE,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,EACvF,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,wBAAwB,CAAC,EAAE,EAAE,KAAK,EAAO,CAAC,CAC1E;IACD,YAAY,EAAE,QAAQ,CACpB,KAAK,CAAC,eAAe,EAAE,4BAA4B,EAAE,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,EACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,2BAA2B,CAAC,EAAE,EAAE,KAAK,EAAO,CAAC,CAC7E;IACD,gGAAgG;IAChG,yFAAyF;IACzF,uEAAuE;IACvE,aAAa,EAAE,QAAQ,CACrB,KAAK,CAAC,6BAA6B,EAAE,kCAAkC,EAAE,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,EACxG,QAAQ,CAAC,KAAK,EAAwB,CAAC,EACvC,EAAE,MAAM,EAAE,UAAU,EAAE,CACvB;IACD,YAAY,EAAE,QAAQ,CACpB,KAAK,CAAC,4BAA4B,EAAE,iCAAiC,EAAE,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,EACvG,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,4BAA4B,CAAC,EAAE,EAAE,KAAK,EAAa,CAAC,EACnF,EAAE,MAAM,EAAE,UAAU,EAAE,CACvB;CACF,CAAA"}