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

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
45 lines · 1.3 KB Raw History
// Reading a JWT without verifying it.
//
// Every token this app decodes was either signed by a server it just spoke to
// over TLS, or is about to be handed straight back to that server. Nothing here
// decides anything: the payloads are read so a page can show them, and the
// signature is checked by whichever server receives the token.

/**
 * @typedef {Object} DecodedJwt
 * @property {Record<string, any>} header
 * @property {Record<string, any>} payload
 */

/**
 * @param {string} segment - base64url, unpadded
 * @returns {Record<string, any>}
 */
function decodeSegment(segment) {
  const padded = segment.replace(/-/g, '+').replace(/_/g, '/');
  return JSON.parse(atob(padded.padEnd(Math.ceil(padded.length / 4) * 4, '=')));
}

/**
 * @param {string} jwt
 * @returns {DecodedJwt|null} null for anything that is not one
 */
export function decodeJwt(jwt) {
  try {
    const [header, payload] = jwt.split('.');
    return { header: decodeSegment(header), payload: decodeSegment(payload) };
  } catch {
    return null;
  }
}

/**
 * The `exp` a JWT states, in epoch milliseconds, or 0 for a token that states
 * none.
 * @param {string} jwt
 * @returns {number}
 */
export function expiryOf(jwt) {
  const exp = decodeJwt(jwt)?.payload.exp;
  return typeof exp === 'number' ? exp * 1000 : 0;
}