chadtmiller.com/hatk
AT Protocol app framework
1
0
// Browser crypto utilities for OAuth (DPoP, PKCE, JWT)
export function base64UrlEncode(buffer) {
const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer)
let binary = ''
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i])
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
}
export function randomString(byteLength = 32) {
return base64UrlEncode(crypto.getRandomValues(new Uint8Array(byteLength)))
}
export async function sha256(data) {
return new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(data)))
}
export async function sha256Base64Url(data) {
return base64UrlEncode(await sha256(data))
}
export async function signJwt(header, payload, privateKey) {
const enc = new TextEncoder()
const h = base64UrlEncode(enc.encode(JSON.stringify(header)))
const p = base64UrlEncode(enc.encode(JSON.stringify(payload)))
const input = `${h}.${p}`
const sig = await crypto.subtle.sign({ name: 'ECDSA', hash: 'SHA-256' }, privateKey, enc.encode(input))
return `${input}.${base64UrlEncode(sig)}`
}