@calimero-network/mero-js 22.1.0 → 22.3.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 +7 -5
- package/dist/cloud/cloud-client.d.ts +44 -14
- package/dist/cloud/cloud-client.js +82 -37
- package/dist/cloud/connect.d.ts +2 -1
- package/dist/cloud/connect.js +23 -12
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +3 -3
- package/dist/index.cjs +113 -45
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +113 -45
- package/dist/index.mjs.map +2 -2
- package/dist/sealed/release.d.ts +16 -4
- package/dist/sealed/release.js +35 -5
- package/package.json +1 -1
package/dist/sealed/release.d.ts
CHANGED
|
@@ -97,6 +97,10 @@ export declare function nodeReleaseVersionFromImage(osImage: string): string;
|
|
|
97
97
|
* `GET /admin-api/tee/info` reports. The node's own claim, and not trusted:
|
|
98
98
|
* it only picks which signed release to fetch, and the quote must then match
|
|
99
99
|
* that release's measurements.
|
|
100
|
+
*
|
|
101
|
+
* `/tee/info` is read in the clear, before any session exists. A node that
|
|
102
|
+
* requires sealing serves it unsealed from core#4196 on; an older one refuses
|
|
103
|
+
* it with `403 sealed_required`, and then this throws saying so.
|
|
100
104
|
*/
|
|
101
105
|
export declare function fetchNodeReleaseVersion(baseUrl: string, options?: {
|
|
102
106
|
fetch?: typeof fetch;
|
|
@@ -172,15 +176,22 @@ export interface SignedReleaseSealedFetchOptions extends Omit<SignedReleaseVerif
|
|
|
172
176
|
* URL of a mirror serving {@link cloudNodeReleaseUrl}'s path, defaulting to
|
|
173
177
|
* {@link DEFAULT_RELEASE_MIRROR}; a function gets the version and returns
|
|
174
178
|
* the release, e.g. from a file bundled with the app. Whichever it is, it is
|
|
175
|
-
* not trusted: the release is verified. `/tee/info` is read in the clear
|
|
176
|
-
*
|
|
177
|
-
* function that ignores `version` and returns the release you expect.
|
|
179
|
+
* not trusted: the release is verified. `/tee/info` is read in the clear;
|
|
180
|
+
* for a node that refuses that, see `releaseVersion`.
|
|
178
181
|
*/
|
|
179
182
|
releaseSource?: string | ((context: {
|
|
180
183
|
baseUrl: string;
|
|
181
184
|
version: string;
|
|
182
185
|
fetch: typeof fetch;
|
|
183
186
|
}) => Promise<SignedNodeRelease>);
|
|
187
|
+
/**
|
|
188
|
+
* The release to fetch when the node will not name one: a node that
|
|
189
|
+
* requires sealing (`[server.sealed] required`) and predates core#4196
|
|
190
|
+
* refuses `/tee/info` unsealed. Used only then; a node that answers is
|
|
191
|
+
* taken at its word. Either way untrusted: the quote must match the signed
|
|
192
|
+
* release, so a wrong version only fails the attestation.
|
|
193
|
+
*/
|
|
194
|
+
releaseVersion?: string;
|
|
184
195
|
/** Also require the node to run this application with this bytecode hash. */
|
|
185
196
|
applicationId?: string;
|
|
186
197
|
applicationHash?: string;
|
|
@@ -190,7 +201,8 @@ export interface SignedReleaseSealedFetchOptions extends Omit<SignedReleaseVerif
|
|
|
190
201
|
/**
|
|
191
202
|
* {@link createAttestedSealedFetch} for a TEE node known only by URL, trusting
|
|
192
203
|
* whatever signed release at or above `minReleaseVersion` it runs: it reads
|
|
193
|
-
* the release the node names from its `/tee/info
|
|
204
|
+
* the release the node names from its `/tee/info` (or takes `releaseVersion`
|
|
205
|
+
* when a node too old to serve that unsealed requires sealing), gets that release from
|
|
194
206
|
* `releaseSource` (the public mirror unless you say otherwise), verifies its
|
|
195
207
|
* signature, builds the quote verifier from its measurements, attests the node
|
|
196
208
|
* and seals everything to it.
|
package/dist/sealed/release.js
CHANGED
|
@@ -127,10 +127,35 @@ export function nodeReleaseVersionFromImage(osImage) {
|
|
|
127
127
|
* `GET /admin-api/tee/info` reports. The node's own claim, and not trusted:
|
|
128
128
|
* it only picks which signed release to fetch, and the quote must then match
|
|
129
129
|
* that release's measurements.
|
|
130
|
+
*
|
|
131
|
+
* `/tee/info` is read in the clear, before any session exists. A node that
|
|
132
|
+
* requires sealing serves it unsealed from core#4196 on; an older one refuses
|
|
133
|
+
* it with `403 sealed_required`, and then this throws saying so.
|
|
130
134
|
*/
|
|
131
135
|
export async function fetchNodeReleaseVersion(baseUrl, options = {}) {
|
|
132
|
-
const
|
|
133
|
-
|
|
136
|
+
const version = await readNodeReleaseVersion(baseUrl, options.fetch ?? fetch);
|
|
137
|
+
if (version === undefined) {
|
|
138
|
+
throw new Error(`${infoUrl(baseUrl)} was refused unsealed: the node requires sealing and is too old to name its ` +
|
|
139
|
+
"release before a session exists. Name the release it runs yourself (createSignedReleaseSealedFetch's " +
|
|
140
|
+
'`releaseVersion`), or upgrade the node');
|
|
141
|
+
}
|
|
142
|
+
return version;
|
|
143
|
+
}
|
|
144
|
+
function infoUrl(baseUrl) {
|
|
145
|
+
return `${baseUrl.replace(/\/+$/, '')}/admin-api/tee/info`;
|
|
146
|
+
}
|
|
147
|
+
/** As {@link fetchNodeReleaseVersion}, but `undefined` when the node refuses `/tee/info` as `sealed_required`. */
|
|
148
|
+
async function readNodeReleaseVersion(baseUrl, givenFetch) {
|
|
149
|
+
const url = infoUrl(baseUrl);
|
|
150
|
+
const response = await givenFetch(url, { headers: { accept: 'application/json' } });
|
|
151
|
+
if (response.status === 403) {
|
|
152
|
+
const code = await response
|
|
153
|
+
.json()
|
|
154
|
+
.then((body) => body?.error?.code)
|
|
155
|
+
.catch(() => undefined);
|
|
156
|
+
if (code === 'sealed_required')
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
134
159
|
if (!response.ok)
|
|
135
160
|
throw new Error(`Fetching ${url} failed: HTTP ${response.status}`);
|
|
136
161
|
let osImage;
|
|
@@ -211,7 +236,8 @@ export function createSignedReleaseVerifier(options) {
|
|
|
211
236
|
/**
|
|
212
237
|
* {@link createAttestedSealedFetch} for a TEE node known only by URL, trusting
|
|
213
238
|
* whatever signed release at or above `minReleaseVersion` it runs: it reads
|
|
214
|
-
* the release the node names from its `/tee/info
|
|
239
|
+
* the release the node names from its `/tee/info` (or takes `releaseVersion`
|
|
240
|
+
* when a node too old to serve that unsealed requires sealing), gets that release from
|
|
215
241
|
* `releaseSource` (the public mirror unless you say otherwise), verifies its
|
|
216
242
|
* signature, builds the quote verifier from its measurements, attests the node
|
|
217
243
|
* and seals everything to it.
|
|
@@ -232,10 +258,14 @@ export function createSignedReleaseVerifier(options) {
|
|
|
232
258
|
* ```
|
|
233
259
|
*/
|
|
234
260
|
export function createSignedReleaseSealedFetch(options) {
|
|
235
|
-
const { baseUrl, releaseSource, applicationId, applicationHash, fetch: givenFetch, ...verifierOptions } = options;
|
|
261
|
+
const { baseUrl, releaseSource, releaseVersion: fallbackVersion, applicationId, applicationHash, fetch: givenFetch, ...verifierOptions } = options;
|
|
262
|
+
if (fallbackVersion !== undefined)
|
|
263
|
+
releaseVersion(fallbackVersion, 'releaseVersion');
|
|
236
264
|
const baseFetch = givenFetch ?? ((input, init) => fetch(input, init));
|
|
237
265
|
const release = async () => {
|
|
238
|
-
const version =
|
|
266
|
+
const version = fallbackVersion === undefined
|
|
267
|
+
? await fetchNodeReleaseVersion(baseUrl, { fetch: baseFetch })
|
|
268
|
+
: ((await readNodeReleaseVersion(baseUrl, baseFetch)) ?? fallbackVersion);
|
|
239
269
|
return typeof releaseSource === 'function'
|
|
240
270
|
? releaseSource({ baseUrl, version, fetch: baseFetch })
|
|
241
271
|
: fetchNodeRelease(cloudNodeReleaseUrl(releaseSource ?? DEFAULT_RELEASE_MIRROR, version), { fetch: baseFetch });
|