diff --git a/packages/api/src/routes/pins-add.js b/packages/api/src/routes/pins-add.js index 52acfea840..7d7392463e 100644 --- a/packages/api/src/routes/pins-add.js +++ b/packages/api/src/routes/pins-add.js @@ -3,6 +3,7 @@ import * as cluster from '../cluster.js' import { checkAuth, validate } from '../utils/auth.js' import { parseCidPinning } from '../utils/utils.js' import { toPinsResponse } from '../utils/db-transforms.js' +import { Multiaddr } from 'multiaddr' /** @type {import('../bindings').Handler} */ export async function pinsAdd(event, ctx) { @@ -45,11 +46,28 @@ export async function pinsAdd(event, ctx) { Object.entries(pinData.meta).filter(([, v]) => typeof v === 'string') ) } - + // validate origins + if (pinData.origins && pinData.origins.length !== 0) { + for (const o of pinData.origins) { + try { + const multi = new Multiaddr(o) + continue + } catch { + return new JSONResponse( + { + error: { + reason: 'INVALID_PIN_DATA', + details: `invalid origins: ${o} is not a multiaddr`, + }, + }, + { status: 400 } + ) + } + } + } await cluster.pin(cid.sourceCid, { origins: pinData.origins, }) - const upload = await db.createUpload({ type: 'Remote', content_cid: cid.contentCid, diff --git a/packages/api/test/pin-add.spec.js b/packages/api/test/pin-add.spec.js index d03cec769d..a1d47102c6 100644 --- a/packages/api/test/pin-add.spec.js +++ b/packages/api/test/pin-add.spec.js @@ -1,5 +1,6 @@ import assert from 'assert' import { CID } from 'multiformats' +import { Multiaddr } from 'multiaddr' import { createClientWithUser, DBTestClient, @@ -182,6 +183,49 @@ describe('Pin add ', () => { }) }) + it('should be ok pinning with an empty origins array', async () => { + const cid = 'bafkreidvbhs33ighmljlvr7zbv2ywwzcmp5adtf4kqvlly67cy56bdtmve' + const res = await fetch('pins', { + method: 'POST', + headers: { Authorization: `Bearer ${client.token}` }, + body: JSON.stringify({ cid, origins: [] }), + }) + const value = await res.json() + assert.deepStrictEqual(value.status, 'queued') + }) + + it.only('should be ok pinning an origins array with multiaddresses', async () => { + const cid = 'bafkreidvbhs33ighmljlvr7zbv2ywwzcmp5adtf4kqvlly67cy56bdtmve' + const multiOrigin = Multiaddr.fromNodeAddress( + { address: '127.0.0.1', port: 4001, family: 4 }, + 'tcp' + ) + const res = await fetch('pins', { + method: 'POST', + headers: { Authorization: `Bearer ${client.token}` }, + body: JSON.stringify({ cid, origins: [multiOrigin] }), + }) + const value = await res.json() + assert.deepStrictEqual(value, 'queued') + }) + + it('should error pinning with non-multiaddr origins', async () => { + const cid = 'bafkreidvbhs33ighmljlvr7zbv2ywwzcmp5adtf4kqvlly67cy56bdtmve' + const res = await fetch('pins', { + method: 'POST', + headers: { Authorization: `Bearer ${client.token}` }, + body: JSON.stringify({ cid, origins: ['garlic-barber'] }), + }) + const value = await res.json() + assert.deepStrictEqual(value, { + error: { + reason: 'INVALID_PIN_DATA', + details: + 'invalid origins: one or more of the origins are not a multiaddr', + }, + }) + }) + it('should pin to cluster by source CID', async () => { const cidv0 = 'QmXRdb4vemfS7Z6EL2p47XdjRatZ5Ne8DEnwr5uaHqXnak' const cidv1 = CID.parse(cidv0).toV1().toString()