diff --git a/packages/w3up-client/package.json b/packages/w3up-client/package.json index 0fb38e4a6..3fdafa870 100644 --- a/packages/w3up-client/package.json +++ b/packages/w3up-client/package.json @@ -140,6 +140,7 @@ "mock": "run-p mock:*", "mock:bucket-200": "PORT=8989 STATUS=200 node test/helpers/bucket-server.js", "mock:receipts-server": "PORT=9201 node test/helpers/receipts-server.js", + "mock:gateway-server": "PORT=5001 node test/helpers/gateway-server.js", "coverage": "c8 report -r html && open coverage/index.html", "rc": "npm version prerelease --preid rc", "docs": "npm run build && typedoc --out docs-generated" diff --git a/packages/w3up-client/src/client.js b/packages/w3up-client/src/client.js index e0e096fa8..42b6af9f4 100644 --- a/packages/w3up-client/src/client.js +++ b/packages/w3up-client/src/client.js @@ -313,11 +313,16 @@ export class Client extends Base { authorizeGatewayServices = [ UcantoClient.connect({ id: { - did: () => 'did:web:w3s.link', + did: () => + /** @type {`did:${string}:${string}`} */ ( + process.env.DEFAULT_GATEWAY_ID ?? 'did:web:w3s.link' + ), }, codec: CAR.outbound, channel: HTTP.open({ - url: new URL(' https://freeway.dag.haus'), + url: new URL( + process.env.DEFAULT_GATEWAY_URL ?? 'https://freeway.dag.haus' + ), }), }), ] diff --git a/packages/w3up-client/test/client.test.js b/packages/w3up-client/test/client.test.js index c9e1d5350..198779c59 100644 --- a/packages/w3up-client/test/client.test.js +++ b/packages/w3up-client/test/client.test.js @@ -658,6 +658,7 @@ export const testClient = { }, 'should authorize the Storacha Gateway Service when no Gateway Services are provided': async (assert, { mail, grantAccess, connection }) => { + Test // Step 1: Create a client for Alice and login const aliceClient = new Client( await AgentData.create({ @@ -679,6 +680,9 @@ export const testClient = { await grantAccess(message) const aliceAccount = await aliceLogin + process.env.DEFAULT_GATEWAY_ID = gateway.did() + process.env.DEFAULT_GATEWAY_URL = 'http://localhost:5001' + const spaceA = await aliceClient.createSpace( 'authorize-gateway-space', { diff --git a/packages/w3up-client/test/helpers/gateway-server.js b/packages/w3up-client/test/helpers/gateway-server.js new file mode 100644 index 000000000..d5df5b83d --- /dev/null +++ b/packages/w3up-client/test/helpers/gateway-server.js @@ -0,0 +1,60 @@ +import { createServer } from 'node:http' +import { + createUcantoServer, + getContentServeMockService, +} from '../mocks/service.js' +import { gateway } from '../../../upload-api/test/helpers/utils.js' + +const port = 5001 + +const server = createServer(async (req, res) => { + res.setHeader('Access-Control-Allow-Origin', '*') + res.setHeader('Access-Control-Allow-Methods', '*') + res.setHeader('Access-Control-Allow-Headers', '*') + if (req.method === 'OPTIONS') return res.end() + + if (req.method === 'POST') { + console.time('Service Setup') + const service = getContentServeMockService() + const server = createUcantoServer(gateway, service) + console.timeEnd('Service Setup') + + console.time('Collect Request Body') + const bodyBuffer = Buffer.concat(await collect(req)) + console.timeEnd('Collect Request Body') + + console.time('Server Request') + const { headers, body, status } = await server.request({ + body: new Uint8Array( + bodyBuffer.buffer, + bodyBuffer.byteOffset, + bodyBuffer.byteLength + ), + headers: /** @type {Record} */ ( + Object.fromEntries(Object.entries(req.headers)) + ), + }) + console.timeEnd('Server Request') + return new Response(body, { headers, status: status ?? 200 }) + } + res.end() +}) + +/** @param {import('node:stream').Readable} stream */ +const collect = (stream) => { + return /** @type {Promise} */ ( + new Promise((resolve, reject) => { + const chunks = /** @type {Buffer[]} */ ([]) + stream.on('data', (chunk) => chunks.push(Buffer.from(chunk))) + stream.on('error', (err) => reject(err)) + stream.on('end', () => resolve(chunks)) + }) + ) +} + +// eslint-disable-next-line no-console +server.listen(port, () => + console.log(`[Mock] Gateway Server Listening on :${port}`) +) + +process.on('SIGTERM', () => process.exit(0)) diff --git a/packages/w3up-client/test/mocks/service.js b/packages/w3up-client/test/mocks/service.js index 4b8805fde..0d199d5bf 100644 --- a/packages/w3up-client/test/mocks/service.js +++ b/packages/w3up-client/test/mocks/service.js @@ -12,7 +12,8 @@ import * as AccessCaps from '@web3-storage/capabilities' export function getContentServeMockService(result = { ok: {} }) { return { access: { - delegate: Server.provide(AccessCaps.Access.delegate, async () => { + delegate: Server.provide(AccessCaps.Access.delegate, async (data) => { + console.log('Access Caps Delegate', data) return result }), }, @@ -20,19 +21,29 @@ export function getContentServeMockService(result = { ok: {} }) { } /** - * Generic function to create connection to any type of mock service with any type of signer id. + * Creates a new Ucanto server with the given options. * * @param {any} id * @param {any} service - * @param {string | undefined} [url] */ -export function getConnection(id, service, url = undefined) { - const server = Server.create({ +export function createUcantoServer(id, service) { + return Server.create({ id: id, service, codec: CAR.inbound, validateAuthorization: () => ({ ok: {} }), }) +} + +/** + * Generic function to create connection to any type of mock service with any type of signer id. + * + * @param {any} id + * @param {any} service + * @param {string | undefined} [url] + */ +export function getConnection(id, service, url = undefined) { + const server = createUcantoServer(id, service) const connection = Client.connect({ id: id, codec: CAR.outbound,