MCPcopy
hub / github.com/codeaashu/claude-code / TokenAuthAdapter

Class TokenAuthAdapter

src/server/web/auth/token-auth.ts:16–81  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

14 * user or trusted-network deployments where you just want a simple password.
15 */
16export class TokenAuthAdapter implements AuthAdapter {
17 private readonly token: string | undefined;
18 private readonly adminUsers: ReadonlySet<string>;
19
20 constructor() {
21 this.token = process.env.AUTH_TOKEN;
22 this.adminUsers = new Set(
23 (process.env.ADMIN_USERS ?? "")
24 .split(",")
25 .map((s) => s.trim())
26 .filter(Boolean),
27 );
28 }
29
30 authenticate(req: IncomingMessage): AuthUser | null {
31 if (!this.token) {
32 return { id: "default", isAdmin: true };
33 }
34 if (this.extractToken(req) === this.token) {
35 return {
36 id: "default",
37 isAdmin: this.adminUsers.size === 0 || this.adminUsers.has("default"),
38 };
39 }
40 return null;
41 }
42
43 setupRoutes(_app: Application): void {
44 // Token auth needs no login/callback/logout routes.
45 }
46
47 requireAuth(req: Request, res: Response, next: NextFunction): void {
48 const user = this.authenticate(req as unknown as IncomingMessage);
49 if (!user) {
50 res.status(401).json({ error: "Unauthorized" });
51 return;
52 }
53 (req as AuthenticatedRequest).user = user;
54 next();
55 }
56
57 // ── Internals ─────────────────────────────────────────────────────────────
58
59 private extractToken(req: IncomingMessage): string | null {
60 // 1. ?token= query param (used by WebSocket clients and simple links)
61 const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
62 const qp = url.searchParams.get("token");
63 if (qp) return qp;
64
65 // 2. Authorization: Bearer <token>
66 const auth = req.headers["authorization"];
67 if (auth?.startsWith("Bearer ")) return auth.slice(7);
68
69 // 3. Cookie cc_token (set by token-auth login page if any)
70 const cookieHeader = req.headers.cookie ?? "";
71 for (const part of cookieHeader.split(";")) {
72 const eq = part.indexOf("=");
73 if (eq === -1) continue;

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected