~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/hatk

AT Protocol app framework

1
0
main
29 lines · 1.1 KB Raw History
// 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)}`
}