@owlmeans/oidc 0.1.18-rc.50 → 0.1.18-rc.52

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
@@ -12,7 +12,7 @@ Shared OIDC protocol abstractions — guard/gate aliases, models, and immutable
12
12
  ## Installation
13
13
 
14
14
  ```bash
15
- bun add @owlmeans/oidc@^0.1.18-rc.50
15
+ bun add @owlmeans/oidc@^0.1.18-rc.52
16
16
  ```
17
17
 
18
18
  ## Usage
@@ -95,7 +95,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
95
95
  your project's skill store (`.agents/skills/`):
96
96
 
97
97
  ```sh
98
- npx @owlmeans/agent-skills@^0.1.18-rc.44
98
+ npx @owlmeans/agent-skills@^0.1.18-rc.46
99
99
  ```
100
100
 
101
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.50",
5
- "generatedAt": "2026-09-30T09:41:02.827Z",
4
+ "version": "0.1.18-rc.52",
5
+ "generatedAt": "2026-10-03T11:19:50.782Z",
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 — the OIDC names both sides share — the OIDC_GATE alias, the guard, the requested-scope contract, provider descriptors, the dispatcher entrypoints 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.
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,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/oidc
9
9
 
10
10
  **Layer:** Core
11
- **Install:** `"@owlmeans/oidc": "^0.1.18-rc.50"` in `dependencies`
11
+ **Install:** `"@owlmeans/oidc": "^0.1.18-rc.52"` in `dependencies`
12
12
 
13
13
  The shared half of the OIDC stack: no transport, no library. It owns the names, the shapes and the
14
14
  guard that the server relying party (`@owlmeans/server-oidc-rp`), the browser relying party
@@ -23,13 +23,16 @@ guard that the server relying party (`@owlmeans/server-oidc-rp`), the browser re
23
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
24
  | `makeOidcGuard(opts?)` / `appendOidcGuard(context, opts?)` | The wrapped-token guard, and its registration. The target-specific packages wrap these |
25
25
  | `withOidcGuard(protocolTree, coguards?)` | Returns a decorated immutable protocol tree, prepending `OIDC_GUARD` to selected guarded declarations (default `DEFAULT_GUARD`) |
26
- | `oidcProtocols` | Shared dispatcher declarations: `DISPATCHER_OIDC_INIT` (`POST /authenticate/oidc/init`) and `DISPATCHER_OIDC` (`POST /authenticate/oidc/process`) |
27
- | `DISPATCHER_OIDC_INIT`, `DISPATCHER_OIDC` | Their aliases |
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
28
  | `OIDC_WRAPPED_TOKEN`, `WRAPPED_OIDC` | The authorization-header scheme for an OIDC-wrapped token, and the service alias that refreshes one |
29
29
  | `OIDC_CLIENT_AUTH`, `GOOGLE_CLIENT_AUTH` | Authentication plugin types — the generic OIDC one and the Google one |
30
30
  | `GOOGLE_SERVICE` | Provider service value for Google (`'google'`) |
31
31
  | `OIDC_RP_BASE_SCOPES` / `OIDC_RP_BASE_SCOPE` | The scopes every OwlMeans RP requests, as array / space-delimited string |
32
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 |
33
36
  | `OIDC_CODE_QUERY`, `OIDC_ERROR_QUERY`, `OIDC_ERROR_DESCRIPTION_QUERY` | Redirect-URI params an authorization server sets on success and on failure |
34
37
  | `INTERACTION`, `INTERACTION_PATH`, `INTERACTION_UID` | Interaction screen alias, path, and the uid path param the path must declare |
35
38
  | `PROVIDER_INTERACTION`, `OIDC_AUTHEN_MODULE`, `OIDC_FLOW` | The provider-side interaction alias, the IAM authentication entrypoint alias, and the flow name |
@@ -39,10 +42,14 @@ guard that the server relying party (`@owlmeans/server-oidc-rp`), the browser re
39
42
  | `OidcSharedConfig` / `WithSharedConfig` | `cfg.oidc`: `providers`, `restrictedProviders`, `clientCookie.interaction` |
40
43
  | `OidcIamConfig` | `{ iamMode?: 'keycloak' \| 'integrated' }` — the IAM-mode seam, kept here to avoid a cycle with `@owlmeans/iam` |
41
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 |
42
- | `OIDCAuthInitParams`, `OIDCClientAuthPayload`, `OIDCTokenUpdate`, `CommonTokenSetParams` | The dispatcher wire shapes |
43
- | `OIDCAuthInitParamsSchema`, `OIDCClientAuthPayloadSchema`, `OIDCTokenUpdateSchema`, `ProviderProfileDetailsSchema` | Their AJV schemas |
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), except `OIDCClientAuthPayloadSchema`, which admits any further string param of the provider's redirect |
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 |
44
51
  | `ProviderProfileDetails`, `OidcUserDetails`, `OidcProviderSettings` | What an identity provider reports about a subject |
45
- | `WrappedOIDCService` | The `AuthorizationService` that keeps a wrapped token fresh |
52
+ | `WrappedOIDCService` | The `AuthorizationService` that keeps a wrapped token fresh; `update` answers a `WrappedOIDCUpdate` |
46
53
 
47
54
  ## Usage
48
55
 
