Skip to content

Commit 1903214

Browse files
author
Travis Vachon
authored
feat: NFT.storage changes (#2560)
Make all (most?) of the requested changes from https://github.com/orgs/w3s-project/projects/1/views/1?pane=issue&itemId=57594940 Note that once this PR is deployed, new user signups will be disabled - I did not put these behind a feature flag as there doesn't seem to be a strong need for one. A few caveats: 1) I put the same banner at the top of every page - since the menu is in the global layout it's tricky to get different banners displaying on different pages. This means that the requests to have different pages link to different URLs are challenging to accommodate, so I've gone down the easy path. 2) The error message for new users is a little janky - I followed the letter of the request but it's not terribly pretty: <img width="1254" alt="Screenshot 2024-04-04 at 12 28 33 PM" src="https://github.com/nftstorage/nft.storage/assets/1113/db13e99e-49f4-4453-bb90-e7c1d95afb62"> We could make this prettier but it's nontrivial work, so I'm proposing we ship with this and iterate but would be open to iterating before we ship.
1 parent bf19e36 commit 1903214

8 files changed

Lines changed: 745 additions & 40 deletions

File tree

packages/api/src/errors.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,27 @@ export class ErrorAgentDIDRequired extends HTTPError {
284284
}
285285
}
286286
ErrorAgentDIDRequired.CODE = 'ERROR_AGENT_DID_REQUIRED'
287+
288+
/**
289+
* Error indicating a new user signup was denied and probably will be indefinitely,
290+
* and the user should try a new product instead.
291+
*/
292+
export class NewUserDeniedTryOtherProductError extends HTTPError {
293+
/**
294+
* @param {string} message
295+
* @param {URL} otherProduct
296+
*/
297+
constructor(message, otherProduct) {
298+
super(message, 403)
299+
this.code = 'NEW_USER_DENIED_TRY_OTHER_PRODUCT'
300+
this.otherProduct = otherProduct
301+
}
302+
303+
toJSON() {
304+
return {
305+
message: this.message,
306+
code: this.code,
307+
otherProduct: this.otherProduct.toString(),
308+
}
309+
}
310+
}

packages/api/src/utils/auth.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
ErrorUnauthenticated,
88
ErrorTokenBlocked,
99
ErrorAgentDIDRequired,
10+
NewUserDeniedTryOtherProductError,
1011
} from '../errors.js'
1112
import { parseJWT, verifyJWT } from './jwt.js'
1213
import * as Ucan from 'ucan-storage/ucan-storage'
@@ -137,6 +138,18 @@ export async function loginOrRegister(event, data, { db }) {
137138
? await parseGithub(data.data, metadata)
138139
: parseMagic(metadata)
139140

141+
const dbUser =
142+
data.type === 'github'
143+
? await db.getUser(parsed.sub)
144+
: await db.getUser(parsed.issuer)
145+
if (!dbUser) {
146+
const otherProduct = new URL('https://nft.storage/')
147+
throw new NewUserDeniedTryOtherProductError(
148+
`We're no longer accepting new accounts for NFT.Storage Classic. Learn more about our new experience>> ${otherProduct.toString()}`,
149+
otherProduct
150+
)
151+
}
152+
140153
const upsert = await db.upsertUser({
141154
email: parsed.email,
142155
github_id: parsed.sub,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export function DeprecationBanner() {
2+
return (
3+
<div className="w-full text-center p-3 bg-black text-white text-sm">
4+
We&apos;re evolving our platform for you. Learn more &gt;&gt;&nbsp;
5+
<a href="https://nft.storage/blog/the-next-chapter-of-nftstorage">
6+
https://nft.storage/blog/the-next-chapter-of-nftstorage
7+
</a>
8+
</div>
9+
)
10+
}

packages/website/components/footer.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ export default function Footer() {
105105
</Link>
106106
</span>
107107
<Dot />
108+
<span className="block lg:inline-block my-4">
109+
<Link
110+
href="/privacy"
111+
className="nspink no-underline underline-hover align-middle"
112+
onClick={onLinkClick}
113+
>
114+
Privacy
115+
</Link>
116+
</span>
117+
<Dot />
108118
<span className="block lg:inline-block my-4">
109119
<span className="align-middle">Need Help? </span>
110120
<a

packages/website/components/layout.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { getStatusPageSummary } from '../lib/statuspage-api'
66
import { getVersion } from '../lib/api'
77
import { useQuery } from 'react-query'
88
import { useUser } from '../lib/user'
9+
import { DeprecationBanner } from './deprecationBanner.js'
910

1011
const MaintenanceBanner = () => {
1112
let bannerMessage = ''
@@ -133,6 +134,7 @@ export default function Layout({
133134
) : (
134135
<>
135136
<MaintenanceBanner />
137+
<DeprecationBanner />
136138
<Navbar bgColor={navBgColor} logo={logo} user={user} />
137139
<div className="flex flex-col flex-auto">{children({ user })}</div>
138140
<Footer />

packages/website/pages/files.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -554,15 +554,7 @@ export default function Files({ user }) {
554554
'flex justify-center pt-4',
555555
status === 'loading' && 'hidden'
556556
)}
557-
>
558-
<Button
559-
data-tf-popup="OTxv3w2O"
560-
className="mx-4 mb-4"
561-
variant="dark"
562-
>
563-
{'Tell us how we are doing'}
564-
</Button>
565-
</div>
557+
></div>
566558
</div>
567559
</main>
568560
</>

0 commit comments

Comments
 (0)