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

Class ApiKeyAdapter

src/server/web/auth/apikey-auth.ts:24–135  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

22 * prefixes that receive the admin role
23 */
24export class ApiKeyAdapter implements AuthAdapter {
25 private readonly store: SessionStore;
26 private readonly adminUsers: ReadonlySet<string>;
27
28 constructor(store: SessionStore) {
29 this.store = store;
30 this.adminUsers = new Set(
31 (process.env.ADMIN_USERS ?? "")
32 .split(",")
33 .map((s) => s.trim())
34 .filter(Boolean),
35 );
36 }
37
38 authenticate(req: IncomingMessage): AuthUser | null {
39 const session = this.store.getFromRequest(req);
40 if (!session || !session.encryptedApiKey) return null;
41
42 const apiKey = this.store.decrypt(session.encryptedApiKey);
43 if (!apiKey) return null;
44
45 return {
46 id: session.userId,
47 email: session.email,
48 name: session.name,
49 isAdmin:
50 session.isAdmin ||
51 this.adminUsers.has(session.userId),
52 apiKey,
53 };
54 }
55
56 setupRoutes(app: Application): void {
57 const loginHtml = this.loadLoginPage();
58
59 // GET /auth/login — serve the API key login form
60 app.get("/auth/login", (_req, res) => {
61 res.setHeader("Content-Type", "text/html");
62 res.send(loginHtml);
63 });
64
65 // POST /auth/login — validate key, create encrypted session
66 app.post(
67 "/auth/login",
68 // express.urlencoded is registered in pty-server.ts before setupRoutes
69 (req: Request, res: Response) => {
70 const apiKey = (req.body as Record<string, string>)?.api_key?.trim() ?? "";
71
72 if (!apiKey.startsWith("sk-ant-")) {
73 res.setHeader("Content-Type", "text/html");
74 res.status(400).send(
75 loginHtml.replace(
76 "<!--ERROR-->",
77 `<p class="error">Invalid API key format. Keys must start with <code>sk-ant-</code>.</p>`,
78 ),
79 );
80 return;
81 }

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected