Skip to content

Commit

Permalink
feat: get bluesky auth working (#8)
Browse files Browse the repository at this point in the history
Get Bluesky auth working on Cloudflare - this involved a bit of a
redesign of the client metadata system.

Also unify storacha and bluesky auth experiences on the homepage.
  • Loading branch information
travis authored Feb 26, 2025
1 parent b6faf8b commit 9a5e5e7
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 100 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:
echo "NEXT_PUBLIC_STORACHA_GATEWAY_HOST=https://staging.w3s.link" >> .env
echo "NEXT_PUBLIC_STORACHA_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_BLUESKY_CLIENT_URI=${{ (github.ref_name == 'main') && 'https://bluesky-backup-staging.pages.dev/' || 'https://bluesky-backup-preview.pages.dev/' }}" >> .env
echo "NEXT_PUBLIC_SENTRY_ENV=staging" >> .env
echo "SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}" >> .env
# as long as this uses https://github.com/cloudflare/next-on-pages/blob/dc529d7efa8f8568ea8f71b5cdcf78df89be6c12/packages/next-on-pages/bin/index.js,
Expand Down Expand Up @@ -136,6 +137,7 @@ jobs:
echo "NEXT_PUBLIC_STORACHA_GATEWAY_ID=did:web:w3s.link" >> .env
echo "NEXT_PUBLIC_IPFS_GATEWAY_URL=https://%ROOT_CID%.ipfs.w3s.link" >> .env
echo "NEXT_PUBLIC_SENTRY_ENV=production" >> .env
echo "NEXT_PUBLIC_BLUESKY_CLIENT_URI=https://bluesky-backup-production.pages.dev/" >> .env
echo "SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}" >> .env
- run: pnpm pages:build
# as long as this uses https://github.com/cloudflare/next-on-pages/blob/dc529d7efa8f8568ea8f71b5cdcf78df89be6c12/packages/next-on-pages/bin/index.js,
Expand Down
7 changes: 7 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { setupDevPlatform } from '@cloudflare/next-on-pages/next-dev';

const nextConfig = {
/* config options here */
};

export default nextConfig;
13 changes: 0 additions & 13 deletions next.config.ts

This file was deleted.

12 changes: 0 additions & 12 deletions public/client-metadata.json

This file was deleted.

18 changes: 0 additions & 18 deletions src/app/auth/storacha/page.tsx

This file was deleted.

7 changes: 7 additions & 0 deletions src/app/bluesky-client-metadata/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { blueskyClientMetadata } from "@/lib/bluesky";

export const runtime = 'edge'

export async function GET() {
return Response.json(blueskyClientMetadata)
}
49 changes: 12 additions & 37 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,16 @@
"use client";

import { useBskyAuthContext } from "@/contexts/bluesky";
import { useCallback, useState } from "react";

export default function Home() {
const { authenticated, bskyAuthClient } = useBskyAuthContext();

const [handle, setHandle] = useState<string>("");

const signIn = useCallback(async () => {
if (!bskyAuthClient) return;
try {
await bskyAuthClient.signIn(handle, {
scope: "atproto transition:generic",
});
} catch (err) {
console.log(err);
}
}, [handle, bskyAuthClient]);
import BlueskyAuthenticator from "@/components/BlueskyAuthenticator";
import StorachaAuthenticator from "@/components/StorachaAuthenticator";

export default function Home () {
return (
<>
<h1>Blusky Backup Webapp</h1>
<div>
<h1>Bluesky Backup Webapp</h1>
<p>Lets get started</p>
<div>
<h4>Bluesky Auth</h4>
<div>{authenticated ? "Auth" : "Not auth"}</div>
<input
onChange={(e) => {
e.preventDefault();
setHandle(e.target.value);
}}
value={handle}
placeholder="Handler"
/>
<button onClick={signIn}>#</button>
</div>
</>
);
<h4>Bluesky Auth</h4>
<BlueskyAuthenticator />

<h4>Storacha Auth</h4>
<StorachaAuthenticator />
</div>
)
}
13 changes: 11 additions & 2 deletions src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,23 @@ export default function RootProviders ({
})
);

