forked from
rocksky.app/rocksky
A decentralized music tracking and discovery platform built on AT Protocol 馃幍
1import { MethodAuthContext, verifyJwt } from "@atp/xrpc-server";
2import { DidResolver } from "@atp/identity";
3
4export type NullOutput = {
5 credentials: {
6 type: "none";
7 iss: null;
8 };
9 artifacts: unknown;
10};
11
12export type StandardOutput = {
13 credentials: {
14 type: "standard";
15 iss: string;
16 };
17 artifacts: unknown;
18};
19
20export class AuthVerifier {
21 ownDid: string;
22 didResolver: DidResolver;
23 constructor(ownDid: string, didResolver: DidResolver) {
24 this.ownDid = ownDid ?? "";
25 this.didResolver = didResolver;
26 }
27
28 standardOptional = async (
29 ctx: MethodAuthContext,
30 ): Promise<StandardOutput | NullOutput> => {
31 try {
32 const authorization = ctx.req.headers.get("Authorization") ?? "";
33
34 if (!authorization) {
35 return this.nullCreds();
36 }
37
38 // Check for Bearer token
39 const BEARER = "Bearer ";
40 if (authorization.startsWith(BEARER)) {
41 const jwt = authorization.replace(BEARER, "").trim();
42
43 try {
44 const parsed = await verifyJwt(
45 jwt,
46 null,
47 null,
48 async (did: string) => {
49 return await this.didResolver.resolveAtprotoKey(did);
50 },
51 );
52 return {
53 credentials: {
54 type: "standard",
55 iss: parsed.iss,
56 },
57 artifacts: null,
58 };
59 } catch (error) {
60 // Log JWT verification errors for debugging
61 console.error("JWT verification failed:", error);
62 console.error(
63 "JWT preview:",
64 jwt.length > 20 ? jwt.substring(0, 20) + "..." : jwt,
65 );
66 console.error("ownDid:", this.ownDid);
67 // If JWT verification fails, treat as unauthenticated
68 return this.nullCreds();
69 }
70 } else {
71 return this.nullCreds();
72 }
73 } catch (error) {
74 console.error("Unexpected error in standardOptional:", error);
75 return this.nullCreds();
76 }
77 };
78 nullCreds = (): NullOutput => {
79 return {
80 credentials: {
81 type: "none",
82 iss: null,
83 },
84 artifacts: null,
85 };
86 };
87}