(email: string, privateKeyPem: string, scopes: string[])
| 12 | } |
| 13 | |
| 14 | async function createJwt(email: string, privateKeyPem: string, scopes: string[]): Promise<string> { |
| 15 | const now = Math.floor(Date.now() / 1000); |
| 16 | const header = { alg: "RS256", typ: "JWT" }; |
| 17 | const payload = { iss: email, scope: scopes.join(" "), aud: "https://oauth2.googleapis.com/token", iat: now, exp: now + 3600 }; |
| 18 | const enc = new TextEncoder(); |
| 19 | const headerB64 = base64url(enc.encode(JSON.stringify(header))); |
| 20 | const payloadB64 = base64url(enc.encode(JSON.stringify(payload))); |
| 21 | const unsignedToken = `${headerB64}.${payloadB64}`; |
| 22 | const pemBody = privateKeyPem.replace(/-----BEGIN PRIVATE KEY-----/g, "").replace(/-----END PRIVATE KEY-----/g, "").replace(/\s/g, ""); |
| 23 | const keyBytes = Uint8Array.from(atob(pemBody), (c) => c.charCodeAt(0)); |
| 24 | const key = await crypto.subtle.importKey("pkcs8", keyBytes, { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" }, false, ["sign"]); |
| 25 | const sig = new Uint8Array(await crypto.subtle.sign("RSASSA-PKCS1-v1_5", key, enc.encode(unsignedToken))); |
| 26 | return `${unsignedToken}.${base64url(sig)}`; |
| 27 | } |
| 28 | |
| 29 | let cachedToken: { token: string; expiresAt: number } | null = null; |
| 30 |
no test coverage detected