@nubisco/openbridge 1.4.1 → 1.5.1

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.
Files changed (44) hide show
  1. package/dist/__tests__/auth-origin.test.js +2 -4
  2. package/dist/__tests__/auth-origin.test.js.map +1 -1
  3. package/dist/__tests__/mcp.test.d.ts +2 -0
  4. package/dist/__tests__/mcp.test.d.ts.map +1 -0
  5. package/dist/__tests__/mcp.test.js +464 -0
  6. package/dist/__tests__/mcp.test.js.map +1 -0
  7. package/dist/access.d.ts +148 -0
  8. package/dist/access.d.ts.map +1 -0
  9. package/dist/access.js +401 -0
  10. package/dist/access.js.map +1 -0
  11. package/dist/auth.d.ts +13 -5
  12. package/dist/auth.d.ts.map +1 -1
  13. package/dist/auth.js +16 -10
  14. package/dist/auth.js.map +1 -1
  15. package/dist/index.js +8 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/mcp/index.d.ts +48 -0
  18. package/dist/mcp/index.d.ts.map +1 -0
  19. package/dist/mcp/index.js +173 -0
  20. package/dist/mcp/index.js.map +1 -0
  21. package/dist/mcp/oauth.d.ts +35 -0
  22. package/dist/mcp/oauth.d.ts.map +1 -0
  23. package/dist/mcp/oauth.js +319 -0
  24. package/dist/mcp/oauth.js.map +1 -0
  25. package/dist/mcp/tools.d.ts +39 -0
  26. package/dist/mcp/tools.d.ts.map +1 -0
  27. package/dist/mcp/tools.js +432 -0
  28. package/dist/mcp/tools.js.map +1 -0
  29. package/dist/server.d.ts.map +1 -1
  30. package/dist/server.js +67 -114
  31. package/dist/server.js.map +1 -1
  32. package/dist/services/bridge.d.ts +102 -0
  33. package/dist/services/bridge.d.ts.map +1 -0
  34. package/dist/services/bridge.js +191 -0
  35. package/dist/services/bridge.js.map +1 -0
  36. package/dist/token-cli.d.ts +10 -0
  37. package/dist/token-cli.d.ts.map +1 -0
  38. package/dist/token-cli.js +76 -0
  39. package/dist/token-cli.js.map +1 -0
  40. package/package.json +6 -5
  41. package/ui-dist/assets/{index-CL7JhxrS.css → index-9bWNU3bq.css} +2 -2
  42. package/ui-dist/assets/index-DIyesg4J.js +109 -0
  43. package/ui-dist/index.html +2 -2
  44. package/ui-dist/assets/index-Rvs_bO_V.js +0 -109
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Who may use the MCP endpoint: personal tokens and OAuth grants.
3
+ *
4
+ * OpenBridge has no database, so this is one JSON file, `access.json` in the
5
+ * state directory, written atomically with mode 600. Only hashes of secrets are
6
+ * stored. The file is re-read whenever it changes on disk, so a token made with
7
+ * `openbridge token create` on the host works without restarting the daemon.
8
+ *
9
+ * Two scopes, and they are the whole permission model of the endpoint:
10
+ *
11
+ * - `openbridge:read` sees devices, history, events, observations and logs.
12
+ * - `openbridge:control` also runs device controls and writes HomeKit
13
+ * characteristics, which move physical things (a gate, a heat pump).
14
+ *
15
+ * Control implies read. Nothing here reaches plugin installs, config, the
16
+ * shell or updates: those stay behind the dashboard.
17
+ *
18
+ * The OAuth half follows Tally's (tally/apps/api/src/services/oauth.service.ts):
19
+ * public clients only, S256 PKCE only, exact redirect matching, codes single
20
+ * use for five minutes, access tokens for an hour, refresh tokens rotating on
21
+ * every use.
22
+ */
23
+ export declare const READ_SCOPE = "openbridge:read";
24
+ export declare const CONTROL_SCOPE = "openbridge:control";
25
+ export declare const SCOPES: readonly ["openbridge:read", "openbridge:control"];
26
+ export type Scope = (typeof SCOPES)[number];
27
+ export type Access = 'read' | 'control';
28
+ /** Every OpenBridge credential starts with this, so a leaked one is recognisable on sight. */
29
+ export declare const TOKEN_PREFIX = "obt_";
30
+ /** The most never-approved clients held at once. Registration is unauthenticated by design. */
31
+ export declare const MAX_UNUSED_CLIENTS = 100;
32
+ export declare function scopesFor(access: Access): Scope[];
33
+ export declare function accessOf(scopes: readonly string[]): Access;
34
+ export declare function hashToken(raw: string): string;
35
+ /** PKCE: base64url(SHA-256(verifier)), unpadded, per RFC 7636. */
36
+ export declare function s256Challenge(verifier: string): string;
37
+ /** https for the world, plain http only for loopback tooling (Claude Code listens on localhost). */
38
+ export declare function acceptableRedirect(uri: string): boolean;
39
+ /** Who made a token or approved a connector: the signed-in person, or `local` when sign-in is off. */
40
+ export interface Owner {
41
+ id: string;
42
+ email: string | null;
43
+ }
44
+ /** What a credential resolves to. The MCP endpoint needs nothing else. */
45
+ export interface Credential {
46
+ kind: 'personal' | 'oauth';
47
+ name: string;
48
+ scopes: Scope[];
49
+ owner: Owner;
50
+ /** Stable across refreshes, so a retried write op is recognised as the same caller. */
51
+ id: string;
52
+ }
53
+ export interface TokenPair {
54
+ access_token: string;
55
+ token_type: 'Bearer';
56
+ expires_in: number;
57
+ refresh_token: string;
58
+ scope: string;
59
+ }
60
+ export type TokenResult = {
61
+ ok: true;
62
+ pair: TokenPair;
63
+ } | {
64
+ ok: false;
65
+ error: string;
66
+ };
67
+ export declare class AccessStore {
68
+ private readonly path;
69
+ private data;
70
+ private mtimeMs;
71
+ constructor(path: string);
72
+ /** Re-reads the file when it changed on disk, which is how the CLI's writes arrive. */
73
+ private load;
74
+ /** Read, change, write. The file is replaced by rename, so a reader never sees half of it. */
75
+ private mutate;
76
+ private prune;
77
+ /** Creates a token and returns the raw value, the only time it exists outside the caller. */
78
+ createToken(name: string, access: Access, owner: Owner): {
79
+ id: string;
80
+ token: string;
81
+ };
82
+ /**
83
+ * Every token on this bridge. A bridge is one household's: whoever can sign in
84
+ * to the dashboard can already open its shell, so nobody's tokens are hidden
85
+ * from another person who manages it.
86
+ */
87
+ listTokens(): {
88
+ id: string;
89
+ name: string;
90
+ access: Access;
91
+ owner: string | null;
92
+ createdAt: string;
93
+ lastUsedAt: string | null;
94
+ }[];
95
+ /** Deleted outright: a personal token has no refresh to refuse later. */
96
+ revokeToken(id: string): boolean;
97
+ verify(raw: string): Credential | null;
98
+ private touch;
99
+ registerClient(body: {
100
+ redirect_uris?: unknown;
101
+ client_name?: unknown;
102
+ }): {
103
+ ok: true;
104
+ id: string;
105
+ name: string;
106
+ uris: string[];
107
+ } | {
108
+ ok: false;
109
+ error: string;
110
+ description: string;
111
+ };
112
+ /**
113
+ * The client, when this exact redirect is one it registered. Exact match,
114
+ * never a prefix: "starts with" is the classic open redirect.
115
+ */
116
+ client(clientId: string, redirectUri: string): {
117
+ id: string;
118
+ name: string;
119
+ } | null;
120
+ issueCode(p: {
121
+ clientId: string;
122
+ redirectUri: string;
123
+ codeChallenge: string;
124
+ access: Access;
125
+ }, owner: Owner): string;
126
+ private pair;
127
+ /** grant_type=authorization_code. Every check here fails open if omitted. */
128
+ exchangeCode(get: (k: string) => string): TokenResult;
129
+ /** grant_type=refresh_token. Rotates, so the presented token dies here. */
130
+ refresh(get: (k: string) => string): TokenResult;
131
+ /**
132
+ * One row per client rather than per grant: authorising Claude twice makes
133
+ * two grants for what the person thinks of as one connection, and a revoke
134
+ * that left the sibling alive would be a revoke that did not work.
135
+ */
136
+ listConnections(): {
137
+ clientId: string;
138
+ name: string;
139
+ access: Access;
140
+ owners: string[];
141
+ connectedAt: string;
142
+ lastUsedAt: string | null;
143
+ }[];
144
+ /** Revokes every live grant of one client, including its refresh tokens. */
145
+ revokeConnection(clientId: string): boolean;
146
+ }
147
+ export declare function extractBearer(header: string | undefined): string | null;
148
+ //# sourceMappingURL=access.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"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"}
package/dist/access.js ADDED
@@ -0,0 +1,401 @@
1
+ /**
2
+ * Who may use the MCP endpoint: personal tokens and OAuth grants.
3
+ *
4
+ * OpenBridge has no database, so this is one JSON file, `access.json` in the
5
+ * state directory, written atomically with mode 600. Only hashes of secrets are
6
+ * stored. The file is re-read whenever it changes on disk, so a token made with
7
+ * `openbridge token create` on the host works without restarting the daemon.
8
+ *
9
+ * Two scopes, and they are the whole permission model of the endpoint:
10
+ *
11
+ * - `openbridge:read` sees devices, history, events, observations and logs.
12
+ * - `openbridge:control` also runs device controls and writes HomeKit
13
+ * characteristics, which move physical things (a gate, a heat pump).
14
+ *
15
+ * Control implies read. Nothing here reaches plugin installs, config, the
16
+ * shell or updates: those stay behind the dashboard.
17
+ *
18
+ * The OAuth half follows Tally's (tally/apps/api/src/services/oauth.service.ts):
19
+ * public clients only, S256 PKCE only, exact redirect matching, codes single
20
+ * use for five minutes, access tokens for an hour, refresh tokens rotating on
21
+ * every use.
22
+ */
23
+ import { createHash, randomBytes, randomUUID } from 'crypto';
24
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from 'fs';
25
+ import { dirname } from 'path';
26
+ export const READ_SCOPE = 'openbridge:read';
27
+ export const CONTROL_SCOPE = 'openbridge:control';
28
+ export const SCOPES = [READ_SCOPE, CONTROL_SCOPE];
29
+ /** Every OpenBridge credential starts with this, so a leaked one is recognisable on sight. */
30
+ export const TOKEN_PREFIX = 'obt_';
31
+ const PERSONAL_PREFIX = `${TOKEN_PREFIX}pat_`;
32
+ const ACCESS_PREFIX = `${TOKEN_PREFIX}mcp_`;
33
+ const REFRESH_PREFIX = `${TOKEN_PREFIX}ref_`;
34
+ const CODE_PREFIX = `${TOKEN_PREFIX}code_`;
35
+ const CODE_TTL_MS = 5 * 60 * 1000;
36
+ const ACCESS_TTL_MS = 60 * 60 * 1000;
37
+ const REFRESH_TTL_MS = 30 * 24 * 60 * 60 * 1000;
38
+ /** A client that registered and was never approved is dropped after this. */
39
+ const UNUSED_CLIENT_TTL_MS = 3 * 24 * 60 * 60 * 1000;
40
+ /** The most never-approved clients held at once. Registration is unauthenticated by design. */
41
+ export const MAX_UNUSED_CLIENTS = 100;
42
+ /** lastUsedAt is written at most this often, so a busy agent does not rewrite the file per call. */
43
+ const LAST_USED_GRANULARITY_MS = 60 * 1000;
44
+ export function scopesFor(access) {
45
+ return access === 'control' ? [READ_SCOPE, CONTROL_SCOPE] : [READ_SCOPE];
46
+ }
47
+ export function accessOf(scopes) {
48
+ return scopes.includes(CONTROL_SCOPE) ? 'control' : 'read';
49
+ }
50
+ export function hashToken(raw) {
51
+ return createHash('sha256').update(raw).digest('hex');
52
+ }
53
+ function randomSecret(prefix) {
54
+ return `${prefix}${randomBytes(32).toString('base64url')}`;
55
+ }
56
+ /** PKCE: base64url(SHA-256(verifier)), unpadded, per RFC 7636. */
57
+ export function s256Challenge(verifier) {
58
+ return createHash('sha256').update(verifier).digest('base64url');
59
+ }
60
+ /** https for the world, plain http only for loopback tooling (Claude Code listens on localhost). */
61
+ export function acceptableRedirect(uri) {
62
+ try {
63
+ const u = new URL(uri);
64
+ if (u.protocol === 'https:')
65
+ return true;
66
+ return u.protocol === 'http:' && (u.hostname === 'localhost' || u.hostname === '127.0.0.1');
67
+ }
68
+ catch {
69
+ return false;
70
+ }
71
+ }
72
+ const empty = () => ({ tokens: [], clients: [], codes: [], grants: [] });
73
+ const iso = (ms) => new Date(ms).toISOString();
74
+ const past = (at, now) => at !== null && Date.parse(at) <= now;
75
+ export class AccessStore {
76
+ path;
77
+ data = empty();
78
+ mtimeMs = -1;
79
+ constructor(path) {
80
+ this.path = path;
81
+ }
82
+ /** Re-reads the file when it changed on disk, which is how the CLI's writes arrive. */
83
+ load() {
84
+ let mtime = -1;
85
+ try {
86
+ mtime = statSync(this.path).mtimeMs;
87
+ }
88
+ catch {
89
+ this.data = empty();
90
+ this.mtimeMs = -1;
91
+ return this.data;
92
+ }
93
+ if (mtime !== this.mtimeMs) {
94
+ try {
95
+ const parsed = JSON.parse(readFileSync(this.path, 'utf8'));
96
+ this.data = { ...empty(), ...parsed };
97
+ }
98
+ catch {
99
+ // A torn or hand-broken file grants nothing rather than crashing the daemon.
100
+ this.data = empty();
101
+ }
102
+ this.mtimeMs = mtime;
103
+ }
104
+ return this.data;
105
+ }
106
+ /** Read, change, write. The file is replaced by rename, so a reader never sees half of it. */
107
+ mutate(fn) {
108
+ const d = this.load();
109
+ const now = Date.now();
110
+ const out = fn(d, now);
111
+ this.prune(d, now);
112
+ const dir = dirname(this.path);
113
+ if (!existsSync(dir))
114
+ mkdirSync(dir, { recursive: true });
115
+ const tmp = `${this.path}.${process.pid}.tmp`;
116
+ writeFileSync(tmp, JSON.stringify(d, null, 2), { mode: 0o600 });
117
+ try {
118
+ chmodSync(tmp, 0o600);
119
+ }
120
+ catch {
121
+ // best effort: chmod fails on non-POSIX volumes
122
+ }
123
+ renameSync(tmp, this.path);
124
+ this.mtimeMs = statSync(this.path).mtimeMs;
125
+ return out;
126
+ }
127
+ prune(d, now) {
128
+ d.codes = d.codes.filter((c) => !c.usedAt && !past(c.expiresAt, now));
129
+ d.grants = d.grants.filter((g) => !g.revokedAt && !past(g.refreshExpiresAt, now));
130
+ const live = new Set([...d.codes.map((c) => c.clientId), ...d.grants.map((g) => g.clientId)]);
131
+ d.clients = d.clients.filter((c) => c.usedAt !== null || live.has(c.id) || now - Date.parse(c.createdAt) < UNUSED_CLIENT_TTL_MS);
132
+ }
133
+ // ── Personal tokens ────────────────────────────────────────────────────────
134
+ /** Creates a token and returns the raw value, the only time it exists outside the caller. */
135
+ createToken(name, access, owner) {
136
+ const token = randomSecret(PERSONAL_PREFIX);
137
+ const id = randomUUID();
138
+ this.mutate((d, now) => {
139
+ d.tokens.push({
140
+ id,
141
+ name: name.trim().slice(0, 120) || 'Unnamed token',
142
+ hash: hashToken(token),
143
+ scopes: scopesFor(access),
144
+ owner,
145
+ createdAt: iso(now),
146
+ lastUsedAt: null,
147
+ });
148
+ });
149
+ return { id, token };
150
+ }
151
+ /**
152
+ * Every token on this bridge. A bridge is one household's: whoever can sign in
153
+ * to the dashboard can already open its shell, so nobody's tokens are hidden
154
+ * from another person who manages it.
155
+ */
156
+ listTokens() {
157
+ return this.load().tokens.map((t) => ({
158
+ id: t.id,
159
+ name: t.name,
160
+ access: accessOf(t.scopes),
161
+ owner: t.owner.email,
162
+ createdAt: t.createdAt,
163
+ lastUsedAt: t.lastUsedAt,
164
+ }));
165
+ }
166
+ /** Deleted outright: a personal token has no refresh to refuse later. */
167
+ revokeToken(id) {
168
+ if (!this.load().tokens.some((t) => t.id === id))
169
+ return false;
170
+ return this.mutate((d) => {
171
+ const before = d.tokens.length;
172
+ d.tokens = d.tokens.filter((t) => t.id !== id);
173
+ return d.tokens.length < before;
174
+ });
175
+ }
176
+ // ── Resolving a bearer ─────────────────────────────────────────────────────
177
+ verify(raw) {
178
+ if (!raw.startsWith(TOKEN_PREFIX))
179
+ return null;
180
+ const hash = hashToken(raw);
181
+ const d = this.load();
182
+ const now = Date.now();
183
+ const token = d.tokens.find((t) => t.hash === hash);
184
+ if (token) {
185
+ this.touch('tokens', token.id, token.lastUsedAt, now);
186
+ return { kind: 'personal', name: token.name, scopes: token.scopes, owner: token.owner, id: `token:${token.id}` };
187
+ }
188
+ if (!raw.startsWith(ACCESS_PREFIX))
189
+ return null;
190
+ const grant = d.grants.find((g) => g.accessHash === hash);
191
+ if (!grant || grant.revokedAt || past(grant.accessExpiresAt, now))
192
+ return null;
193
+ this.touch('grants', grant.id, grant.lastUsedAt, now);
194
+ const client = d.clients.find((c) => c.id === grant.clientId);
195
+ return {
196
+ kind: 'oauth',
197
+ name: client?.name ?? 'Connector',
198
+ scopes: grant.scopes,
199
+ owner: grant.owner,
200
+ id: `oauth:${grant.id}`,
201
+ };
202
+ }
203
+ touch(kind, id, last, now) {
204
+ if (last && now - Date.parse(last) < LAST_USED_GRANULARITY_MS)
205
+ return;
206
+ this.mutate((d) => {
207
+ const row = d[kind].find((r) => r.id === id);
208
+ if (row)
209
+ row.lastUsedAt = iso(now);
210
+ });
211
+ }
212
+ // ── OAuth: registration ────────────────────────────────────────────────────
213
+ registerClient(body) {
214
+ const uris = Array.isArray(body.redirect_uris)
215
+ ? body.redirect_uris.filter((u) => typeof u === 'string')
216
+ : [];
217
+ if (uris.length === 0 || !uris.every(acceptableRedirect)) {
218
+ return {
219
+ ok: false,
220
+ error: 'invalid_redirect_uri',
221
+ description: 'redirect_uris must be https URLs, or http on localhost',
222
+ };
223
+ }
224
+ const name = ((typeof body.client_name === 'string' && body.client_name.trim()) || 'Unnamed client').slice(0, 120);
225
+ return this.mutate((d, now) => {
226
+ this.prune(d, now);
227
+ if (d.clients.filter((c) => c.usedAt === null).length >= MAX_UNUSED_CLIENTS) {
228
+ return {
229
+ ok: false,
230
+ error: 'temporarily_unavailable',
231
+ description: 'Registration is paused. Try again later.',
232
+ };
233
+ }
234
+ const id = randomUUID();
235
+ d.clients.push({ id, name, redirectUris: uris, createdAt: iso(now), usedAt: null });
236
+ return { ok: true, id, name, uris };
237
+ });
238
+ }
239
+ /**
240
+ * The client, when this exact redirect is one it registered. Exact match,
241
+ * never a prefix: "starts with" is the classic open redirect.
242
+ */
243
+ client(clientId, redirectUri) {
244
+ const c = this.load().clients.find((x) => x.id === clientId);
245
+ if (!c || !c.redirectUris.includes(redirectUri))
246
+ return null;
247
+ return { id: c.id, name: c.name };
248
+ }
249
+ // ── OAuth: code and token ──────────────────────────────────────────────────
250
+ issueCode(p, owner) {
251
+ const code = randomSecret(CODE_PREFIX);
252
+ this.mutate((d, now) => {
253
+ d.codes.push({
254
+ hash: hashToken(code),
255
+ clientId: p.clientId,
256
+ owner,
257
+ redirectUri: p.redirectUri,
258
+ challenge: p.codeChallenge,
259
+ scopes: scopesFor(p.access),
260
+ expiresAt: iso(now + CODE_TTL_MS),
261
+ usedAt: null,
262
+ });
263
+ // A person approved this client, so it is in use and is never pruned.
264
+ const client = d.clients.find((c) => c.id === p.clientId);
265
+ if (client && !client.usedAt)
266
+ client.usedAt = iso(now);
267
+ });
268
+ return code;
269
+ }
270
+ pair(scopes) {
271
+ const access = randomSecret(ACCESS_PREFIX);
272
+ const refresh = randomSecret(REFRESH_PREFIX);
273
+ return {
274
+ access,
275
+ refresh,
276
+ pair: {
277
+ access_token: access,
278
+ token_type: 'Bearer',
279
+ expires_in: Math.floor(ACCESS_TTL_MS / 1000),
280
+ refresh_token: refresh,
281
+ scope: scopes.join(' '),
282
+ },
283
+ };
284
+ }
285
+ /** grant_type=authorization_code. Every check here fails open if omitted. */
286
+ exchangeCode(get) {
287
+ const hash = hashToken(get('code'));
288
+ return this.mutate((d, now) => {
289
+ const row = d.codes.find((c) => c.hash === hash);
290
+ if (!row || row.usedAt || past(row.expiresAt, now))
291
+ return { ok: false, error: 'invalid_grant' };
292
+ if (row.clientId !== get('client_id'))
293
+ return { ok: false, error: 'invalid_grant' };
294
+ // Repeated here so a code minted for one target cannot be redeemed while claiming another.
295
+ if (row.redirectUri !== get('redirect_uri'))
296
+ return { ok: false, error: 'invalid_grant' };
297
+ // The proof. Without it the code alone is enough, which is why PKCE exists for public clients.
298
+ if (s256Challenge(get('code_verifier')) !== row.challenge)
299
+ return { ok: false, error: 'invalid_grant' };
300
+ // Single use. The whole read-change-write runs synchronously, so two
301
+ // requests racing with one code cannot both get past this line.
302
+ row.usedAt = iso(now);
303
+ const { access, refresh, pair } = this.pair(row.scopes);
304
+ d.grants.push({
305
+ id: randomUUID(),
306
+ clientId: row.clientId,
307
+ owner: row.owner,
308
+ accessHash: hashToken(access),
309
+ refreshHash: hashToken(refresh),
310
+ scopes: row.scopes,
311
+ accessExpiresAt: iso(now + ACCESS_TTL_MS),
312
+ refreshExpiresAt: iso(now + REFRESH_TTL_MS),
313
+ createdAt: iso(now),
314
+ lastUsedAt: null,
315
+ revokedAt: null,
316
+ });
317
+ return { ok: true, pair };
318
+ });
319
+ }
320
+ /** grant_type=refresh_token. Rotates, so the presented token dies here. */
321
+ refresh(get) {
322
+ const hash = hashToken(get('refresh_token'));
323
+ return this.mutate((d, now) => {
324
+ const row = d.grants.find((g) => g.refreshHash === hash);
325
+ if (!row || row.revokedAt || past(row.refreshExpiresAt, now))
326
+ return { ok: false, error: 'invalid_grant' };
327
+ if (get('client_id') && get('client_id') !== row.clientId)
328
+ return { ok: false, error: 'invalid_grant' };
329
+ const { access, refresh, pair } = this.pair(row.scopes);
330
+ row.accessHash = hashToken(access);
331
+ row.refreshHash = hashToken(refresh);
332
+ row.accessExpiresAt = iso(now + ACCESS_TTL_MS);
333
+ row.refreshExpiresAt = iso(now + REFRESH_TTL_MS);
334
+ return { ok: true, pair };
335
+ });
336
+ }
337
+ // ── Connected applications ─────────────────────────────────────────────────
338
+ /**
339
+ * One row per client rather than per grant: authorising Claude twice makes
340
+ * two grants for what the person thinks of as one connection, and a revoke
341
+ * that left the sibling alive would be a revoke that did not work.
342
+ */
343
+ listConnections() {
344
+ const d = this.load();
345
+ const now = Date.now();
346
+ const byClient = new Map();
347
+ for (const g of d.grants) {
348
+ if (g.revokedAt || past(g.refreshExpiresAt, now))
349
+ continue;
350
+ const app = byClient.get(g.clientId) ?? {
351
+ clientId: g.clientId,
352
+ name: d.clients.find((c) => c.id === g.clientId)?.name ?? 'Connector',
353
+ scopes: new Set(),
354
+ owners: new Set(),
355
+ connectedAt: g.createdAt,
356
+ lastUsedAt: null,
357
+ };
358
+ for (const s of g.scopes)
359
+ app.scopes.add(s);
360
+ if (g.owner.email)
361
+ app.owners.add(g.owner.email);
362
+ if (g.createdAt < app.connectedAt)
363
+ app.connectedAt = g.createdAt;
364
+ if (g.lastUsedAt && (!app.lastUsedAt || g.lastUsedAt > app.lastUsedAt))
365
+ app.lastUsedAt = g.lastUsedAt;
366
+ byClient.set(g.clientId, app);
367
+ }
368
+ return [...byClient.values()]
369
+ .sort((a, b) => b.connectedAt.localeCompare(a.connectedAt))
370
+ .map((a) => ({
371
+ clientId: a.clientId,
372
+ name: a.name,
373
+ access: accessOf([...a.scopes]),
374
+ owners: [...a.owners],
375
+ connectedAt: a.connectedAt,
376
+ lastUsedAt: a.lastUsedAt,
377
+ }));
378
+ }
379
+ /** Revokes every live grant of one client, including its refresh tokens. */
380
+ revokeConnection(clientId) {
381
+ if (!this.load().grants.some((g) => g.clientId === clientId && !g.revokedAt))
382
+ return false;
383
+ return this.mutate((d, now) => {
384
+ let n = 0;
385
+ for (const g of d.grants) {
386
+ if (g.clientId === clientId && !g.revokedAt) {
387
+ g.revokedAt = iso(now);
388
+ n++;
389
+ }
390
+ }
391
+ return n > 0;
392
+ });
393
+ }
394
+ }
395
+ export function extractBearer(header) {
396
+ if (!header)
397
+ return null;
398
+ const match = /^Bearer\s+(.+)$/i.exec(header);
399
+ return match ? match[1].trim() : null;
400
+ }
401
+ //# sourceMappingURL=access.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.js","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAC5D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;AACxG,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAE9B,MAAM,CAAC,MAAM,UAAU,GAAG,iBAAiB,CAAA;AAC3C,MAAM,CAAC,MAAM,aAAa,GAAG,oBAAoB,CAAA;AACjD,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,UAAU,EAAE,aAAa,CAAU,CAAA;AAI1D,8FAA8F;AAC9F,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAA;AAClC,MAAM,eAAe,GAAG,GAAG,YAAY,MAAM,CAAA;AAC7C,MAAM,aAAa,GAAG,GAAG,YAAY,MAAM,CAAA;AAC3C,MAAM,cAAc,GAAG,GAAG,YAAY,MAAM,CAAA;AAC5C,MAAM,WAAW,GAAG,GAAG,YAAY,OAAO,CAAA;AAE1C,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA;AACjC,MAAM,aAAa,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AACpC,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAC/C,6EAA6E;AAC7E,MAAM,oBAAoB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AACpD,+FAA+F;AAC/F,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;AACrC,oGAAoG;AACpG,MAAM,wBAAwB,GAAG,EAAE,GAAG,IAAI,CAAA;AAE1C,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;AAC1E,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAyB;IAChD,OAAO,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAA;AAC5D,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACvD,CAAC;AAED,SAAS,YAAY,CAAC,MAAc;IAClC,OAAO,GAAG,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAA;AAC5D,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;AAClE,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QACtB,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAA;QACxC,OAAO,CAAC,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,QAAQ,KAAK,WAAW,IAAI,CAAC,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAA;IAC7F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AA8ED,MAAM,KAAK,GAAG,GAAe,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;AACpF,MAAM,GAAG,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;AACtD,MAAM,IAAI,GAAG,CAAC,EAAiB,EAAE,GAAW,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,GAAG,CAAA;AAErF,MAAM,OAAO,WAAW;IAIO;IAHrB,IAAI,GAAe,KAAK,EAAE,CAAA;IAC1B,OAAO,GAAG,CAAC,CAAC,CAAA;IAEpB,YAA6B,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAE7C,uFAAuF;IAC/E,IAAI;QACV,IAAI,KAAK,GAAG,CAAC,CAAC,CAAA;QACd,IAAI,CAAC;YACH,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAA;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,IAAI,GAAG,KAAK,EAAE,CAAA;YACnB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;YACjB,OAAO,IAAI,CAAC,IAAI,CAAA;QAClB,CAAC;QACD,IAAI,KAAK,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAwB,CAAA;gBACjF,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,CAAA;YACvC,CAAC;YAAC,MAAM,CAAC;gBACP,6EAA6E;gBAC7E,IAAI,CAAC,IAAI,GAAG,KAAK,EAAE,CAAA;YACrB,CAAC;YACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACtB,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAA;IAClB,CAAC;IAED,8FAA8F;IACtF,MAAM,CAAI,EAAqC;QACrD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QACtB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAClB,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC9B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACzD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAA;QAC7C,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAC/D,IAAI,CAAC;YACH,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,gDAAgD;QAClD,CAAC;QACD,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAC1B,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAA;QAC1C,OAAO,GAAG,CAAA;IACZ,CAAC;IAEO,KAAK,CAAC,CAAa,EAAE,GAAW;QACtC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAA;QACrE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAA;QACjF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QAC7F,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,CAC1B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,oBAAoB,CACnG,CAAA;IACH,CAAC;IAED,8EAA8E;IAE9E,6FAA6F;IAC7F,WAAW,CAAC,IAAY,EAAE,MAAc,EAAE,KAAY;QACpD,MAAM,KAAK,GAAG,YAAY,CAAC,eAAe,CAAC,CAAA;QAC3C,MAAM,EAAE,GAAG,UAAU,EAAE,CAAA;QACvB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YACrB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;gBACZ,EAAE;gBACF,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,eAAe;gBAClD,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC;gBACtB,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;gBACzB,KAAK;gBACL,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC;gBACnB,UAAU,EAAE,IAAI;aACjB,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QACF,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAA;IACtB,CAAC;IAED;;;;OAIG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1B,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK;YACpB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB,CAAC,CAAC,CAAA;IACL,CAAC;IAED,yEAAyE;IACzE,WAAW,CAAC,EAAU;QACpB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;YAAE,OAAO,KAAK,CAAA;QAC9D,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACvB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAA;YAC9B,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;YAC9C,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAA;QACjC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,8EAA8E;IAE9E,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC;YAAE,OAAO,IAAI,CAAA;QAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAA;QAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEtB,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;QACnD,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;YACrD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,SAAS,KAAK,CAAC,EAAE,EAAE,EAAE,CAAA;QAClH,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC;YAAE,OAAO,IAAI,CAAA;QAC/C,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAA;QACzD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;QAC9E,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;QACrD,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAA;QAC7D,OAAO;YACL,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,WAAW;YACjC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,EAAE,EAAE,SAAS,KAAK,CAAC,EAAE,EAAE;SACxB,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,IAAyB,EAAE,EAAU,EAAE,IAAmB,EAAE,GAAW;QACnF,IAAI,IAAI,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,wBAAwB;YAAE,OAAM;QACrE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YAChB,MAAM,GAAG,GAAI,CAAC,CAAC,IAAI,CAAsD,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;YAClG,IAAI,GAAG;gBAAE,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;QACpC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,8EAA8E;IAE9E,cAAc,CAAC,IAGd;QACC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC;YAC5C,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YACtE,CAAC,CAAC,EAAE,CAAA;QACN,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACzD,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,sBAAsB;gBAC7B,WAAW,EAAE,wDAAwD;aACtE,CAAA;QACH,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,IAAI,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAClH,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YAC5B,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;YAClB,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,MAAM,IAAI,kBAAkB,EAAE,CAAC;gBAC5E,OAAO;oBACL,EAAE,EAAE,KAAc;oBAClB,KAAK,EAAE,yBAAyB;oBAChC,WAAW,EAAE,0CAA0C;iBACxD,CAAA;YACH,CAAC;YACD,MAAM,EAAE,GAAG,UAAU,EAAE,CAAA;YACvB,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;YACnF,OAAO,EAAE,EAAE,EAAE,IAAa,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;QAC9C,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,QAAgB,EAAE,WAAmB;QAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAA;QAC5D,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAA;QAC5D,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IACnC,CAAC;IAED,8EAA8E;IAE9E,SAAS,CAAC,CAAmF,EAAE,KAAY;QACzG,MAAM,IAAI,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;QACtC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YACrB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC;gBACrB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,KAAK;gBACL,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,SAAS,EAAE,CAAC,CAAC,aAAa;gBAC1B,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;gBAC3B,SAAS,EAAE,GAAG,CAAC,GAAG,GAAG,WAAW,CAAC;gBACjC,MAAM,EAAE,IAAI;aACb,CAAC,CAAA;YACF,sEAAsE;YACtE,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAA;YACzD,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM;gBAAE,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;QACxD,CAAC,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,IAAI,CAAC,MAAe;QAC1B,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa,CAAC,CAAA;QAC1C,MAAM,OAAO,GAAG,YAAY,CAAC,cAAc,CAAC,CAAA;QAC5C,OAAO;YACL,MAAM;YACN,OAAO;YACP,IAAI,EAAE;gBACJ,YAAY,EAAE,MAAM;gBACpB,UAAU,EAAE,QAAQ;gBACpB,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC5C,aAAa,EAAE,OAAO;gBACtB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;aACxB;SACF,CAAA;IACH,CAAC;IAED,6EAA6E;IAC7E,YAAY,CAAC,GAA0B;QACrC,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;QACnC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAe,EAAE;YACzC,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;YAChD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAA;YAChG,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,WAAW,CAAC;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAA;YACnF,2FAA2F;YAC3F,IAAI,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC,cAAc,CAAC;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAA;YACzF,+FAA+F;YAC/F,IAAI,aAAa,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,KAAK,GAAG,CAAC,SAAS;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAA;YACvG,qEAAqE;YACrE,gEAAgE;YAChE,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;YAErB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACvD,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;gBACZ,EAAE,EAAE,UAAU,EAAE;gBAChB,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC;gBAC7B,WAAW,EAAE,SAAS,CAAC,OAAO,CAAC;gBAC/B,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,eAAe,EAAE,GAAG,CAAC,GAAG,GAAG,aAAa,CAAC;gBACzC,gBAAgB,EAAE,GAAG,CAAC,GAAG,GAAG,cAAc,CAAC;gBAC3C,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC;gBACnB,UAAU,EAAE,IAAI;gBAChB,SAAS,EAAE,IAAI;aAChB,CAAC,CAAA;YACF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;QAC3B,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,2EAA2E;IAC3E,OAAO,CAAC,GAA0B;QAChC,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAA;QAC5C,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAe,EAAE;YACzC,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,CAAA;YACxD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,CAAC;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAA;YAC1G,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,QAAQ;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAA;YACvG,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACvD,GAAG,CAAC,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;YAClC,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;YACpC,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,GAAG,GAAG,aAAa,CAAC,CAAA;YAC9C,GAAG,CAAC,gBAAgB,GAAG,GAAG,CAAC,GAAG,GAAG,cAAc,CAAC,CAAA;YAChD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;QAC3B,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,8EAA8E;IAE9E;;;;OAIG;IACH,eAAe;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAUrB,CAAA;QACH,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,gBAAgB,EAAE,GAAG,CAAC;gBAAE,SAAQ;YAC1D,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI;gBACtC,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,IAAI,WAAW;gBACrE,MAAM,EAAE,IAAI,GAAG,EAAS;gBACxB,MAAM,EAAE,IAAI,GAAG,EAAU;gBACzB,WAAW,EAAE,CAAC,CAAC,SAAS;gBACxB,UAAU,EAAE,IAAI;aACjB,CAAA;YACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;gBAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YAC3C,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK;gBAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YAChD,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,WAAW;gBAAE,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,SAAS,CAAA;YAChE,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;gBAAE,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAA;YACrG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;QAC/B,CAAC;QACD,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;aAC1B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;aAC1D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,MAAM,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;YACrB,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB,CAAC,CAAC,CAAA;IACP,CAAC;IAED,4EAA4E;IAC5E,gBAAgB,CAAC,QAAgB;QAC/B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAAE,OAAO,KAAK,CAAA;QAC1F,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YAC5B,IAAI,CAAC,GAAG,CAAC,CAAA;YACT,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;gBACzB,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;oBAC5C,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;oBACtB,CAAC,EAAE,CAAA;gBACL,CAAC;YACH,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,CAAA;QACd,CAAC,CAAC,CAAA;IACJ,CAAC;CACF;AAED,MAAM,UAAU,aAAa,CAAC,MAA0B;IACtD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACxB,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC7C,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACxC,CAAC"}
package/dist/auth.d.ts CHANGED
@@ -13,7 +13,7 @@
13
13
  * The check uses the route the router matched and a normalized path,
