Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Sign and verify session tokens (HS256) with WebCrypto

Đang mở
#230 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
55/100
Loại issue
Tính năng
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
node.js, typescript

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
TypeScript
Star
13
Fork
7
Merge trung bình
4 giờ 11 phút
Pull request đã merge (30 ngày)
122

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của codercops/chatcops

Tất cả issue của codercops/chatcops

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.