@calimero-network/mero-js 22.7.0 → 22.9.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/dist/account/account.d.ts +99 -4
- package/dist/account/account.js +0 -0
- package/dist/account/index.d.ts +6 -2
- package/dist/account/index.js +3 -1
- package/dist/admin-api/admin-client.d.ts +154 -2
- package/dist/admin-api/admin-client.js +255 -1
- package/dist/admin-api/admin-types.d.ts +193 -5
- package/dist/cloud/cloud-client.d.ts +38 -8
- package/dist/cloud/cloud-client.js +38 -21
- package/dist/cloud/connect.d.ts +101 -2
- package/dist/cloud/connect.js +84 -8
- package/dist/cloud/enrol-redirect.d.ts +195 -0
- package/dist/cloud/enrol-redirect.js +236 -0
- package/dist/cloud/index.d.ts +6 -2
- package/dist/cloud/index.js +7 -1
- package/dist/cloud/link-redirect.d.ts +85 -0
- package/dist/cloud/link-redirect.js +105 -0
- package/dist/crypto/internal.d.ts +15 -0
- package/dist/crypto/internal.js +18 -0
- package/dist/device-cert/device-cert.d.ts +96 -2
- package/dist/device-cert/device-cert.js +101 -11
- package/dist/device-cert/device-scope.d.ts +58 -0
- package/dist/device-cert/device-scope.js +76 -0
- package/dist/device-cert/index.d.ts +4 -2
- package/dist/device-cert/index.js +2 -1
- package/dist/events/sse.d.ts +22 -2
- package/dist/events/sse.js +20 -11
- package/dist/http-client/http-types.d.ts +18 -0
- package/dist/http-client/web-client.js +21 -1
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +1955 -496
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +13 -4
- package/dist/index.js +21 -2
- package/dist/index.mjs +1955 -496
- package/dist/index.mjs.map +4 -4
- package/dist/invitation/index.d.ts +2 -0
- package/dist/invitation/index.js +2 -0
- package/dist/invitation/invitation.d.ts +106 -0
- package/dist/invitation/invitation.js +104 -0
- package/dist/login/login.d.ts +11 -1
- package/dist/login/login.js +5 -4
- package/dist/login/session.d.ts +21 -5
- package/dist/login/session.js +7 -15
- package/dist/namespace-op/namespace-op.d.ts +14 -2
- package/dist/namespace-op/namespace-op.js +13 -19
- package/dist/relay/index.d.ts +2 -2
- package/dist/relay/index.js +1 -1
- package/dist/relay/nonce-source.d.ts +135 -0
- package/dist/relay/nonce-source.js +187 -19
- package/dist/relay/relay-client.d.ts +60 -5
- package/dist/relay/relay-client.js +84 -4
- package/dist/relay-attestation/attest-node-key.d.ts +66 -0
- package/dist/relay-attestation/attest-node-key.js +110 -0
- package/dist/relay-attestation/index.d.ts +1 -0
- package/dist/relay-attestation/index.js +1 -0
- package/dist/request-proof/authorizer.d.ts +48 -0
- package/dist/request-proof/authorizer.js +65 -0
- package/dist/request-proof/index.d.ts +4 -0
- package/dist/request-proof/index.js +2 -0
- package/dist/request-proof/request-proof.d.ts +56 -0
- package/dist/request-proof/request-proof.js +111 -0
- package/dist/rpc/index.d.ts +21 -0
- package/dist/rpc/index.js +20 -0
- package/dist/transport/index.d.ts +6 -0
- package/dist/transport/index.js +3 -0
- package/dist/transport/mero-client.d.ts +286 -0
- package/dist/transport/mero-client.js +379 -0
- package/dist/transport/relay-observer.d.ts +152 -0
- package/dist/transport/relay-observer.js +173 -0
- package/dist/transport/relay-transport.d.ts +73 -0
- package/dist/transport/relay-transport.js +94 -0
- package/dist/transport/types.d.ts +100 -0
- package/dist/transport/types.js +32 -0
- package/package.json +1 -1
package/dist/events/sse.d.ts
CHANGED
|
@@ -19,9 +19,22 @@ type SseEvent = SseEventData | GroupMembershipEventData | GroupMigrationEventDat
|
|
|
19
19
|
type SseEventHandler = (event: SseEvent) => void;
|
|
20
20
|
type SseConnectHandler = (sessionId: string) => void;
|
|
21
21
|
type SseErrorHandler = (error: Error) => void;
|
|
22
|
+
/**
|
|
23
|
+
* How one request to the SSE endpoints is authenticated.
|
|
24
|
+
*
|
|
25
|
+
* A bearer token is one value reused across requests; a request proof commits to
|
|
26
|
+
* the method, the path and the body, so it must be produced per request. Both
|
|
27
|
+
* reduce to the same thing from this client's point of view — headers — so the
|
|
28
|
+
* stream takes the general form and {@link SseClient} adapts `getAuthToken` to it.
|
|
29
|
+
*/
|
|
30
|
+
export type SseAuthorizer = (request: {
|
|
31
|
+
method: string;
|
|
32
|
+
path: string;
|
|
33
|
+
body?: string;
|
|
34
|
+
}) => Promise<Record<string, string>>;
|
|
22
35
|
export declare class SseClient {
|
|
23
36
|
private baseUrl;
|
|
24
|
-
private
|
|
37
|
+
private authorize;
|
|
25
38
|
private reconnectDelayMs;
|
|
26
39
|
private sessionId;
|
|
27
40
|
private abortController;
|
|
@@ -33,7 +46,14 @@ export declare class SseClient {
|
|
|
33
46
|
private fetchImpl;
|
|
34
47
|
constructor(opts: {
|
|
35
48
|
baseUrl: string;
|
|
36
|
-
|
|
49
|
+
/** A bearer token provider. The historical form, and still the default. */
|
|
50
|
+
getAuthToken?: () => Promise<string>;
|
|
51
|
+
/**
|
|
52
|
+
* Per-request authorization, for a credential that commits to the request —
|
|
53
|
+
* a device cert signing a request proof. Takes precedence over
|
|
54
|
+
* `getAuthToken`; one of the two is required.
|
|
55
|
+
*/
|
|
56
|
+
authorize?: SseAuthorizer;
|
|
37
57
|
reconnectDelayMs?: number;
|
|
38
58
|
fetch?: typeof fetch;
|
|
39
59
|
});
|
package/dist/events/sse.js
CHANGED
|
@@ -42,7 +42,16 @@ export class SseClient {
|
|
|
42
42
|
this.closed = false;
|
|
43
43
|
this.listeners = { connect: [], event: [], error: [] };
|
|
44
44
|
this.baseUrl = opts.baseUrl.replace(/\/+$/, '');
|
|
45
|
-
|
|
45
|
+
if (opts.authorize) {
|
|
46
|
+
this.authorize = opts.authorize;
|
|
47
|
+
}
|
|
48
|
+
else if (opts.getAuthToken) {
|
|
49
|
+
const getAuthToken = opts.getAuthToken;
|
|
50
|
+
this.authorize = async () => ({ Authorization: `Bearer ${await getAuthToken()}` });
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
throw new Error('SseClient needs either `getAuthToken` or `authorize`');
|
|
54
|
+
}
|
|
46
55
|
this.reconnectDelayMs = opts.reconnectDelayMs ?? 3000;
|
|
47
56
|
// globalThis.fetch must be called as a method on globalThis, not through a
|
|
48
57
|
// variable, or browsers throw "Illegal invocation".
|
|
@@ -123,11 +132,10 @@ export class SseClient {
|
|
|
123
132
|
this.closed = false;
|
|
124
133
|
this.abortController = new AbortController();
|
|
125
134
|
try {
|
|
126
|
-
const token = await this.getAuthToken();
|
|
127
135
|
const url = `${this.baseUrl}/sse`;
|
|
128
136
|
const response = await this.fetchImpl(url, {
|
|
129
137
|
headers: {
|
|
130
|
-
'
|
|
138
|
+
...(await this.authorize({ method: 'GET', path: new URL(url).pathname })),
|
|
131
139
|
'Accept': 'text/event-stream',
|
|
132
140
|
},
|
|
133
141
|
signal: this.abortController.signal,
|
|
@@ -297,23 +305,24 @@ export class SseClient {
|
|
|
297
305
|
}
|
|
298
306
|
async sendSubscription(method, ids) {
|
|
299
307
|
try {
|
|
300
|
-
const token = await this.getAuthToken();
|
|
301
308
|
const params = {};
|
|
302
309
|
if (ids.contextIds && ids.contextIds.length > 0)
|
|
303
310
|
params.contextIds = ids.contextIds;
|
|
304
311
|
if (ids.groupIds && ids.groupIds.length > 0)
|
|
305
312
|
params.groupIds = ids.groupIds;
|
|
306
|
-
const
|
|
313
|
+
const url = `${this.baseUrl}/sse/subscription`;
|
|
314
|
+
// Serialized once and both signed and sent, because a proof commits to the
|
|
315
|
+
// body: re-stringifying for the signature risks two byte sequences that
|
|
316
|
+
// differ in key order, which fails as a refused credential rather than as
|
|
317
|
+
// anything that names the real cause.
|
|
318
|
+
const body = JSON.stringify({ id: this.sessionId, method, params });
|
|
319
|
+
const response = await this.fetchImpl(url, {
|
|
307
320
|
method: 'POST',
|
|
308
321
|
headers: {
|
|
309
|
-
'
|
|
322
|
+
...(await this.authorize({ method: 'POST', path: new URL(url).pathname, body })),
|
|
310
323
|
'Content-Type': 'application/json',
|
|
311
324
|
},
|
|
312
|
-
body
|
|
313
|
-
id: this.sessionId,
|
|
314
|
-
method,
|
|
315
|
-
params,
|
|
316
|
-
}),
|
|
325
|
+
body,
|
|
317
326
|
});
|
|
318
327
|
if (!response.ok) {
|
|
319
328
|
// The subscribe path used to report only the status. On the one failure
|
|
@@ -4,6 +4,24 @@ export interface Transport {
|
|
|
4
4
|
baseUrl: string;
|
|
5
5
|
defaultHeaders?: Record<string, string>;
|
|
6
6
|
getAuthToken?: () => Promise<string | undefined>;
|
|
7
|
+
/**
|
|
8
|
+
* Per-request authorization, for a credential that commits to the request.
|
|
9
|
+
*
|
|
10
|
+
* `getAuthToken` returns one value reused across requests; a request proof
|
|
11
|
+
* signs the method, the path and the body, so it can only be produced where
|
|
12
|
+
* those are known. This is called with exactly that, and whatever it returns
|
|
13
|
+
* is merged into the headers.
|
|
14
|
+
*
|
|
15
|
+
* It runs AFTER `getAuthToken`, so a transport holding both sends both and
|
|
16
|
+
* lets the node decide — which it does by answering a request carrying a token
|
|
17
|
+
* by that token, and consulting a proof only when there is none.
|
|
18
|
+
*/
|
|
19
|
+
authorizeRequest?: (request: {
|
|
20
|
+
method: string;
|
|
21
|
+
/** The path the node will see, query excluded. */
|
|
22
|
+
path: string;
|
|
23
|
+
body?: string | Uint8Array;
|
|
24
|
+
}) => Promise<Record<string, string>>;
|
|
7
25
|
/**
|
|
8
26
|
* Sign each request instead of, or alongside, presenting a session.
|
|
9
27
|
*
|
|
@@ -193,8 +193,28 @@ export class WebHttpClient {
|
|
|
193
193
|
else {
|
|
194
194
|
headersObj = headers;
|
|
195
195
|
}
|
|
196
|
+
const method = init?.method || 'GET';
|
|
197
|
+
// A credential that commits to the request can only be produced here, where
|
|
198
|
+
// the method, the assembled path and the body are all known. The path comes
|
|
199
|
+
// from the URL rather than from `path`, because a base URL may carry a prefix
|
|
200
|
+
// (`…/admin-api`) that the node sees and a bare relative path would not sign.
|
|
201
|
+
if (this.transport.authorizeRequest) {
|
|
202
|
+
const body = init?.body;
|
|
203
|
+
if (body !== undefined && typeof body !== 'string' && !(body instanceof Uint8Array)) {
|
|
204
|
+
throw new Error('this transport authorizes each request against its body, so the body must be a string ' +
|
|
205
|
+
'or Uint8Array — a stream cannot be signed, because the signature would have to read ' +
|
|
206
|
+
'bytes the request then cannot send.');
|
|
207
|
+
}
|
|
208
|
+
Object.assign(headersObj, await this.transport.authorizeRequest({
|
|
209
|
+
method,
|
|
210
|
+
path: new URL(url).pathname,
|
|
211
|
+
// Narrowed by the guard above; `BodyInit` is wider than what can be
|
|
212
|
+
// signed.
|
|
213
|
+
body: body,
|
|
214
|
+
}));
|
|
215
|
+
}
|
|
196
216
|
const requestInit = {
|
|
197
|
-
method
|
|
217
|
+
method,
|
|
198
218
|
headers: headersObj,
|
|
199
219
|
};
|
|
200
220
|
// Check if body is a stream (ReadableStream) that can't be reused
|