Skip to content
Source
Sign inSign up

telemetryAuth.ts

44 lines2.0 KB

1import { decodeJwt, type JWTVerifyGetKey } from "jose";
2import { authorize } from "../vendor/vite-plus-remote-cache-cloudflare/src/auth.ts";
3import type { Scope } from "../vendor/vite-plus-remote-cache-cloudflare/src/database.ts";
4import { HttpError } from "../vendor/vite-plus-remote-cache-cloudflare/src/errors.ts";
5​
6function audienceScope(request: Request, scope: Scope, telemetry = false) {
7 const authorization = request.headers.get("authorization");
8 if (!authorization || authorization.length > 16 * 1024) throw new HttpError(401, "invalid_token");
9 let payload;
10 try {
11 payload = decodeJwt(authorization.slice(7));
12 } catch {
13 throw new HttpError(401, "invalid_token");
14 }
15 // The decoded base only selects policy; authorize verifies all claims and the signature.
16 const branch =
17 telemetry && payload.event_name === "pull_request" && typeof payload.base_ref === "string"
18 ? `refs/heads/${payload.base_ref}`
19 : scope.branch;
20 let endpoint = scope.endpoint;
21 if (typeof payload.aud === "string") {
22 try {
23 const audience = new URL(payload.aud);
24 audience.username = "";
25 audience.password = "";
26 // Vite+ uses the configured URL, including read credentials, as its OIDC audience.
27 if (audience.href.replace(/\/$/, "") === scope.endpoint.replace(/\/$/, ""))
28 endpoint = payload.aud;
29 } catch {
30 // The verified authorization below rejects malformed and foreign audiences.
31 }
32 }
33 return { ...scope, branch, endpoint, pull_requests: telemetry ? 1 : scope.pull_requests };
35​
36export async function authorizeCacheWrite(request: Request, scope: Scope, keys: JWTVerifyGetKey) {
37 return authorize(request, audienceScope(request, scope), keys);
39​
40export async function authorizeTelemetry(request: Request, scope: Scope, keys: JWTVerifyGetKey) {
41 await authorize(request, audienceScope(request, { ...scope, writes_enabled: 1 }, true), keys);
42 const payload = decodeJwt(request.headers.get("authorization")!.slice(7));
43 return `github/${typeof payload.actor === "string" ? payload.actor : "unknown"}`;