@modelprofile.com/authswitch 6.3.0 → 6.4.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.
Files changed (40) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/authority-contract.d.ts +142 -0
  3. package/dist_ts/authority-contract.js +3 -0
  4. package/dist_ts/authority-runtime-contract.d.ts +32 -0
  5. package/dist_ts/authority-runtime-contract.js +2 -0
  6. package/dist_ts/classes.authoritybroker.d.ts +73 -0
  7. package/dist_ts/classes.authoritybroker.js +548 -0
  8. package/dist_ts/classes.authorityclient.d.ts +34 -0
  9. package/dist_ts/classes.authorityclient.js +200 -0
  10. package/dist_ts/classes.authoritydaemon.d.ts +26 -0
  11. package/dist_ts/classes.authoritydaemon.js +249 -0
  12. package/dist_ts/classes.authoritydatabase.d.ts +94 -0
  13. package/dist_ts/classes.authoritydatabase.js +736 -0
  14. package/dist_ts/classes.authorityframing.d.ts +8 -0
  15. package/dist_ts/classes.authorityframing.js +22 -0
  16. package/dist_ts/classes.authoritymodels.d.ts +215 -0
  17. package/dist_ts/classes.authoritymodels.js +818 -0
  18. package/dist_ts/classes.authoritysecrets.d.ts +9 -0
  19. package/dist_ts/classes.authoritysecrets.js +30 -0
  20. package/dist_ts/classes.authorityservice.d.ts +28 -0
  21. package/dist_ts/classes.authorityservice.js +71 -0
  22. package/dist_ts/index.d.ts +2 -0
  23. package/dist_ts/index.js +26 -1
  24. package/dist_ts/plugins.d.ts +9 -2
  25. package/dist_ts/plugins.js +10 -3
  26. package/package.json +17 -3
  27. package/readme.md +34 -0
  28. package/ts/00_commitinfo_data.ts +1 -1
  29. package/ts/authority-contract.ts +109 -0
  30. package/ts/authority-runtime-contract.ts +27 -0
  31. package/ts/classes.authoritybroker.ts +530 -0
  32. package/ts/classes.authorityclient.ts +183 -0
  33. package/ts/classes.authoritydaemon.ts +219 -0
  34. package/ts/classes.authoritydatabase.ts +725 -0
  35. package/ts/classes.authorityframing.ts +21 -0
  36. package/ts/classes.authoritymodels.ts +367 -0
  37. package/ts/classes.authoritysecrets.ts +27 -0
  38. package/ts/classes.authorityservice.ts +83 -0
  39. package/ts/index.ts +25 -0
  40. package/ts/plugins.ts +9 -2
