From 1defed682adfc52d464bcff1edf52fc100edf908 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Thu, 9 Jan 2025 19:29:59 -0300 Subject: [PATCH] fix: set ipfs gateway url based on env var (#177) ### Context - When creating a space, the system will use an environment variable to determine which Gateway is authorized to serve its content. If the environment variable is not defined, the Storacha Production Gateway will be authorized by default. - If the Staging Gateway is specified, IPFS links must point to `ipfs-staging.w3s.link` instead of `ipfs.w3s.link`. Otherwise, requests will bypass the correct service, preventing proper validation of the content authorization flow. ### Changes - Refactored the code to dynamically read the IPFS Gateway URL from the environment variable and construct the appropriate URL for content retrieval. - Updated deployment configuration files to include the new environment variable for Gateway selection. - Resolved a minor compilation issue in `nft-storage.ts` and `web3-storage.ts`. --- .env.tpl | 1 + .github/workflows/deploy-storacha.yml | 2 ++ .github/workflows/deploy.yml | 2 ++ src/app/space/[did]/root/[cid]/page.tsx | 3 ++- src/components/SpaceCreator.tsx | 6 +++--- src/components/Uploader.tsx | 4 ++-- src/components/services.ts | 9 +++++++-- src/lib/migrations/nft-storage.ts | 2 +- src/lib/migrations/web3-storage.ts | 1 - 9 files changed, 20 insertions(+), 10 deletions(-) diff --git a/.env.tpl b/.env.tpl index b00872b..44da683 100644 --- a/.env.tpl +++ b/.env.tpl @@ -3,6 +3,7 @@ NEXT_PUBLIC_W3UP_SERVICE_URL=https://staging.up.web3.storage NEXT_PUBLIC_W3UP_RECEIPTS_URL=https://staging.up.web3.storage/receipt/ NEXT_PUBLIC_W3UP_SERVICE_DID=did:web:staging.web3.storage NEXT_PUBLIC_W3UP_PROVIDER=did:web:staging.web3.storage +NEXT_PUBLIC_IPFS_GATEWAY_URL=https://%ROOT_CID%.ipfs-staging.w3s.link # set these to your gateway service URL and DID NEXT_PUBLIC_W3UP_GATEWAY_HOST=https://freeway-staging.dag.haus diff --git a/.github/workflows/deploy-storacha.yml b/.github/workflows/deploy-storacha.yml index b816a2d..cefa398 100644 --- a/.github/workflows/deploy-storacha.yml +++ b/.github/workflows/deploy-storacha.yml @@ -42,6 +42,7 @@ jobs: echo "NEXT_PUBLIC_W3UP_PROVIDER=did:web:staging.web3.storage" >> .env echo "NEXT_PUBLIC_W3UP_GATEWAY_HOST=https://freeway-staging.dag.haus" >> .env echo "NEXT_PUBLIC_W3UP_GATEWAY_ID=did:web:staging.w3s.link" >> .env + echo "NEXT_PUBLIC_IPFS_GATEWAY_URL=https://%ROOT_CID%.ipfs-staging.w3s.link" >> .env echo "NEXT_PUBLIC_STRIPE_PRICING_TABLE_ID=prctbl_1NzhdvF6A5ufQX5vKNZuRhie" >> .env echo "NEXT_PUBLIC_STRIPE_TRIAL_PRICING_TABLE_ID=prctbl_1QIDHGF6A5ufQX5vOK9Xl8Up" >> .env echo "NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_51LO87hF6A5ufQX5viNsPTbuErzfavdrEFoBuaJJPfoIhzQXdOUdefwL70YewaXA32ZrSRbK4U4fqebC7SVtyeNcz00qmgNgueC" >> .env @@ -139,6 +140,7 @@ jobs: echo "NEXT_PUBLIC_W3UP_PROVIDER=did:web:web3.storage" >> .env echo "NEXT_PUBLIC_W3UP_GATEWAY_HOST=https://w3s.link" >> .env echo "NEXT_PUBLIC_W3UP_GATEWAY_ID=did:web:w3s.link" >> .env + echo "NEXT_PUBLIC_IPFS_GATEWAY_URL=https://%ROOT_CID%.ipfs.w3s.link" >> .env echo "NEXT_PUBLIC_STRIPE_PRICING_TABLE_ID=prctbl_1OCJ1qF6A5ufQX5vM5DWg4rA" >> .env echo "NEXT_PUBLIC_STRIPE_TRIAL_PRICING_TABLE_ID=prctbl_1QPYsuF6A5ufQX5vdIGAe54g" >> .env echo "NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_51LO87hF6A5ufQX5vQTO5BHyz8y9ybJp4kg1GsBjYuqwluuwtQTkbeZzkoQweFQDlv7JaGjuIdUWAyuwXp3tmCfsM005lJK9aS8" >> .env diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index fab0334..8666389 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -42,6 +42,7 @@ jobs: echo "NEXT_PUBLIC_W3UP_PROVIDER=did:web:staging.web3.storage" >> .env echo "NEXT_PUBLIC_W3UP_GATEWAY_HOST=https://freeway-staging.dag.haus" >> .env echo "NEXT_PUBLIC_W3UP_GATEWAY_ID=did:web:staging.w3s.link" >> .env + echo "NEXT_PUBLIC_IPFS_GATEWAY_URL=https://%ROOT_CID%.ipfs-staging.w3s.link" >> .env echo "NEXT_PUBLIC_STRIPE_PRICING_TABLE_ID=prctbl_1NzhdvF6A5ufQX5vKNZuRhie" >> .env echo "NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_51LO87hF6A5ufQX5viNsPTbuErzfavdrEFoBuaJJPfoIhzQXdOUdefwL70YewaXA32ZrSRbK4U4fqebC7SVtyeNcz00qmgNgueC" >> .env echo "NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL_LINK=https://billing.stripe.com/p/login/test_6oE29Gff99KO6mk8ww" >> .env @@ -132,6 +133,7 @@ jobs: echo "NEXT_PUBLIC_W3UP_PROVIDER=did:web:web3.storage" >> .env echo "NEXT_PUBLIC_W3UP_GATEWAY_HOST=https://w3s.link" >> .env echo "NEXT_PUBLIC_W3UP_GATEWAY_ID=did:web:w3s.link" >> .env + echo "NEXT_PUBLIC_IPFS_GATEWAY_URL=https://%ROOT_CID%.ipfs.w3s.link" >> .env echo "NEXT_PUBLIC_STRIPE_PRICING_TABLE_ID=prctbl_1OCJ1qF6A5ufQX5vM5DWg4rA" >> .env echo "NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_51LO87hF6A5ufQX5vQTO5BHyz8y9ybJp4kg1GsBjYuqwluuwtQTkbeZzkoQweFQDlv7JaGjuIdUWAyuwXp3tmCfsM005lJK9aS8" >> .env echo "NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL_LINK=https://billing.stripe.com/p/login/cN22aA62U6bO1sA9AA" >> .env diff --git a/src/app/space/[did]/root/[cid]/page.tsx b/src/app/space/[did]/root/[cid]/page.tsx index 2230121..0fa17dc 100644 --- a/src/app/space/[did]/root/[cid]/page.tsx +++ b/src/app/space/[did]/root/[cid]/page.tsx @@ -13,6 +13,7 @@ import CopyIcon from '@/components/CopyIcon' import { Breadcrumbs } from '@/components/Breadcrumbs' import { useRouter } from 'next/navigation' import { createUploadsListKey } from '@/cache' +import { ipfsGatewayURL } from '@/components/services' interface PageProps { params: { @@ -58,7 +59,7 @@ export default function ItemPage ({ params }: PageProps): JSX.Element { router.replace(`/space/${spaceDID}`) } - const url = `https://${root}.ipfs.w3s.link` + const url = ipfsGatewayURL(root) return (
diff --git a/src/components/SpaceCreator.tsx b/src/components/SpaceCreator.tsx index 15ada8d..d439b25 100644 --- a/src/components/SpaceCreator.tsx +++ b/src/components/SpaceCreator.tsx @@ -12,6 +12,7 @@ import { H3 } from './Text' import * as UcantoClient from '@ucanto/client' import { HTTP } from '@ucanto/transport' import * as CAR from '@ucanto/transport/car' +import { gatewayHost } from './services' export function SpaceCreatorCreating(): JSX.Element { return ( @@ -59,15 +60,14 @@ export function SpaceCreatorForm({ setSubmitted(true) try { - const gatewayId = toWebDID(process.env.NEXT_PUBLIC_W3UP_GATEWAY_ID) || toWebDID('did:web:w3s.link') - const gatewayUrl = process.env.NEXT_PUBLIC_W3UP_GATEWAY_HOST || 'https://w3s.link' + const gatewayId = toWebDID(process.env.NEXT_PUBLIC_W3UP_GATEWAY_ID) ?? toWebDID('did:web:w3s.link') const storachaGateway = UcantoClient.connect({ id: { did: () => gatewayId }, codec: CAR.outbound, - channel: HTTP.open({ url: new URL(gatewayUrl) }), + channel: HTTP.open({ url: new URL(gatewayHost) }), }) const space = await client.createSpace(name, { diff --git a/src/components/Uploader.tsx b/src/components/Uploader.tsx index 1e2aef6..32bbf65 100644 --- a/src/components/Uploader.tsx +++ b/src/components/Uploader.tsx @@ -12,7 +12,7 @@ import { WrapInDirectoryCheckbox, useUploader } from '@w3ui/react' -import { gatewayHost } from '../components/services' +import { ipfsGatewayURL } from '../components/services' import { useEffect, useState } from 'react' import { RadioGroup } from '@headlessui/react' import { H2 } from './Text' @@ -94,7 +94,7 @@ export const Done = ({ dataCID }: DoneProps): JSX.Element => {

Uploaded

{cid} diff --git a/src/components/services.ts b/src/components/services.ts index 93477a2..03d247f 100644 --- a/src/components/services.ts +++ b/src/components/services.ts @@ -1,4 +1,4 @@ -import type { Service } from '@w3ui/react' +import type { Service, UnknownLink } from '@w3ui/react' import { connect } from '@ucanto/client' import { CAR, HTTP } from '@ucanto/transport' import * as DID from '@ipld/dag-ucan/did' @@ -19,6 +19,11 @@ export const servicePrincipal = DID.parse( process.env.NEXT_PUBLIC_W3UP_SERVICE_DID ?? 'did:web:web3.storage' ) +export const ipfsGatewayURL = (rootCID: UnknownLink | string) => new URL( + // 'https://%ROOT_CID%.ipfs.w3s.link' or 'https://%ROOT_CID%.ipfs-staging.w3s.link' + process.env.NEXT_PUBLIC_IPFS_GATEWAY_URL?.replace('%ROOT_CID%', rootCID.toString()) ?? `https://${rootCID}.ipfs.w3s.link` +).toString() + export const serviceConnection = connect({ id: servicePrincipal, codec: CAR.outbound, @@ -28,4 +33,4 @@ export const serviceConnection = connect({ }), }) -export const gatewayHost = process.env.NEXT_PUBLIC_W3UP_GATEWAY_HOST ?? 'w3s.link' +export const gatewayHost = process.env.NEXT_PUBLIC_W3UP_GATEWAY_HOST ?? 'https://w3s.link' diff --git a/src/lib/migrations/nft-storage.ts b/src/lib/migrations/nft-storage.ts index cb6a203..d6c27a0 100644 --- a/src/lib/migrations/nft-storage.ts +++ b/src/lib/migrations/nft-storage.ts @@ -101,7 +101,7 @@ class Reader { // // If so we should be able to get a location claim, and key in the // claim should be the CAR CID. - const claims = await Claims.read(root) + const claims = await Claims.read(root.multihash) const locationClaims = [] for (const c of claims) { if (c.type === 'assert/location') { diff --git a/src/lib/migrations/web3-storage.ts b/src/lib/migrations/web3-storage.ts index 6c6486e..b190cfb 100644 --- a/src/lib/migrations/web3-storage.ts +++ b/src/lib/migrations/web3-storage.ts @@ -50,7 +50,6 @@ class Reader { } const root = Link.parse(raw.cid) - // @ts-expect-error not in client types const parts: string[] = raw.parts const shards: Shard[] = []