fedipod-server 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -15
- package/dist/claims.d.ts +10 -11
- package/dist/claims.js +19 -17
- package/dist/directory.d.ts +11 -3
- package/dist/directory.js +28 -14
- package/dist/handler.d.ts +30 -7
- package/dist/handler.js +133 -42
- package/dist/handler.jsonld +14 -6
- package/dist/streaming-handler.js +7 -2
- package/lib/client/c2s.mjs +95 -61
- package/lib/client/masto/index.mjs +7 -1
- package/lib/client/masto/timelines.mjs +1 -1
- package/lib/client/oidc-auth.mjs +5 -3
- package/lib/core/contexts/anno.json +126 -0
- package/lib/core/contexts/index.mjs +4 -0
- package/lib/core/contexts/map.json +2 -1
- package/lib/core/intake/index.mjs +32 -5
- package/lib/core/publisher/index.mjs +15 -1
- package/lib/core/publisher/notes.mjs +84 -2
- package/lib/core/publisher/questions.mjs +1 -0
- package/lib/core/publisher/restore.mjs +27 -2
- package/lib/core/social.mjs +1 -0
- package/lib/core/store.mjs +4 -0
- package/lib/core/wire.mjs +20 -13
- package/lib/device/admin/routes/gateway.mjs +1 -1
- package/lib/device/admin/surface.mjs +25 -17
- package/lib/device/cli/commands/setup.mjs +9 -1
- package/lib/device/setup.mjs +6 -0
- package/lib/gateway/front-core.mjs +66 -12
- package/lib/gateway/gateway-core.mjs +40 -0
- package/lib/pod/actor.mjs +2 -2
- package/lib/pod/root.mjs +11 -0
- package/lib/pod/transport.mjs +9 -3
- package/lib/server/embed.mjs +23 -6
- package/package.json +2 -1
- package/run-agent.mjs +10 -1
- package/vendor/gate.cjs +5 -2
- package/web/admin/index.html +2 -0
- package/web/admin/upkeep.js +9 -1
- package/web/app/README.md +1 -1
- package/web/app/agent.mjs +11 -1
- package/web/app/boot.mjs +49 -10
- package/web/app/dist/boot.js +89 -37
- package/web/app/dist/boot.js.map +3 -3
- package/web/app/dist/sw.js +1326 -662
- package/web/app/dist/sw.js.map +4 -4
- package/web/app/index.html +16 -6
- package/web/app/signup.mjs +3 -1
- package/web/app/site/admin/index.html +2 -0
- package/web/app/site/admin/upkeep.js +9 -1
- package/web/app/site/boot.js +89 -37
- package/web/app/site/index.html +16 -6
- package/web/app/site/sw.js +1326 -662
- package/web/front/#new-account.html# +0 -43
- package/web/front/new-account.html~ +0 -50
package/README.md
CHANGED
|
@@ -30,9 +30,13 @@ before installing: a server that does not meet them cannot offer accounts, and
|
|
|
30
30
|
sign-up refuses rather than half-working.
|
|
31
31
|
|
|
32
32
|
- **Community Solid Server 7.**
|
|
33
|
-
- **Pods on subdomains.**
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
- **Pods on subdomains or on paths.** A subdomain pod answers on its own
|
|
34
|
+
address (`@mei@mei.example.org`); a suffix pod on a path of the server's own
|
|
35
|
+
host answers under that path, and the server fronts it so its address is the
|
|
36
|
+
server's host (`@aisha@server.example`, for a pod at
|
|
37
|
+
`https://server.example/aisha/`). Either works — a suffix pod cannot resolve
|
|
38
|
+
its own handle, so it is followable only through the server's apex, which the
|
|
39
|
+
server also runs.
|
|
36
40
|
- **A single worker.** Run the server as one copy of itself — `--workers 1`,
|
|
37
41
|
which is the default. With more, it still serves pods normally, but no pod
|
|
38
42
|
can be an account: sign-up is refused, and an account set up earlier goes on
|
|
@@ -66,8 +70,8 @@ Add the package context to your CSS config and import the shipped snippet:
|
|
|
66
70
|
|
|
67
71
|
Then set what you need on the `urn:fedipod:server:Handler` node and restart
|
|
68
72
|
the server.
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
A subdomain-pods CSS config gives each identity an origin of its own; a
|
|
74
|
+
suffix (path) config hosts each on a path of the shared host. Both opt in.
|
|
71
75
|
The snippet places the component in the routing waterfall ahead of
|
|
72
76
|
the LDP catch-all, on the initializer and finalizer lists so identities start
|
|
73
77
|
and stop with the server, and on the websocket handler list for the live feed.
|
|
@@ -84,8 +88,9 @@ and stop with the server, and on the websocket handler list for the live feed.
|
|
|
84
88
|
```
|
|
85
89
|
|
|
86
90
|
An identity is provisioned when its owner opts in: its name is the pod's
|
|
87
|
-
subdomain label,
|
|
88
|
-
|
|
91
|
+
subdomain label, or its last path segment on a suffix pod, and it publishes an
|
|
92
|
+
actor and a signing key on the pod itself. Its handle resolves on the pod for a
|
|
93
|
+
subdomain, and through the server's apex for a suffix pod. Everything it is made of lives on its pod — its state, its private
|
|
89
94
|
signing key, the secret guarding its own pages, and the credentials for any
|
|
90
95
|
accounts its owner connects on other servers. Each identity has its own
|
|
91
96
|
secret; one owner's opens nobody else's door. The opt-in reply is where the
|
|
@@ -103,7 +108,7 @@ naming the pod the identity runs on. Nothing private is in it.
|
|
|
103
108
|
|---|---|
|
|
104
109
|
| `agentRuntimeOptIn` | Whether pod owners can sign up. With it off, nothing runs. |
|
|
105
110
|
| `agentDataDir` | Where each identity keeps the file naming its pod; its log lines go to the server's own log. Required whenever sign-up is on. |
|
|
106
|
-
| `agentUiPath` | Where the owner's pages live on the pod's origin. `/
|
|
111
|
+
| `agentUiPath` | Where the owner's pages live on the pod's origin. `/fp/` by default; empty serves no pages. On a suffix pod it is under the pod's path, e.g. `/aisha/fp/`. |
|
|
107
112
|
| `agentRegistryContainer` | The internal container holding the sign-up rows. |
|
|
108
113
|
| `runPage` | The HTML served at `/run`: the page where a pod owner opts in or out. The package's own `web/front/run.html` is served unless you set this. |
|
|
109
114
|
| `agentWebIdSuffix` | Path from a pod's base to its owner's WebID. Defaults to `profile/card#me`. |
|
|
@@ -149,9 +154,12 @@ that document's address and registers nothing here. Once in, it posts to the
|
|
|
149
154
|
outbox the actor names, and reads what the identity received at `/ap/inbox`,
|
|
150
155
|
which nobody but the owner may read.
|
|
151
156
|
|
|
152
|
-
A
|
|
153
|
-
|
|
154
|
-
|
|
157
|
+
A subdomain pod gets an origin of its own and answers at its root; a suffix
|
|
158
|
+
pod shares the host and answers under its own path (`/aisha/ap/actor`,
|
|
159
|
+
`/aisha/api/…`, `/aisha/oauth/…`, its door at `/aisha/fp/`). So a host carries
|
|
160
|
+
at most one root identity, but any number of path pods beside it; a second
|
|
161
|
+
root identity on a host, or a path pod nesting under another, is refused at
|
|
162
|
+
opt-in rather than half-working.
|
|
155
163
|
|
|
156
164
|
### Before you turn it on
|
|
157
165
|
|
|
@@ -164,16 +172,24 @@ for anyone hosting other people, it is a promise being made to them.
|
|
|
164
172
|
owner's door, with that identity's own door secret:
|
|
165
173
|
|
|
166
174
|
```
|
|
167
|
-
|
|
175
|
+
# subdomain pod:
|
|
176
|
+
curl -X POST https://mei.example.org/fp/config \
|
|
177
|
+
-H 'x-dk-token: THE_DOOR_SECRET_FROM_THE_OPT_IN_REPLY' -H 'content-type: application/json' \
|
|
178
|
+
-d '{"password":"the one you will type into your phone"}'
|
|
179
|
+
# suffix pod — the door is under the pod's path:
|
|
180
|
+
curl -X POST https://server.example/aisha/fp/config \
|
|
168
181
|
-H 'x-dk-token: THE_DOOR_SECRET_FROM_THE_OPT_IN_REPLY' -H 'content-type: application/json' \
|
|
169
182
|
-d '{"password":"the one you will type into your phone"}'
|
|
170
183
|
```
|
|
171
184
|
|
|
172
|
-
**Some pod paths stop being served.** On
|
|
185
|
+
**Some pod paths stop being served.** On a subdomain pod the paths above
|
|
173
186
|
belong to the identity, so pod resources at those names — a container called
|
|
174
|
-
`api`, `oauth` or `
|
|
187
|
+
`api`, `oauth` or `fp`, or documents at `ap/actor`, `ap/outbox`,
|
|
175
188
|
`ap/inbox`, `.well-known/oauth-authorization-server`,
|
|
176
189
|
`.well-known/nodeinfo` and `nodeinfo/2.0` — are not served over HTTP there.
|
|
190
|
+
On a suffix pod the same names are taken under the pod's own path
|
|
191
|
+
(`/aisha/api/…`, `/aisha/ap/actor`, `/aisha/fp/`, and so on); the rest of the
|
|
192
|
+
path, and every other pod on the host, is untouched.
|
|
177
193
|
They stay in the pod and in its listings. Every other path is the pod, exactly
|
|
178
194
|
as before.
|
|
179
195
|
|
|
@@ -228,7 +244,8 @@ TypeScript, built the way CSS builds its own components.
|
|
|
228
244
|
npm install
|
|
229
245
|
npm run build # tsc → dist, then componentsjs-generator → dist/components
|
|
230
246
|
npm test # unit tests, plus the transport against a real CSS store
|
|
231
|
-
npm run test:e2e # boots a real server and uses it as a client would
|
|
247
|
+
npm run test:e2e # boots a real server (subdomain pods) and uses it as a client would
|
|
248
|
+
npm run test:e2e:suffix # the same, for pods on paths of one host (mode d)
|
|
232
249
|
```
|
|
233
250
|
|
|
234
251
|
`npm test` drives a genuine CSS store stack — ETags, conditional writes,
|
|
@@ -241,6 +258,11 @@ lease protocol and the deletion deny-list still hold across it.
|
|
|
241
258
|
become identities up front; the third opts in and out at runtime), then signs in as a phone app does, posts,
|
|
242
259
|
receives a follow from another server, and watches the live feed. It takes
|
|
243
260
|
about a minute. `FEDIPOD_E2E_LOG=info` shows the server's log while it runs.
|
|
261
|
+
`npm run test:e2e:suffix` does the same on a server whose pods live on paths of
|
|
262
|
+
one host (`@aisha@server`): it proves the apex WebFinger resolves straight to
|
|
263
|
+
the pod actor, that the actor, inbox, client API, OAuth and door all answer
|
|
264
|
+
under the pod's path, that two path pods on one origin stay separate, and that
|
|
265
|
+
a signed delivery is verified at the pod's own door.
|
|
244
266
|
|
|
245
267
|
`dist/` and `node_modules/` are gitignored; `src/`, `config/` and this file are
|
|
246
268
|
the sources.
|
package/dist/claims.d.ts
CHANGED
|
@@ -2,19 +2,18 @@ export declare function claims(input: {
|
|
|
2
2
|
host?: string;
|
|
3
3
|
pathname: string;
|
|
4
4
|
}, frontHost: string): boolean;
|
|
5
|
+
export declare const isInboxPath: (pathname: string) => boolean;
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* the
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*
|
|
14
|
-
* `agentHosts` is keyed by host including port, as the Host header carries it.
|
|
7
|
+
* True when this path belongs to an identity's client surface.
|
|
8
|
+
*
|
|
9
|
+
* `pathname` is RELATIVE to the identity's mount: the handler has already
|
|
10
|
+
* matched the request's host and mount to one identity (see resolveClaim) and
|
|
11
|
+
* stripped the mount, so a host-root/subdomain pod passes its path unchanged
|
|
12
|
+
* and a suffix pod on `/aisha/` passes the part after `/aisha`. That keeps this
|
|
13
|
+
* a pure statement about which routes an identity owns, with no notion of host
|
|
14
|
+
* or of where on the origin it lives.
|
|
15
15
|
*/
|
|
16
16
|
export declare function agentClaims(input: {
|
|
17
|
-
host?: string;
|
|
18
17
|
pathname: string;
|
|
19
18
|
method?: string;
|
|
20
|
-
},
|
|
19
|
+
}, uiPath?: string): boolean;
|
package/dist/claims.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// front's apex the gateway answers the fediverse routes; a pod subdomain is a
|
|
5
5
|
// real Solid pod and is never claimed.
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
7
|
+
exports.isInboxPath = void 0;
|
|
8
8
|
exports.claims = claims;
|
|
9
9
|
exports.agentClaims = agentClaims;
|
|
10
10
|
const FRONT_PATHS = new Set(['/', '/signup', '/new-account', '/run', '/roster',
|
|
@@ -36,27 +36,29 @@ const AGENT_PATHS = new Set([
|
|
|
36
36
|
'/.well-known/oauth-authorization-server',
|
|
37
37
|
]);
|
|
38
38
|
const AGENT_PREFIXES = ['/api/', '/oauth/'];
|
|
39
|
+
// An identity's inbox is the container `/<root>/ap/inbox/`, matched by shape
|
|
40
|
+
// rather than a fixed root. A POST here is a delivery, verified at the door
|
|
41
|
+
// before it is written; the handler checks the exact path per identity. The
|
|
42
|
+
// path is relative to the identity's mount (see agentClaims), so a suffix pod's
|
|
43
|
+
// `/aisha/fedipod/ap/inbox/` arrives here already stripped to `/fedipod/ap/inbox/`.
|
|
44
|
+
const isInboxPath = (pathname) => /^\/[^/]+\/ap\/inbox\/$/u.test(pathname);
|
|
45
|
+
exports.isInboxPath = isInboxPath;
|
|
39
46
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* the
|
|
47
|
+
* True when this path belongs to an identity's client surface.
|
|
48
|
+
*
|
|
49
|
+
* `pathname` is RELATIVE to the identity's mount: the handler has already
|
|
50
|
+
* matched the request's host and mount to one identity (see resolveClaim) and
|
|
51
|
+
* stripped the mount, so a host-root/subdomain pod passes its path unchanged
|
|
52
|
+
* and a suffix pod on `/aisha/` passes the part after `/aisha`. That keeps this
|
|
53
|
+
* a pure statement about which routes an identity owns, with no notion of host
|
|
54
|
+
* or of where on the origin it lives.
|
|
44
55
|
*/
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* True when this request belongs to an identity's client surface.
|
|
48
|
-
* `agentHosts` is keyed by host including port, as the Host header carries it.
|
|
49
|
-
*/
|
|
50
|
-
function agentClaims(input, agentHosts, uiPath = '/fedipod/') {
|
|
51
|
-
if (!input.host || agentHosts.size === 0)
|
|
52
|
-
return false;
|
|
53
|
-
if (!agentHosts.has(String(input.host).toLowerCase()))
|
|
54
|
-
return false;
|
|
56
|
+
function agentClaims(input, uiPath = '/fp/') {
|
|
55
57
|
const { pathname } = input;
|
|
58
|
+
if ((0, exports.isInboxPath)(pathname))
|
|
59
|
+
return String(input.method ?? '').toUpperCase() === 'POST';
|
|
56
60
|
if (AGENT_PATHS.has(pathname))
|
|
57
61
|
return true;
|
|
58
|
-
if (pathname === exports.INBOX_PATH)
|
|
59
|
-
return String(input.method ?? '').toUpperCase() === 'POST';
|
|
60
62
|
if (AGENT_PREFIXES.some((prefix) => pathname.startsWith(prefix)))
|
|
61
63
|
return true;
|
|
62
64
|
// The owner's door, when there is one: '' turns the pages off entirely.
|
package/dist/directory.d.ts
CHANGED
|
@@ -39,11 +39,19 @@ export interface AgentRegistryRecord {
|
|
|
39
39
|
webId: string;
|
|
40
40
|
optedInAt: string;
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* The registry key for an opted-in pod: its host plus its path. Several pods
|
|
44
|
+
* can share a host (suffix pods on one origin), so the host alone is not
|
|
45
|
+
* unique. A host-root or subdomain pod has an empty path, so its key is just
|
|
46
|
+
* its host — exactly the shape rows were keyed by before suffix pods existed,
|
|
47
|
+
* which is why old rows still resolve with no migration.
|
|
48
|
+
*/
|
|
49
|
+
export declare function agentKey(host: string, podBase: string): string;
|
|
42
50
|
export interface AgentRegistry {
|
|
43
|
-
|
|
44
|
-
get(
|
|
51
|
+
listKeys(): Promise<string[]>;
|
|
52
|
+
get(key: string): Promise<AgentRegistryRecord | null>;
|
|
45
53
|
add(record: AgentRegistryRecord): Promise<void>;
|
|
46
|
-
remove(
|
|
54
|
+
remove(key: string): Promise<void>;
|
|
47
55
|
}
|
|
48
56
|
export declare function makeAgentRegistry(io: IO, containerUrl: string): AgentRegistry;
|
|
49
57
|
export declare function makeStorePodPut(io: IO): (url: string, body: string, contentType: string) => Promise<boolean>;
|
package/dist/directory.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.frontRow = frontRow;
|
|
7
7
|
exports.makeDirectory = makeDirectory;
|
|
8
|
+
exports.agentKey = agentKey;
|
|
8
9
|
exports.makeAgentRegistry = makeAgentRegistry;
|
|
9
10
|
exports.makeStorePodPut = makeStorePodPut;
|
|
10
11
|
// One JSON document per key in a container — the shape both registries share.
|
|
@@ -57,28 +58,41 @@ function makeDirectory(io, containerUrl) {
|
|
|
57
58
|
putDirectory: (handle, record) => table.put(handle, record),
|
|
58
59
|
};
|
|
59
60
|
}
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
/**
|
|
62
|
+
* The registry key for an opted-in pod: its host plus its path. Several pods
|
|
63
|
+
* can share a host (suffix pods on one origin), so the host alone is not
|
|
64
|
+
* unique. A host-root or subdomain pod has an empty path, so its key is just
|
|
65
|
+
* its host — exactly the shape rows were keyed by before suffix pods existed,
|
|
66
|
+
* which is why old rows still resolve with no migration.
|
|
67
|
+
*/
|
|
68
|
+
function agentKey(host, podBase) {
|
|
69
|
+
return host + new URL(podBase).pathname.replace(/\/+$/u, '');
|
|
70
|
+
}
|
|
71
|
+
// The registry of runtime-opted-in pods, keyed by agentKey (host+path). The
|
|
72
|
+
// IO layer cannot enumerate a container, so index.json carries the key list;
|
|
62
73
|
// the row is written FIRST, so a crash between the two writes still leaves a
|
|
63
|
-
// row the next boot claims once the index catches up on the next change.
|
|
74
|
+
// row the next boot claims once the index catches up on the next change. The
|
|
75
|
+
// index field stays named `hosts`: for a host-root pod a key IS its host, so
|
|
76
|
+
// documents an older server wrote are read back unchanged.
|
|
64
77
|
function makeAgentRegistry(io, containerUrl) {
|
|
65
78
|
const table = jsonTable(io, containerUrl);
|
|
66
79
|
const index = jsonTable(io, containerUrl);
|
|
67
80
|
const INDEX = 'index';
|
|
68
|
-
const
|
|
81
|
+
const keys = async () => (await index.get(INDEX))?.hosts ?? [];
|
|
69
82
|
return {
|
|
70
|
-
|
|
71
|
-
get: (
|
|
83
|
+
listKeys: keys,
|
|
84
|
+
get: (key) => table.get(key),
|
|
72
85
|
async add(record) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
86
|
+
const key = agentKey(record.host, record.podBase);
|
|
87
|
+
await table.put(key, record);
|
|
88
|
+
const list = await keys();
|
|
89
|
+
if (!list.includes(key))
|
|
90
|
+
await index.put(INDEX, { hosts: [...list, key] });
|
|
77
91
|
},
|
|
78
|
-
async remove(
|
|
79
|
-
const list = await
|
|
80
|
-
await index.put(INDEX, { hosts: list.filter((h) => h !==
|
|
81
|
-
await table.remove(
|
|
92
|
+
async remove(key) {
|
|
93
|
+
const list = await keys();
|
|
94
|
+
await index.put(INDEX, { hosts: list.filter((h) => h !== key) });
|
|
95
|
+
await table.remove(key);
|
|
82
96
|
},
|
|
83
97
|
};
|
|
84
98
|
}
|
package/dist/handler.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ export declare class FediPodServerHandler extends HttpHandler implements Initial
|
|
|
65
65
|
readonly dir: Directory;
|
|
66
66
|
private readonly podPut;
|
|
67
67
|
private readonly logger;
|
|
68
|
-
private readonly
|
|
68
|
+
private readonly claimed;
|
|
69
69
|
private readonly agentHandles;
|
|
70
70
|
private readonly frontHost;
|
|
71
71
|
private readonly uiPath;
|
|
@@ -79,11 +79,26 @@ export declare class FediPodServerHandler extends HttpHandler implements Initial
|
|
|
79
79
|
private onSignal;
|
|
80
80
|
constructor(args: FediPodServerArgs);
|
|
81
81
|
/**
|
|
82
|
-
* Whether this pod may become an identity here
|
|
83
|
-
*
|
|
84
|
-
* two pods must never share <agentDataDir>/<handle>/.
|
|
82
|
+
* Whether this pod may become an identity here, and the claim it earns: a
|
|
83
|
+
* real URL, a place no other identity already sits, and a handle no other
|
|
84
|
+
* identity uses — two pods must never share <agentDataDir>/<handle>/.
|
|
85
|
+
*
|
|
86
|
+
* A HOST-ROOT or subdomain pod needs an origin of its own, and it may not be
|
|
87
|
+
* the front's host: the whole surface answers at the origin root, so two of
|
|
88
|
+
* them, or one sharing the front, would collide. A SUFFIX pod lives on a path
|
|
89
|
+
* (`server/aisha/`), so it may share its host — with the front and with other
|
|
90
|
+
* suffix pods — provided no claim already contains or nests under its path.
|
|
85
91
|
*/
|
|
86
|
-
private
|
|
92
|
+
private validateAgentPod;
|
|
93
|
+
/**
|
|
94
|
+
* The claim a request belongs to, or null. A request matches when its host is
|
|
95
|
+
* the claim's host and its path is at or under the claim's mount; the deepest
|
|
96
|
+
* mount wins, so a suffix pod's own routes are never swallowed by a shallower
|
|
97
|
+
* claim on the same host.
|
|
98
|
+
*/
|
|
99
|
+
private resolveClaim;
|
|
100
|
+
/** A request path relative to a mount: `/aisha/ap/actor` under `/aisha` → `/ap/actor`. */
|
|
101
|
+
private stripMount;
|
|
87
102
|
/**
|
|
88
103
|
* Start an agent for each opted-in pod. Runs before the server listens, so
|
|
89
104
|
* the identities come up in the background and boot is never held on a pod.
|
|
@@ -118,8 +133,16 @@ export declare class FediPodServerHandler extends HttpHandler implements Initial
|
|
|
118
133
|
* of them can answer for it.
|
|
119
134
|
*/
|
|
120
135
|
private runsIdentities;
|
|
121
|
-
/**
|
|
122
|
-
|
|
136
|
+
/**
|
|
137
|
+
* The identity a request belongs to (matched by host and mount) and the
|
|
138
|
+
* request path relative to that identity's mount, or null. The identity is
|
|
139
|
+
* undefined when the pod is claimed but still starting. Used by the streaming
|
|
140
|
+
* upgrade, which has only the request to go on.
|
|
141
|
+
*/
|
|
142
|
+
matchIdentity(host?: string, pathname?: string): {
|
|
143
|
+
identity: EmbeddedIdentity | undefined;
|
|
144
|
+
rel: string;
|
|
145
|
+
} | null;
|
|
123
146
|
/**
|
|
124
147
|
* A pod owner, already proven to control podBase, asks this server to run
|
|
125
148
|
* their identity. Returns { httpStatus, ...body }; the secret appears in the
|