@@ -0,0 +1,34 @@
1
+ import type { IAuthSwitchAccountEvent, IAuthSwitchSnapshot, IReq_AuthSwitchBeginAdd, IReq_AuthSwitchBeginReauth, IReq_AuthSwitchCancelOperation, IReq_AuthSwitchEvents, IReq_AuthSwitchGetOperation, IReq_AuthSwitchRemoveAccount, IReq_AuthSwitchRenameAccount, IReq_AuthSwitchSnapshot } from './authority-contract.js';
2
+ import type { IReq_AuthSwitchBindAccount, IReq_AuthSwitchResolveAccess } from './authority-runtime-contract.js';
3
+ /** Node-only client for the per-user daemon. Each request has its own bounded Unix connection. */
4
+ export declare class AuthSwitchClient {
5
+ readonly socketPath: string;
6
+ readonly runtimeSocketPath: string;
7
+ private readonly target;
8
+ private readonly runtimeTarget;
9
+ constructor(socketPath: string, runtimeSocketPath: string);
10
+ private request;
11
+ snapshot(options?: IReq_AuthSwitchSnapshot['request'], signal?: AbortSignal): Promise<IAuthSwitchSnapshot>;
12
+ /** Assemble a consistent view from bounded database pages; restart if a writer changes the revision. */
13
+ snapshotAll(options?: {
14
+ limit?: number;
15
+ signal?: AbortSignal;
16
+ }): Promise<IAuthSwitchSnapshot>;
17
+ events(epoch: string, afterRevision: number, waitMs?: number, signal?: AbortSignal): Promise<IReq_AuthSwitchEvents['response']>;
18
+ /** Always obtains a fresh snapshot after reconnect or an event-log gap. */
19
+ subscribe(onSnapshot: (snapshot: IAuthSwitchSnapshot) => void | Promise<void>, onEvent: (event: IAuthSwitchAccountEvent) => void | Promise<void>, signal: AbortSignal): Promise<void>;
20
+ beginAddOpenAi(): Promise<IReq_AuthSwitchBeginAdd['response']['operation']>;
21
+ beginReauthOpenAi(accountId: string): Promise<IReq_AuthSwitchBeginReauth['response']['operation']>;
22
+ getOperation(operationId: string): Promise<IReq_AuthSwitchGetOperation['response']['operation']>;
23
+ cancelOperation(operationId: string): Promise<IReq_AuthSwitchCancelOperation['response']['operation']>;
24
+ renameAccount(accountId: string, expectedRevision: number, label: string): Promise<IReq_AuthSwitchRenameAccount['response']['account']>;
25
+ removeAccount(accountId: string, expectedRevision: number): Promise<IReq_AuthSwitchRemoveAccount['response']['account']>;
26
+ bindAccount(input: IReq_AuthSwitchBindAccount['request']): Promise<IReq_AuthSwitchBindAccount['response']>;
27
+ resolveAccess(input: IReq_AuthSwitchResolveAccess['request']): Promise<IReq_AuthSwitchResolveAccess['response']>;
28
+ }
29
+ /** Container-facing client. It can only resolve a previously issued binding capability. */
30
+ export declare class AuthSwitchRuntimeClient {
31
+ private readonly target;
32
+ constructor(runtimeSocketPath: string);
33
+ resolveAccess(input: IReq_AuthSwitchResolveAccess['request']): Promise<IReq_AuthSwitchResolveAccess['response']>;
34
+ }
@@ -0,0 +1,200 @@
1
+ import * as plugins from './plugins.js';
2
+ import { AuthSwitchAuthorityFrameReader, authSwitchAuthorityFrameBytes, maxAuthSwitchAuthorityFrameBytes } from './classes.authorityframing.js';
3
+ const post = (path, payload, signal) => {
4
+ return new Promise((resolve, reject) => {
5
+ if (signal?.aborted) {
6
+ reject(signal.reason);
7
+ return;
8
+ }
9
+ const socket = plugins.net.createConnection(path);
10
+ let settled = false;
11
+ const frame = new AuthSwitchAuthorityFrameReader();
12
+ const finish = (error, response) => {
13
+ if (settled)
14
+ return;
15
+ settled = true;
16
+ signal?.removeEventListener('abort', abort);
17
+ socket.destroy();
18
+ if (error)
19
+ reject(error);
20
+ else if (response)
21
+ resolve(response);
22
+ else
23
+ reject(new Error('Authswitch daemon returned no response.'));
24
+ };
25
+ const abort = () => finish(signal?.reason ?? new Error('Account request was cancelled.'));
26
+ signal?.addEventListener('abort', abort, { once: true });
27
+ socket.setTimeout(35_000, () => finish(new Error('Authswitch daemon request timed out.')));
28
+ socket.on('connect', () => {
29
+ const raw = JSON.stringify(payload);
30
+ if (authSwitchAuthorityFrameBytes(raw) > maxAuthSwitchAuthorityFrameBytes) {
31
+ finish(new Error('Account request is too large.'));
32
+ return;
33
+ }
34
+ socket.write(raw + '\n');
35
+ });
36
+ socket.on('data', chunk => {
37
+ if (!Buffer.isBuffer(chunk)) {
38
+ finish(new Error('Account response must be a byte frame.'));
39
+ return;
40
+ }
41
+ let input;
42
+ try {
43
+ input = frame.add(chunk);
44
+ }
45
+ catch (error) {
46
+ finish(error);
47
+ return;
48
+ }
49
+ if (input === null)
50
+ return;
51
+ try {
52
+ finish(undefined, JSON.parse(input));
53
+ }
54
+ catch {
55
+ finish(new Error('Account response could not be decoded.'));
56
+ }
57
+ });
58
+ socket.on('error', () => finish(new Error('Authswitch daemon is unavailable.')));
59
+ socket.on('close', () => finish(new Error('Authswitch daemon connection closed before its response.')));
60
+ });
61
+ };
62
+ /** Node-only client for the per-user daemon. Each request has its own bounded Unix connection. */
63
+ export class AuthSwitchClient {
64
+ socketPath;
65
+ runtimeSocketPath;
66
+ target;
67
+ runtimeTarget;
68
+ constructor(socketPath, runtimeSocketPath) {
69
+ this.socketPath = socketPath;
70
+ this.runtimeSocketPath = runtimeSocketPath;
71
+ this.target = new plugins.typedrequest.TypedTarget({
72
+ supportsAbortSignal: true,
73
+ postMethod: (payload, options) => post(this.socketPath, payload, options?.signal),
74
+ });
75
+ this.runtimeTarget = new plugins.typedrequest.TypedTarget({
76
+ supportsAbortSignal: true,
77
+ postMethod: (payload, options) => post(this.runtimeSocketPath, payload, options?.signal),
78
+ });
79
+ }
80
+ request(method, request, timeoutMs = 35_000, runtime = false, signal) {
81
+ return new plugins.typedrequest.TypedRequest(runtime ? this.runtimeTarget : this.target, method)
82
+ .fire(request, { timeoutMs, maxRetries: 0, abortSignal: signal });
83
+ }
84
+ async snapshot(options = {}, signal) {
85
+ return (await this.request('authswitch.authority.snapshot', options, 35_000, false, signal)).snapshot;
86
+ }
87
+ /** Assemble a consistent view from bounded database pages; restart if a writer changes the revision. */
88
+ async snapshotAll(options = {}) {
89
+ while (true) {
90
+ if (options.signal?.aborted)
91
+ throw options.signal.reason ?? new Error('Account snapshot cancelled.');
92
+ let accountAfter;
93
+ let bindingAfter;
94
+ let aggregate;
95
+ let changed = false;
96
+ while (true) {
97
+ const page = await this.snapshot({ accountAfter, bindingAfter, limit: options.limit }, options.signal);
98
+ if (!aggregate)
99
+ aggregate = { ...page, accounts: [...page.accounts], bindings: [...page.bindings] };
100
+ else if (aggregate.epoch !== page.epoch || aggregate.revision !== page.revision) {
101
+ changed = true;
102
+ break;
103
+ }
104
+ else {
105
+ aggregate.accounts.push(...page.accounts);
106
+ aggregate.bindings.push(...page.bindings);
107
+ }
108
+ accountAfter = page.nextAccountCursor ?? accountAfter ?? page.accounts.at(-1)?.id;
109
+ bindingAfter = page.nextBindingCursor ?? bindingAfter ?? page.bindings.at(-1)?.id;
110
+ if (!page.nextAccountCursor && !page.nextBindingCursor) {
111
+ return { ...aggregate, nextAccountCursor: null, nextBindingCursor: null };
112
+ }
113
+ }
114
+ if (!changed)
115
+ throw new Error('Authority snapshot could not complete.');
116
+ }
117
+ }
118
+ events(epoch, afterRevision, waitMs = 30_000, signal) {
119
+ return this.request('authswitch.authority.events', { epoch, afterRevision, waitMs }, waitMs + 5_000, false, signal);
120
+ }
121
+ /** Always obtains a fresh snapshot after reconnect or an event-log gap. */
122
+ async subscribe(onSnapshot, onEvent, signal) {
123
+ const retry = () => new Promise(resolve => {
124
+ const timer = setTimeout(() => { signal.removeEventListener('abort', aborted); resolve(); }, 250);
125
+ const aborted = () => { clearTimeout(timer); resolve(); };
126
+ signal.addEventListener('abort', aborted, { once: true });
127
+ });
128
+ let snapshot;
129
+ while (!signal.aborted) {
130
+ if (!snapshot) {
131
+ try {
132
+ snapshot = await this.snapshotAll({ signal });
133
+ }
134
+ catch {
135
+ if (signal.aborted)
136
+ break;
137
+ await retry();
138
+ continue;
139
+ }
140
+ await onSnapshot(snapshot);
141
+ }
142
+ let result;
143
+ try {
144
+ result = await this.events(snapshot.epoch, snapshot.revision, 30_000, signal);
145
+ }
146
+ catch {
147
+ if (signal.aborted)
148
+ break;
149
+ snapshot = undefined;
150
+ await retry();
151
+ continue;
152
+ }
153
+ if (result.resyncRequired || result.epoch !== snapshot.epoch) {
154
+ snapshot = undefined;
155
+ continue;
156
+ }
157
+ for (const event of result.events)
158
+ await onEvent(event);
159
+ snapshot = { ...snapshot, revision: result.revision };
160
+ }
161
+ }
162
+ async beginAddOpenAi() {
163
+ return (await this.request('authswitch.authority.add', { providerId: 'openai', flow: 'device' })).operation;
164
+ }
165
+ async beginReauthOpenAi(accountId) {
166
+ return (await this.request('authswitch.authority.reauth', { accountId, flow: 'device' })).operation;
167
+ }
168
+ async getOperation(operationId) {
169
+ return (await this.request('authswitch.authority.operation', { operationId })).operation;
170
+ }
171
+ async cancelOperation(operationId) {
172
+ return (await this.request('authswitch.authority.cancel', { operationId })).operation;
173
+ }
174
+ async renameAccount(accountId, expectedRevision, label) {
175
+ return (await this.request('authswitch.authority.rename', { accountId, expectedRevision, label })).account;
176
+ }
177
+ async removeAccount(accountId, expectedRevision) {
178
+ return (await this.request('authswitch.authority.remove', { accountId, expectedRevision })).account;
179
+ }
180
+ bindAccount(input) {
181
+ return this.request('authswitch.authority.bind', input);
182
+ }
183
+ resolveAccess(input) {
184
+ return this.request('authswitch.authority.resolveAccess', input, 35_000, true);
185
+ }
186
+ }
187
+ /** Container-facing client. It can only resolve a previously issued binding capability. */
188
+ export class AuthSwitchRuntimeClient {
189
+ target;
190
+ constructor(runtimeSocketPath) {
191
+ this.target = new plugins.typedrequest.TypedTarget({
192
+ supportsAbortSignal: true,
193
+ postMethod: (payload, options) => post(runtimeSocketPath, payload, options?.signal),
194
+ });
195
+ }
196
+ resolveAccess(input) {
197
+ return new plugins.typedrequest.TypedRequest(this.target, 'authswitch.authority.resolveAccess').fire(input, { timeoutMs: 35_000, maxRetries: 0 });
198
+ }
199
+ }
200
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hdXRob3JpdHljbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmF1dGhvcml0eWNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQVF4QyxPQUFPLEVBQUUsOEJBQThCLEVBQUUsNkJBQTZCLEVBQ3BFLGdDQUFnQyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFMUUsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFZLEVBQUUsT0FBc0IsRUFBRSxNQUFvQixFQUEwQixFQUFFO0lBQ2hHLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsSUFBSSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQUMsT0FBTztRQUFDLENBQUM7UUFDdkQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsRCxJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDcEIsTUFBTSxLQUFLLEdBQUcsSUFBSSw4QkFBOEIsRUFBRSxDQUFDO1FBQ25ELE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBZSxFQUFFLFFBQXdCLEVBQVEsRUFBRTtZQUNqRSxJQUFJLE9BQU87Z0JBQUUsT0FBTztZQUNwQixPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQ2YsTUFBTSxFQUFFLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM1QyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsSUFBSSxLQUFLO2dCQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDcEIsSUFBSSxRQUFRO2dCQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQzs7Z0JBQ2hDLE1BQU0sQ0FBQyxJ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
@@ -0,0 +1,26 @@
1
+ import { AuthSwitchAuthorityBroker, type IAuthSwitchAuthorityBrokerOptions } from './classes.authoritybroker.js';
2
+ import { AuthSwitchAuthorityDatabase, type IAuthSwitchAuthorityDatabaseOptions } from './classes.authoritydatabase.js';
3
+ export interface IAuthSwitchAuthorityDaemonOptions extends IAuthSwitchAuthorityDatabaseOptions {
4
+ authoritySocketPath: string;
5
+ runtimeSocketPath: string;
6
+ broker?: IAuthSwitchAuthorityBrokerOptions;
7
+ }
8
+ /** TypedRequest handlers over a private one-request-per-connection Unix socket. */
9
+ export declare class AuthSwitchAuthorityDaemon {
10
+ private readonly options;
11
+ readonly database: AuthSwitchAuthorityDatabase;
12
+ readonly broker: AuthSwitchAuthorityBroker;
13
+ private readonly managementRouter;
14
+ private readonly runtimeRouter;
15
+ private managementServer?;
16
+ private runtimeServer?;
17
+ private readonly sockets;
18
+ constructor(options: IAuthSwitchAuthorityDaemonOptions);
19
+ private register;
20
+ start(): Promise<void>;
21
+ private listen;
22
+ /** A killed daemon leaves a pathname behind; only remove an unchanged, owned, refused Unix socket. */
23
+ private clearStaleSocket;
24
+ private accept;
25
+ close(): Promise<void>;
26
+ }
@@ -0,0 +1,249 @@
1
+ import * as plugins from './plugins.js';
2
+ import { AuthSwitchAuthorityBroker } from './classes.authoritybroker.js';
3
+ import { AuthSwitchAuthorityDatabase } from './classes.authoritydatabase.js';
4
+ import { AuthSwitchAuthorityFrameReader, authSwitchAuthorityFrameBytes, maxAuthSwitchAuthorityFrameBytes } from './classes.authorityframing.js';
5
+ const hasKeys = (value, keys) => value !== null && typeof value === 'object' && !Array.isArray(value)
6
+ && Object.keys(value).length === keys.length && keys.every(key => Object.hasOwn(value, key));
7
+ const invalid = () => { throw new plugins.typedrequest.TypedResponseError('Invalid authswitch authority request.'); };
8
+ /** TypedRequest handlers over a private one-request-per-connection Unix socket. */
9
+ export class AuthSwitchAuthorityDaemon {
10
+ options;
11
+ database;
12
+ broker;
13
+ managementRouter = new plugins.typedrequest.TypedRouter();
14
+ runtimeRouter = new plugins.typedrequest.TypedRouter();
15
+ managementServer;
16
+ runtimeServer;
17
+ sockets = new Set();
18
+ constructor(options) {
19
+ this.options = options;
20
+ this.database = new AuthSwitchAuthorityDatabase(options);
21
+ this.broker = new AuthSwitchAuthorityBroker(this.database, options.broker);
22
+ this.register();
23
+ }
24
+ register() {
25
+ this.managementRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('authswitch.authority.snapshot', async (request) => {
26
+ if (request === null || typeof request !== 'object' || Array.isArray(request))
27
+ invalid();
28
+ const keys = Object.keys(request);
29
+ if (keys.some(key => !['accountAfter', 'bindingAfter', 'limit'].includes(key)))
30
+ invalid();
31
+ return { snapshot: await this.broker.snapshot(request) };
32
+ }));
33
+ this.managementRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('authswitch.authority.events', async (request, tools) => {
34
+ if (!hasKeys(request, ['epoch', 'afterRevision', 'waitMs']))
35
+ invalid();
36
+ return this.broker.events(request.epoch, request.afterRevision, request.waitMs, tools?.abortSignal);
37
+ }));
38
+ this.managementRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('authswitch.authority.add', async (request) => {
39
+ if (!hasKeys(request, ['providerId', 'flow']) || request.providerId !== 'openai' || request.flow !== 'device')
40
+ invalid();
41
+ return { operation: await this.broker.beginAddOpenAi() };
42
+ }));
43
+ this.managementRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('authswitch.authority.reauth', async (request) => {
44
+ if (!hasKeys(request, ['accountId', 'flow']) || request.flow !== 'device' || typeof request.accountId !== 'string')
45
+ invalid();
46
+ return { operation: await this.broker.beginReauthOpenAi(request.accountId) };
47
+ }));
48
+ this.managementRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('authswitch.authority.operation', async (request) => {
49
+ if (!hasKeys(request, ['operationId']) || typeof request.operationId !== 'string')
50
+ invalid();
51
+ return { operation: this.broker.getOperation(request.operationId) };
52
+ }));
53
+ this.managementRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('authswitch.authority.cancel', async (request) => {
54
+ if (!hasKeys(request, ['operationId']) || typeof request.operationId !== 'string')
55
+ invalid();
56
+ return { operation: await this.broker.cancelOperation(request.operationId) };
57
+ }));
58
+ this.managementRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('authswitch.authority.rename', async (request) => {
59
+ if (!hasKeys(request, ['accountId', 'expectedRevision', 'label']) || typeof request.accountId !== 'string'
60
+ || typeof request.expectedRevision !== 'number' || typeof request.label !== 'string')
61
+ invalid();
62
+ return { account: await this.broker.renameAccount(request.accountId, request.expectedRevision, request.label) };
63
+ }));
64
+ this.managementRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('authswitch.authority.remove', async (request) => {
65
+ if (!hasKeys(request, ['accountId', 'expectedRevision']) || typeof request.accountId !== 'string'
66
+ || typeof request.expectedRevision !== 'number')
67
+ invalid();
68
+ return { account: await this.broker.removeAccount(request.accountId, request.expectedRevision) };
69
+ }));
70
+ this.managementRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('authswitch.authority.bind', async (request) => {
71
+ if (!hasKeys(request, ['accountId', 'runtime', 'scopeId', 'incarnationId'])
72
+ || typeof request.accountId !== 'string' || typeof request.scopeId !== 'string'
73
+ || typeof request.incarnationId !== 'string')
74
+ invalid();
75
+ return this.broker.bindAccount(request);
76
+ }));
77
+ this.runtimeRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('authswitch.authority.resolveAccess', async (request) => {
78
+ if (!hasKeys(request, ['bindingId', 'capability', 'minValidityMs'])
79
+ || typeof request.bindingId !== 'string' || typeof request.capability !== 'string'
80
+ || typeof request.minValidityMs !== 'number')
81
+ invalid();
82
+ return this.broker.resolveAccess(request.bindingId, request.capability, request.minValidityMs);
83
+ }));
84
+ }
85
+ async start() {
86
+ if (this.managementServer || this.runtimeServer)
87
+ throw new Error('Authswitch authority daemon is already started.');
88
+ await this.database.start();
89
+ try {
90
+ await this.broker.start();
91
+ const managementDirectory = plugins.path.dirname(this.options.authoritySocketPath);
92
+ const runtimeDirectory = plugins.path.dirname(this.options.runtimeSocketPath);
93
+ const databaseDirectory = plugins.path.dirname(this.options.socketPath);
94
+ if (managementDirectory === runtimeDirectory || databaseDirectory === runtimeDirectory
95
+ || managementDirectory.startsWith(runtimeDirectory + plugins.path.sep)
96
+ || databaseDirectory.startsWith(runtimeDirectory + plugins.path.sep)
97
+ || runtimeDirectory.startsWith(managementDirectory + plugins.path.sep)
98
+ || runtimeDirectory.startsWith(databaseDirectory + plugins.path.sep)) {
99
+ throw new Error('Runtime socket directory must contain no management or database endpoint.');
100
+ }
101
+ this.managementServer = await this.listen(this.options.authoritySocketPath, this.managementRouter);
102
+ this.runtimeServer = await this.listen(this.options.runtimeSocketPath, this.runtimeRouter);
103
+ }
104
+ catch (error) {
105
+ try {
106
+ await this.close();
107
+ }
108
+ catch { /* Preserve startup failure. */ }
109
+ throw error;
110
+ }
111
+ }
112
+ async listen(path, router) {
113
+ const directory = plugins.path.dirname(path);
114
+ await plugins.fs.promises.mkdir(directory, { recursive: true, mode: 0o700 });
115
+ const stat = await plugins.fs.promises.lstat(directory);
116
+ if (!stat.isDirectory() || stat.isSymbolicLink() || stat.uid !== process.getuid?.()) {
117
+ throw new Error('Authswitch authority socket directory is not private.');
118
+ }
119
+ await plugins.fs.promises.chmod(directory, 0o700);
120
+ await this.clearStaleSocket(path);
121
+ const server = plugins.net.createServer(socket => this.accept(socket, router));
122
+ try {
123
+ await new Promise((resolve, reject) => {
124
+ server.once('error', reject);
125
+ server.listen(path, () => { server.off('error', reject); resolve(); });
126
+ });
127
+ await plugins.fs.promises.chmod(path, 0o600);
128
+ return server;
129
+ }
130
+ catch (error) {
131
+ if (server.listening)
132
+ await new Promise(resolve => server.close(() => resolve()));
133
+ throw error;
134
+ }
135
+ }
136
+ /** A killed daemon leaves a pathname behind; only remove an unchanged, owned, refused Unix socket. */
137
+ async clearStaleSocket(path) {
138
+ let before;
139
+ try {
140
+ before = await plugins.fs.promises.lstat(path);
141
+ }
142
+ catch (error) {
143
+ if (error.code === 'ENOENT')
144
+ return;
145
+ throw error;
146
+ }
147
+ if (!before.isSocket() || before.uid !== process.getuid?.())
148
+ throw new Error('Authswitch socket path is unsafe.');
149
+ const refused = await new Promise((resolve, reject) => {
150
+ const probe = plugins.net.createConnection(path);
151
+ probe.setTimeout(1_000, () => { probe.destroy(); reject(new Error('Authswitch socket probe timed out.')); });
152
+ probe.once('connect', () => { probe.destroy(); resolve(false); });
153
+ probe.once('error', error => {
154
+ probe.destroy();
155
+ if (error.code === 'ECONNREFUSED')
156
+ resolve(true);
157
+ else
158
+ reject(error);
159
+ });
160
+ });
161
+ if (!refused)
162
+ throw new Error('Authswitch authority socket is already active.');
163
+ const after = await plugins.fs.promises.lstat(path);
164
+ if (!after.isSocket() || after.uid !== before.uid || after.dev !== before.dev || after.ino !== before.ino) {
165
+ throw new Error('Authswitch socket path changed during startup.');
166
+ }
167
+ await plugins.fs.promises.unlink(path);
168
+ }
169
+ accept(socket, router) {
170
+ this.sockets.add(socket);
171
+ const abort = new AbortController();
172
+ socket.on('close', () => { this.sockets.delete(socket); abort.abort(); });
173
+ const frame = new AuthSwitchAuthorityFrameReader();
174
+ let handled = false;
175
+ socket.setTimeout(35_000, () => socket.destroy());
176
+ socket.on('data', chunk => {
177
+ if (handled) {
178
+ socket.destroy();
179
+ return;
180
+ }
181
+ if (!Buffer.isBuffer(chunk)) {
182
+ socket.destroy();
183
+ return;
184
+ }
185
+ let input;
186
+ try {
187
+ input = frame.add(chunk);
188
+ }
189
+ catch {
190
+ socket.destroy();
191
+ return;
192
+ }
193
+ if (input === null)
194
+ return;
195
+ handled = true;
196
+ let request;
197
+ try {
198
+ request = JSON.parse(input);
199
+ }
200
+ catch {
201
+ socket.destroy();
202
+ return;
203
+ }
204
+ void router.routeAndAddResponse(request, { trustedLocalData: { authoritySocket: socket },
205
+ trustedAbortSignal: abort.signal })
206
+ .then(response => {
207
+ const raw = JSON.stringify(response);
208
+ if (authSwitchAuthorityFrameBytes(raw) > maxAuthSwitchAuthorityFrameBytes) {
209
+ socket.destroy();
210
+ return;
211
+ }
212
+ socket.end(raw + '\n');
213
+ }).catch(() => socket.destroy());
214
+ });
215
+ }
216
+ async close() {
217
+ const errors = [];
218
+ try {
219
+ await this.broker.close();
220
+ }
221
+ catch (error) {
222
+ errors.push(error);
223
+ }
224
+ const management = this.managementServer;
225
+ const runtime = this.runtimeServer;
226
+ this.managementServer = undefined;
227
+ this.runtimeServer = undefined;
228
+ for (const socket of this.sockets)
229
+ socket.destroy();
230
+ for (const server of [management, runtime]) {
231
+ if (server)
232
+ try {
233
+ await new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve()));
234
+ }
235
+ catch (error) {
236
+ errors.push(error);
237
+ }
238
+ }
239
+ try {
240
+ await this.database.stop();
241
+ }
242
+ catch (error) {
243
+ errors.push(error);
244
+ }
245
+ if (errors.length)
246
+ throw new AggregateError(errors, 'Authswitch authority shutdown was incomplete.');
247
+ }
248
+ }
249
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hdXRob3JpdHlkYWVtb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmF1dGhvcml0eWRhZW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQU94QyxPQUFPLEVBQUUseUJBQXlCLEVBQTBDLE1BQU0sOEJBQThCLENBQUM7QUFDakgsT0FBTyxFQUFFLDJCQUEyQixFQUE0QyxNQUFNLGdDQUFnQyxDQUFDO0FBQ3ZILE9BQU8sRUFBRSw4QkFBOEIsRUFBRSw2QkFBNkIsRUFDcEUsZ0NBQWdDLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQVExRSxNQUFNLE9BQU8sR0FBRyxDQUFDLEtBQWMsRUFBRSxJQUF1QixFQUFvQyxFQUFFLENBQzVGLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7T0FDakUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUMvRixNQUFNLE9BQU8sR0FBRyxHQUFVLEVBQUUsR0FBRyxNQUFNLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRTdILG1GQUFtRjtBQUNuRixNQUFNLE9BQU8seUJBQXlCO0lBU1A7SUFSYixRQUFRLENBQThCO0lBQ3RDLE1BQU0sQ0FBNEI7SUFDakMsZ0JBQWdCLEdBQUcsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQzFELGFBQWEsR0FBRyxJQUFJLE9BQU8s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