@@ -61,8 +68,7 @@ protocol(
61
68
 
62
69
  The verification itself happens in `@owlmeans/server-oidc-rp` (server) and `@owlmeans/web-oidc-rp`
63
70
  (browser); this package gives both sides one name to refer to. `OIDC_GATE` is for OIDC/UMA-style
64
- authorization. A product that authenticates over OIDC but authorizes against its own identity
65
- resources declares its own gate alias instead.
71
+ authorization only (`server-oidc-rp` → Rules).
66
72
 
67
73
  ## Scope names are a cross-package contract
68
74
 
@@ -77,6 +83,28 @@ server for, and two sides read it from here:
77
83
  Never hardcode a scope string on either side. Adding one to `OIDC_RP_BASE_SCOPES` must widen every
78
84
  client allowlist derived from it in the same change.
79
85
 
86
+ ## Organizations of a tenanted client
87
+
88
+ A client that asks for `ORGANIZATIONS_SCOPE` gets two claims from the integrated provider: the
89
+ `organizations` claim (`OidcOrganizationClaim[]`) and the FULL `permissions` claim, in which a set
90
+ bound to an organization carries `entitySlug`. A client that never asks gets the flattened claim of
91
+ the one organization it acts in and no `organizations` claim — so the scope is what turns tenancy
92
+ on, and a single-organization client never sees an `organizations` claim or a set carrying
93
+ `entitySlug`.
94
+
95
+ Only the relying party's server sees the claims; what the session keeps and what the browser token
96
+ carries is governed by `server-oidc-rp` → "Organizations".
97
+
98
+ The guard attaches `updated.entity` to the request whenever the wrapping service answers one. A
99
+ relying party of a tenanted client has no organization registry of its own, so this is the only
100
+ way `req.entity` gets set there; `attachEntity` (`@owlmeans/auth-common`) keeps it only while its
101
+ `slug` is exactly the token's.
102
+
103
+ The switch is two protocols guarded by `OIDC_GUARD` alone — they act on the session the wrapped
104
+ token names, after the guard has validated it against the provider. There is no per-request
105
+ organization selector: the server's AJV strips unknown query keys, and the session, not the
106
+ request, decides which organization a request acts in.
107
+
80
108
  ## Provider descriptors
81
109
 
82
110
  `cfg.oidc.providers` is the list. `discoveryUrl` is the canonical form — the fully-qualified issuer,
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"}
@@ -1,3 +1,5 @@
1
+ import type { AuthToken } from '@owlmeans/auth';
2
+ import type { OidcOrganizationList } from './types.js';
1
3
  /** Shared OIDC browser-to-server protocols, bound by the relying-party packages. */
2
4
  export declare const oidcProtocols: {
3
5
  init: import("@owlmeans/entrypoint").EntrypointProtocol<{
@@ -6,5 +8,9 @@ export declare const oidcProtocols: {
6
8
  authenticate: import("@owlmeans/entrypoint").EntrypointProtocol<{
7
9
  body: import("./types.js").OIDCClientAuthPayload;
8
10
  }, any>;
11
+ organizations: import("@owlmeans/entrypoint").EntrypointProtocol<{}, OidcOrganizationList>;
12
+ organization: import("@owlmeans/entrypoint").EntrypointProtocol<{
13
+ body: import("./types.js").OidcOrganizationSwitch;
14
+ }, AuthToken>;
9
15
  };
10
16
  //# sourceMappingURL=entrypoints.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entrypoints.d.ts","sourceRoot":"","sources":["../src/entrypoints.ts"],"names":[],"mappings":"AAKA,oFAAoF;AACpF,eAAO,MAAM,aAAa;IACxB,IAAI;;;IAIJ,YAAY;;;CAIb,CAAA"}
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"}
@@ -1,10 +1,15 @@
1
1
  import { contract, protocol, typed } from '@owlmeans/entrypoint';
2
2
  import { route, RouteMethod, backend } from '@owlmeans/route';
3
- import { DISPATCHER_OIDC, DISPATCHER_OIDC_INIT } from './consts.js';
4
- import { OIDCAuthInitParamsSchema, OIDCClientAuthPayloadSchema } from './models.js';
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
5
  /** Shared OIDC browser-to-server protocols, bound by the relying-party packages. */
6
6
  export const oidcProtocols = {
7
7
  init: protocol(route(DISPATCHER_OIDC_INIT, '/authenticate/oidc/init', backend(null, RouteMethod.POST)), contract.request({ body: typed(OIDCAuthInitParamsSchema) }, typed())),
8
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 }),
9
14
  };
10
15
  //# sourceMappingURL=entrypoints.js.map
@@ -1 +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;AAC7D,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACnE,OAAO,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AAEnF,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;CACF,CAAA"}
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"}
@@ -1 +1 @@
1
- {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAsB,MAAM,YAAY,CAAA;AAGlG,OAAO,KAAK,EAAqC,cAAc,EAAgB,MAAM,sBAAsB,CAAA;AAQ3G,eAAO,MAAM,aAAa,UAAW,gBAAgB,KAAG,SAqGvD,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAC3D,CAAC,SAAS,gBAAgB,MAKpC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,IAAI,SAAS,cAAc,QACjD,IAAI,aAAa,MAAM,GAAG,SAAS,MAAM,EAAE,KAChD,IAcF,CAAA"}
1
+ {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAyC,MAAM,YAAY,CAAA;AAGrH,OAAO,KAAK,EAAqC,cAAc,EAAgB,MAAM,sBAAsB,CAAA;AAQ3G,eAAO,MAAM,aAAa,UAAW,gBAAgB,KAAG,SA4GvD,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAC3D,CAAC,SAAS,gBAAgB,MAKpC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,IAAI,SAAS,cAAc,QACjD,IAAI,aAAa,MAAM,GAAG,SAAS,MAAM,EAAE,KAChD,IAcF,CAAA"}
package/build/guard.js CHANGED
@@ -77,6 +77,12 @@ export const makeOidcGuard = (opts) => {
77
77
  if (updated == null) {
78
78
  return false;
79
79
  }
80
+ // The provider names the organization this session acts in, and a relying party of a
81
+ // tenanted client has no registry to resolve it from by slug. `attachEntity` keeps this one
82
+ // only while its slug is the token's, so a stale attachment can never stand in for it.
83
+ if (updated.entity != null) {
84
+ req.entity = updated.entity;
85
+ }
80
86
  if (updated.token !== token) {
81
87
  const [, newAuth] = updated.token.split(' ');
82
88
  const envelope = makeEnvelopeModel(newAuth, EnvelopeKind.Token);
@@ -1 +1 @@
1
- {"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1E,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAE/E,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAE,WAAW,EAAwB,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACtF,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAE9D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAuB,EAAa,EAAE;IAClE,2FAA2F;IAC3F,kFAAkF;IAClF,WAAW;IAEX,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,IAAI,aAAa,CAAC,CAAA;IAEnG,MAAM,KAAK,GAAc,aAAa,CAAY,UAAU,EAAE;QAC5D,cAAc;QAEd,gBAAgB;QAChB,mDAAmD;QACnD,oCAAoC;QACpC,uBAAuB;QACvB,MAAM;QAEN,0DAA0D;QAC1D,6DAA6D;QAC7D,6BAA6B;QAC7B,oDAAoD;QACpD,sBAAsB;QACtB,KAAK;QAEL,aAAa,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;YACzB,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;YAC7B,qDAAqD;YACrD,yEAAyE;YACzE,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAe,IAAI,EAAE,YAAY,IAAI,OAAO,CAAC,CAAA;YACrE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;YAC3C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;gBAClB,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;gBAC/B,IAAI,IAAI,KAAK,kBAAkB,CAAC,WAAW,EAAE,EAAE,CAAC;oBAC9C,OAAO,KAAK,CAAA;gBACd,CAAC;YACH,CAAC;YAED,OAAO,IAAI,CAAA;QACb,CAAC;QAED,cAAc;QACd,KAAK,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,kBAAkB,CAAC,IAAI,IAAI;QAErE,MAAM,EAAE,KAAK,EAAK,GAAoB,EAAE,GAA2B,EAAE,EAAE;YACrE,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAA;YAC/D,IAAI,aAAa,IAAI,IAAI,EAAE,CAAC;gBAC1B,OAAO,KAAU,CAAA;YACnB,CAAC;YAED,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;YAC7B,MAAM,OAAO,GAAG,MAAM,KAAK,CAAkB,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAE5F,wFAAwF;YACxF,0FAA0F;YAC1F,IAAI,QAAoD,CAAA;YACxD,IAAI,QAAQ,GAAG,KAAK,CAAA;YACpB,IAAI,CAAC;gBACH,QAAQ,GAAG,iBAAiB,CAAO,aAAa,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;gBACrE,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,GAAG,KAAK,CAAA;YAClB,CAAC;YACD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,KAAU,CAAA;YACnB,CAAC;YAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,EAAE,kBAAkB,EAAE,KAAK,CAAE,CAAA;YAE/D,IAAI,OAAO,GAAqB,IAAI,CAAA;YAEpC,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAA;YACtD,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,YAAY,kBAAkB,EAAE,CAAC;oBACpC,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;oBAC7C,GAAG,CAAC,OAAO,GAAG,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,CAAA;gBACrD,CAAC;gBAED,MAAM,CAAC,CAAA;YACT,CAAC;YAED,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;gBACpB,OAAO,KAAU,CAAA;YACnB,CAAC;YAED,IAAI,OAAO,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;gBAC5B,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;gBAC5C,MAAM,QAAQ,GAAG,iBAAiB,CAAO,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;gBAErE,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;gBACxD,GAAG,CAAC,OAAO,GAAG,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAA;gBAE9D,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;YACjC,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,OAAO,CAAC,QAAS,CAAC,OAAO,EAAE,CAAC,CAAA;YAClC,CAAC;YAED,OAAO,IAAS,CAAA;QAClB,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,OAAU,EAAE,IAAuB,EACnC,EAAE;IACF,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAA;IAE5C,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,IAAU,EAAE,QAAqC,EAC3C,EAAE;IACR,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,aAAa,CAAC,CAAC,CAAA;IAC1F,MAAM,QAAQ,GAAG,CAAC,IAAoB,EAAkB,EAAE,CAAC,MAAM,CAAC,WAAW,CAC3E,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACxC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;QAC/D,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC1F,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACrB,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;IACpF,CAAC,CAAC,CACH,CAAA;IAED,OAAO,QAAQ,CAAC,IAAI,CAAS,CAAA;AAC/B,CAAC,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,OAAgB,EAAsB,EAAE,CACvD,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC;IAC9B,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC;IAC/B,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE,CAAC,KAAK,EAAwB,CAAA"}
1
+ {"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"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"}
package/build/models.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import type { JSONSchemaType } from 'ajv';
2
- import type { OIDCAuthInitParams, OIDCClientAuthPayload, OIDCTokenUpdate, ProviderProfileDetails } from './types.js';
2
+ import type { OIDCAuthInitParams, OIDCClientAuthPayload, OidcOrganizationSwitch, OIDCTokenUpdate, ProviderProfileDetails } from './types.js';
3
3
  export declare const OIDCAuthInitParamsSchema: JSONSchemaType<OIDCAuthInitParams>;
4
4
  export declare const OIDCClientAuthPayloadSchema: JSONSchemaType<OIDCClientAuthPayload>;
5
+ export declare const OidcOrganizationSwitchSchema: JSONSchemaType<OidcOrganizationSwitch>;
5
6
  export declare const OIDCTokenUpdateSchema: JSONSchemaType<OIDCTokenUpdate>;
6
7
  export declare const ProviderProfileDetailsSchema: JSONSchemaType<ProviderProfileDetails>;
7
8
  //# sourceMappingURL=models.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAGpH,eAAO,MAAM,wBAAwB,EAAE,cAAc,CAAC,kBAAkB,CAQvE,CAAA;AAED,eAAO,MAAM,2BAA2B,EAAE,cAAc,CAAC,qBAAqB,CAQ7E,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC,eAAe,CAqBjE,CAAA;AAED,eAAO,MAAM,4BAA4B,EAAE,cAAc,CAAC,sBAAsB,CAe/E,CAAA"}
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AACzC,OAAO,KAAK,EACV,kBAAkB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,eAAe,EAAE,sBAAsB,EAC3G,MAAM,YAAY,CAAA;AAKnB,eAAO,MAAM,wBAAwB,EAAE,cAAc,CAAC,kBAAkB,CASvE,CAAA;AAED,eAAO,MAAM,2BAA2B,EAAE,cAAc,CAAC,qBAAqB,CAQ7E,CAAA;AAED,eAAO,MAAM,4BAA4B,EAAE,cAAc,CAAC,sBAAsB,CAO/E,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC,eAAe,CAqBjE,CAAA;AAED,eAAO,MAAM,4BAA4B,EAAE,cAAc,CAAC,sBAAsB,CAe/E,CAAA"}
package/build/models.js CHANGED
@@ -1,9 +1,10 @@
1
- import { AuthTokenSchema, EntityValueSchema, IdValueSchema, ScopeValueSchema, TypeNameSchema } from '@owlmeans/auth';
1
+ import { AuthTokenSchema, EntitySlugValueSchema, EntityValueSchema, IdValueSchema, ScopeValueSchema, TypeNameSchema, } from '@owlmeans/auth';
2
2
  export const OIDCAuthInitParamsSchema = {
3
3
  type: 'object',
4
4
  properties: {
5
5
  entity: { ...EntityValueSchema, nullable: true },
6
6
  profile: { ...IdValueSchema, nullable: true },
7
+ entitySlug: { ...EntitySlugValueSchema, nullable: true },
7
8
  },
8
9
  required: [],
9
10
  additionalProperties: false,
@@ -17,6 +18,14 @@ export const OIDCClientAuthPayloadSchema = {
17
18
  additionalProperties: { type: 'string', minLength: 0, maxLength: 512 },
18
19
  required: ['code', 'authUrl'],
19
20
  };
21
+ export const OidcOrganizationSwitchSchema = {
22
+ type: 'object',
23
+ properties: {
24
+ entitySlug: { ...EntitySlugValueSchema },
25
+ },
26
+ required: ['entitySlug'],
27
+ additionalProperties: false,
28
+ };
20
29
  export const OIDCTokenUpdateSchema = {
21
30
  type: 'object',
22
31
  properties: {
@@ -1 +1 @@
1
- {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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"}
package/build/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import type { AuthToken } from '@owlmeans/auth';
1
+ import type { AuthToken, PermissionSet } from '@owlmeans/auth';
2
2
  import type { AuthorizationService } from '@owlmeans/auth-common';
3
3
  import type { BasicConfig, BasicContext } from '@owlmeans/context';
4
- import type { GuardService } from '@owlmeans/entrypoint';
4
+ import type { GuardService, ResolvedEntity } from '@owlmeans/entrypoint';
5
5
  export interface Config extends BasicConfig {
6
6
  }
7
7
  export interface Context<C extends Config = Config> extends BasicContext<C> {
@@ -73,12 +73,62 @@ export interface OidcGuardOptions {
73
73
  export interface OIDCAuthInitParams {
74
74
  entity?: string;
75
75
  profile?: string;
76
+ /**
77
+ * The organization the person asked to act in after sign-in. Honoured only when the provider
78
+ * names it among the subject's organizations; otherwise the session starts in the home one.
79
+ */
80
+ entitySlug?: string;
81
+ }
82
+ /** One organization of the subject, as the provider claims it under `ORGANIZATIONS_SCOPE`. */
83
+ export interface OidcOrganizationClaim {
84
+ entitySlug: string;
85
+ /**
86
+ * The organization's frozen IAM key — stable across renames, which is why a session remembers
87
+ * its acting organization by it. Server-side only: never copied into a browser token or into a
88
+ * response.
89
+ */
90
+ entityKey: string;
91
+ title?: string;
92
+ owner: boolean;
93
+ groups?: string[];
94
+ home?: boolean;
95
+ }
96
+ /**
97
+ * A permission set as the provider claims it. A set carrying `entitySlug` is bound to that
98
+ * organization and applies only while the session acts in it; one without applies everywhere.
99
+ */
100
+ export interface OidcPermissionSetClaim extends PermissionSet {
101
+ entitySlug?: string;
102
+ }
103
+ /** One organization of the session, as the switch lists it — the key never leaves the server. */
104
+ export interface OidcOrganizationItem {
105
+ entitySlug: string;
106
+ title?: string;
107
+ owner: boolean;
108
+ groups?: string[];
109
+ home?: boolean;
110
+ acting: boolean;
111
+ }
112
+ export interface OidcOrganizationList {
113
+ items: OidcOrganizationItem[];
114
+ }
115
+ export interface OidcOrganizationSwitch {
116
+ entitySlug: string;
76
117
  }
77
118
  export interface OIDCClientAuthPayload extends Record<string, string> {
78
119
  code: string;
79
120
  authUrl: string;
80
121
  }
122
+ /**
123
+ * A refreshed wrapped token, plus the organization the session acts in when the provider names
124
+ * one. The guard attaches that entity to the request, because a relying party of a tenanted
125
+ * client has no resolver of its own that could find it by slug.
126
+ */
127
+ export interface WrappedOIDCUpdate extends AuthToken {
128
+ entity?: ResolvedEntity;
129
+ }
81
130
  export interface WrappedOIDCService extends AuthorizationService {
131
+ update: (token?: string | AuthToken, thr?: boolean) => Promise<WrappedOIDCUpdate | null>;
82
132
  }
83
133
  export interface OIDCTokenUpdate extends AuthToken {
84
134
  tokenSet: CommonTokenSetParams;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/oidc",
3
- "version": "0.1.18-rc.50",
3
+ "version": "0.1.18-rc.52",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -21,12 +21,12 @@
21
21
  }
22
22
  },
23
23
  "dependencies": {
24
- "@owlmeans/auth": "^0.1.18-rc.36",
25
- "@owlmeans/auth-common": "^0.1.18-rc.42",
26
- "@owlmeans/basic-envelope": "^0.1.18-rc.41",
27
- "@owlmeans/config": "^0.1.18-rc.39",
24
+ "@owlmeans/auth": "^0.1.18-rc.38",
25
+ "@owlmeans/auth-common": "^0.1.18-rc.44",
26
+ "@owlmeans/basic-envelope": "^0.1.18-rc.43",
27
+ "@owlmeans/config": "^0.1.18-rc.41",
28
28
  "@owlmeans/context": "^0.1.18-rc.32",
29
- "@owlmeans/entrypoint": "^0.1.18-rc.37",
29
+ "@owlmeans/entrypoint": "^0.1.18-rc.39",
30
30
  "@owlmeans/resource": "^0.1.18-rc.37",
31
31
  "@owlmeans/route": "^0.1.18-rc.33"
32
32
  },
package/src/consts.ts CHANGED
@@ -33,6 +33,12 @@ export const DISPATCHER_OIDC_INIT = 'dispatcher:oidc:init'
33
33
 
34
34
  export const DISPATCHER_OIDC = 'dispatcher:oidc:authenticate'
35
35
 
36
+ /** Lists the organizations the session's subject belongs to. */
37
+ export const DISPATCHER_OIDC_ORGANIZATIONS = 'dispatcher:oidc:organizations'
38
+
39
+ /** Switches the organization the session acts in. */
40
+ export const DISPATCHER_OIDC_ORGANIZATION = 'dispatcher:oidc:organization'
41
+
36
42
  export const OIDC_CODE_QUERY = 'code'
37
43
 
38
44
  /**
@@ -71,3 +77,22 @@ export const OIDC_RP_BASE_SCOPE = OIDC_RP_BASE_SCOPES.join(' ')
71
77
 
72
78
  /** Token/userinfo claim carrying the subject's PermissionSet[] for the requesting client. */
73
79
  export const PERMISSIONS_CLAIM = 'permissions'
80
+
81
+ /**
82
+ * OIDC scope of a tenanted client: the provider answers it with the subject's organizations and
83
+ * the full permission claim, bound sets included. A client that never asks for it gets the
84
+ * flattened claim of the one organization it acts in, exactly as before the scope existed.
85
+ */
86
+ export const ORGANIZATIONS_SCOPE = 'organizations'
87
+
88
+ /** Token/userinfo claim carrying the subject's `OidcOrganizationClaim[]`. */
89
+ export const ORGANIZATIONS_CLAIM = 'organizations'
90
+
91
+ /** `AuthForbidden` reason: the organization named is not one the subject belongs to. */
92
+ export const ORGANIZATION_REFUSAL = 'organization'
93
+
94
+ /** `AuthForbidden` reason: the action needs the organization's owner. */
95
+ export const ORGANIZATION_OWNER_REFUSAL = 'organization:owner'
96
+
97
+ /** Discovery-document field carrying the base URL of the provider's runtime IAM API. */
98
+ export const IAM_API_METADATA = 'owlmeans_iam_api'
@@ -1,7 +1,11 @@
1
1
  import { contract, protocol, typed } from '@owlmeans/entrypoint'
2
2
  import { route, RouteMethod, backend } from '@owlmeans/route'
3
- import { DISPATCHER_OIDC, DISPATCHER_OIDC_INIT } from './consts.js'
4
- import { OIDCAuthInitParamsSchema, OIDCClientAuthPayloadSchema } from './models.js'
3
+ import type { AuthToken } from '@owlmeans/auth'
4
+ import {
5
+ DISPATCHER_OIDC, DISPATCHER_OIDC_INIT, DISPATCHER_OIDC_ORGANIZATION, DISPATCHER_OIDC_ORGANIZATIONS, OIDC_GUARD,
6
+ } from './consts.js'
7
+ import { OIDCAuthInitParamsSchema, OIDCClientAuthPayloadSchema, OidcOrganizationSwitchSchema } from './models.js'
8
+ import type { OidcOrganizationList } from './types.js'
5
9
 
6
10
  /** Shared OIDC browser-to-server protocols, bound by the relying-party packages. */
7
11
  export const oidcProtocols = {
@@ -13,4 +17,17 @@ export const oidcProtocols = {
13
17
  route(DISPATCHER_OIDC, '/authenticate/oidc/process', backend(null, RouteMethod.POST)),
14
18
  contract.request({ body: typed(OIDCClientAuthPayloadSchema) }, typed<any>()),
15
19
  ),
20
+ // The organization switch acts on the session the wrapped token names, so only that token's own
21
+ // guard can reach it — and it runs after the guard has refreshed the session against the
22
+ // provider, so the list it answers from is the provider's current one.
23
+ organizations: protocol(
24
+ route(DISPATCHER_OIDC_ORGANIZATIONS, '/authenticate/oidc/organizations', backend(null, RouteMethod.GET)),
25
+ contract(typed<OidcOrganizationList>()),
26
+ { guards: OIDC_GUARD },
27
+ ),
28
+ organization: protocol(
29
+ route(DISPATCHER_OIDC_ORGANIZATION, '/authenticate/oidc/organization', backend(null, RouteMethod.POST)),
30
+ contract.request({ body: typed(OidcOrganizationSwitchSchema) }, typed<AuthToken>()),
31
+ { guards: OIDC_GUARD },
32
+ ),
16
33
  }
package/src/guard.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { createService } from '@owlmeans/context'
2
- import type { Config, Context, OidcGuard, OidcGuardOptions, WrappedOIDCService } from './types.js'
2
+ import type { Config, Context, OidcGuard, OidcGuardOptions, WrappedOIDCService, WrappedOIDCUpdate } from './types.js'
3
3
  import { OIDC_GUARD, OIDC_WRAPPED_TOKEN, WRAPPED_OIDC } from './consts.js'
4
4
  import { decorateEntrypoint, isEntrypointProtocol } from '@owlmeans/entrypoint'
5
5
  import type { AbstractRequest, AbstractResponse, EntrypointTree, GuardService } from '@owlmeans/entrypoint'
6
6
  import { DEFAULT_GUARD, TOKEN_UPDATE } from '@owlmeans/auth-common'
7
- import { AUTH_HEADER, type Auth, AuthToken, AuthorizationError } from '@owlmeans/auth'
7
+ import { AUTH_HEADER, type Auth, AuthorizationError } from '@owlmeans/auth'
8
8
  import { EnvelopeKind, makeEnvelopeModel } from '@owlmeans/basic-envelope'
9
9
  import { trust } from '@owlmeans/auth-common/utils'
10
10
  import { TRUSTED } from '@owlmeans/config'
@@ -77,7 +77,7 @@ export const makeOidcGuard = (opts?: OidcGuardOptions): OidcGuard => {
77
77
 
78
78
  const token = extractAuthToken(req, OIDC_WRAPPED_TOKEN, false)!
79
79
 
80
- let updated: AuthToken | null = null
80
+ let updated: WrappedOIDCUpdate | null = null
81
81
 
82
82
  try {
83
83
  updated = await wrapper(ctx).update({ token }, true)
@@ -94,6 +94,13 @@ export const makeOidcGuard = (opts?: OidcGuardOptions): OidcGuard => {
94
94
  return false as T
95
95
  }
96
96
 
97
+ // The provider names the organization this session acts in, and a relying party of a
98
+ // tenanted client has no registry to resolve it from by slug. `attachEntity` keeps this one
99
+ // only while its slug is the token's, so a stale attachment can never stand in for it.
100
+ if (updated.entity != null) {
101
+ req.entity = updated.entity
102
+ }
103
+
97
104
  if (updated.token !== token) {
98
105
  const [, newAuth] = updated.token.split(' ')
99
106
  const envelope = makeEnvelopeModel<Auth>(newAuth, EnvelopeKind.Token)
package/src/models.ts CHANGED
@@ -1,12 +1,17 @@
1
1
  import type { JSONSchemaType } from 'ajv'
2
- import type { OIDCAuthInitParams, OIDCClientAuthPayload, OIDCTokenUpdate, ProviderProfileDetails } from './types.js'
3
- import { AuthTokenSchema, EntityValueSchema, IdValueSchema, ScopeValueSchema, TypeNameSchema } from '@owlmeans/auth'
2
+ import type {
3
+ OIDCAuthInitParams, OIDCClientAuthPayload, OidcOrganizationSwitch, OIDCTokenUpdate, ProviderProfileDetails,
4
+ } from './types.js'
5
+ import {
6
+ AuthTokenSchema, EntitySlugValueSchema, EntityValueSchema, IdValueSchema, ScopeValueSchema, TypeNameSchema,
7
+ } from '@owlmeans/auth'
4
8
 
5
9
  export const OIDCAuthInitParamsSchema: JSONSchemaType<OIDCAuthInitParams> = {
6
10
  type: 'object',
7
11
  properties: {
8
12
  entity: { ...EntityValueSchema, nullable: true },
9
13
  profile: { ...IdValueSchema, nullable: true },
14
+ entitySlug: { ...EntitySlugValueSchema, nullable: true },
10
15
  },
11
16
  required: [],
12
17
  additionalProperties: false,
@@ -22,6 +27,15 @@ export const OIDCClientAuthPayloadSchema: JSONSchemaType<OIDCClientAuthPayload>
22
27
  required: ['code', 'authUrl'],
23
28
  }
24
29
 
30
+ export const OidcOrganizationSwitchSchema: JSONSchemaType<OidcOrganizationSwitch> = {
31
+ type: 'object',
32
+ properties: {
33
+ entitySlug: { ...EntitySlugValueSchema },
34
+ },
35
+ required: ['entitySlug'],
36
+ additionalProperties: false,
37
+ }
38
+
25
39
  export const OIDCTokenUpdateSchema: JSONSchemaType<OIDCTokenUpdate> = {
26
40
  type: 'object',
27
41
  properties: {
package/src/types.ts CHANGED
@@ -1,7 +1,7 @@
1
- import type { AuthToken } from '@owlmeans/auth'
1
+ import type { AuthToken, PermissionSet } from '@owlmeans/auth'
2
2
  import type { AuthorizationService } from '@owlmeans/auth-common'
3
3
  import type { BasicConfig, BasicContext } from '@owlmeans/context'
4
- import type { GuardService } from '@owlmeans/entrypoint'
4
+ import type { GuardService, ResolvedEntity } from '@owlmeans/entrypoint'
5
5
 
6
6
  export interface Config extends BasicConfig { }
7
7
  export interface Context<C extends Config = Config> extends BasicContext<C> { }
@@ -84,6 +84,52 @@ export interface OidcGuardOptions {
84
84
  export interface OIDCAuthInitParams {
85
85
  entity?: string
86
86
  profile?: string
87
+ /**
88
+ * The organization the person asked to act in after sign-in. Honoured only when the provider
89
+ * names it among the subject's organizations; otherwise the session starts in the home one.
90
+ */
91
+ entitySlug?: string
92
+ }
93
+
94
+ /** One organization of the subject, as the provider claims it under `ORGANIZATIONS_SCOPE`. */
95
+ export interface OidcOrganizationClaim {
96
+ entitySlug: string
97
+ /**
98
+ * The organization's frozen IAM key — stable across renames, which is why a session remembers
99
+ * its acting organization by it. Server-side only: never copied into a browser token or into a
100
+ * response.
101
+ */
102
+ entityKey: string
103
+ title?: string
104
+ owner: boolean
105
+ groups?: string[]
106
+ home?: boolean
107
+ }
108
+
109
+ /**
110
+ * A permission set as the provider claims it. A set carrying `entitySlug` is bound to that
111
+ * organization and applies only while the session acts in it; one without applies everywhere.
112
+ */
113
+ export interface OidcPermissionSetClaim extends PermissionSet {
114
+ entitySlug?: string
115
+ }
116
+
117
+ /** One organization of the session, as the switch lists it — the key never leaves the server. */
118
+ export interface OidcOrganizationItem {
119
+ entitySlug: string
120
+ title?: string
121
+ owner: boolean
122
+ groups?: string[]
123
+ home?: boolean
124
+ acting: boolean
125
+ }
126
+
127
+ export interface OidcOrganizationList {
128
+ items: OidcOrganizationItem[]
129
+ }
130
+
131
+ export interface OidcOrganizationSwitch {
132
+ entitySlug: string
87
133
  }
88
134
 
89
135
  // @TODO replace arbitarary Record params with specific possible params for OIDC
@@ -92,7 +138,17 @@ export interface OIDCClientAuthPayload extends Record<string, string> {
92
138
  authUrl: string
93
139
  }
94
140
 
141
+ /**
142
+ * A refreshed wrapped token, plus the organization the session acts in when the provider names
143
+ * one. The guard attaches that entity to the request, because a relying party of a tenanted
144
+ * client has no resolver of its own that could find it by slug.
145
+ */
146
+ export interface WrappedOIDCUpdate extends AuthToken {
147
+ entity?: ResolvedEntity
148
+ }
149
+
95
150
  export interface WrappedOIDCService extends AuthorizationService {
151
+ update: (token?: string | AuthToken, thr?: boolean) => Promise<WrappedOIDCUpdate | null>
96
152
  }
97
153
 
98
154
  export interface OIDCTokenUpdate extends AuthToken {
@@ -0,0 +1,29 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+ import { RouteMethod } from '@owlmeans/route'
3
+ import { oidcProtocols } from '../src/entrypoints.js'
4
+ import { DISPATCHER_OIDC_ORGANIZATION, DISPATCHER_OIDC_ORGANIZATIONS, OIDC_GUARD } from '../src/consts.js'
5
+ import { OidcOrganizationSwitchSchema } from '../src/models.js'
6
+
7
+ describe('oidcProtocols — organization switch', () => {
8
+ test('lists organizations on GET, behind the wrapped-token guard alone', () => {
9
+ const { organizations } = oidcProtocols
10
+ expect(organizations.alias).toBe(DISPATCHER_OIDC_ORGANIZATIONS)
11
+ expect(organizations.route.route.path).toBe('/authenticate/oidc/organizations')
12
+ expect(organizations.route.route.method).toBe(RouteMethod.GET)
13
+ expect(organizations.guards).toEqual([OIDC_GUARD])
14
+ })
15
+
16
+ test('switches on POST with a closed slug body, behind the same guard', () => {
17
+ const { organization } = oidcProtocols
18
+ expect(organization.alias).toBe(DISPATCHER_OIDC_ORGANIZATION)
19
+ expect(organization.route.route.path).toBe('/authenticate/oidc/organization')
20
+ expect(organization.route.route.method).toBe(RouteMethod.POST)
21
+ expect(organization.guards).toEqual([OIDC_GUARD])
22
+ expect(organization.contract?.requestSchemas.body).toEqual(OidcOrganizationSwitchSchema)
23
+ })
24
+
25
+ test('the sign-in pair stays unguarded', () => {
26
+ expect(oidcProtocols.init.guards).toEqual([])
27
+ expect(oidcProtocols.authenticate.guards).toEqual([])
28
+ })
29
+ })
@@ -1,4 +1,12 @@
1
1
  import { describe, expect, mock, test } from 'bun:test'
2
+ import { AuthRole } from '@owlmeans/auth'
3
+ import type { Auth } from '@owlmeans/auth'
4
+ import { EnvelopeKind, makeEnvelopeModel } from '@owlmeans/basic-envelope'
5
+ import type { AbstractRequest, ResolvedEntity } from '@owlmeans/entrypoint'
6
+ import type { WrappedOIDCUpdate } from '../src/types.js'
7
+
8
+ /** Whether the trusted key accepts a signature — off for the undecodable-token cases. */
9
+ let accept = false
2
10
 
3
11
  /**
4
12
  * A bearer that cannot be decoded is a credential the server does not accept — the guard answers
@@ -6,7 +14,7 @@ import { describe, expect, mock, test } from 'bun:test'
6
14
  * never throws the decoder's own error (which the API layer answers with 500).
7
15
  */
8
16
  mock.module('@owlmeans/auth-common/utils', () => ({
9
- trust: async () => ({ key: { verify: async () => false } }),
17
+ trust: async () => ({ key: { verify: async () => accept } }),
10
18
  extractAuthToken: (req: { headers: Record<string, string> }, type: string, strip = true) => {
11
19
  const header = req.headers.authorization
12
20
  if (header == null || !header.toUpperCase().startsWith(type.toUpperCase())) return null
@@ -15,21 +23,69 @@ mock.module('@owlmeans/auth-common/utils', () => ({
15
23
  }))
16
24
 
17
25
  const { makeOidcGuard } = await import('../src/guard.js')
26
+ const { OIDC_WRAPPED_TOKEN, WRAPPED_OIDC } = await import('../src/consts.js')
18
27
 
19
- const call = async (authorization: string) => {
28
+ const call = async (authorization: string, update?: (token: string) => WrappedOIDCUpdate) => {
20
29
  const guard = makeOidcGuard() as any
21
- guard.assertCtx = () => ({ cfg: { alias: 'app' } })
22
- const res = { responseProvider: { header: () => undefined } }
23
- return await guard.handle({ headers: { authorization } }, res)
30
+ guard.assertCtx = () => ({
31
+ cfg: { alias: 'app' },
32
+ hasService: (alias: string) => alias === WRAPPED_OIDC && update != null,
33
+ service: () => ({ update: async ({ token }: { token: string }) => update!(token) }),
34
+ })
35
+ const req = { headers: { authorization } } as unknown as AbstractRequest
36
+ const res = { responseProvider: { header: () => undefined }, resolve: () => undefined }
37
+ return { outcome: await guard.handle(req, res), req }
38
+ }
39
+
40
+ const wrapped = async (auth: Partial<Auth>): Promise<string> => {
41
+ const envelope = makeEnvelopeModel<Auth>(OIDC_WRAPPED_TOKEN).send({
42
+ type: OIDC_WRAPPED_TOKEN, token: 'session', userId: 'sub', role: AuthRole.Guest, scopes: [],
43
+ isUser: true, createdAt: new Date(), ...auth,
44
+ } as Auth, null)
45
+ const token = await envelope.sign({ sign: async () => 'signature' } as never, EnvelopeKind.Token)
46
+
47
+ return `${OIDC_WRAPPED_TOKEN.toUpperCase()} ${token}`
24
48
  }
25
49
 
26
50
  describe('oidc guard', () => {
27
51
  test('an undecodable wrapped token is unauthenticated, not a server error', async () => {
28
- expect(await call('OIDC-WRAPPED-TOKEN bogus.token')).toBe(false)
52
+ accept = false
53
+ expect((await call('OIDC-WRAPPED-TOKEN bogus.token')).outcome).toBe(false)
29
54
  })
30
55
 
31
56
  test('garbage of every shape stays unauthenticated', async () => {
32
- expect(await call('OIDC-WRAPPED-TOKEN %%%')).toBe(false)
33
- expect(await call('OIDC-WRAPPED-TOKEN ')).toBe(false)
57
+ accept = false
58
+ expect((await call('OIDC-WRAPPED-TOKEN %%%')).outcome).toBe(false)
59
+ expect((await call('OIDC-WRAPPED-TOKEN ')).outcome).toBe(false)
60
+ })
61
+ })
62
+
63
+ describe('oidc guard — the acting organization', () => {
64
+ const acme: ResolvedEntity = { id: 'iam-key-acme', slug: 'acme', iamKey: 'iam-key-acme' }
65
+
66
+ test('attaches the entity the wrapper resolved', async () => {
67
+ accept = true
68
+ const authorization = await wrapped({ entitySlug: 'acme' })
69
+ const { outcome, req } = await call(authorization, token => ({ token, entity: acme }))
70
+
71
+ expect(outcome).toBe(true)
72
+ expect(req.entity).toEqual(acme)
73
+ })
74
+
75
+ test('attaches nothing when the wrapper names no organization', async () => {
76
+ accept = true
77
+ const authorization = await wrapped({ entitySlug: 'acme' })
78
+ const { outcome, req } = await call(authorization, token => ({ token }))
79
+
80
+ expect(outcome).toBe(true)
81
+ expect(req.entity).toBeUndefined()
82
+ })
83
+
84
+ test('without a wrapping service there is nothing to attach', async () => {
85
+ accept = true
86
+ const { outcome, req } = await call(await wrapped({ entitySlug: 'acme' }))
87
+
88
+ expect(outcome).toBe(true)
89
+ expect(req.entity).toBeUndefined()
34
90
  })
35
91
  })
@@ -0,0 +1,42 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+ import Ajv from 'ajv'
3
+ import { OIDCAuthInitParamsSchema, OidcOrganizationSwitchSchema } from '../src/models.js'
4
+
5
+ const strict = new Ajv()
6
+ // The server's own options: a closed schema STRIPS what it does not declare instead of failing,
7
+ // so an undeclared field would vanish without an error ever reaching the caller.
8
+ const server = new Ajv({ removeAdditional: true, useDefaults: true, coerceTypes: true, allErrors: true, strict: false })
9
+
10
+ describe('OIDCAuthInitParamsSchema', () => {
11
+ const validate = strict.compile(OIDCAuthInitParamsSchema)
12
+
13
+ test('accepts the requested organization next to the provider entity', () => {
14
+ expect(validate({ entity: 'acme-client', entitySlug: 'acme-team' })).toBe(true)
15
+ expect(validate({ entitySlug: 'acme-team' })).toBe(true)
16
+ expect(validate({})).toBe(true)
17
+ })
18
+
19
+ test('refuses a slug too short to name an organization', () => {
20
+ expect(validate({ entitySlug: 'ab' })).toBe(false)
21
+ })
22
+
23
+ test('stays closed to anything it does not declare', () => {
24
+ expect(validate({ entitySlug: 'acme-team', entityId: '0123456789abcdef01234567' })).toBe(false)
25
+ })
26
+
27
+ test('the server keeps the requested slug rather than stripping it', () => {
28
+ const body: Record<string, unknown> = { entity: 'acme-client', entitySlug: 'acme-team', stray: 'x' }
29
+ expect(server.compile(OIDCAuthInitParamsSchema)(body)).toBe(true)
30
+ expect(body).toEqual({ entity: 'acme-client', entitySlug: 'acme-team' })
31
+ })
32
+ })
33
+
34
+ describe('OidcOrganizationSwitchSchema', () => {
35
+ const validate = strict.compile(OidcOrganizationSwitchSchema)
36
+
37
+ test('names the organization by slug and nothing else', () => {
38
+ expect(validate({ entitySlug: 'acme-team' })).toBe(true)
39
+ expect(validate({})).toBe(false)
40
+ expect(validate({ entitySlug: 'acme-team', entityKey: 'frozen-key' })).toBe(false)
41
+ })
42
+ })