A web app to better navigate saved skeets
1import {
2 NodeOAuthClient,
3 NodeSavedSession,
4 NodeSavedState
5} from "@atproto/oauth-client-node";
6
7const APP_URL = process.env.NEXT_PUBLIC_APP_URL;
8
9if (!APP_URL) {
10 throw new Error(
11 "NEXT_PUBLIC_APP_URL is not set. This is required for OAuth configuration."
12 );
13}
14
15const sessionStore = new Map<string, NodeSavedSession>();
16const stateStore = new Map<string, NodeSavedState>();
17
18export const atprotoClient = new NodeOAuthClient({
19 clientMetadata: {
20 application_type: "web",
21 client_id: `${APP_URL}/api/auth/atproto/client-metadata.json`,
22 client_name: "ebb&follow",
23 dpop_bound_access_tokens: true,
24 grant_types: ["authorization_code", "refresh_token"],
25 redirect_uris: [`${APP_URL}/api/auth/atproto/callback`],
26 response_types: ["code"],
27 scope: "atproto transition:generic",
28 token_endpoint_auth_method: "none"
29 },
30 handleResolver:
31 "https://bsky.social/xrpc/com.atproto.identity.resolveHandle",
32 sessionStore: {
33 async del(sub: string): Promise<void> {
34 sessionStore.delete(sub);
35 },
36 async get(sub: string): Promise<NodeSavedSession | undefined> {
37 return sessionStore.get(sub);
38 },
39 async set(sub: string, session: NodeSavedSession): Promise<void> {
40 sessionStore.set(sub, session);
41 }
42 },
43 stateStore: {
44 async del(key: string): Promise<void> {
45 stateStore.delete(key);
46 },
47 async get(key: string): Promise<NodeSavedState | undefined> {
48 return stateStore.get(key);
49 },
50 async set(key: string, internalState: NodeSavedState): Promise<void> {
51 stateStore.set(key, internalState);
52 }
53 }
54});