an attempt to make a lightweight, easily self-hostable, scoped bluesky appview
1import {
2 AuthResult,
3 MethodAuthVerifier,
4 XRPCError,
5} from "npm:@atproto/xrpc-server";
6import * as borrowed from "./auth.borrowed.ts";
7
8export interface AuthConfig {
9 serviceDid: string;
10}
11
12let serviceDid: string;
13let isInitialized = false;
14
15export function setupAuth(config: AuthConfig) {
16 if (!config.serviceDid || !config.serviceDid.startsWith("did:")) {
17 throw new Error("A valid serviceDid must be provided in the auth config.");
18 }
19
20 serviceDid = config.serviceDid;
21 isInitialized = true;
22 console.log("Authentication module initialized.");
23}
24
25export async function getAuthenticatedDid(
26 req: Request
27): Promise<string | null> {
28 const authHeader = req.headers.get("Authorization");
29 return await internalGetAuthenticatedDid(authHeader ?? undefined);
30}
31
32async function internalGetAuthenticatedDid(
33 authHeader: string | undefined
34): Promise<string | null> {
35 if (!isInitialized) {
36 console.error(
37 "Authentication module has not been initialized. Call setupAuth() first."
38 );
39 return null;
40 }
41 if (!authHeader || !authHeader.startsWith("Bearer ")) {
42 return null;
43 }
44
45 try {
46 // use the verifyJWT function from the borrowed module.
47 // it handles DID resolution and JWT verification internally.
48 // thanks usounds and Skyblur !
49 const result = await borrowed.verifyJWT(authHeader, serviceDid);
50
51 if (!result.payload.iss) {
52 throw new Error("Missing issuer (iss) in verified JWT payload");
53 }
54
55 return result.payload.iss as string;
56 } catch (err) {
57 console.warn(
58 "JWT verification failed:",
59 err instanceof Error ? err.message : String(err)
60 );
61 return null;
62 }
63}
64/**
65 * @deprecated dont use this use getAuthenticatedDid() instead
66 * @param param0
67 * @returns
68 */
69export const authVerifier: MethodAuthVerifier<AuthResult> = async ({ req }) => {
70 //console.log("help us all fuck you",req)
71 console.log("you are doing well")
72 const url = (req as any).url;
73 const params = (req as any).params ?? {};
74 console.log("Request info:", { url, params });
75 return {
76 credentials: "did:plc:mn45tewwnse5btfftvd3powc",
77 };
78 const authHeader = (req as any).headers["authorization"];
79
80 const did = await internalGetAuthenticatedDid(authHeader);
81
82 // throw this later dont do it here
83 // if (!did) {
84 // // i dont know the correct xrpc spec for this
85 // throw new XRPCError(401, 'AuthenticationRequired', 'Invalid or missing authentication token.');
86 // }
87
88 console.log(`Successfully authenticated DID: ${did}`);
89
90 return {
91 credentials: {
92 did: did,
93 },
94 };
95};