diff --git a/bin.js b/bin.js index 2b8fccf..2bfb4e9 100755 --- a/bin.js +++ b/bin.js @@ -131,7 +131,29 @@ cli .option('-c, --customer ', 'Billing account email') .option('-na, --no-account', 'Skip account setup') .option('-a, --account ', 'Managing account email') - .action(Space.create) + .option('-ag, --authorize-gateway-services ', 'Authorize Gateways to serve the content uploaded to this space, e.g: \'[{"id":"did:key:z6Mki...","serviceEndpoint":"https://gateway.example.com"}]\'') + .option('-nga, --no-gateway-authorization', 'Skip Gateway Authorization') + .action((name, options) => { + let authorizeGatewayServices = [] + if (options['authorize-gateway-services']) { + try { + authorizeGatewayServices = JSON.parse(options['authorize-gateway-services']) + } catch (err) { + console.error('Invalid JSON format for --authorize-gateway-services') + process.exit(1) + } + } + + const parsedOptions = { + ...options, + // if defined it means we want to skip gateway authorization, so the client will not validate the gateway services + skipGatewayAuthorization: options['gateway-authorization'] === false || options['gateway-authorization'] === undefined, + // default to empty array if not set, so the client will validate the gateway services + authorizeGatewayServices: authorizeGatewayServices || [], + } + + return Space.create(name, parsedOptions) + }) cli .command('space provision [name]') diff --git a/can.js b/can.js index ed4362b..37523ad 100644 --- a/can.js +++ b/can.js @@ -37,11 +37,11 @@ export async function blobAdd(blobPath) { } spinner.start('Storing') - const { multihash } = await client.capability.blob.add(blob, { + const { digest } = await client.capability.blob.add(blob, { receiptsEndpoint: client._receiptsEndpoint.toString() }) - const cid = Link.create(raw.code, multihash) - spinner.stopAndPersist({ symbol: '⁂', text: `Stored ${base58btc.encode(multihash.bytes)} (${cid})` }) + const cid = Link.create(raw.code, digest) + spinner.stopAndPersist({ symbol: '⁂', text: `Stored ${base58btc.encode(digest.bytes)} (${cid})` }) } /** diff --git a/index.js b/index.js index 1080cd0..3314269 100644 --- a/index.js +++ b/index.js @@ -110,7 +110,9 @@ export async function authorize(email, opts = {}) { export async function upload(firstPath, opts) { /** @type {import('@web3-storage/w3up-client/types').FileLike[]} */ let files + /** @type {number} */ let totalSize // -1 when unknown size (input from stdin) + /** @type {import('ora').Ora} */ let spinner const client = await getClient() if (firstPath) { @@ -246,7 +248,9 @@ export async function remove(rootCid, opts) { */ export async function createSpace(name) { const client = await getClient() - const space = await client.createSpace(name) + const space = await client.createSpace(name, { + skipGatewayAuthorization: true + }) await client.setCurrentSpace(space.did()) console.log(space.did()) } diff --git a/package-lock.json b/package-lock.json index a600869..2aa6cbf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,11 +18,11 @@ "@ucanto/core": "^10.0.1", "@ucanto/principal": "^9.0.1", "@ucanto/transport": "^9.1.1", - "@web3-storage/access": "^20.0.0", - "@web3-storage/capabilities": "^17.2.0", + "@web3-storage/access": "^20.1.1", + "@web3-storage/capabilities": "^18.0.0", "@web3-storage/data-segment": "^5.0.0", "@web3-storage/did-mailto": "^2.1.0", - "@web3-storage/w3up-client": "^14.1.1", + "@web3-storage/w3up-client": "^17.1.0", "ansi-escapes": "^6.2.0", "chalk": "^5.3.0", "crypto-random-string": "^5.0.0", @@ -901,27 +901,18 @@ } }, "node_modules/@ipld/dag-cbor": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/@ipld/dag-cbor/-/dag-cbor-9.0.6.tgz", - "integrity": "sha512-3kNab5xMppgWw6DVYx2BzmFq8t7I56AGWfp5kaU1fIPkwHVpBRglJJTYsGtbVluCi/s/q97HZM3bC+aDW4sxbQ==", + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@ipld/dag-cbor/-/dag-cbor-9.2.2.tgz", + "integrity": "sha512-uIEOuruCqKTP50OBWwgz4Js2+LhiBQaxc57cnP71f45b1mHEAo1OCR1Zn/TbvSW/mV1x+JqhacIktkKyaYqhCw==", "dependencies": { "cborg": "^4.0.0", - "multiformats": "^12.0.1" + "multiformats": "^13.1.0" }, "engines": { "node": ">=16.0.0", "npm": ">=7.0.0" } }, - "node_modules/@ipld/dag-cbor/node_modules/multiformats": { - "version": "12.1.3", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.1.3.tgz", - "integrity": "sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw==", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, "node_modules/@ipld/dag-json": { "version": "10.1.5", "resolved": "https://registry.npmjs.org/@ipld/dag-json/-/dag-json-10.1.5.tgz", @@ -945,9 +936,9 @@ } }, "node_modules/@ipld/dag-pb": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-4.1.1.tgz", - "integrity": "sha512-wsSNjIvcABXuH9MKXpvRGMXsS20+Kf2Q0Hq2+2dxN6Wpw/K0kDF3nDmCnO6wlpninQ0vzx1zq54O3ttn5pTH9A==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-4.1.3.tgz", + "integrity": "sha512-ueULCaaSCcD+dQga6nKiRr+RSeVgdiYiEPKVUu5iQMNYDN+9osd0KpR3UDd9uQQ+6RWuv9L34SchfEwj7YIbOA==", "dependencies": { "multiformats": "^13.1.0" }, @@ -1210,6 +1201,11 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@storacha/one-webcrypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@storacha/one-webcrypto/-/one-webcrypto-1.0.1.tgz", + "integrity": "sha512-bD+vWmcgsEBqU0Dz04BR43SA03bBoLTAY29vaKasY9Oe8cb6XIP0/vkm0OS2UwKC13c8uRgFW4rjJUgDCNLejQ==" + }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", @@ -1636,25 +1632,25 @@ } }, "node_modules/@web3-storage/access": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@web3-storage/access/-/access-20.0.0.tgz", - "integrity": "sha512-kl2b3ZuN3NvAxDM6K8GlPgu1o67JtA3EGId8Bg+tFRqZiQlERQmMMOfLl8zKVOUvlq4bDFtWHl6EViLO4BwSJw==", + "version": "20.1.1", + "resolved": "https://registry.npmjs.org/@web3-storage/access/-/access-20.1.1.tgz", + "integrity": "sha512-W2C9sn8NTWw7zIUVzEk5MtwWQLFsOREF6Ju6VK+MYcuAkQ6yVll6Q7YtB5zLPwu29xJ7KIR6e5KzbDNSXHSfrA==", "dependencies": { "@ipld/car": "^5.1.1", "@ipld/dag-ucan": "^3.4.0", "@scure/bip39": "^1.2.1", + "@storacha/one-webcrypto": "^1.0.1", "@ucanto/client": "^9.0.1", "@ucanto/core": "^10.0.1", "@ucanto/interface": "^10.0.1", "@ucanto/principal": "^9.0.1", "@ucanto/transport": "^9.1.1", "@ucanto/validator": "^9.0.2", - "@web3-storage/capabilities": "^17.1.1", + "@web3-storage/capabilities": "^18.0.0", "@web3-storage/did-mailto": "^2.1.0", "bigint-mod-arith": "^3.1.2", "conf": "11.0.2", "multiformats": "^12.1.2", - "one-webcrypto": "git+https://github.com/web3-storage/one-webcrypto.git", "p-defer": "^4.0.0", "type-fest": "^4.9.0", "uint8arrays": "^4.0.6" @@ -1681,14 +1677,15 @@ } }, "node_modules/@web3-storage/blob-index": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@web3-storage/blob-index/-/blob-index-1.0.3.tgz", - "integrity": "sha512-VjGLhf6Gf4ZmzjJXS6wU4aRvnM+HLcuRCJHegjQ36ka52sR2WWOcqDNNVvabtlpnYjGtVFQCPUzaCcs18wpqHQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@web3-storage/blob-index/-/blob-index-1.0.5.tgz", + "integrity": "sha512-mhzupWeRfxLljoULcagU++mOmQOriCBMKniUhsmrCXrtRV8voF7op/ymqix1f9uX1M5iB93YXcfxAVBwGWWKoA==", "dependencies": { "@ipld/dag-cbor": "^9.0.6", + "@storacha/one-webcrypto": "^1.0.1", "@ucanto/core": "^10.0.1", "@ucanto/interface": "^10.0.1", - "@web3-storage/capabilities": "^17.1.1", + "@web3-storage/capabilities": "^18.0.1", "carstream": "^2.1.0", "multiformats": "^13.0.1", "uint8arrays": "^5.0.3" @@ -1706,38 +1703,19 @@ } }, "node_modules/@web3-storage/capabilities": { - "version": "17.2.0", - "resolved": "https://registry.npmjs.org/@web3-storage/capabilities/-/capabilities-17.2.0.tgz", - "integrity": "sha512-hnJGIQcCAMBbR8sfgkEwnjBVcpNpNRBnzSEB2E/wKkKIjHKimw3ClsVznu6jjFExCXFaKHd6r1eAU4NcTYsueg==", + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/@web3-storage/capabilities/-/capabilities-18.0.1.tgz", + "integrity": "sha512-FLAUpuuFYkLrMkXy/W7iVNQdFlqGCZUrQr30L2C05SbQdpb/4tN6jqRG+l2nvAYTaYjWTYzsYLHGy2illsuNZQ==", "dependencies": { "@ucanto/core": "^10.0.1", "@ucanto/interface": "^10.0.1", "@ucanto/principal": "^9.0.1", "@ucanto/transport": "^9.1.1", "@ucanto/validator": "^9.0.2", - "@web3-storage/data-segment": "^3.2.0", + "@web3-storage/data-segment": "^5.2.0", "uint8arrays": "^5.0.3" } }, - "node_modules/@web3-storage/capabilities/node_modules/@web3-storage/data-segment": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@web3-storage/data-segment/-/data-segment-3.2.0.tgz", - "integrity": "sha512-SM6eNumXzrXiQE2/J59+eEgCRZNYPxKhRoHX2QvV3/scD4qgcf4g+paWBc3UriLEY1rCboygGoPsnqYJNyZyfA==", - "dependencies": { - "@ipld/dag-cbor": "^9.0.5", - "multiformats": "^11.0.2", - "sync-multihash-sha2": "^1.0.0" - } - }, - "node_modules/@web3-storage/capabilities/node_modules/multiformats": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz", - "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, "node_modules/@web3-storage/capabilities/node_modules/uint8arrays": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.0.tgz", @@ -1746,11 +1724,6 @@ "multiformats": "^13.0.0" } }, - "node_modules/@web3-storage/capabilities/node_modules/uint8arrays/node_modules/multiformats": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.1.0.tgz", - "integrity": "sha512-HzdtdBwxsIkzpeXzhQ5mAhhuxcHbjEHH+JQoxt7hG/2HGFjjwyolLo7hbaexcnhoEuV4e0TNJ8kkpMjiEYY4VQ==" - }, "node_modules/@web3-storage/content-claims": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@web3-storage/content-claims/-/content-claims-5.0.0.tgz", @@ -1766,24 +1739,15 @@ } }, "node_modules/@web3-storage/data-segment": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@web3-storage/data-segment/-/data-segment-5.0.0.tgz", - "integrity": "sha512-5CbElsxec2DsKhEHEh3XRGISAyna+bCjKjjvFrLcYyXLCaiSt/nF3ypcllxwjpE4newMUArymGKGzzZnRWL2kg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@web3-storage/data-segment/-/data-segment-5.3.0.tgz", + "integrity": "sha512-zFJ4m+pEKqtKatJNsFrk/2lHeFSbkXZ6KKXjBe7/2ayA9wAar7T/unewnOcZrrZTnCWmaxKsXWqdMFy9bXK9dw==", "dependencies": { - "@ipld/dag-cbor": "^9.0.5", - "multiformats": "^11.0.2", + "@ipld/dag-cbor": "^9.2.1", + "multiformats": "^13.3.0", "sync-multihash-sha2": "^1.0.0" } }, - "node_modules/@web3-storage/data-segment/node_modules/multiformats": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz", - "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, "node_modules/@web3-storage/did-mailto": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@web3-storage/did-mailto/-/did-mailto-2.1.0.tgz", @@ -1828,81 +1792,87 @@ "node": ">=16.15" } }, - "node_modules/@web3-storage/filecoin-api/node_modules/@web3-storage/data-segment": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@web3-storage/data-segment/-/data-segment-4.0.0.tgz", - "integrity": "sha512-AnNyJp3wHMa7LBzguQzm4rmXSi8vQBz4uFs+jiXnSNtLR5dAqHfhMvi9XdWonWPYvxNvT5ZhYCSF0mpDjymqKg==", - "dev": true, - "dependencies": { - "@ipld/dag-cbor": "^9.0.5", - "multiformats": "^11.0.2", - "sync-multihash-sha2": "^1.0.0" - } - }, - "node_modules/@web3-storage/filecoin-api/node_modules/multiformats": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz", - "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==", + "node_modules/@web3-storage/filecoin-api/node_modules/@web3-storage/capabilities": { + "version": "17.4.1", + "resolved": "https://registry.npmjs.org/@web3-storage/capabilities/-/capabilities-17.4.1.tgz", + "integrity": "sha512-GogLfON8PZabi03CUyncBvMcCi36yQ/0iR5P8kr4pxdnZm7OuAn4sEwbEB8rTKbah5V10Vwgb3O5dh0FBgyjHg==", "dev": true, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@web3-storage/filecoin-client": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@web3-storage/filecoin-client/-/filecoin-client-3.3.3.tgz", - "integrity": "sha512-xFL8odr5PpTjQvpfw/4jphcm7ZvcBRMSKHn3ReEaVcFjxQL45Rojjleuq/QEdMwrNfsLCqqAxC54jk55o5/ERQ==", - "dependencies": { - "@ipld/dag-ucan": "^3.4.0", - "@ucanto/client": "^9.0.1", - "@ucanto/core": "^10.0.1", - "@ucanto/interface": "^10.0.1", - "@ucanto/transport": "^9.1.1", - "@web3-storage/capabilities": "^16.0.0" - } - }, - "node_modules/@web3-storage/filecoin-client/node_modules/@web3-storage/capabilities": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/@web3-storage/capabilities/-/capabilities-16.0.0.tgz", - "integrity": "sha512-wCjLpYc6t8tFRZrF2k2vBteJDWzHkmQjoJG0Yy/fjA04IjNN48iVZaCMQIANHXZxDGlYRGxhwzDwl4dovAdSTQ==", "dependencies": { "@ucanto/core": "^10.0.1", "@ucanto/interface": "^10.0.1", "@ucanto/principal": "^9.0.1", "@ucanto/transport": "^9.1.1", "@ucanto/validator": "^9.0.2", - "@web3-storage/data-segment": "^3.2.0", + "@web3-storage/data-segment": "^5.2.0", "uint8arrays": "^5.0.3" } }, - "node_modules/@web3-storage/filecoin-client/node_modules/@web3-storage/data-segment": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@web3-storage/data-segment/-/data-segment-3.2.0.tgz", - "integrity": "sha512-SM6eNumXzrXiQE2/J59+eEgCRZNYPxKhRoHX2QvV3/scD4qgcf4g+paWBc3UriLEY1rCboygGoPsnqYJNyZyfA==", + "node_modules/@web3-storage/filecoin-api/node_modules/@web3-storage/capabilities/node_modules/@web3-storage/data-segment": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@web3-storage/data-segment/-/data-segment-5.3.0.tgz", + "integrity": "sha512-zFJ4m+pEKqtKatJNsFrk/2lHeFSbkXZ6KKXjBe7/2ayA9wAar7T/unewnOcZrrZTnCWmaxKsXWqdMFy9bXK9dw==", + "dev": true, + "dependencies": { + "@ipld/dag-cbor": "^9.2.1", + "multiformats": "^13.3.0", + "sync-multihash-sha2": "^1.0.0" + } + }, + "node_modules/@web3-storage/filecoin-api/node_modules/@web3-storage/capabilities/node_modules/multiformats": { + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.3.1.tgz", + "integrity": "sha512-QxowxTNwJ3r5RMctoGA5p13w5RbRT2QDkoM+yFlqfLiioBp78nhDjnRLvmSBI9+KAqN4VdgOVWM9c0CHd86m3g==", + "dev": true + }, + "node_modules/@web3-storage/filecoin-api/node_modules/@web3-storage/data-segment": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@web3-storage/data-segment/-/data-segment-4.0.0.tgz", + "integrity": "sha512-AnNyJp3wHMa7LBzguQzm4rmXSi8vQBz4uFs+jiXnSNtLR5dAqHfhMvi9XdWonWPYvxNvT5ZhYCSF0mpDjymqKg==", + "dev": true, "dependencies": { "@ipld/dag-cbor": "^9.0.5", "multiformats": "^11.0.2", "sync-multihash-sha2": "^1.0.0" } }, - "node_modules/@web3-storage/filecoin-client/node_modules/@web3-storage/data-segment/node_modules/multiformats": { + "node_modules/@web3-storage/filecoin-api/node_modules/multiformats": { "version": "11.0.2", "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz", "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==", + "dev": true, "engines": { "node": ">=16.0.0", "npm": ">=7.0.0" } }, - "node_modules/@web3-storage/filecoin-client/node_modules/uint8arrays": { + "node_modules/@web3-storage/filecoin-api/node_modules/uint8arrays": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.0.tgz", "integrity": "sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==", + "dev": true, "dependencies": { "multiformats": "^13.0.0" } }, + "node_modules/@web3-storage/filecoin-api/node_modules/uint8arrays/node_modules/multiformats": { + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.3.1.tgz", + "integrity": "sha512-QxowxTNwJ3r5RMctoGA5p13w5RbRT2QDkoM+yFlqfLiioBp78nhDjnRLvmSBI9+KAqN4VdgOVWM9c0CHd86m3g==", + "dev": true + }, + "node_modules/@web3-storage/filecoin-client": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@web3-storage/filecoin-client/-/filecoin-client-3.3.5.tgz", + "integrity": "sha512-3JFKnHFizlljRSJyyCdNN3Np4MN5riBvjAXweqNmu4s2sChMB8kopnCkAFoMeEom9r7ZAnBAkMO3Wacjs6Nlcw==", + "dependencies": { + "@ipld/dag-ucan": "^3.4.0", + "@ucanto/client": "^9.0.1", + "@ucanto/core": "^10.0.1", + "@ucanto/interface": "^10.0.1", + "@ucanto/transport": "^9.1.1", + "@web3-storage/capabilities": "^18.0.0" + } + }, "node_modules/@web3-storage/sigv4": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@web3-storage/sigv4/-/sigv4-1.0.2.tgz", @@ -1913,9 +1883,9 @@ } }, "node_modules/@web3-storage/upload-api": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@web3-storage/upload-api/-/upload-api-17.0.0.tgz", - "integrity": "sha512-LXV5Atvyfwvfe0G6g1ym2bn6M1LR/DudCMiJOMpSZxwFtjDxneMaWrE+Nrfns+NIFuqrEhz3MNyRABGuBaPSFg==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@web3-storage/upload-api/-/upload-api-17.1.0.tgz", + "integrity": "sha512-lcEreqJ+4ft+rKX5e+buM9GlY+PHa5WdNhh5mW7z52oj2XBIcZQw596PguJJLGvESpBd4YZk9uJ2CUvKEe5XTw==", "dev": true, "dependencies": { "@ucanto/client": "^9.0.1", @@ -1925,8 +1895,8 @@ "@ucanto/transport": "^9.1.1", "@ucanto/validator": "^9.0.2", "@web3-storage/access": "^20.0.0", - "@web3-storage/blob-index": "^1.0.2", - "@web3-storage/capabilities": "^17.1.1", + "@web3-storage/blob-index": "^1.0.3", + "@web3-storage/capabilities": "^17.2.0", "@web3-storage/content-claims": "^5.0.0", "@web3-storage/did-mailto": "^2.1.0", "@web3-storage/filecoin-api": "^7.1.0", @@ -1938,6 +1908,21 @@ "node": ">=16.15" } }, + "node_modules/@web3-storage/upload-api/node_modules/@web3-storage/capabilities": { + "version": "17.4.1", + "resolved": "https://registry.npmjs.org/@web3-storage/capabilities/-/capabilities-17.4.1.tgz", + "integrity": "sha512-GogLfON8PZabi03CUyncBvMcCi36yQ/0iR5P8kr4pxdnZm7OuAn4sEwbEB8rTKbah5V10Vwgb3O5dh0FBgyjHg==", + "dev": true, + "dependencies": { + "@ucanto/core": "^10.0.1", + "@ucanto/interface": "^10.0.1", + "@ucanto/principal": "^9.0.1", + "@ucanto/transport": "^9.1.1", + "@ucanto/validator": "^9.0.2", + "@web3-storage/data-segment": "^5.2.0", + "uint8arrays": "^5.0.3" + } + }, "node_modules/@web3-storage/upload-api/node_modules/multiformats": { "version": "12.1.3", "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.1.3.tgz", @@ -1964,9 +1949,9 @@ "dev": true }, "node_modules/@web3-storage/upload-client": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/@web3-storage/upload-client/-/upload-client-16.1.1.tgz", - "integrity": "sha512-aVGpcqnLxRk4u3uZAum1jwC5BbEbjuqAZZBrGNZ3UZVFnnJJXPm3DE+r1WC8FV2mbgC/yKKqDMu1FP1uB9wJkA==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@web3-storage/upload-client/-/upload-client-17.1.3.tgz", + "integrity": "sha512-pOD5EM6RJgsJ3gRZWfhwfbD21OLvNQ239aD4D5BsQsEEgEoqR8aXdrjDWU4T8DA4YXU6VIai/VGIsDXgw+eg7g==", "dependencies": { "@ipld/car": "^5.2.2", "@ipld/dag-cbor": "^9.0.6", @@ -1976,35 +1961,16 @@ "@ucanto/core": "^10.0.1", "@ucanto/interface": "^10.0.1", "@ucanto/transport": "^9.1.1", - "@web3-storage/blob-index": "^1.0.3", - "@web3-storage/capabilities": "^17.2.0", + "@web3-storage/blob-index": "^1.0.4", + "@web3-storage/capabilities": "^18.0.0", "@web3-storage/data-segment": "^5.1.0", - "@web3-storage/filecoin-client": "^3.3.3", + "@web3-storage/filecoin-client": "^3.3.5", "ipfs-utils": "^9.0.14", "multiformats": "^12.1.2", "p-retry": "^5.1.2", "varint": "^6.0.0" } }, - "node_modules/@web3-storage/upload-client/node_modules/@web3-storage/data-segment": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@web3-storage/data-segment/-/data-segment-5.1.0.tgz", - "integrity": "sha512-FYdmtKvNiVz+maZ++k4PdD43rfJW5DeagLpstq2y84CyOKNRBWbHLCZ/Ec5zT9iGI+0WgsCGbpC/WlG0jlrnhA==", - "dependencies": { - "@ipld/dag-cbor": "^9.0.5", - "multiformats": "^11.0.2", - "sync-multihash-sha2": "^1.0.0" - } - }, - "node_modules/@web3-storage/upload-client/node_modules/@web3-storage/data-segment/node_modules/multiformats": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz", - "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, "node_modules/@web3-storage/upload-client/node_modules/multiformats": { "version": "12.1.3", "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.1.3.tgz", @@ -2015,9 +1981,9 @@ } }, "node_modules/@web3-storage/w3up-client": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@web3-storage/w3up-client/-/w3up-client-14.1.1.tgz", - "integrity": "sha512-brBmN1aCJpjtNLwWpz0Jg1OkfsYs7r27m5VMOET9x+j4jy3DCtSqlUkHFIumLYrNhUn5oZrqh0kbWokcaUvrLg==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@web3-storage/w3up-client/-/w3up-client-17.1.0.tgz", + "integrity": "sha512-EFi29S6HKmamsmXXXK/pqeJHleS9Gjar1I7FWIH4EQ6TA/bHiAbiV886Y2/h0t8Sn65UQ6CHLAf0KkiNrh6qJw==", "dependencies": { "@ipld/dag-ucan": "^3.4.0", "@ucanto/client": "^9.0.1", @@ -2025,12 +1991,12 @@ "@ucanto/interface": "^10.0.1", "@ucanto/principal": "^9.0.1", "@ucanto/transport": "^9.1.1", - "@web3-storage/access": "^20.0.0", - "@web3-storage/blob-index": "^1.0.3", - "@web3-storage/capabilities": "^17.2.0", + "@web3-storage/access": "^20.1.1", + "@web3-storage/blob-index": "^1.0.5", + "@web3-storage/capabilities": "^18.0.1", "@web3-storage/did-mailto": "^2.1.0", - "@web3-storage/filecoin-client": "^3.3.3", - "@web3-storage/upload-client": "^16.1.1" + "@web3-storage/filecoin-client": "^3.3.5", + "@web3-storage/upload-client": "^17.1.3" }, "engines": { "node": ">=18" @@ -4952,9 +4918,9 @@ } }, "node_modules/multiformats": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.1.3.tgz", - "integrity": "sha512-CZPi9lFZCM/+7oRolWYsvalsyWQGFo+GpdaTmjxXXomC+nP/W1Rnxb9sUgjvmNmRZ5bOPqRAl4nuK+Ydw/4tGw==" + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.3.1.tgz", + "integrity": "sha512-QxowxTNwJ3r5RMctoGA5p13w5RbRT2QDkoM+yFlqfLiioBp78nhDjnRLvmSBI9+KAqN4VdgOVWM9c0CHd86m3g==" }, "node_modules/murmurhash3js-revisited": { "version": "3.0.0", @@ -4973,9 +4939,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -5722,9 +5688,9 @@ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" }, "node_modules/protobufjs": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.0.tgz", - "integrity": "sha512-YWD03n3shzV9ImZRX3ccbjqLxj7NokGN0V/ESiBV5xWqrommYHYiihuIyavq03pWSGqlyvYUFmfoMKd+1rPA/g==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", diff --git a/package.json b/package.json index 87748d9..f07ff7d 100644 --- a/package.json +++ b/package.json @@ -53,11 +53,11 @@ "@ucanto/core": "^10.0.1", "@ucanto/principal": "^9.0.1", "@ucanto/transport": "^9.1.1", - "@web3-storage/access": "^20.0.0", - "@web3-storage/capabilities": "^17.2.0", + "@web3-storage/access": "^20.1.1", + "@web3-storage/capabilities": "^18.0.0", "@web3-storage/data-segment": "^5.0.0", "@web3-storage/did-mailto": "^2.1.0", - "@web3-storage/w3up-client": "^14.1.1", + "@web3-storage/w3up-client": "^17.1.0", "ansi-escapes": "^6.2.0", "chalk": "^5.3.0", "crypto-random-string": "^5.0.0", diff --git a/space.js b/space.js index 5fe3ae3..478e95d 100644 --- a/space.js +++ b/space.js @@ -1,5 +1,8 @@ import * as W3Space from '@web3-storage/w3up-client/space' import * as W3Account from '@web3-storage/w3up-client/account' +import * as UcantoClient from '@ucanto/client' +import { HTTP } from '@ucanto/transport' +import * as CAR from '@ucanto/transport/car' import { getClient } from './lib.js' import process from 'node:process' import * as DIDMailto from '@web3-storage/did-mailto' @@ -17,6 +20,8 @@ import * as Result from '@web3-storage/w3up-client/result' * @property {false} [caution] * @property {DIDMailto.EmailAddress|false} [customer] * @property {string|false} [account] + * @property {Array<{id: import('@ucanto/interface').DID, serviceEndpoint: string}>} [authorizeGatewayServices] - The DID Key or DID Web and URL of the Gateway to authorize to serve content from the created space. + * @property {boolean} [skipGatewayAuthorization] - Whether to skip the Gateway authorization. It means that the content of the space will not be served by any Gateway. * * @param {string|undefined} name * @param {CreateOptions} options @@ -25,7 +30,28 @@ export const create = async (name, options) => { const client = await getClient() const spaces = client.spaces() - const space = await client.createSpace(await chooseName(name ?? '', spaces)) + let space + if (options.skipGatewayAuthorization === true) { + space = await client.createSpace(await chooseName(name ?? '', spaces), { + skipGatewayAuthorization: true, + }) + } else { + const gateways = options.authorizeGatewayServices ?? [] + const connections = gateways.map(({ id, serviceEndpoint }) => { + /** @type {UcantoClient.ConnectionView} */ + const connection = UcantoClient.connect({ + id: { + did: () => id, + }, + codec: CAR.outbound, + channel: HTTP.open({ url: new URL(serviceEndpoint) }), + }) + return connection + }) + space = await client.createSpace(await chooseName(name ?? '', spaces), { + authorizeGatewayServices: connections, + }) + } // Unless use opted-out from paper key recovery, we go through the flow if (options.recovery !== false) { @@ -185,7 +211,7 @@ export const provision = async (name = '', options = {}) => { const { ok: bytes, error: fetchError } = await fetch(options.coupon) .then((response) => response.arrayBuffer()) .then((buffer) => Result.ok(new Uint8Array(buffer))) - .catch((error) => Result.error(/** @type {Error} */ (error))) + .catch((error) => Result.error(/** @type {Error} */(error))) if (fetchError) { console.error(`Failed to fetch coupon from ${options.coupon}`) @@ -221,8 +247,7 @@ export const provision = async (name = '', options = {}) => { if (result.error) { console.error( - `⚠️ Failed to set up billing account,\n ${ - Object(result.error).message ?? '' + `⚠️ Failed to set up billing account,\n ${Object(result.error).message ?? '' }` ) process.exit(1) @@ -261,7 +286,7 @@ const chooseSpace = (client, { name }) => { * @param {W3Space.Model} space * @param {CreateOptions} options */ -export const setupEmailRecovery = async (space, options = {}) => {} +export const setupEmailRecovery = async (space, options = {}) => { } /** * @param {string} email @@ -391,9 +416,9 @@ export const setupAccount = async (client) => { return email ? await Account.loginWithClient( - /** @type {DIDMailto.EmailAddress} */ (email), - client - ) + /** @type {DIDMailto.EmailAddress} */(email), + client + ) : null } diff --git a/test/bin.spec.js b/test/bin.spec.js index b2a0fb8..2d651a5 100644 --- a/test/bin.spec.js +++ b/test/bin.spec.js @@ -100,7 +100,7 @@ export const testAccount = { export const testSpace = { 'w3 space create': test(async (assert, context) => { - const command = w3.args(['space', 'create']).env(context.env.alice).fork() + const command = w3.args(['space', 'create', '--no-gateway-authorization']).env(context.env.alice).fork() const line = await command.output.take(1).text() @@ -111,7 +111,7 @@ export const testSpace = { 'w3 space create home': test(async (assert, context) => { const create = w3 - .args(['space', 'create', 'home']) + .args(['space', 'create', 'home', '--no-gateway-authorization']) .env(context.env.alice) .fork() @@ -132,7 +132,7 @@ export const testSpace = { 'w3 space create home --no-caution': test(async (assert, context) => { const create = w3 - .args(['space', 'create', 'home', '--no-caution']) + .args(['space', 'create', 'home', '--no-caution', '--no-gateway-authorization']) .env(context.env.alice) .fork() @@ -155,7 +155,7 @@ export const testSpace = { 'w3 space create my-space --no-recovery': test(async (assert, context) => { const create = w3 - .args(['space', 'create', 'home', '--no-recovery']) + .args(['space', 'create', 'home', '--no-recovery', '--no-gateway-authorization']) .env(context.env.alice) .fork() @@ -173,7 +173,7 @@ export const testSpace = { await selectPlan(context) const create = w3 - .args(['space', 'create', 'home', '--no-recovery']) + .args(['space', 'create', 'home', '--no-recovery', '--no-gateway-authorization']) .env(context.env.alice) .fork() @@ -191,7 +191,7 @@ export const testSpace = { await login(context, { email: 'alice@email.me' }) const create = w3 - .args(['space', 'create', 'my-space', '--no-recovery']) + .args(['space', 'create', 'my-space', '--no-recovery', '--no-gateway-authorization']) .env(context.env.alice) .fork() @@ -219,6 +219,7 @@ export const testSpace = { 'create', 'home', '--no-recovery', + '--no-gateway-authorization', '--customer', 'unknown@web.mail', '--no-account', @@ -234,7 +235,6 @@ export const testSpace = { 'w3 space create home --no-recovery --customer alice@web.mail --no-account': test(async (assert, context) => { await login(context, { email: 'alice@web.mail' }) - await login(context, { email: 'alice@email.me' }) selectPlan(context) @@ -244,6 +244,7 @@ export const testSpace = { 'create', 'home', '--no-recovery', + '--no-gateway-authorization', '--customer', 'alice@web.mail', '--no-account', @@ -273,6 +274,7 @@ export const testSpace = { 'create', 'home', '--no-recovery', + '--no-gateway-authorization', '--customer', email, '--account', @@ -306,7 +308,7 @@ export const testSpace = { const { output, error } = await w3 .env(context.env.alice) - .args(['space', 'create', 'home', '--no-recovery']) + .args(['space', 'create', 'home', '--no-recovery', '--no-gateway-authorization']) .join() assert.match(output, /billing account is set/i) @@ -314,6 +316,43 @@ export const testSpace = { } ), + 'storacha space create home --no-recovery --customer alice@web.mail --account alice@web.mail --authorize-gateway-services': + test(async (assert, context) => { + const email = 'alice@web.mail' + await login(context, { email }) + await selectPlan(context, { email }) + + const serverId = context.connection.id + const serverURL = context.serverURL + + const { output } = await w3 + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--customer', + email, + '--account', + email, + '--authorize-gateway-services', + `[{"id":"${serverId}","serviceEndpoint":"${serverURL}"}]`, + ]) + .env(context.env.alice) + .join() + + assert.match(output, /account is authorized/i) + + const result = await context.delegationsStorage.find({ + audience: DIDMailto.fromEmail(email), + }) + + assert.ok( + result.ok?.find((d) => d.capabilities[0].can === '*'), + 'account has been delegated access to the space' + ) + }), + 'w3 space add': test(async (assert, context) => { const { env } = context @@ -619,6 +658,7 @@ export const testW3Up = { 'home', '--no-recovery', '--no-account', + '--no-gateway-authorization', '--customer', email, ]) @@ -651,6 +691,7 @@ export const testW3Up = { 'home', '--no-recovery', '--no-account', + '--no-gateway-authorization', '--customer', email, ]) @@ -683,6 +724,7 @@ export const testW3Up = { 'home', '--no-recovery', '--no-account', + '--no-gateway-authorization', '--customer', email, ]) @@ -714,6 +756,7 @@ export const testW3Up = { 'home', '--no-recovery', '--no-account', + '--no-gateway-authorization', '--customer', email, ]) @@ -1407,6 +1450,7 @@ export const createSpace = async ( name, '--no-recovery', '--no-account', + '--no-gateway-authorization', ...(customer ? ['--customer', customer] : ['--no-customer']), ]) .env(env) diff --git a/test/helpers/receipt-http-server.js b/test/helpers/receipt-http-server.js index bc34667..a29628c 100644 --- a/test/helpers/receipt-http-server.js +++ b/test/helpers/receipt-http-server.js @@ -64,6 +64,7 @@ const generateReceipt = async (taskCid) => { fx: { fork: [locationClaim], }, + /** @ts-expect-error not a UCAN Link */ ran: parseLink(taskCid), result: { ok: {