const BskyAuthProvider = dynamic(() => import('../components/BskyAuthProvider'), {
const BskyAuthProvider = dynamic(() => import('../components/BlueskyAuthProvider'), {
loading: () => <p>Loading...</p>,
ssr: false
})

const StorachaAuthProvider = dynamic(() => import('../components/W3UIProvider'), {
loading: () => <p>Loading...</p>,
ssr: false
})

return (
<QueryClientProvider client={queryClient}>
<BskyAuthProvider>{children}</BskyAuthProvider>
<BskyAuthProvider>
<StorachaAuthProvider>
{children}
</StorachaAuthProvider>
</BskyAuthProvider>
</QueryClientProvider>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client'

import { BskyAuthContext } from "@/contexts";
import { blueskyClientMetadata } from "@/lib/bluesky";
import { Agent } from "@atproto/api";
import {
OAuthSession,
Expand Down Expand Up @@ -43,8 +44,8 @@ export const BskyAuthProvider = ({ children }: Props) => {

useEffect(() => {
const initBsky = async () => {
const bskyAuthClient = await BrowserOAuthClient.load({
clientId: "https://spread-accurately-group-misc.trycloudflare.com/",
const bskyAuthClient = new BrowserOAuthClient({
clientMetadata: blueskyClientMetadata,
handleResolver: "https://bsky.social",
});
setBskyAuthClient(bskyAuthClient);
Expand Down
41 changes: 41 additions & 0 deletions src/components/BlueskyAuthenticator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"use client";

import { useBskyAuthContext } from "@/contexts/bluesky";
import { useCallback, useState } from "react";

export default function BlueskyAuthenticator () {
const { authenticated, bskyAuthClient } = useBskyAuthContext();

const [handle, setHandle] = useState<string>("");

const signIn = useCallback(async () => {
if (!bskyAuthClient) return;
try {
await bskyAuthClient.signIn(handle, {
scope: "atproto transition:generic",
});
} catch (err) {
console.log(err);
}
}, [handle, bskyAuthClient]);

return (
<div>
{authenticated ? (
<div>Authenticated to Bluesky!</div>
) : (
<div>
<input
onChange={(e) => {
e.preventDefault();
setHandle(e.target.value);
}}
value={handle}
placeholder="Bluesky Handle"
/>
<button onClick={signIn}>#</button>
</div>
)}
</div>
);
}
18 changes: 8 additions & 10 deletions src/components/StorachaAuthenticator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import { Authenticator, useW3 } from '@w3ui/react'
import { AuthenticationEnsurer } from '@/components/Authenticator'
import { Provider as W3UIProvider } from '@w3ui/react'

function Identity () {
const [{ client, accounts }] = useW3()
Expand All @@ -21,14 +20,13 @@ function Identity () {
)
}

export default function StorachaAuthenticator() {

export default function StorachaAuthenticator () {
return (
<W3UIProvider>
<Authenticator>
<AuthenticationEnsurer>
<Identity />
</AuthenticationEnsurer>
</Authenticator>
</W3UIProvider>
<Authenticator>
<AuthenticationEnsurer>
<Identity />
</AuthenticationEnsurer>
</Authenticator>
)
}
}
8 changes: 4 additions & 4 deletions src/components/W3UIProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Provider as W3UIProvider } from '@w3ui/react'
import { Provider } from '@w3ui/react'

export default function Provider({ children }: { children: React.ReactNode }) {
export default function W3UIProvider({ children }: { children: React.ReactNode }) {
return (
<W3UIProvider>
<Provider>
{children}
</W3UIProvider>
</Provider>
)
}
17 changes: 17 additions & 0 deletions src/lib/bluesky.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { OAuthClientMetadataInput } from "@atproto/oauth-client-browser";

export const blueskyClientUri = process.env.NEXT_PUBLIC_BLUESKY_CLIENT_URI || "https://localhost:3000/"

export const blueskyClientMetadata: OAuthClientMetadataInput = {
"client_id": `${blueskyClientUri}bluesky-client-metadata`,
"client_name": "Local Dev App",
"client_uri": blueskyClientUri,
"application_type": "web",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"redirect_uris": [blueskyClientUri],
"token_endpoint_auth_method": "none",
"scope": "atproto transition:generic",
"dpop_bound_access_tokens": true

}
4 changes: 2 additions & 2 deletions wrangler.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name = "bluesky-backup-webapp"
compatibility_date = "2024-07-29"
name = "bluesky-backup-dev"
compatibility_date = "2024-09-23"
compatibility_flags = ["nodejs_compat"]
pages_build_output_dir = ".vercel/output/static"

0 comments on commit 9a5e5e7

Please # to comment.