@owlmeans/web-auth 0.1.18-rc.63 → 0.1.18-rc.65
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 +161 -1
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/web-auth/SKILL.md +1 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -1,3 +1,163 @@
|
|
|
1
|
+
# @owlmeans/web-auth
|
|
2
|
+
|
|
3
|
+
Web-side authentication plugins that register into the shared `@owlmeans/client-auth/manager`
|
|
4
|
+
plugin registry. Today it ships one plugin: the development-only **PK supervisor** login form, where
|
|
5
|
+
a holder of one of the project's trusted private keys signs a server challenge to sign in as any
|
|
6
|
+
user id or email. A web client uses it to give end-to-end tests and operators a deterministic way in
|
|
7
|
+
on development and staging deployments. It is not a general sign-in package: regular login methods
|
|
8
|
+
come from `@owlmeans/client-auth` and its plugin packages (`@owlmeans/web-oidc-rp` for OIDC), and
|
|
9
|
+
the server half of the supervisor login — signature verification and user resolution — lives in
|
|
10
|
+
`@owlmeans/server-auth/manager`. The whole feature is described by the `supervisor-auth` skill; this
|
|
11
|
+
package by the `web-auth` skill.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bun add @owlmeans/web-auth@^0.1.18-rc.65
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`react` is a peer dependency.
|
|
20
|
+
|
|
21
|
+
## Concepts
|
|
22
|
+
|
|
23
|
+
- **Supervisor login** — `AuthenticationType.Supervisor` (`'pk-supervisor'`) from `@owlmeans/auth`.
|
|
24
|
+
The browser signs `buildSupervisorPayload(challenge, userId, salt)` with an entered private key;
|
|
25
|
+
the server checks the signature against its trusted public keys and issues a regular token.
|
|
26
|
+
- **Client auth plugin** — an `AuthenticationPlugin` placed into the `plugins` registry of
|
|
27
|
+
`@owlmeans/client-auth/manager`, keyed by authentication type. The standard typed authentication
|
|
28
|
+
route renders whichever plugin is registered for the type in its URL.
|
|
29
|
+
- **Restricted method** — `supervisorClientPlugin.method.restricted` is `true`, so registering the
|
|
30
|
+
plugin does not put it on the sign-in screen. It is offered only where
|
|
31
|
+
`cfg.security.auth.login.overrides` names it.
|
|
32
|
+
- **Deployment gate** — `appendSupervisorAuth` turns itself on only when `cfg.debug.supervisor ===
|
|
33
|
+
true`. It deliberately ignores `cfg.debug.all`, which many applications set for unrelated reasons.
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### 1. Wire the gated append into the web context
|
|
38
|
+
|
|
39
|
+
Call it once in the web client's context factory, after the layer context is built.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { appendSupervisorAuth } from '@owlmeans/web-auth'
|
|
43
|
+
import { makeContext as makePanelContext } from '@owlmeans/web-panel'
|
|
44
|
+
import type { AppConfig, AppContext } from '@owlmeans/web-panel'
|
|
45
|
+
|
|
46
|
+
export const makeContext = <C extends AppConfig, T extends AppContext<C>>(cfg: C): T => {
|
|
47
|
+
const context = makePanelContext<C, T>(cfg)
|
|
48
|
+
appendSupervisorAuth(context)
|
|
49
|
+
|
|
50
|
+
return context
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
With `cfg.debug.supervisor` unset the call returns the context untouched. With it set, the call
|
|
55
|
+
registers the plugin and fills the sign-in configuration that makes it offerable — only where a
|
|
56
|
+
value is missing:
|
|
57
|
+
|
|
58
|
+
| Path | Value written |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `cfg.security.auth.login.secretKey` | `true` |
|
|
61
|
+
| `cfg.security.auth.login.overrides['pk-supervisor']` | `{ enabled: true }` |
|
|
62
|
+
|
|
63
|
+
### 2. Force it on or register it unadvertised
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { appendSupervisorAuth, SUPERVISOR_LOGIN_PATH } from '@owlmeans/web-auth'
|
|
67
|
+
|
|
68
|
+
// ignore the debug flags — e.g. a dedicated e2e build
|
|
69
|
+
appendSupervisorAuth(context, { enabled: true })
|
|
70
|
+
|
|
71
|
+
// reachable only by URL, never listed on the sign-in screen
|
|
72
|
+
appendSupervisorAuth(context, { enabled: true, offer: false })
|
|
73
|
+
|
|
74
|
+
console.log(SUPERVISOR_LOGIN_PATH) // '/authentication/login/pk-supervisor'
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 3. Always-on side-effect import
|
|
78
|
+
|
|
79
|
+
The `./auth/plugins` subpath registers the plugin at import time with no gate and no sign-in
|
|
80
|
+
override. Prefer the gated append; use this only where the bundle itself is development-only.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import '@owlmeans/web-auth/auth/plugins'
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 4. Drive the form from a test
|
|
87
|
+
|
|
88
|
+
The form lives at `SUPERVISOR_LOGIN_PATH` and exposes stable test ids. `@owlmeans/test-ui` wraps
|
|
89
|
+
them (`makePageHelper(page).loginViaSupervisorForm(...)`), but a raw Playwright test can fill them
|
|
90
|
+
directly:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { SUPERVISOR_LOGIN_PATH } from '@owlmeans/web-auth'
|
|
94
|
+
|
|
95
|
+
await page.goto(`${baseUrl}${SUPERVISOR_LOGIN_PATH}`, { waitUntil: 'domcontentloaded' })
|
|
96
|
+
await page.getByTestId('supervisor-user-id').fill('person@example.com')
|
|
97
|
+
await page.getByTestId('supervisor-pk').fill(process.env.SUPERVISOR_PK!)
|
|
98
|
+
await page.getByTestId('supervisor-submit').click()
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
On submit the form requests a fresh allowance, signs the challenge, user id and a fresh 16-character
|
|
102
|
+
salt, sends `JSON.stringify({ salt, signature })` as the credential (never the key), stores the
|
|
103
|
+
issued token through the client `AuthService`, and navigates via `landAfterLogin()` /
|
|
104
|
+
`landingUrl()` from `@owlmeans/client-auth/login`.
|
|
105
|
+
|
|
106
|
+
## API
|
|
107
|
+
|
|
108
|
+
### Main entry `@owlmeans/web-auth`
|
|
109
|
+
|
|
110
|
+
| Symbol | Kind | Purpose |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| `appendSupervisorAuth(context, opts?)` | function | Register `supervisorClientPlugin` and, unless `offer: false`, write the sign-in overrides; returns the same context. No-op unless enabled |
|
|
113
|
+
| `WebSupervisorAuthOptions` | type | `{ enabled?: boolean, offer?: boolean }` — `enabled` defaults to `cfg.debug.supervisor === true`, `offer` to `true` |
|
|
114
|
+
| `SUPERVISOR_LOGIN_PATH` | const | `/authentication/login/${AuthenticationType.Supervisor}` — the typed authentication route for the form |
|
|
115
|
+
| `supervisorClientPlugin` | `AuthenticationPlugin` | The self-contained form plugin |
|
|
116
|
+
|
|
117
|
+
`appendSupervisorAuth` accepts any context whose `cfg` carries optional `debug` and `security`
|
|
118
|
+
fields, so it works on every web client context.
|
|
119
|
+
|
|
120
|
+
### `supervisorClientPlugin`
|
|
121
|
+
|
|
122
|
+
| Member | Value |
|
|
123
|
+
|---|---|
|
|
124
|
+
| `type` | `AuthenticationType.Supervisor` |
|
|
125
|
+
| `method` | `{ order: 900, icon: 'key', emphasis: 'link', restricted: true }` — last, rendered as a link |
|
|
126
|
+
| `Implementation` | React form with test ids `supervisor-auth-form`, `supervisor-user-id`, `supervisor-pk`, `supervisor-submit`, `supervisor-error` |
|
|
127
|
+
| `authenticate(credentials)` | Signs the payload with `credentials.credential` as the private key, replaces it with the packed `{ salt, signature }`, returns `{ token: '' }`; the real token comes from the backend through the auth control |
|
|
128
|
+
|
|
129
|
+
### Subpath `@owlmeans/web-auth/auth/plugins`
|
|
130
|
+
|
|
131
|
+
| Symbol | Purpose |
|
|
132
|
+
|---|---|
|
|
133
|
+
| (side effect) | `plugins[AuthenticationType.Supervisor] = supervisorClientPlugin` on import |
|
|
134
|
+
| `plugins` | the shared `@owlmeans/client-auth/manager` registry, re-exported |
|
|
135
|
+
| `supervisorClientPlugin` | same object as the main entry |
|
|
136
|
+
|
|
137
|
+
## Common pitfalls
|
|
138
|
+
|
|
139
|
+
- Setting only `cfg.debug.all` does not enable the web form; set `cfg.debug.supervisor` (the server
|
|
140
|
+
half honours either flag, so `debug.supervisor` is the one both halves agree on).
|
|
141
|
+
- The web plugin alone signs nothing useful: the server must call `appendSupervisorAuth` from
|
|
142
|
+
`@owlmeans/server-auth/manager` with `supervisors` naming trusted records whose private keys you
|
|
143
|
+
hold.
|
|
144
|
+
- Registering the plugin by hand (or through the side-effect import) does not offer it — the method
|
|
145
|
+
is `restricted` until `cfg.security.auth.login.overrides` enables it.
|
|
146
|
+
- Overrides already present in the config win: `appendSupervisorAuth` only fills missing values, so
|
|
147
|
+
an explicit `{ enabled: false }` keeps the method off the screen.
|
|
148
|
+
- Never ship a supervisor-enabled build to real production — anyone holding a supervisor private key
|
|
149
|
+
can sign in as, and register, any user.
|
|
150
|
+
- No extra route is needed; the form renders through the standard `CAUTHEN_AUTHEN_TYPED` route.
|
|
151
|
+
|
|
152
|
+
## Related packages
|
|
153
|
+
|
|
154
|
+
- [`@owlmeans/client-auth`](../client-auth) — the plugin registry, auth control and post-login landing
|
|
155
|
+
- [`@owlmeans/server-auth`](../server-auth) — the server `appendSupervisorAuth` that verifies the signature
|
|
156
|
+
- [`@owlmeans/auth`](../auth) — `AuthenticationType.Supervisor` and `buildSupervisorPayload`
|
|
157
|
+
- [`@owlmeans/basic-keys`](../basic-keys) — the key model used to sign
|
|
158
|
+
- [`@owlmeans/web-oidc-rp`](../web-oidc-rp) — another web auth plugin registering into the same registry
|
|
159
|
+
- [`@owlmeans/test-ui`](../test-ui) — supervisor login helpers for API and Playwright tests
|
|
160
|
+
|
|
1
161
|
<!-- owlmeans:agent-guidance:start -->
|
|
2
162
|
## Agent guidance
|
|
3
163
|
|
|
@@ -6,7 +166,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
6
166
|
your project's skill store (`.agents/skills/`):
|
|
7
167
|
|
|
8
168
|
```sh
|
|
9
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
169
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.53
|
|
10
170
|
```
|
|
11
171
|
|
|
12
172
|
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
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/web-auth",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-10-
|
|
4
|
+
"version": "0.1.18-rc.65",
|
|
5
|
+
"generatedAt": "2026-10-09T11:30:42.745Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/web-auth
|
|
9
9
|
|
|
10
10
|
**Layer:** Web
|
|
11
|
-
**Install:** `"@owlmeans/web-auth": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/web-auth": "^0.1.18-rc.65"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
Web-side auth UI plugins registering into the shared `@owlmeans/client-auth/manager` plugin registry
|
|
14
14
|
(mirroring `@owlmeans/web-oidc-rp`). It ships the **PK supervisor** login form.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/web-auth",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.65",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -29,16 +29,16 @@
|
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
33
|
-
"@owlmeans/auth-common": "^0.1.18-rc.
|
|
34
|
-
"@owlmeans/basic-ids": "^0.1.18-rc.
|
|
35
|
-
"@owlmeans/basic-keys": "^0.1.18-rc.
|
|
36
|
-
"@owlmeans/client": "^0.1.18-rc.
|
|
37
|
-
"@owlmeans/client-auth": "^0.1.18-rc.
|
|
38
|
-
"@owlmeans/client-flow": "^0.1.18-rc.
|
|
32
|
+
"@owlmeans/auth": "^0.1.18-rc.41",
|
|
33
|
+
"@owlmeans/auth-common": "^0.1.18-rc.49",
|
|
34
|
+
"@owlmeans/basic-ids": "^0.1.18-rc.39",
|
|
35
|
+
"@owlmeans/basic-keys": "^0.1.18-rc.50",
|
|
36
|
+
"@owlmeans/client": "^0.1.18-rc.53",
|
|
37
|
+
"@owlmeans/client-auth": "^0.1.18-rc.61",
|
|
38
|
+
"@owlmeans/client-flow": "^0.1.18-rc.56",
|
|
39
39
|
"@owlmeans/config": "^0.1.18-rc.44",
|
|
40
40
|
"@owlmeans/context": "^0.1.18-rc.34",
|
|
41
|
-
"@owlmeans/web-client": "^0.1.18-rc.
|
|
41
|
+
"@owlmeans/web-client": "^0.1.18-rc.64"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"react": "*"
|