@owlmeans/auth-common 0.1.18-rc.9 → 0.1.18
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 +31 -17
- package/agent-meta/manifest.json +3 -3
- package/agent-meta/skills/auth-common/SKILL.md +124 -23
- package/build/consts.d.ts +9 -0
- package/build/consts.d.ts.map +1 -1
- package/build/consts.js +9 -0
- package/build/consts.js.map +1 -1
- package/build/entity/types.d.ts +52 -0
- package/build/entity/types.d.ts.map +1 -0
- package/build/entity/types.js +2 -0
- package/build/entity/types.js.map +1 -0
- package/build/entity.d.ts +5 -37
- package/build/entity.d.ts.map +1 -1
- package/build/entity.js +44 -65
- package/build/entity.js.map +1 -1
- package/build/entrypoints.d.ts +41 -0
- package/build/entrypoints.d.ts.map +1 -0
- package/build/entrypoints.js +46 -0
- package/build/entrypoints.js.map +1 -0
- package/build/guards/basic-ed25519/consts.local.d.ts +3 -0
- package/build/guards/basic-ed25519/consts.local.d.ts.map +1 -0
- package/build/guards/basic-ed25519/consts.local.js +4 -0
- package/build/guards/basic-ed25519/consts.local.js.map +1 -0
- package/build/guards/basic-ed25519/index.d.ts +1 -0
- package/build/guards/basic-ed25519/index.d.ts.map +1 -1
- package/build/guards/basic-ed25519/index.js +1 -0
- package/build/guards/basic-ed25519/index.js.map +1 -1
- package/build/guards/basic-ed25519/replay.d.ts +14 -0
- package/build/guards/basic-ed25519/replay.d.ts.map +1 -0
- package/build/guards/basic-ed25519/replay.js +49 -0
- package/build/guards/basic-ed25519/replay.js.map +1 -0
- package/build/guards/basic-ed25519/service.d.ts +0 -5
- package/build/guards/basic-ed25519/service.d.ts.map +1 -1
- package/build/guards/basic-ed25519/service.js +34 -20
- package/build/guards/basic-ed25519/service.js.map +1 -1
- package/build/guards/basic-ed25519/types.d.ts +16 -0
- package/build/guards/basic-ed25519/types.d.ts.map +1 -1
- package/build/index.d.ts +2 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/middleware.d.ts +1 -1
- package/build/middleware.d.ts.map +1 -1
- package/build/middleware.js +13 -12
- package/build/middleware.js.map +1 -1
- package/build/modules.d.ts.map +1 -1
- package/build/modules.js +2 -11
- package/build/modules.js.map +1 -1
- package/build/schemas.d.ts +1 -13
- package/build/schemas.d.ts.map +1 -1
- package/build/schemas.js.map +1 -1
- package/build/types.d.ts +13 -0
- package/build/types.d.ts.map +1 -1
- package/build/types.local.d.ts +5 -0
- package/build/types.local.d.ts.map +1 -0
- package/build/types.local.js +2 -0
- package/build/types.local.js.map +1 -0
- package/build/utils/trusted.d.ts.map +1 -1
- package/build/utils/trusted.js +4 -3
- package/build/utils/trusted.js.map +1 -1
- package/package.json +13 -13
- package/src/consts.ts +10 -0
- package/src/entity/types.ts +52 -0
- package/src/entity.ts +51 -66
- package/src/entrypoints.ts +68 -0
- package/src/guards/basic-ed25519/consts.local.ts +4 -0
- package/src/guards/basic-ed25519/index.ts +1 -0
- package/src/guards/basic-ed25519/replay.ts +55 -0
- package/src/guards/basic-ed25519/service.ts +44 -25
- package/src/guards/basic-ed25519/types.ts +17 -0
- package/src/index.ts +2 -1
- package/src/middleware.ts +15 -18
- package/src/schemas.ts +1 -14
- package/src/types.local.ts +5 -0
- package/src/types.ts +14 -0
- package/src/utils/trusted.ts +5 -4
- package/tests/basic-ed25519.spec.ts +99 -0
- package/tests/context.ts +1 -2
- package/tests/dispatcher.spec.ts +15 -15
- package/tests/entity.spec.ts +112 -0
- package/src/modules.ts +0 -65
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# @owlmeans/auth-common
|
|
2
2
|
|
|
3
|
-
Predefined authentication
|
|
3
|
+
Predefined authentication protocols, guards, and constants shared between server and client packages.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
- Exports
|
|
7
|
+
- Exports the immutable `authProtocols` and `managerProtocols` trees for login, init, rely, and dispatcher flows
|
|
8
8
|
- Provides `DEFAULT_GUARD` and `GUARD_ED25519` constants for protecting routes
|
|
9
9
|
- Implements the Basic ED25519 signature guard service for cryptographic request authentication
|
|
10
10
|
- Headers: `BED255_NONCE_HEADER`, `BED255_TIME_HEADER` for auth challenge/response
|
|
@@ -12,35 +12,41 @@ Predefined authentication modules, guards, and constants shared between server a
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
bun add @owlmeans/auth-common
|
|
15
|
+
bun add @owlmeans/auth-common@^0.1.18
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Import the shared declarations and bind them only through the server or browser package that owns
|
|
21
|
+
the runtime behaviour:
|
|
21
22
|
|
|
22
23
|
```typescript
|
|
23
|
-
import {
|
|
24
|
+
import { authProtocols } from '@owlmeans/auth-common'
|
|
24
25
|
import { GUARD_ED25519, DEFAULT_GUARD } from '@owlmeans/auth-common'
|
|
25
26
|
|
|
26
|
-
//
|
|
27
|
-
await
|
|
27
|
+
// Call the exact registered declaration; do not look up auth routes by an alias string.
|
|
28
|
+
await context.entrypoint(authProtocols.dispatcherAuthenticate).call({ body: token })
|
|
28
29
|
```
|
|
29
30
|
|
|
30
31
|
Protect a route with the ED25519 signature guard (re-exported via `@owlmeans/server-app`):
|
|
31
32
|
|
|
32
33
|
```typescript
|
|
33
34
|
import { GUARD_ED25519 } from '@owlmeans/auth-common'
|
|
34
|
-
import {
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
import { contract, protocol, typed } from '@owlmeans/entrypoint'
|
|
36
|
+
import { route } from '@owlmeans/route'
|
|
37
|
+
|
|
38
|
+
const adminProtocol = protocol(
|
|
39
|
+
route('admin', '/api/admin'),
|
|
40
|
+
contract(typed<AdminResponse>()),
|
|
41
|
+
{ guards: GUARD_ED25519 },
|
|
42
|
+
)
|
|
37
43
|
```
|
|
38
44
|
|
|
39
45
|
## API
|
|
40
46
|
|
|
41
|
-
### `
|
|
47
|
+
### `authProtocols`
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
Immutable shared declarations covering the standard auth flow:
|
|
44
50
|
- `AUTHEN` — backend `/authentication` base route
|
|
45
51
|
- `AUTHEN_INIT` — POST `/authentication/init` (allowance request)
|
|
46
52
|
- `AUTHEN_AUTHEN` — POST `/authentication/authenticate` (credential submission)
|
|
@@ -48,6 +54,14 @@ Array of pre-built `CommonModule` instances covering the standard auth flow:
|
|
|
48
54
|
- `CAUTHEN`, `CAUTHEN_AUTHEN` — frontend auth routes
|
|
49
55
|
- `DISPATCHER` — frontend dispatcher route (sticky, handles redirect auth tokens)
|
|
50
56
|
|
|
57
|
+
`@owlmeans/server-auth`, `@owlmeans/client-auth`, and the OIDC packages export local runtime
|
|
58
|
+
binding arrays for the declarations they serve. Keep those arrays local to the runtime; application
|
|
59
|
+
code uses this tree's protocol objects.
|
|
60
|
+
|
|
61
|
+
### `managerProtocols`
|
|
62
|
+
|
|
63
|
+
Immutable shared manager protocol tree for profile-to-organization mapping and auth delegation.
|
|
64
|
+
|
|
51
65
|
### Guard Constants
|
|
52
66
|
|
|
53
67
|
```typescript
|
|
@@ -66,15 +80,15 @@ BED255_CASHE_RESOURCE // resource alias for nonce cache
|
|
|
66
80
|
## Product-Viable Integration Notes
|
|
67
81
|
|
|
68
82
|
- `DEFAULT_GUARD` protects manager routes after bearer authentication is installed by `@owlmeans/server-auth`.
|
|
69
|
-
- Product authorization composes a custom gate
|
|
83
|
+
- Product authorization composes a custom gate in the protocol options rather than using `OIDC_GATE` for Google login flows.
|
|
70
84
|
- `GUARD_ED25519` remains the service-to-service guard for internal/publisher/payment/auth-service calls.
|
|
71
|
-
- The browser-side
|
|
85
|
+
- The browser-side binding from `@owlmeans/client-auth` uses the same protocol references as the shared declarations.
|
|
72
86
|
|
|
73
87
|
## Related Packages
|
|
74
88
|
|
|
75
89
|
- [`@owlmeans/auth`](../auth) — auth type definitions and schemas
|
|
76
|
-
- [`@owlmeans/server-auth`](../server-auth) — server guard implementation
|
|
77
|
-
- [`@owlmeans/client-auth`](../client-auth) —
|
|
90
|
+
- [`@owlmeans/server-auth`](../server-auth) — server bindings and guard implementation
|
|
91
|
+
- [`@owlmeans/client-auth`](../client-auth) — browser bindings and auth service
|
|
78
92
|
|
|
79
93
|
<!-- owlmeans:agent-guidance:start -->
|
|
80
94
|
## Agent guidance
|
|
@@ -84,7 +98,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
84
98
|
your project's skill store (`.agents/skills/`):
|
|
85
99
|
|
|
86
100
|
```sh
|
|
87
|
-
npx @owlmeans/agent-skills
|
|
101
|
+
npx @owlmeans/agent-skills@^0.1.18
|
|
88
102
|
```
|
|
89
103
|
|
|
90
104
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion":
|
|
2
|
+
"schemaVersion": 3,
|
|
3
3
|
"package": "@owlmeans/auth-common",
|
|
4
|
-
"version": "0.1.18
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18",
|
|
5
|
+
"generatedAt": "2026-10-28T00:31:34.721Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: auth-common
|
|
3
|
-
description: How to use @owlmeans/auth-common —
|
|
3
|
+
description: How to use @owlmeans/auth-common — the auth vocabulary both sides of the wire share, covering guard aliases (DEFAULT_GUARD, GUARD_ED25519), the shared auth protocol trees, the Ed25519 signature guard, the TRUSTED-record trust() helper, and the organization-entity resolver contract (ENTITY_RESOLVER, makeEntityScope). Auto-invoked when importing guard constants, shared auth protocols, or entity-resolution helpers.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
@@ -8,46 +8,147 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/auth-common
|
|
9
9
|
|
|
10
10
|
**Layer:** Core
|
|
11
|
-
**Install:** `"@owlmeans/auth-common": "^0.1.18
|
|
11
|
+
**Install:** `"@owlmeans/auth-common": "^0.1.18"` in `dependencies`
|
|
12
|
+
|
|
13
|
+
Everything a server and a browser must agree on to talk authentication: aliases, the shared
|
|
14
|
+
protocol declarations, the signature guard, and the contract for resolving the organization
|
|
15
|
+
entity a token names.
|
|
12
16
|
|
|
13
17
|
## Key Exports
|
|
14
18
|
|
|
19
|
+
### Aliases and constants
|
|
20
|
+
|
|
21
|
+
| Export | Value / description |
|
|
22
|
+
|--------|---------------------|
|
|
23
|
+
| `DEF_AUTH_SRV` / `DEFAULT_GUARD` | `'auth'` — the canonical auth guard alias, the same string on both sides |
|
|
24
|
+
| `GUARD_ED25519` | `'guard:ed25519-basic-signature'` — the Ed25519 request-signature guard |
|
|
25
|
+
| `TOKEN_UPDATE` | `'auth-token-refresh'` |
|
|
26
|
+
| `WEB_API` | `'web-auth-api'` — service alias of the auth manager's web API |
|
|
27
|
+
| `DISPATCHER_PATH` / `SURROGATE_PATH` | `'/dispatcher'` / `'/surrogate'` — both reserved; an application must never declare its own route at either |
|
|
28
|
+
| `ENTITY_RESOLVER` | `'entity-resolver'` — the organization-entity resolver's service alias |
|
|
29
|
+
| `ENTITY_SLUG_PATTERN` | A lowercase DNS label. Slugs compose hostnames, cluster object names and OIDC client ids, so anything needing sanitising is rejected where it is chosen |
|
|
30
|
+
| `RELY_PIN_PERFIX`, `RELY_TOKEN_PREFIX`, `RELY_CALL_TIMEOUT`, `RELY_ACTION_TIMEOUT` | Rely-handshake constants |
|
|
31
|
+
| `BED255_TIME_HEADER`, `BED255_NONCE_HEADER`, `BED255_SIG_TTL`, `BED255_CASHE_RESOURCE` | Ed25519 signature-guard headers, replay window and nonce-cache alias |
|
|
32
|
+
| `authApi` | Alias tree for the manager API entrypoints (`profile`, `entity`, `auth`) |
|
|
33
|
+
|
|
34
|
+
### Entrypoints, guard and middleware
|
|
35
|
+
|
|
15
36
|
| Export | Description |
|
|
16
37
|
|--------|-------------|
|
|
17
|
-
| `
|
|
18
|
-
| `
|
|
19
|
-
| `
|
|
20
|
-
|
|
|
21
|
-
|
|
|
38
|
+
| `authProtocols` | The shared auth protocol tree — `AUTHEN*`, `CAUTHEN*`, `DISPATCHER`, `DISPATCHER_SURROGATE`, `DISPATCHER_AUTHEN`. Server and client packages bind the entries they serve |
|
|
39
|
+
| `managerProtocols` | The auth-manager web API protocol tree (profile → entity slug, auth delegation) |
|
|
40
|
+
| `makeBasicEd25519Guard(resource, opts?)` | The `GUARD_ED25519` guard service: signs outgoing requests as a client, verifies time/nonce/signature as a server |
|
|
41
|
+
| `authMiddleware` | Loading-stage context middleware that attaches the guard's token to every guarded backend entrypoint's `invoke`/`call` |
|
|
42
|
+
| `SurrogateQuery`, `SurrogateQuerySchema` | The surrogate window's `intent` / `next` / `method` query |
|
|
43
|
+
|
|
44
|
+
### Types
|
|
45
|
+
|
|
46
|
+
| Type | Description |
|
|
47
|
+
|------|-------------|
|
|
48
|
+
| `AuthService` | `GuardService` + `authenticate(token)`, `update(token)`, `user()`, `store<T>()` — the client-side auth manager contract |
|
|
49
|
+
| `AuthorizationService` | `isAllowed(permissions, token?, thr?)`, `update(token?, thr?)` |
|
|
50
|
+
| `TrustedRecord` | A `ConfigRecord` carrying a known signing identity's `name`, `credential` (public key) and optional `secret` |
|
|
51
|
+
| `AuthRequest` | An `AbstractRequest` whose `query` is an `AuthToken` |
|
|
52
|
+
| `AuthUIParams` | `{ type? }` — the typed login route's params |
|
|
53
|
+
| `OrgEntityRef` | `{ id, slug, formerSlugs?, iamKey }` |
|
|
54
|
+
| `EntityResolverService` | `resolve`, `byId`, `mintSlug`, `rename`, `mintName` — see below |
|
|
55
|
+
| `ProfileToEntityIdRequest` / `ProfileToEntityIdResponse` | The manager API body/response that maps a `profileId` to an `entitySlug` |
|
|
56
|
+
|
|
57
|
+
### Subpath `./utils`
|
|
58
|
+
|
|
59
|
+
| Export | Description |
|
|
60
|
+
|--------|-------------|
|
|
61
|
+
| `trust(context, resource, userName, field = 'name')` | Load a `TrustedRecord` from a config resource and return `{ user, key }`, where `key` is a signing `KeyPairModel` when the record has a `secret` and a verify-only one otherwise |
|
|
62
|
+
| `extractAuthToken(req, type?, onlyValue?)` | Pull the `authorization` header, optionally requiring an `AuthroizationType` prefix |
|
|
63
|
+
| `Config`, `Context` | The minimal context shape `trust` needs |
|
|
64
|
+
|
|
65
|
+
## The organization entity
|
|
22
66
|
|
|
23
|
-
|
|
67
|
+
The customer organization is an **organization entity**. Two values name it and they are not
|
|
68
|
+
interchangeable:
|
|
24
69
|
|
|
25
|
-
-
|
|
70
|
+
- **`entitySlug`** — renameable, human-readable, and the only organization value on the wire. It is
|
|
71
|
+
what a token, a URL, a query param and a form carry.
|
|
72
|
+
- **`entityId`** — the stable record id. It never travels; it is what database rows, permission
|
|
73
|
+
grants and third-party records key on, and it is why a rename costs one write.
|
|
74
|
+
|
|
75
|
+
`EntityResolverService` is the contract between the two. It is registered **only** by an
|
|
76
|
+
implementation that actually stores organizations (`@owlmeans/server-auth-identity` registers one);
|
|
77
|
+
a deployment backed by an external IAM registers none, and every consumer must treat an unresolved
|
|
78
|
+
entity as ordinary rather than exceptional.
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { makeEntityScope } from '@owlmeans/auth-common'
|
|
82
|
+
|
|
83
|
+
const scope = makeEntityScope(request) // once at the top of a handler, never stored
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
| Helper | What it answers |
|
|
87
|
+
|--------|-----------------|
|
|
88
|
+
| `scope.attachEntity(context)` | Resolve the slug on `request.auth` and set `request.entity`, canonicalizing a retired slug to the current one. Keeps an entity the guard already attached when its `slug` equals the token's exactly, and drops one that does not. Otherwise a no-op when no resolver is registered; throws `AuthenFailed('entity')` when the token names an organization that will not resolve |
|
|
89
|
+
| `scope.entityKeyOf()` | The value to store and query organization-scoped records by — `req.entity?.id`, falling back to the token's slug where no resolver exists |
|
|
90
|
+
| `scope.requireEntityKey()` | Same, throwing `AuthorizationError` when the request carries no organization |
|
|
91
|
+
| `scope.requireEntity()` | The full `ResolvedEntity` (`id`, `slug`, `iamKey`), throwing `AuthorizationError` when nothing resolved |
|
|
92
|
+
|
|
93
|
+
`scope.attachEntity(context)` must be called wherever authentication is **established** — the HTTP
|
|
94
|
+
boundary, and any socket that authenticates after its connection is already open. A path that
|
|
95
|
+
authenticates without it leaves `request.entity` empty and its handlers silently compare a slug
|
|
96
|
+
against stored ids.
|
|
97
|
+
|
|
98
|
+
A guard may attach the entity itself when its authority names the organization — the OIDC guard does
|
|
99
|
+
for a session of a tenanted client (`@owlmeans/oidc`), whose relying party has no registry to
|
|
100
|
+
resolve from. `scope.attachEntity` trusts that attachment only while its `slug` is the token's
|
|
101
|
+
`authHelper.entitySlugOf(request.auth)`; on any mismatch it removes it and resolves as if nothing
|
|
102
|
+
had been attached, so a stale or foreign entity can never reach a handler. That attached entity is
|
|
103
|
+
keyed by the organization's frozen IAM key (`{ id: entityKey, slug, iamKey: entityKey }`) — the
|
|
104
|
+
registry's record id never leaves the provider — so on such a relying party
|
|
105
|
+
`scope.requireEntityKey()` answers the `entityKey`, which survives a rename exactly as a record id
|
|
106
|
+
would.
|
|
107
|
+
|
|
108
|
+
Never build a user-facing name (a hostname, a display label) from `scope.entityKeyOf()`. Those want
|
|
109
|
+
the current slug, `req.entity?.slug`.
|
|
26
110
|
|
|
27
111
|
## Usage
|
|
28
112
|
|
|
29
|
-
|
|
113
|
+
Declare an entrypoint with a guard so both sides agree on the alias, and compose authorization as a
|
|
114
|
+
gate inside the same options object:
|
|
30
115
|
|
|
31
116
|
```typescript
|
|
32
|
-
import {
|
|
33
|
-
import { route } from '@owlmeans/route'
|
|
117
|
+
import { contract, protocol, typed } from '@owlmeans/entrypoint'
|
|
118
|
+
import { route, backend } from '@owlmeans/route'
|
|
34
119
|
import { DEFAULT_GUARD } from '@owlmeans/auth-common'
|
|
35
|
-
import { OIDC_GATE } from '@owlmeans/oidc'
|
|
36
120
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
121
|
+
// PRODUCT_GATE is the consuming app's own gate alias, registered as a GateService on its context.
|
|
122
|
+
protocol(
|
|
123
|
+
route('api:account', '/account', backend()),
|
|
124
|
+
contract(typed<Account>()),
|
|
125
|
+
{ guards: DEFAULT_GUARD, gate: { alias: PRODUCT_GATE, params: ['my-service-account-{entity}'] } },
|
|
40
126
|
)
|
|
41
127
|
```
|
|
42
128
|
|
|
43
|
-
|
|
129
|
+
`{entity}` is a placeholder each **gate service** substitutes for itself — this package declares
|
|
130
|
+
neither the token nor the substitution. `@owlmeans/server-iam` substitutes the resolved id
|
|
131
|
+
(`server-iam` → "`{entity}` in a permission name"); `@owlmeans/server-oidc-rp`'s gate model the
|
|
132
|
+
token's slug only; both write `'-'` when neither is available. Read the gate you are wiring first.
|
|
133
|
+
|
|
134
|
+
## Rules
|
|
44
135
|
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
- `
|
|
48
|
-
|
|
136
|
+
- `DEFAULT_GUARD` is the bearer-token guard shared by server and web; `@owlmeans/client-auth` exports
|
|
137
|
+
the matching client-side alias as `DEFAULT_ALIAS`.
|
|
138
|
+
- `GUARD_ED25519` is for service-to-service calls, where the caller signs the request rather than
|
|
139
|
+
presenting a bearer token. Give it a Redis-backed nonce cache (`BED255_CASHE_RESOURCE`) in any
|
|
140
|
+
deployment that runs more than one replica, or replay protection is per-process only. The guard
|
|
141
|
+
accepts only canonical timestamps inside its symmetric 60-second window and claims the
|
|
142
|
+
credential-and-nonce pair until that timestamp's absolute expiry; a replay-store error refuses
|
|
143
|
+
authentication rather than disabling deduplication.
|
|
144
|
+
- OIDC used only to sign in authorizes with a product gate, not `OIDC_GATE` (`server-oidc-rp` → Rules).
|
|
145
|
+
- The trust resource (`TRUSTED`, from `@owlmeans/config`) is the system's source of truth for known
|
|
146
|
+
signing identities — the auth service, peer services, wallet providers, supervisors.
|
|
49
147
|
|
|
50
148
|
## Depends On
|
|
51
149
|
|
|
52
|
-
- `@owlmeans/auth` — types
|
|
53
|
-
- `@owlmeans/entrypoint` — entrypoint/guard/gate
|
|
150
|
+
- `@owlmeans/auth` — types, errors, entrypoint aliases
|
|
151
|
+
- `@owlmeans/entrypoint` — `entrypoint` / `guard` / `gate`, `GuardService`, `ResolvedEntity`
|
|
152
|
+
- `@owlmeans/route` — route builders for the shared protocol trees
|
|
153
|
+
- `@owlmeans/basic-keys` — key pairs behind `trust()` and the Ed25519 guard
|
|
154
|
+
- `@owlmeans/basic-ids`, `@owlmeans/context`, `@owlmeans/resource`, `@owlmeans/client-entrypoint`
|
package/build/consts.d.ts
CHANGED
|
@@ -45,4 +45,13 @@ export declare const authApi: {
|
|
|
45
45
|
delegate: string;
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* The request header an authenticated call carries, re-exported for the packages that only depend
|
|
50
|
+
* on this half of the vocabulary.
|
|
51
|
+
*
|
|
52
|
+
* One spelling, one home: it is declared by `@owlmeans/auth` and named here so a client-side
|
|
53
|
+
* package does not have to take a dependency on the whole auth package to recognise its own
|
|
54
|
+
* bearer on a request it is about to send.
|
|
55
|
+
*/
|
|
56
|
+
export { AUTH_HEADER } from '@owlmeans/auth';
|
|
48
57
|
//# sourceMappingURL=consts.d.ts.map
|
package/build/consts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,cAAc,CAAA;AAE1C,eAAO,MAAM,iBAAiB,gBAAgB,CAAA;AAE9C,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC,eAAO,MAAM,mBAAmB,MAAM,CAAA;AAEtC,eAAO,MAAM,eAAe,gBAAgB,CAAA;AAE5C;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,eAAe,CAAA;AAE1C,eAAO,MAAM,YAAY,SAAS,CAAA;AAElC,eAAO,MAAM,aAAa,SAAe,CAAA;AAEzC,eAAO,MAAM,YAAY,uBAAuB,CAAA;AAEhD,eAAO,MAAM,OAAO,iBAAiB,CAAA;AAErC,+FAA+F;AAC/F,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,QAA2C,CAAA;AAE3E,eAAO,MAAM,OAAO;IAClB,OAAO;QACL,IAAI;QACJ,UAAU;;IAEZ,MAAM;QACJ,IAAI;QACJ,GAAG;QACH,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,IAAI;;;IAGR,IAAI;QACF,IAAI;QACJ,QAAQ;;CAEX,CAAA"}
|
|
1
|
+
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,cAAc,CAAA;AAE1C,eAAO,MAAM,iBAAiB,gBAAgB,CAAA;AAE9C,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC,eAAO,MAAM,mBAAmB,MAAM,CAAA;AAEtC,eAAO,MAAM,eAAe,gBAAgB,CAAA;AAE5C;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,eAAe,CAAA;AAE1C,eAAO,MAAM,YAAY,SAAS,CAAA;AAElC,eAAO,MAAM,aAAa,SAAe,CAAA;AAEzC,eAAO,MAAM,YAAY,uBAAuB,CAAA;AAEhD,eAAO,MAAM,OAAO,iBAAiB,CAAA;AAErC,+FAA+F;AAC/F,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,QAA2C,CAAA;AAE3E,eAAO,MAAM,OAAO;IAClB,OAAO;QACL,IAAI;QACJ,UAAU;;IAEZ,MAAM;QACJ,IAAI;QACJ,GAAG;QACH,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,IAAI;;;IAGR,IAAI;QACF,IAAI;QACJ,QAAQ;;CAEX,CAAA;AAGD;;;;;;;GAOG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA"}
|
package/build/consts.js
CHANGED
|
@@ -45,4 +45,13 @@ export const authApi = {
|
|
|
45
45
|
delegate: 'api:auth:delegate',
|
|
46
46
|
},
|
|
47
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* The request header an authenticated call carries, re-exported for the packages that only depend
|
|
50
|
+
* on this half of the vocabulary.
|
|
51
|
+
*
|
|
52
|
+
* One spelling, one home: it is declared by `@owlmeans/auth` and named here so a client-side
|
|
53
|
+
* package does not have to take a dependency on the whole auth package to recognise its own
|
|
54
|
+
* bearer on a request it is about to send.
|
|
55
|
+
*/
|
|
56
|
+
export { AUTH_HEADER } from '@owlmeans/auth';
|
|
48
57
|
//# sourceMappingURL=consts.js.map
|
package/build/consts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAA;AAE1C,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAA;AAE9C,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAEpC,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAEtC,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAA;AAE5C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAA;AAE1C,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAA;AAElC,MAAM,CAAC,MAAM,aAAa,GAAG,YAAY,CAAA;AAEzC,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAA;AAEhD,MAAM,CAAC,MAAM,OAAO,GAAG,cAAc,CAAA;AAErC,+FAA+F;AAC/F,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAA;AAEhD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,wCAAwC,CAAA;AAE3E,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,OAAO,EAAE;QACP,IAAI,EAAE,aAAa;QACnB,UAAU,EAAE,0BAA0B;KACvC;IACD,MAAM,EAAE;QACN,IAAI,EAAE,YAAY;QAClB,GAAG,EAAE,gBAAgB;QACrB,OAAO,EAAE;YACP,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,yBAAyB;YAC/B,IAAI,EAAE,yBAAyB;SAChC;KACF;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,mBAAmB;KAC9B;CACF,CAAA"}
|
|
1
|
+
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAA;AAE1C,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAA;AAE9C,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAEpC,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAEtC,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAA;AAE5C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAA;AAE1C,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAA;AAElC,MAAM,CAAC,MAAM,aAAa,GAAG,YAAY,CAAA;AAEzC,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAA;AAEhD,MAAM,CAAC,MAAM,OAAO,GAAG,cAAc,CAAA;AAErC,+FAA+F;AAC/F,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAA;AAEhD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,wCAAwC,CAAA;AAE3E,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,OAAO,EAAE;QACP,IAAI,EAAE,aAAa;QACnB,UAAU,EAAE,0BAA0B;KACvC;IACD,MAAM,EAAE;QACN,IAAI,EAAE,YAAY;QAClB,GAAG,EAAE,gBAAgB;QACrB,OAAO,EAAE;YACP,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,yBAAyB;YAC/B,IAAI,EAAE,yBAAyB;SAChC;KACF;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,mBAAmB;KAC9B;CACF,CAAA;AAGD;;;;;;;GAOG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { BasicContext } from '@owlmeans/context';
|
|
2
|
+
import type { ResolvedEntity } from '@owlmeans/entrypoint';
|
|
3
|
+
/** The organization entity one request acts for — built once at the top of a handler, never stored. */
|
|
4
|
+
export interface EntityScope {
|
|
5
|
+
/**
|
|
6
|
+
* The value a handler should store and query organization-scoped records by.
|
|
7
|
+
*
|
|
8
|
+
* Prefers the entity's stable id, which is the whole point of resolving one: records keyed by it
|
|
9
|
+
* survive a rename untouched. Falls back to the slug on the token for deployments that register no
|
|
10
|
+
* resolver — there the slug IS the only identifier the system has, and refusing to serve them
|
|
11
|
+
* would break every installation backed by an external IAM.
|
|
12
|
+
*
|
|
13
|
+
* Never use this to compose a user-facing name (a hostname, a display label). Those want the
|
|
14
|
+
* current slug, `req.entity?.slug`, precisely because it can change.
|
|
15
|
+
*/
|
|
16
|
+
entityKeyOf: () => string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* `entityKeyOf` for handlers that cannot proceed without an organization.
|
|
19
|
+
*
|
|
20
|
+
* @throws {AuthorizationError} when the request carries no organization at all.
|
|
21
|
+
*/
|
|
22
|
+
requireEntityKey: () => string;
|
|
23
|
+
/**
|
|
24
|
+
* The full resolved entity, for handlers that need the slug or the frozen key as well as the id.
|
|
25
|
+
*
|
|
26
|
+
* @throws {AuthorizationError} when no resolver is registered or the entity did not resolve.
|
|
27
|
+
*/
|
|
28
|
+
requireEntity: () => ResolvedEntity;
|
|
29
|
+
/**
|
|
30
|
+
* Resolve the organization a just-authenticated request acts for, and attach it.
|
|
31
|
+
*
|
|
32
|
+
* Called wherever authentication is ESTABLISHED — the HTTP boundary, and any socket that
|
|
33
|
+
* authenticates on its own once the connection is already open. Both need it for the same reason:
|
|
34
|
+
* the token names the organization by a slug that can move, while everything downstream keys on
|
|
35
|
+
* the record. A path that authenticates without calling this leaves `request.entity` empty, and
|
|
36
|
+
* its handlers quietly fall back to comparing a slug against stored ids — which surfaces as "this
|
|
37
|
+
* project does not exist" rather than as a missing resolution, and costs an afternoon to find.
|
|
38
|
+
*
|
|
39
|
+
* An entity the guard already attached is kept while its slug is exactly the token's: a guard
|
|
40
|
+
* whose authority names the organization itself (an OIDC session of a tenanted client) is the only
|
|
41
|
+
* source such a deployment has, because the registry that owns the organization is not its own.
|
|
42
|
+
* One whose slug differs is never trusted — it is dropped, and resolution proceeds as if it had
|
|
43
|
+
* not been there.
|
|
44
|
+
*
|
|
45
|
+
* Otherwise a no-op when no resolver is registered: such a deployment has no organization store,
|
|
46
|
+
* and the slug is the only identifier it has.
|
|
47
|
+
*
|
|
48
|
+
* @throws {AuthenFailed} when the token names an organization that cannot be resolved.
|
|
49
|
+
*/
|
|
50
|
+
attachEntity: (context: BasicContext<any>) => Promise<ResolvedEntity | undefined>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/entity/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D,uGAAuG;AACvG,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;;OAUG;IACH,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACrC;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,MAAM,CAAA;IAC9B;;;;OAIG;IACH,aAAa,EAAE,MAAM,cAAc,CAAA;IACnC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,YAAY,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAA;CAClF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/entity/types.ts"],"names":[],"mappings":""}
|
package/build/entity.d.ts
CHANGED
|
@@ -1,43 +1,11 @@
|
|
|
1
1
|
import type { AbstractRequest, ResolvedEntity } from '@owlmeans/entrypoint';
|
|
2
2
|
import type { BasicContext } from '@owlmeans/context';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* Prefers the entity's stable id, which is the whole point of resolving one: records keyed by it
|
|
7
|
-
* survive a rename untouched. Falls back to the slug on the token for deployments that register no
|
|
8
|
-
* resolver — there the slug IS the only identifier the system has, and refusing to serve them
|
|
9
|
-
* would break every installation backed by an external IAM.
|
|
10
|
-
*
|
|
11
|
-
* Never use this to compose a user-facing name (a hostname, a display label). Those want the
|
|
12
|
-
* current slug, `req.entity?.slug`, precisely because it can change.
|
|
13
|
-
*/
|
|
3
|
+
import type { EntityScope } from './entity/types.js';
|
|
4
|
+
export declare const makeEntityScope: (req: AbstractRequest) => EntityScope;
|
|
5
|
+
/** @deprecated compat:factory-refactor — use `makeEntityScope(req).entityKeyOf()` */
|
|
14
6
|
export declare const entityKeyOf: (req: AbstractRequest) => string | undefined;
|
|
15
|
-
/**
|
|
16
|
-
* `entityKeyOf` for handlers that cannot proceed without an organization.
|
|
17
|
-
*
|
|
18
|
-
* @throws {AuthorizationError} when the request carries no organization at all.
|
|
19
|
-
*/
|
|
7
|
+
/** @deprecated compat:factory-refactor — use `makeEntityScope(req).requireEntityKey()` */
|
|
20
8
|
export declare const requireEntityKey: (req: AbstractRequest) => string;
|
|
21
|
-
/**
|
|
22
|
-
* The full resolved entity, for handlers that need the slug or the frozen key as well as the id.
|
|
23
|
-
*
|
|
24
|
-
* @throws {AuthorizationError} when no resolver is registered or the entity did not resolve.
|
|
25
|
-
*/
|
|
26
|
-
export declare const requireEntity: (req: AbstractRequest) => ResolvedEntity;
|
|
27
|
-
/**
|
|
28
|
-
* Resolve the organization a just-authenticated request acts for, and attach it.
|
|
29
|
-
*
|
|
30
|
-
* Called wherever authentication is ESTABLISHED — the HTTP boundary, and any socket that
|
|
31
|
-
* authenticates on its own once the connection is already open. Both need it for the same reason:
|
|
32
|
-
* the token names the organization by a slug that can move, while everything downstream keys on
|
|
33
|
-
* the record. A path that authenticates without calling this leaves `request.entity` empty, and
|
|
34
|
-
* its handlers quietly fall back to comparing a slug against stored ids — which surfaces as "this
|
|
35
|
-
* project does not exist" rather than as a missing resolution, and costs an afternoon to find.
|
|
36
|
-
*
|
|
37
|
-
* A no-op when no resolver is registered: such a deployment has no organization store, and the
|
|
38
|
-
* slug is the only identifier it has.
|
|
39
|
-
*
|
|
40
|
-
* @throws {AuthenFailed} when the token names an organization that cannot be resolved.
|
|
41
|
-
*/
|
|
9
|
+
/** @deprecated compat:factory-refactor — use `makeEntityScope(request).attachEntity(context)` */
|
|
42
10
|
export declare const attachEntity: (context: BasicContext<any>, request: AbstractRequest) => Promise<ResolvedEntity | undefined>;
|
|
43
11
|
//# sourceMappingURL=entity.d.ts.map
|
package/build/entity.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAIrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,eAAO,MAAM,eAAe,QAAS,eAAe,KAAG,WAgDtD,CAAA;AAED,qFAAqF;AACrF,eAAO,MAAM,WAAW,QAAS,eAAe,KAAG,MAAM,GAAG,SAA+C,CAAA;AAE3G,0FAA0F;AAC1F,eAAO,MAAM,gBAAgB,QAAS,eAAe,KAAG,MAAiD,CAAA;AAEzG,iGAAiG;AACjG,eAAO,MAAM,YAAY,YACd,YAAY,CAAC,GAAG,CAAC,WAAW,eAAe,KACnD,OAAO,CAAC,cAAc,GAAG,SAAS,CAAyD,CAAA"}
|
package/build/entity.js
CHANGED
|
@@ -1,68 +1,47 @@
|
|
|
1
|
-
import { AuthenFailed, AuthorizationError,
|
|
1
|
+
import { AuthenFailed, AuthorizationError, authHelper } from '@owlmeans/auth';
|
|
2
2
|
import { ENTITY_RESOLVER } from './consts.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
*
|
|
41
|
-
* Called wherever authentication is ESTABLISHED — the HTTP boundary, and any socket that
|
|
42
|
-
* authenticates on its own once the connection is already open. Both need it for the same reason:
|
|
43
|
-
* the token names the organization by a slug that can move, while everything downstream keys on
|
|
44
|
-
* the record. A path that authenticates without calling this leaves `request.entity` empty, and
|
|
45
|
-
* its handlers quietly fall back to comparing a slug against stored ids — which surfaces as "this
|
|
46
|
-
* project does not exist" rather than as a missing resolution, and costs an afternoon to find.
|
|
47
|
-
*
|
|
48
|
-
* A no-op when no resolver is registered: such a deployment has no organization store, and the
|
|
49
|
-
* slug is the only identifier it has.
|
|
50
|
-
*
|
|
51
|
-
* @throws {AuthenFailed} when the token names an organization that cannot be resolved.
|
|
52
|
-
*/
|
|
53
|
-
export const attachEntity = async (context, request) => {
|
|
54
|
-
const slug = entitySlugOf(request.auth);
|
|
55
|
-
if (slug == null || !context.hasService(ENTITY_RESOLVER)) {
|
|
56
|
-
return undefined;
|
|
57
|
-
}
|
|
58
|
-
const entity = await context.service(ENTITY_RESOLVER).resolve(slug);
|
|
59
|
-
if (entity == null) {
|
|
60
|
-
throw new AuthenFailed('entity');
|
|
61
|
-
}
|
|
62
|
-
// Canonicalize: a request that arrived under a retired slug continues under the current one, so
|
|
63
|
-
// nothing echoing the value back can re-publish a name the organization has dropped.
|
|
64
|
-
request.auth.entitySlug = entity.slug;
|
|
65
|
-
request.entity = entity;
|
|
66
|
-
return entity;
|
|
3
|
+
export const makeEntityScope = (req) => {
|
|
4
|
+
const entityKeyOf = () => req.entity?.id ?? authHelper.entitySlugOf(req.auth);
|
|
5
|
+
const requireEntityKey = () => {
|
|
6
|
+
const key = entityKeyOf();
|
|
7
|
+
if (key == null || key === '') {
|
|
8
|
+
throw new AuthorizationError();
|
|
9
|
+
}
|
|
10
|
+
return key;
|
|
11
|
+
};
|
|
12
|
+
const requireEntity = () => {
|
|
13
|
+
if (req.entity == null) {
|
|
14
|
+
throw new AuthorizationError();
|
|
15
|
+
}
|
|
16
|
+
return req.entity;
|
|
17
|
+
};
|
|
18
|
+
const attachEntity = async (context) => {
|
|
19
|
+
const slug = authHelper.entitySlugOf(req.auth);
|
|
20
|
+
if (req.entity != null) {
|
|
21
|
+
if (slug != null && req.entity.slug === slug) {
|
|
22
|
+
return req.entity;
|
|
23
|
+
}
|
|
24
|
+
req.entity = undefined;
|
|
25
|
+
}
|
|
26
|
+
if (slug == null || !context.hasService(ENTITY_RESOLVER)) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const entity = await context.service(ENTITY_RESOLVER).resolve(slug);
|
|
30
|
+
if (entity == null) {
|
|
31
|
+
throw new AuthenFailed('entity');
|
|
32
|
+
}
|
|
33
|
+
// Canonicalize: a request that arrived under a retired slug continues under the current one, so
|
|
34
|
+
// nothing echoing the value back can re-publish a name the organization has dropped.
|
|
35
|
+
req.auth.entitySlug = entity.slug;
|
|
36
|
+
req.entity = entity;
|
|
37
|
+
return entity;
|
|
38
|
+
};
|
|
39
|
+
return { entityKeyOf, requireEntityKey, requireEntity, attachEntity };
|
|
67
40
|
};
|
|
41
|
+
/** @deprecated compat:factory-refactor — use `makeEntityScope(req).entityKeyOf()` */
|
|
42
|
+
export const entityKeyOf = (req) => makeEntityScope(req).entityKeyOf();
|
|
43
|
+
/** @deprecated compat:factory-refactor — use `makeEntityScope(req).requireEntityKey()` */
|
|
44
|
+
export const requireEntityKey = (req) => makeEntityScope(req).requireEntityKey();
|
|
45
|
+
/** @deprecated compat:factory-refactor — use `makeEntityScope(request).attachEntity(context)` */
|
|
46
|
+
export const attachEntity = async (context, request) => await makeEntityScope(request).attachEntity(context);
|
|
68
47
|
//# sourceMappingURL=entity.js.map
|
package/build/entity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity.js","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"entity.js","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE7E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAG7C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAoB,EAAe,EAAE;IACnE,MAAM,WAAW,GAAG,GAAuB,EAAE,CAC3C,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAErD,MAAM,gBAAgB,GAAG,GAAW,EAAE;QACpC,MAAM,GAAG,GAAG,WAAW,EAAE,CAAA;QACzB,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;YAC9B,MAAM,IAAI,kBAAkB,EAAE,CAAA;QAChC,CAAC;QAED,OAAO,GAAG,CAAA;IACZ,CAAC,CAAA;IAED,MAAM,aAAa,GAAG,GAAmB,EAAE;QACzC,IAAI,GAAG,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,kBAAkB,EAAE,CAAA;QAChC,CAAC;QAED,OAAO,GAAG,CAAC,MAAM,CAAA;IACnB,CAAC,CAAA;IAED,MAAM,YAAY,GAAG,KAAK,EAAE,OAA0B,EAAuC,EAAE;QAC7F,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC9C,IAAI,GAAG,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC7C,OAAO,GAAG,CAAC,MAAM,CAAA;YACnB,CAAC;YACD,GAAG,CAAC,MAAM,GAAG,SAAS,CAAA;QACxB,CAAC;QAED,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YACzD,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAwB,eAAe,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC1F,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAA;QAClC,CAAC;QAED,gGAAgG;QAChG,qFAAqF;QACrF,GAAG,CAAC,IAAK,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAA;QAClC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAA;QAEnB,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;IAED,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,CAAA;AACvE,CAAC,CAAA;AAED,qFAAqF;AACrF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAoB,EAAsB,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA;AAE3G,0FAA0F;AAC1F,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAoB,EAAU,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,gBAAgB,EAAE,CAAA;AAEzG,iGAAiG;AACjG,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,OAA0B,EAAE,OAAwB,EACf,EAAE,CAAC,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA"}
|