Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

Sign and verify session tokens (HS256) with WebCrypto

Geschlossen
#230 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

@bhushan4work arbeitet bereits daran.

Seit 21.10.2026.

  • #290 von @bhushan4work — gemerged

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
1-2 Tage
Anfängerfreundlichkeit
55/100
Issue-Typ
Feature
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
node.js, typescript

Rechercherichtung

Read packages/server/src/webhook.ts for the existing crypto.subtle HMAC usage, then create packages/server/src/security/session-token.ts and its tests at packages/server/tests/security/session-token.test.ts. Implement the specified compact HS256 token format, claim validation, origin and conversation checks, expiry skew, and key rotation; use RFC 7515 Appendix A.1 as a verification vector. Done means the listed acceptance tests pass, including malformed and tampered tokens.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

enhancement hacktoberfest help wanted server

Right now the widget picks its own conversationId and the server trusts it. With a shared store (Redis, Postgres), anyone who guesses another visitor's id can read that conversation's context and add to it. The fix in the next release is a short-lived signed session token: the server gives the widget a token bound to one conversation and one origin, and checks it on every request. This issue is the token format itself, as a new file with no dependencies. The /session route that hands tokens out comes later.

This one needs care, so it's for someone who has had a couple of PRs merged. I'll review it closely.

What to do
Create packages/server/src/security/session-token.ts. Use a compact JWS (header.payload.signature, base64url, no padding) with HS256 through crypto.subtle, so it runs on Node 22, Workers, Bun and Deno with no dependency.

export interface SessionClaims {
  v: 1;
  sid: string;       // session id
  cid: string;       // conversation id
  org: string;       // origin the token was issued for
  uid?: string;
  tier?: string;
  iat: number;       // seconds
  exp: number;       // seconds
}

/** Imports a secret (at least 32 bytes as UTF-8) as an HMAC key. */
export function importSessionKey(secret: string): Promise<CryptoKey>;

/** Signs with keys[0] and puts its index in the header as `kid`. */
export function signSession(claims: SessionClaims, keys: CryptoKey[]): Promise<string>;

export function verifySession(
  token: string,
  keys: CryptoKey[],
  opts: { origin: string | null; conversationId: string; now?: number; clockSkewSec?: number }
): Promise<
  | { ok: true; claims: SessionClaims }
  | { ok: false; code: 'malformed' | 'bad_signature' | 'expired' | 'origin_mismatch' | 'conversation_mismatch' }
>;
  • Header: {"alg":"HS256","typ":"JWT","kid":"<index>"}. Reject any other alg, including none.
  • Verify with crypto.subtle.verify, never by comparing strings. Try the key named by kid first, then the others, so rotating secrets doesn't log everyone out.
  • clockSkewSec defaults to 60 and applies to exp.
  • Check the signature before trusting anything in the payload. Return malformed for a token that doesn't have three parts, isn't valid base64url or JSON, or has a missing or wrongly typed claim.
  • importSessionKey throws a clear error when the secret is shorter than 32 bytes.
  • Don't create keys or call crypto.subtle at module load. Workers don't allow that at global scope.

Where to look

  • packages/server/src/webhook.ts already uses crypto.subtle HMAC for webhook signatures
  • RFC 7515, Appendix A.1, has an HS256 example with its key, usable as a test vector for verification

Acceptance criteria

  • New packages/server/src/security/session-token.ts and packages/server/tests/security/session-token.test.ts
  • Round trip: sign, then verify, gives back the same claims
  • Tests for an expired token, expired but within the skew, a changed payload, a changed signature, alg: none, a wrong origin, a wrong conversation, a malformed token, and rotation (signed with an old key that's second in the list)
  • The RFC 7515 A.1 token verifies with its key (the claims check can be skipped for it)
  • A secret shorter than 32 bytes throws
  • Not exported from @chatcops/server yet, and no changeset needed (pnpm changeset --empty)
  • pnpm test:coverage and pnpm lint pass

Want to work on this? Comment below and I'll assign it to you. Please take one issue at a time, branch off dev, and open your PR against dev with Closes #<this issue number>. Setup notes (pnpm, build before test) are in CONTRIBUTING.md.

Vorherrschende Sprache
TypeScript
Sterne
13
Forks
7
Ø Merge
3 Std. 41 Min.
Gemergte PRs (30 T.)
155

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus codercops/chatcops

Alle Issues in codercops/chatcops

Ähnliche Issues

Weitere Issues zu TypeScript

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.