A webapp implementation of thanosSnap
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Partial ATProto OAuth

modamo-gh 29c70c86 f396c7b7

+616 -2
+50
app/api/auth/atproto/callback/route.ts
··· 1 + import { atprotoClient } from "@/lib/atprotoAuth"; 2 + import { Agent } from "@atproto/api"; 3 + import { cookies } from "next/headers"; 4 + import { NextRequest, NextResponse } from "next/server"; 5 + 6 + const APP_URL = process.env.NEXT_PUBLIC_APP_URL; 7 + 8 + if (!APP_URL) { 9 + throw new Error( 10 + "NEXT_PUBLIC_APP_URL is not set. This is required for OAuth configuration." 11 + ); 12 + } 13 + 14 + export async function GET(request: NextRequest) { 15 + try { 16 + const params = request.nextUrl.searchParams; 17 + const { session } = await atprotoClient.callback(params); 18 + 19 + console.log(`User authenticated as: ${session.did}`); 20 + 21 + const sessionString = JSON.stringify(session); 22 + 23 + (await cookies()).set("atproto_session", sessionString, { 24 + httpOnly: true, 25 + maxAge: 60 * 60 * 24 * 30, 26 + path: "/", 27 + sameSite: "lax", 28 + secure: true 29 + }); 30 + 31 + const agent = new Agent(session); 32 + 33 + await agent.getProfile({ actor: session.did }); 34 + 35 + const redirectURL = new URL("/", APP_URL); 36 + 37 + redirectURL.searchParams.set("atproto_did", session.did); 38 + redirectURL.searchParams.set("auth_status", "success"); 39 + 40 + return NextResponse.redirect(redirectURL); 41 + } catch (error) { 42 + console.error("ATProto Callback Error:", error); 43 + 44 + const redirectURL = new URL("/", APP_URL); 45 + 46 + redirectURL.searchParams.set("auth_error", "failed"); 47 + 48 + return NextResponse.redirect(redirectURL); 49 + } 50 + }
+8
app/api/auth/atproto/client-metadata.json/route.ts
··· 1 + import { atprotoClient } from "@/lib/atprotoAuth"; 2 + import { NextResponse } from "next/server"; 3 + 4 + export async function GET() { 5 + return NextResponse.json(atprotoClient.clientMetadata, { 6 + headers: { "Content-Type": "application/json" } 7 + }); 8 + }
+21
app/api/auth/atproto/login/route.ts
··· 1 + import { atprotoClient } from "@/lib/atprotoAuth"; 2 + import { NextRequest, NextResponse } from "next/server"; 3 + 4 + export async function POST(request: NextRequest) { 5 + const { atProtoIdentifier } = await request.json(); 6 + 7 + try { 8 + const url = await atprotoClient.authorize(atProtoIdentifier, { 9 + state: crypto.randomUUID() 10 + }); 11 + 12 + return NextResponse.json({ 13 + url: url.toString() 14 + }); 15 + } catch (error) { 16 + return NextResponse.json( 17 + { error: error.message, success: false }, 18 + { status: 401 } 19 + ); 20 + } 21 + }
+55 -1
app/page.tsx
··· 9 9 subsets: ["latin"], 10 10 weight: ["300"] 11 11 }); 12 + const loginToATProto = async () => { 13 + setIsLoggingIn(true); 14 + 15 + console.log(atProtoIdentifier); 16 + 17 + try { 18 + const response = await fetch("/api/auth/atproto/login", { 19 + body: JSON.stringify({ 20 + atProtoIdentifier 21 + }), 22 + headers: { "Content-Type": "application/json" }, 23 + method: "POST" 24 + }); 25 + const data = await response.json(); 26 + 27 + if (response.ok && data.url) { 28 + window.location.href = data.url; 29 + } else { 30 + console.error("Login initiation failed:", data.error); 31 + 32 + setIsLoggingIn(false); 33 + } 34 + } catch (error) { 35 + console.error("Error initiating AT Protocol OAuth:", error); 36 + 37 + setIsLoggingIn(false); 38 + } 39 + }; 12 40 const Home = () => { 13 41 const [atProtoIdentifier, setAtProtoIdentifier] = useState(""); 14 42 43 + const loginToATProto = async () => { 44 + console.log(atProtoIdentifier); 45 + 46 + try { 47 + const response = await fetch("/api/auth/atproto/login", { 48 + body: JSON.stringify({ 49 + atProtoIdentifier 50 + }), 51 + headers: { "Content-Type": "application/json" }, 52 + method: "POST" 53 + }); 54 + const data = await response.json(); 55 + 56 + if (response.ok && data.url) { 57 + window.location.href = data.url; 58 + } else { 59 + console.error("Login initiation failed:", data.error); 60 + } 61 + } catch (error) { 62 + console.error("Error initiating AT Protocol OAuth:", error); 63 + } 64 + }; 65 + 15 66 return ( 16 67 <div className="bg-linear-to-br flex flex-col from-[#0081A7] gap-4 items-center justify-center to-[#FDFCDC] via-[#00AFB9] h-screen w-screen"> 17 68 <h1 className={`${manrope.className} text-4xl`}>ebb&follow</h1> ··· 24 75 value={atProtoIdentifier} 25 76 /> 26 77 </div> 27 - <button className="bg-white/90 active:bg-white hover:cursor-pointer h-12 rounded-lg text-xl text-[#00AFB9] w-1/8"> 78 + <button 79 + className="bg-white/90 active:bg-white hover:cursor-pointer h-12 rounded-lg text-xl text-[#00AFB9] w-1/8" 80 + onClick={loginToATProto} 81 + > 28 82 Log In 29 83 </button> 30 84 </div>
+54
lib/atprotoAuth.ts
··· 1 + import { 2 + NodeOAuthClient, 3 + NodeSavedSession, 4 + NodeSavedState 5 + } from "@atproto/oauth-client-node"; 6 + 7 + const APP_URL = process.env.NEXT_PUBLIC_APP_URL; 8 + 9 + if (!APP_URL) { 10 + throw new Error( 11 + "NEXT_PUBLIC_APP_URL is not set. This is required for OAuth configuration." 12 + ); 13 + } 14 + 15 + const sessionStore = new Map<string, NodeSavedSession>(); 16 + const stateStore = new Map<string, NodeSavedState>(); 17 + 18 + export 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 + });
+426 -1
package-lock.json
··· 8 8 "name": "ebbandfollow", 9 9 "version": "0.1.0", 10 10 "dependencies": { 11 + "@atproto/api": "^0.17.7", 12 + "@atproto/oauth-client-node": "^0.3.10", 11 13 "lucide-react": "^0.552.0", 12 14 "next": "16.0.1", 13 15 "react": "19.2.0", ··· 37 39 "url": "https://github.com/sponsors/sindresorhus" 38 40 } 39 41 }, 42 + "node_modules/@atproto-labs/did-resolver": { 43 + "version": "0.2.2", 44 + "resolved": "https://registry.npmjs.org/@atproto-labs/did-resolver/-/did-resolver-0.2.2.tgz", 45 + "integrity": "sha512-ca2B7xR43tVoQ8XxBvha58DXwIH8cIyKQl6lpOKGkPUrJuFoO4iCLlDiSDi2Ueh+yE1rMDPP/qveHdajgDX3WQ==", 46 + "license": "MIT", 47 + "dependencies": { 48 + "@atproto-labs/fetch": "0.2.3", 49 + "@atproto-labs/pipe": "0.1.1", 50 + "@atproto-labs/simple-store": "0.3.0", 51 + "@atproto-labs/simple-store-memory": "0.1.4", 52 + "@atproto/did": "0.2.1", 53 + "zod": "^3.23.8" 54 + } 55 + }, 56 + "node_modules/@atproto-labs/did-resolver/node_modules/zod": { 57 + "version": "3.25.76", 58 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 59 + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 60 + "license": "MIT", 61 + "funding": { 62 + "url": "https://github.com/sponsors/colinhacks" 63 + } 64 + }, 65 + "node_modules/@atproto-labs/fetch": { 66 + "version": "0.2.3", 67 + "resolved": "https://registry.npmjs.org/@atproto-labs/fetch/-/fetch-0.2.3.tgz", 68 + "integrity": "sha512-NZtbJOCbxKUFRFKMpamT38PUQMY0hX0p7TG5AEYOPhZKZEP7dHZ1K2s1aB8MdVH0qxmqX7nQleNrrvLf09Zfdw==", 69 + "license": "MIT", 70 + "dependencies": { 71 + "@atproto-labs/pipe": "0.1.1" 72 + } 73 + }, 74 + "node_modules/@atproto-labs/fetch-node": { 75 + "version": "0.2.0", 76 + "resolved": "https://registry.npmjs.org/@atproto-labs/fetch-node/-/fetch-node-0.2.0.tgz", 77 + "integrity": "sha512-Krq09nH/aeoiU2s9xdHA0FjTEFWG9B5FFenipv1iRixCcPc7V3DhTNDawxG9gI8Ny0k4dBVS9WTRN/IDzBx86Q==", 78 + "license": "MIT", 79 + "dependencies": { 80 + "@atproto-labs/fetch": "0.2.3", 81 + "@atproto-labs/pipe": "0.1.1", 82 + "ipaddr.js": "^2.1.0", 83 + "undici": "^6.14.1" 84 + }, 85 + "engines": { 86 + "node": ">=18.7.0" 87 + } 88 + }, 89 + "node_modules/@atproto-labs/handle-resolver": { 90 + "version": "0.3.2", 91 + "resolved": "https://registry.npmjs.org/@atproto-labs/handle-resolver/-/handle-resolver-0.3.2.tgz", 92 + "integrity": "sha512-KIerCzh3qb+zZoqWbIvTlvBY0XPq0r56kwViaJY/LTe/3oPO2JaqlYKS/F4dByWBhHK6YoUOJ0sWrh6PMJl40A==", 93 + "license": "MIT", 94 + "dependencies": { 95 + "@atproto-labs/simple-store": "0.3.0", 96 + "@atproto-labs/simple-store-memory": "0.1.4", 97 + "@atproto/did": "0.2.1", 98 + "zod": "^3.23.8" 99 + } 100 + }, 101 + "node_modules/@atproto-labs/handle-resolver-node": { 102 + "version": "0.1.21", 103 + "resolved": "https://registry.npmjs.org/@atproto-labs/handle-resolver-node/-/handle-resolver-node-0.1.21.tgz", 104 + "integrity": "sha512-fuJy5Px5pGF3lJX/ATdurbT8tbmaFWtf+PPxAQDFy7ot2no3t+iaAgymhyxYymrssOuWs6BwOP8tyF3VrfdwtQ==", 105 + "license": "MIT", 106 + "dependencies": { 107 + "@atproto-labs/fetch-node": "0.2.0", 108 + "@atproto-labs/handle-resolver": "0.3.2", 109 + "@atproto/did": "0.2.1" 110 + }, 111 + "engines": { 112 + "node": ">=18.7.0" 113 + } 114 + }, 115 + "node_modules/@atproto-labs/handle-resolver/node_modules/zod": { 116 + "version": "3.25.76", 117 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 118 + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 119 + "license": "MIT", 120 + "funding": { 121 + "url": "https://github.com/sponsors/colinhacks" 122 + } 123 + }, 124 + "node_modules/@atproto-labs/identity-resolver": { 125 + "version": "0.3.2", 126 + "resolved": "https://registry.npmjs.org/@atproto-labs/identity-resolver/-/identity-resolver-0.3.2.tgz", 127 + "integrity": "sha512-MYxO9pe0WsFyi5HFdKAwqIqHfiF2kBPoVhAIuH/4PYHzGr799ED47xLhNMxR3ZUYrJm5+TQzWXypGZ0Btw1Ffw==", 128 + "license": "MIT", 129 + "dependencies": { 130 + "@atproto-labs/did-resolver": "0.2.2", 131 + "@atproto-labs/handle-resolver": "0.3.2" 132 + } 133 + }, 134 + "node_modules/@atproto-labs/pipe": { 135 + "version": "0.1.1", 136 + "resolved": "https://registry.npmjs.org/@atproto-labs/pipe/-/pipe-0.1.1.tgz", 137 + "integrity": "sha512-hdNw2oUs2B6BN1lp+32pF7cp8EMKuIN5Qok2Vvv/aOpG/3tNSJ9YkvfI0k6Zd188LeDDYRUpYpxcoFIcGH/FNg==", 138 + "license": "MIT" 139 + }, 140 + "node_modules/@atproto-labs/simple-store": { 141 + "version": "0.3.0", 142 + "resolved": "https://registry.npmjs.org/@atproto-labs/simple-store/-/simple-store-0.3.0.tgz", 143 + "integrity": "sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ==", 144 + "license": "MIT" 145 + }, 146 + "node_modules/@atproto-labs/simple-store-memory": { 147 + "version": "0.1.4", 148 + "resolved": "https://registry.npmjs.org/@atproto-labs/simple-store-memory/-/simple-store-memory-0.1.4.tgz", 149 + "integrity": "sha512-3mKY4dP8I7yKPFj9VKpYyCRzGJOi5CEpOLPlRhoJyLmgs3J4RzDrjn323Oakjz2Aj2JzRU/AIvWRAZVhpYNJHw==", 150 + "license": "MIT", 151 + "dependencies": { 152 + "@atproto-labs/simple-store": "0.3.0", 153 + "lru-cache": "^10.2.0" 154 + } 155 + }, 156 + "node_modules/@atproto-labs/simple-store-memory/node_modules/lru-cache": { 157 + "version": "10.4.3", 158 + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", 159 + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", 160 + "license": "ISC" 161 + }, 162 + "node_modules/@atproto/api": { 163 + "version": "0.17.7", 164 + "resolved": "https://registry.npmjs.org/@atproto/api/-/api-0.17.7.tgz", 165 + "integrity": "sha512-V+OJBZq9chcrD21xk1bUa6oc5DSKfQj5DmUPf5rmZncqL1w9ZEbS38H5cMyqqdhfgo2LWeDRdZHD0rvNyJsIaw==", 166 + "license": "MIT", 167 + "dependencies": { 168 + "@atproto/common-web": "^0.4.3", 169 + "@atproto/lexicon": "^0.5.1", 170 + "@atproto/syntax": "^0.4.1", 171 + "@atproto/xrpc": "^0.7.5", 172 + "await-lock": "^2.2.2", 173 + "multiformats": "^9.9.0", 174 + "tlds": "^1.234.0", 175 + "zod": "^3.23.8" 176 + } 177 + }, 178 + "node_modules/@atproto/api/node_modules/zod": { 179 + "version": "3.25.76", 180 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 181 + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 182 + "license": "MIT", 183 + "funding": { 184 + "url": "https://github.com/sponsors/colinhacks" 185 + } 186 + }, 187 + "node_modules/@atproto/common-web": { 188 + "version": "0.4.3", 189 + "resolved": "https://registry.npmjs.org/@atproto/common-web/-/common-web-0.4.3.tgz", 190 + "integrity": "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg==", 191 + "license": "MIT", 192 + "dependencies": { 193 + "graphemer": "^1.4.0", 194 + "multiformats": "^9.9.0", 195 + "uint8arrays": "3.0.0", 196 + "zod": "^3.23.8" 197 + } 198 + }, 199 + "node_modules/@atproto/common-web/node_modules/zod": { 200 + "version": "3.25.76", 201 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 202 + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 203 + "license": "MIT", 204 + "funding": { 205 + "url": "https://github.com/sponsors/colinhacks" 206 + } 207 + }, 208 + "node_modules/@atproto/did": { 209 + "version": "0.2.1", 210 + "resolved": "https://registry.npmjs.org/@atproto/did/-/did-0.2.1.tgz", 211 + "integrity": "sha512-1i5BTU2GnBaaeYWhxUOnuEKFVq9euT5+dQPFabHpa927BlJ54PmLGyBBaOI7/NbLmN5HWwBa18SBkMpg3jGZRA==", 212 + "license": "MIT", 213 + "dependencies": { 214 + "zod": "^3.23.8" 215 + } 216 + }, 217 + "node_modules/@atproto/did/node_modules/zod": { 218 + "version": "3.25.76", 219 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 220 + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 221 + "license": "MIT", 222 + "funding": { 223 + "url": "https://github.com/sponsors/colinhacks" 224 + } 225 + }, 226 + "node_modules/@atproto/jwk": { 227 + "version": "0.6.0", 228 + "resolved": "https://registry.npmjs.org/@atproto/jwk/-/jwk-0.6.0.tgz", 229 + "integrity": "sha512-bDoJPvt7TrQVi/rBfBrSSpGykhtIriKxeYCYQTiPRKFfyRhbgpElF0wPXADjIswnbzZdOwbY63az4E/CFVT3Tw==", 230 + "license": "MIT", 231 + "dependencies": { 232 + "multiformats": "^9.9.0", 233 + "zod": "^3.23.8" 234 + } 235 + }, 236 + "node_modules/@atproto/jwk-jose": { 237 + "version": "0.1.11", 238 + "resolved": "https://registry.npmjs.org/@atproto/jwk-jose/-/jwk-jose-0.1.11.tgz", 239 + "integrity": "sha512-i4Fnr2sTBYmMmHXl7NJh8GrCH+tDQEVWrcDMDnV5DjJfkgT17wIqvojIw9SNbSL4Uf0OtfEv6AgG0A+mgh8b5Q==", 240 + "license": "MIT", 241 + "dependencies": { 242 + "@atproto/jwk": "0.6.0", 243 + "jose": "^5.2.0" 244 + } 245 + }, 246 + "node_modules/@atproto/jwk-webcrypto": { 247 + "version": "0.2.0", 248 + "resolved": "https://registry.npmjs.org/@atproto/jwk-webcrypto/-/jwk-webcrypto-0.2.0.tgz", 249 + "integrity": "sha512-UmgRrrEAkWvxwhlwe30UmDOdTEFidlIzBC7C3cCbeJMcBN1x8B3KH+crXrsTqfWQBG58mXgt8wgSK3Kxs2LhFg==", 250 + "license": "MIT", 251 + "dependencies": { 252 + "@atproto/jwk": "0.6.0", 253 + "@atproto/jwk-jose": "0.1.11", 254 + "zod": "^3.23.8" 255 + } 256 + }, 257 + "node_modules/@atproto/jwk-webcrypto/node_modules/zod": { 258 + "version": "3.25.76", 259 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 260 + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 261 + "license": "MIT", 262 + "funding": { 263 + "url": "https://github.com/sponsors/colinhacks" 264 + } 265 + }, 266 + "node_modules/@atproto/jwk/node_modules/zod": { 267 + "version": "3.25.76", 268 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 269 + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 270 + "license": "MIT", 271 + "funding": { 272 + "url": "https://github.com/sponsors/colinhacks" 273 + } 274 + }, 275 + "node_modules/@atproto/lexicon": { 276 + "version": "0.5.1", 277 + "resolved": "https://registry.npmjs.org/@atproto/lexicon/-/lexicon-0.5.1.tgz", 278 + "integrity": "sha512-y8AEtYmfgVl4fqFxqXAeGvhesiGkxiy3CWoJIfsFDDdTlZUC8DFnZrYhcqkIop3OlCkkljvpSJi1hbeC1tbi8A==", 279 + "license": "MIT", 280 + "dependencies": { 281 + "@atproto/common-web": "^0.4.3", 282 + "@atproto/syntax": "^0.4.1", 283 + "iso-datestring-validator": "^2.2.2", 284 + "multiformats": "^9.9.0", 285 + "zod": "^3.23.8" 286 + } 287 + }, 288 + "node_modules/@atproto/lexicon/node_modules/zod": { 289 + "version": "3.25.76", 290 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 291 + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 292 + "license": "MIT", 293 + "funding": { 294 + "url": "https://github.com/sponsors/colinhacks" 295 + } 296 + }, 297 + "node_modules/@atproto/oauth-client": { 298 + "version": "0.5.8", 299 + "resolved": "https://registry.npmjs.org/@atproto/oauth-client/-/oauth-client-0.5.8.tgz", 300 + "integrity": "sha512-7YEym6d97+Dd73qGdkQTXi5La8xvCQxwRUDzzlR/NVAARa9a4YP7MCmqBJVeP2anT0By+DSAPyPDLTsxcjIcCg==", 301 + "license": "MIT", 302 + "dependencies": { 303 + "@atproto-labs/did-resolver": "0.2.2", 304 + "@atproto-labs/fetch": "0.2.3", 305 + "@atproto-labs/handle-resolver": "0.3.2", 306 + "@atproto-labs/identity-resolver": "0.3.2", 307 + "@atproto-labs/simple-store": "0.3.0", 308 + "@atproto-labs/simple-store-memory": "0.1.4", 309 + "@atproto/did": "0.2.1", 310 + "@atproto/jwk": "0.6.0", 311 + "@atproto/oauth-types": "0.5.0", 312 + "@atproto/xrpc": "0.7.5", 313 + "core-js": "^3", 314 + "multiformats": "^9.9.0", 315 + "zod": "^3.23.8" 316 + } 317 + }, 318 + "node_modules/@atproto/oauth-client-node": { 319 + "version": "0.3.10", 320 + "resolved": "https://registry.npmjs.org/@atproto/oauth-client-node/-/oauth-client-node-0.3.10.tgz", 321 + "integrity": "sha512-6khKlJqu1Ed5rt3rzcTD5hymB6JUjKdOHWYXwiphw4inkAIo6GxLCighI4eGOqZorYk2j8ueeTNB6KsgH0kcRw==", 322 + "license": "MIT", 323 + "dependencies": { 324 + "@atproto-labs/did-resolver": "0.2.2", 325 + "@atproto-labs/handle-resolver-node": "0.1.21", 326 + "@atproto-labs/simple-store": "0.3.0", 327 + "@atproto/did": "0.2.1", 328 + "@atproto/jwk": "0.6.0", 329 + "@atproto/jwk-jose": "0.1.11", 330 + "@atproto/jwk-webcrypto": "0.2.0", 331 + "@atproto/oauth-client": "0.5.8", 332 + "@atproto/oauth-types": "0.5.0" 333 + }, 334 + "engines": { 335 + "node": ">=18.7.0" 336 + } 337 + }, 338 + "node_modules/@atproto/oauth-client/node_modules/zod": { 339 + "version": "3.25.76", 340 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 341 + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 342 + "license": "MIT", 343 + "funding": { 344 + "url": "https://github.com/sponsors/colinhacks" 345 + } 346 + }, 347 + "node_modules/@atproto/oauth-types": { 348 + "version": "0.5.0", 349 + "resolved": "https://registry.npmjs.org/@atproto/oauth-types/-/oauth-types-0.5.0.tgz", 350 + "integrity": "sha512-33xz7HcXhbl+XRqbIMVu3GE02iK1nKe2oMWENASsfZEYbCz2b9ZOarOFuwi7g4LKqpGowGp0iRKsQHFcq4SDaQ==", 351 + "license": "MIT", 352 + "dependencies": { 353 + "@atproto/did": "0.2.1", 354 + "@atproto/jwk": "0.6.0", 355 + "zod": "^3.23.8" 356 + } 357 + }, 358 + "node_modules/@atproto/oauth-types/node_modules/zod": { 359 + "version": "3.25.76", 360 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 361 + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 362 + "license": "MIT", 363 + "funding": { 364 + "url": "https://github.com/sponsors/colinhacks" 365 + } 366 + }, 367 + "node_modules/@atproto/syntax": { 368 + "version": "0.4.1", 369 + "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.4.1.tgz", 370 + "integrity": "sha512-CJdImtLAiFO+0z3BWTtxwk6aY5w4t8orHTMVJgkf++QRJWTxPbIFko/0hrkADB7n2EruDxDSeAgfUGehpH6ngw==", 371 + "license": "MIT" 372 + }, 373 + "node_modules/@atproto/xrpc": { 374 + "version": "0.7.5", 375 + "resolved": "https://registry.npmjs.org/@atproto/xrpc/-/xrpc-0.7.5.tgz", 376 + "integrity": "sha512-MUYNn5d2hv8yVegRL0ccHvTHAVj5JSnW07bkbiaz96UH45lvYNRVwt44z+yYVnb0/mvBzyD3/ZQ55TRGt7fHkA==", 377 + "license": "MIT", 378 + "dependencies": { 379 + "@atproto/lexicon": "^0.5.1", 380 + "zod": "^3.23.8" 381 + } 382 + }, 383 + "node_modules/@atproto/xrpc/node_modules/zod": { 384 + "version": "3.25.76", 385 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 386 + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 387 + "license": "MIT", 388 + "funding": { 389 + "url": "https://github.com/sponsors/colinhacks" 390 + } 391 + }, 40 392 "node_modules/@babel/code-frame": { 41 393 "version": "7.27.1", 42 394 "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", ··· 2374 2726 "url": "https://github.com/sponsors/ljharb" 2375 2727 } 2376 2728 }, 2729 + "node_modules/await-lock": { 2730 + "version": "2.2.2", 2731 + "resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.2.2.tgz", 2732 + "integrity": "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==", 2733 + "license": "MIT" 2734 + }, 2377 2735 "node_modules/axe-core": { 2378 2736 "version": "4.11.0", 2379 2737 "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz", ··· 2605 2963 "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", 2606 2964 "dev": true, 2607 2965 "license": "MIT" 2966 + }, 2967 + "node_modules/core-js": { 2968 + "version": "3.46.0", 2969 + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.46.0.tgz", 2970 + "integrity": "sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA==", 2971 + "hasInstallScript": true, 2972 + "license": "MIT", 2973 + "funding": { 2974 + "type": "opencollective", 2975 + "url": "https://opencollective.com/core-js" 2976 + } 2608 2977 }, 2609 2978 "node_modules/cross-spawn": { 2610 2979 "version": "7.0.6", ··· 3779 4148 "version": "1.4.0", 3780 4149 "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 3781 4150 "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 3782 - "dev": true, 3783 4151 "license": "MIT" 3784 4152 }, 3785 4153 "node_modules/has-bigints": { ··· 3945 4313 "node": ">= 0.4" 3946 4314 } 3947 4315 }, 4316 + "node_modules/ipaddr.js": { 4317 + "version": "2.2.0", 4318 + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", 4319 + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", 4320 + "license": "MIT", 4321 + "engines": { 4322 + "node": ">= 10" 4323 + } 4324 + }, 3948 4325 "node_modules/is-array-buffer": { 3949 4326 "version": "3.0.5", 3950 4327 "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", ··· 4374 4751 "dev": true, 4375 4752 "license": "ISC" 4376 4753 }, 4754 + "node_modules/iso-datestring-validator": { 4755 + "version": "2.2.2", 4756 + "resolved": "https://registry.npmjs.org/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz", 4757 + "integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==", 4758 + "license": "MIT" 4759 + }, 4377 4760 "node_modules/iterator.prototype": { 4378 4761 "version": "1.1.5", 4379 4762 "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", ··· 4400 4783 "license": "MIT", 4401 4784 "bin": { 4402 4785 "jiti": "lib/jiti-cli.mjs" 4786 + } 4787 + }, 4788 + "node_modules/jose": { 4789 + "version": "5.10.0", 4790 + "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", 4791 + "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", 4792 + "license": "MIT", 4793 + "funding": { 4794 + "url": "https://github.com/sponsors/panva" 4403 4795 } 4404 4796 }, 4405 4797 "node_modules/js-tokens": { ··· 4918 5310 "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 4919 5311 "dev": true, 4920 5312 "license": "MIT" 5313 + }, 5314 + "node_modules/multiformats": { 5315 + "version": "9.9.0", 5316 + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", 5317 + "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==", 5318 + "license": "(Apache-2.0 AND MIT)" 4921 5319 }, 4922 5320 "node_modules/nanoid": { 4923 5321 "version": "3.3.11", ··· 6096 6494 "url": "https://github.com/sponsors/jonschlinkert" 6097 6495 } 6098 6496 }, 6497 + "node_modules/tlds": { 6498 + "version": "1.261.0", 6499 + "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.261.0.tgz", 6500 + "integrity": "sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==", 6501 + "license": "MIT", 6502 + "bin": { 6503 + "tlds": "bin.js" 6504 + } 6505 + }, 6099 6506 "node_modules/to-regex-range": { 6100 6507 "version": "5.0.1", 6101 6508 "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", ··· 6283 6690 "typescript": ">=4.8.4 <6.0.0" 6284 6691 } 6285 6692 }, 6693 + "node_modules/uint8arrays": { 6694 + "version": "3.0.0", 6695 + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.0.0.tgz", 6696 + "integrity": "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==", 6697 + "license": "MIT", 6698 + "dependencies": { 6699 + "multiformats": "^9.4.2" 6700 + } 6701 + }, 6286 6702 "node_modules/unbox-primitive": { 6287 6703 "version": "1.1.0", 6288 6704 "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", ··· 6300 6716 }, 6301 6717 "funding": { 6302 6718 "url": "https://github.com/sponsors/ljharb" 6719 + } 6720 + }, 6721 + "node_modules/undici": { 6722 + "version": "6.22.0", 6723 + "resolved": "https://registry.npmjs.org/undici/-/undici-6.22.0.tgz", 6724 + "integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==", 6725 + "license": "MIT", 6726 + "engines": { 6727 + "node": ">=18.17" 6303 6728 } 6304 6729 }, 6305 6730 "node_modules/undici-types": {
+2
package.json
··· 9 9 "lint": "eslint" 10 10 }, 11 11 "dependencies": { 12 + "@atproto/api": "^0.17.7", 13 + "@atproto/oauth-client-node": "^0.3.10", 12 14 "lucide-react": "^0.552.0", 13 15 "next": "16.0.1", 14 16 "react": "19.2.0",