MCPcopy Create free account
hub / github.com/boringstack-xyz/boringstack / verifyAuthCookie

Function verifyAuthCookie

apps/api/src/api/auth/auth.plugin.ts:97–140  ·  view source on GitHub ↗
(
  jwt: { verify: (token: string) => Promise<unknown> },
  cookieValue: unknown
)

Source from the content-addressed store, hash-verified

95 * the two guards interpret differently.
96 */
97const verifyAuthCookie = async (
98 jwt: { verify: (token: string) => Promise<unknown> },
99 cookieValue: unknown
100): Promise<{ user: IUser; accountId: string } | null> => {
101 if (cookieValue === undefined) {
102 return null;
103 }
104
105 if (typeof cookieValue !== "string") {
106 throw ApiErrors.unauthorized("Invalid authentication cookie");
107 }
108
109 try {
110 const verified = await jwt.verify(cookieValue);
111 const parsed = parseAuthJWTPayload(verified);
112
113 if (parsed.kind !== "ok") {
114 throw ApiErrors.unauthorized("Invalid token payload");
115 }
116
117 await assertNotRevoked(parsed);
118
119 const user = await db.query.users.findFirst({
120 where: eq(users.id, parsed.userId),
121 });
122
123 if (!user) {
124 throw ApiErrors.unauthorized("User not found");
125 }
126
127 /*
128 * Tag the active Sentry scope with the user so any error captured
129 * for the rest of this request carries `user.id` + `user.email`.
130 * The Pino mixin also reads this scope to inject `userId` on every
131 * log record, so a Grafana log line and a GlitchTip error event can
132 * be correlated by the same id. No-op when SENTRY_DSN is unset.
133 */
134 Sentry.setUser({ id: user.id, email: user.email });
135
136 return { user, accountId: parsed.accountId };
137 } catch (err: unknown) {
138 return translateJwtError(err);
139 }
140};
141
142/**
143 * Required-auth guard. Use on every endpoint where an anonymous caller

Callers 2

requireAuthFunction · 0.85
tryAuthFunction · 0.85

Calls 4

parseAuthJWTPayloadFunction · 0.90
assertNotRevokedFunction · 0.85
translateJwtErrorFunction · 0.85
verifyMethod · 0.45

Tested by

no test coverage detected