14
14
  * never the raw URL, see requiresSession().
15
15
  */
16
- import type { FastifyInstance } from 'fastify';
16
+ import type { FastifyInstance, FastifyRequest } from 'fastify';
17
17
  export interface TAuthConfig {
18
18
  enabled: boolean;
19
19
  issuer: string | null;
@@ -51,13 +51,21 @@ export declare function acceptPictureClaim(issuer: string | null, picture: unkno
51
51
  */
52
52
  export declare function acceptNameClaim(name: unknown): string | undefined;
53
53
  /**
54
- * The browser-facing origin for an issuer. PLATFORM_AUTH_ORIGIN wins when it
55
- * is set. Otherwise Nubisco's own issuer maps to Accord's auth host, so an
56
- * install that only sets PLATFORM_ISSUER keeps a working account switcher,
57
- * and any other issuer is its own auth host.
54
+ * The browser-facing origin: where sign-in, sign-out and the account switcher
55
+ * go. PLATFORM_AUTH_ORIGIN when it is set, otherwise the issuer itself. Set it
56
+ * like the issuer, in the install's environment (for Nubisco's own bridge,
57
+ * https://auth.nubisco.io).
58
58
  */
59
59
  export declare function resolveAuthOrigin(issuer: string | null, configured: string | undefined): string | null;
60
60
  export declare function loadAuthConfig(): TAuthConfig;
61
+ /**
62
+ * The signed-in person behind a request, from the session cookie, or null.
63
+ * Always null when sign-in is off, because then there is nobody to be.
64
+ */
65
+ export declare function readSession(config: TAuthConfig, req: FastifyRequest): {
66
+ userId: string;
67
+ email: string;
68
+ } | null;
61
69
  export declare function registerAuthRoutes(app: FastifyInstance, config: TAuthConfig): Promise<void>;
62
70
  /**
63
71
  * Reduce a request path to the form the gate compares against, so that no
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAA;AAS9D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB;;;;OAIG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;CACf;AAYD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAc9F;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAKjE;AA+BD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAKtG;AAED,wBAAgB,cAAc,IAAI,WAAW,CAW5C;AAkCD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwFjG;AASD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0BlE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKrF"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAS9D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB;;;;OAIG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;CACf;AAYD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAc9F;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAKjE;AA2BD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAItG;AAED,wBAAgB,cAAc,IAAI,WAAW,CAW5C;AA8BD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,cAAc,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAK9G;AAMD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwFjG;AASD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0BlE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKrF"}