Fix JWT generation using native Deno Web Crypto API
- Remove external jose library dependency that was causing import errors - Use native crypto.subtle API available in Deno - Manual base64url encoding for JWT header, payload, and signature - Use RSASSA-PKCS1-v1_5 with SHA-256 for RS256 algorithm - Remove cat heredoc wrapper from file
This commit is contained in:
@@ -27,30 +27,11 @@ interface CreateMeetRequest {
|
|||||||
notes?: string;
|
notes?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to create JWT and get access token
|
// Function to create JWT and get access token using native Web Crypto API
|
||||||
async function getGoogleAccessToken(serviceAccount: GoogleServiceAccount): Promise<string> {
|
async function getGoogleAccessToken(serviceAccount: GoogleServiceAccount): Promise<string> {
|
||||||
try {
|
try {
|
||||||
// Use a different JWT library that's more compatible with Google's requirements
|
|
||||||
const { importKey, sign } = await import("https://deno.land/x/jose@v4.15.1/node/crypto.ts");
|
|
||||||
|
|
||||||
const now = Math.floor(Date.now() / 1000);
|
const now = Math.floor(Date.now() / 1000);
|
||||||
|
|
||||||
// Convert PEM format private key to CryptoKey
|
|
||||||
const privateKey = await importKey(
|
|
||||||
"pkcs8",
|
|
||||||
// Convert PEM to binary
|
|
||||||
Uint8Array.from(
|
|
||||||
atob(serviceAccount.private_key
|
|
||||||
.replace(/-----BEGIN PRIVATE KEY-----/g, "")
|
|
||||||
.replace(/-----END PRIVATE KEY-----/g, "")
|
|
||||||
.replace(/\s/g, "")),
|
|
||||||
c => c.charCodeAt(0)
|
|
||||||
),
|
|
||||||
{ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
|
|
||||||
false,
|
|
||||||
["sign"]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Build JWT header and payload manually
|
// Build JWT header and payload manually
|
||||||
const header = {
|
const header = {
|
||||||
alg: "RS256",
|
alg: "RS256",
|
||||||
@@ -65,21 +46,40 @@ async function getGoogleAccessToken(serviceAccount: GoogleServiceAccount): Promi
|
|||||||
iat: now,
|
iat: now,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Encode header and payload
|
// Encode header and payload (base64url)
|
||||||
const encodedHeader = btoa(JSON.stringify(header))
|
const base64UrlEncode = (str: string) => {
|
||||||
.replace(/\+/g, "-")
|
return btoa(str)
|
||||||
.replace(/\//g, "_")
|
.replace(/\+/g, "-")
|
||||||
.replace(/=/g, "");
|
.replace(/\//g, "_")
|
||||||
|
.replace(/=/g, "");
|
||||||
const encodedPayload = btoa(JSON.stringify(payload))
|
};
|
||||||
.replace(/\+/g, "-")
|
|
||||||
.replace(/\//g, "_")
|
|
||||||
.replace(/=/g, "");
|
|
||||||
|
|
||||||
|
const encodedHeader = base64UrlEncode(JSON.stringify(header));
|
||||||
|
const encodedPayload = base64UrlEncode(JSON.stringify(payload));
|
||||||
const signatureInput = `${encodedHeader}.${encodedPayload}`;
|
const signatureInput = `${encodedHeader}.${encodedPayload}`;
|
||||||
|
|
||||||
|
// Convert PEM to binary
|
||||||
|
const keyData = serviceAccount.private_key
|
||||||
|
.replace(/-----BEGIN PRIVATE KEY-----/g, "")
|
||||||
|
.replace(/-----END PRIVATE KEY-----/g, "")
|
||||||
|
.replace(/\s/g, "");
|
||||||
|
|
||||||
|
const binaryKey = Uint8Array.from(atob(keyData), c => c.charCodeAt(0));
|
||||||
|
|
||||||
|
// Import private key using native Web Crypto API
|
||||||
|
const privateKey = await crypto.subtle.importKey(
|
||||||
|
"pkcs8",
|
||||||
|
binaryKey,
|
||||||
|
{
|
||||||
|
name: "RSASSA-PKCS1-v1_5",
|
||||||
|
hash: "SHA-256",
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
["sign"]
|
||||||
|
);
|
||||||
|
|
||||||
// Sign the JWT
|
// Sign the JWT
|
||||||
const signature = await sign(
|
const signature = await crypto.subtle.sign(
|
||||||
"RSASSA-PKCS1-v1_5",
|
"RSASSA-PKCS1-v1_5",
|
||||||
privateKey,
|
privateKey,
|
||||||
new TextEncoder().encode(signatureInput)
|
new TextEncoder().encode(signatureInput)
|
||||||
|
|||||||
Reference in New Issue
Block a user