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

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
61 lines · 2.0 KB Raw History
import { Card } from '#/components/atoms/card.jsx';
import { Copyable } from '#/components/molecules/copyable.jsx';
import { JsonView } from '#/components/molecules/json-view.jsx';
import { until } from '#/lib/format.js';
import { decodeJwt } from '#/lib/jwt.js';

/**
 * One token, read rather than shown as a string. The signature is left off:
 * these are all ES256 over a key the receiving server resolves, so the bytes
 * say nothing a reader can check by eye.
 */
export function TokenView({ title, description, jwt, host, children }) {
  const decoded = decodeJwt(jwt);
  const expiresAt = decoded?.payload.exp ? decoded.payload.exp * 1000 : null;

  return (
    <Card className="flex flex-col gap-3 p-4">
      <div>
        <h3 className="font-semibold text-[13px] text-foreground">{title}</h3>
        {description && (
          <p className="mt-1 text-muted-foreground text-xs leading-relaxed">
            {description}
          </p>
        )}
      </div>

      {host && (
        <div className="flex flex-wrap items-baseline justify-between gap-x-4 gap-y-1">
          <span className="text-muted-foreground text-xs">From</span>
          <span className="font-mono text-[12px] text-foreground">{host}</span>
        </div>
      )}
      {expiresAt && (
        <div className="flex flex-wrap items-baseline justify-between gap-x-4 gap-y-1">
          <span className="text-muted-foreground text-xs">Expires</span>
          <span className="text-[12px] text-foreground">
            {until(expiresAt)}
          </span>
        </div>
      )}

      {children}

      {decoded ? (
        <div className="rounded-xl bg-muted p-3">
          <JsonView
            value={{ header: decoded.header, payload: decoded.payload }}
          />
        </div>
      ) : (
        <p className="text-muted-foreground text-sm">
          That token is not a readable JWT.
        </p>
      )}

      <Copyable value={jwt} className="max-w-full text-[11px]">
        {`${jwt.slice(0, 48)}…`}
      </Copyable>
    </Card>
  );
}