Skip to content

Commit ae2b4f7

Browse files
docs: add CLAUDE.md agent guidelines
Add a canonical CLAUDE.md as the single source of truth for AI coding agents (persona, commands, testing conventions, three-tier boundaries, browser security notes, telemetry via the Auth0-Client header, and the MIGRATION_GUIDE.md rule), and repoint AGENTS.md at @CLAUDE.md so non-Claude agents share the same guidance. No docs/ offload — docs/ holds generated TypeDoc output and the SDK is a lean single package, so the file stays inline.
1 parent 35ec131 commit ae2b4f7

2 files changed

Lines changed: 163 additions & 123 deletions

File tree

AGENTS.md

Lines changed: 3 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,5 @@
1-
## Project Overview
1+
# AI Agent Guidelines for auth0-spa-js
22

3-
Auth0 SDK for Single Page Applications using Authorization Code Grant Flow with PKCE. This is a TypeScript library that provides authentication functionality for browser-based applications.
3+
See @CLAUDE.md for all coding guidelines, commands, project structure, code style, testing conventions, and boundaries.
44

5-
## Common Commands
6-
7-
```bash
8-
# Install dependencies
9-
npm install
10-
11-
# Development (starts dev server at http://localhost:3000 with live reload)
12-
npm start # or npm run dev
13-
14-
# Build production bundles
15-
npm run build
16-
17-
# Run unit tests
18-
npm run test
19-
20-
# Run a single test file
21-
npx jest __tests__/path/to/test.test.ts
22-
23-
# Run tests matching a pattern
24-
npx jest --testNamePattern="pattern"
25-
26-
# Run tests in watch mode
27-
npm run test:watch
28-
29-
# Run integration tests (Cypress)
30-
npm run test:integration
31-
32-
# Run integration tests in watch mode
33-
npm run test:watch:integration
34-
35-
# Lint
36-
npm run lint
37-
38-
# Generate documentation
39-
npm run docs
40-
```
41-
42-
## Project Structure
43-
44-
```
45-
src/
46-
├── Auth0Client.ts # Main SDK entry point and public API
47-
├── Auth0Client.utils.ts # Helper functions for Auth0Client
48-
├── api.ts # Token endpoint API calls
49-
├── cache/ # Token caching implementations (memory, localStorage)
50-
├── dpop/ # DPoP proof-of-possession implementation
51-
├── mfa/ # Multi-factor authentication client
52-
├── worker/ # Web worker for secure token refresh
53-
├── storage.ts # Cookie and session storage abstractions
54-
├── errors.ts # Custom error classes
55-
├── global.ts # TypeScript interfaces and types
56-
├── utils.ts # Crypto, encoding, and general utilities
57-
└── index.ts # Public exports
58-
59-
__tests__/ # Unit tests (Jest)
60-
├── Auth0Client/ # Tests organized by Auth0Client method
61-
├── cache/ # Cache implementation tests
62-
├── dpop/ # DPoP tests
63-
└── mfa/ # MFA client tests
64-
65-
cypress/ # Integration tests (Cypress)
66-
├── e2e/ # End-to-end test specs
67-
└── support/ # Test utilities and commands
68-
69-
scripts/ # Build and dev scripts
70-
└── oidc-provider.mjs # Mock OIDC server for integration tests
71-
72-
static/ # Static files for dev server testing
73-
dist/ # Build output (generated)
74-
```
75-
76-
## Architecture
77-
78-
### Core Components
79-
80-
- **Auth0Client** (`src/Auth0Client.ts`): Main client class that orchestrates all authentication operations. Uses PKCE for secure authorization code flow.
81-
82-
- **CacheManager** (`src/cache/`): Token caching system with multiple storage backends:
83-
- `InMemoryCache`: Default, stores tokens in memory
84-
- `LocalStorageCache`: Persists tokens to localStorage
85-
- Supports custom cache implementations via `ICache` interface
86-
87-
- **TransactionManager** (`src/transaction-manager.ts`): Manages state during redirect flows, storing PKCE verifiers and app state in session storage or cookies.
88-
89-
- **MfaApiClient** (`src/mfa/`): Multi-factor authentication operations (enroll, challenge, verify). Wraps `@auth0/auth0-auth-js` MFA client.
90-
91-
- **Dpop** (`src/dpop/`): DPoP (Demonstrating Proof of Possession) implementation for cryptographically binding tokens.
92-
93-
- **Fetcher** (`src/fetcher.ts`): HTTP client wrapper with automatic auth header injection and DPoP proof generation.
94-
95-
### Token Refresh Strategy
96-
97-
The SDK supports two token refresh mechanisms:
98-
1. **Refresh Tokens** (`useRefreshTokens: true`): Uses refresh_token grant with optional web worker for secure storage
99-
2. **Silent Authentication**: Uses hidden iframe with `prompt=none` (requires custom domain for third-party cookie issues)
100-
101-
### Web Worker
102-
103-
`src/worker/token.worker.ts`: Handles token refresh in a web worker when using refresh tokens with in-memory cache, preventing token exposure in main thread.
104-
105-
### Build Output
106-
107-
Rollup bundles the SDK into multiple formats:
108-
- UMD (browser): `dist/auth0-spa-js.production.js`
109-
- ESM: `dist/auth0-spa-js.production.esm.js`
110-
- CJS: `dist/lib/auth0-spa-js.cjs.js`
111-
- Worker: `dist/auth0-spa-js.worker.production.js`
112-
113-
## Testing
114-
115-
- **Unit tests**: `__tests__/` directory, using Jest with jsdom environment
116-
- **Integration tests**: `cypress/e2e/` directory, testing against a mock OIDC provider (`scripts/oidc-provider.mjs`)
117-
118-
Test files follow the pattern `__tests__/[module]/[feature].test.ts` or `__tests__/Auth0Client/[method].test.ts`.
119-
120-
## Key Dependencies
121-
122-
- `@auth0/auth0-auth-js`: Foundational OAuth/MFA client
123-
- `browser-tabs-lock`: Cross-tab locking for token refresh
124-
- `dpop`: DPoP proof generation (RFC 9449)
125-
- `es-cookie`: Cookie handling
5+
This file exists so that non-Claude AI agents (Codex CLI, Gemini CLI, etc.) read the same instructions. All guidelines are maintained in a single place (`CLAUDE.md`) to avoid duplication and drift.

CLAUDE.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# AI Agent Guidelines for auth0-spa-js
2+
3+
This document provides context and guidelines for AI coding assistants working with the auth0-spa-js codebase.
4+
5+
## Your Role
6+
7+
You are a TypeScript SDK engineer working on auth0-spa-js, the Auth0 authentication SDK for browser-based single-page applications. You write small, well-tested, tree-shakeable code, and you treat PKCE, secure token storage, and DPoP token binding as non-negotiable — this SDK runs in the browser where tokens are exposed to hostile scripts.
8+
9+
---
10+
11+
## Project Overview
12+
13+
**auth0-spa-js** is the Auth0 SDK for Single-Page Applications — authorization-code + PKCE login, token caching, and silent refresh in the browser.
14+
15+
- **Language:** TypeScript (compiled to ES2017 UMD/ESM/CJS bundles via Rollup)
16+
- **Package manager:** npm
17+
- **Test:** Jest (unit, jsdom) + Cypress (integration, against a local mock OIDC provider)
18+
- **Dependencies:** `@auth0/auth0-auth-js` 1.10.0 (foundational OAuth/MFA client), `dpop` 2.1.1, `browser-tabs-lock` 1.3.0, `es-cookie` 1.3.2 — see `package.json` (the authoritative source)
19+
20+
---
21+
22+
## Commands
23+
24+
```bash
25+
# Unit tests (with coverage)
26+
npm test
27+
28+
# Lint
29+
npm run lint
30+
31+
# Dev server with live reload (http://localhost:3000)
32+
npm run dev
33+
34+
# Production build (UMD + ESM + CJS + worker bundles)
35+
npm run build
36+
```
37+
38+
- **Single test file:** `npx jest __tests__/Auth0Client/getTokenSilently.test.ts`
39+
- **Integration (Cypress):** `npm run test:integration` — spins up the local dev server + mock OIDC provider; no live tenant or credentials required.
40+
41+
---
42+
43+
## Testing
44+
45+
- **Unit:** Jest + jsdom, in `__tests__/` — files follow `__tests__/[module]/[feature].test.ts` or `__tests__/Auth0Client/[method].test.ts`.
46+
- **Integration:** Cypress in `cypress/e2e/`, run against a **local** mock OIDC provider (`scripts/oidc-provider.mjs`) — not a live tenant.
47+
- **Coverage:** Jest coverage → Codecov in CI.
48+
- Mock network with `jest-fetch-mock`; storage with `jest-localstorage-mock` / `fake-indexeddb`. Don't hit real endpoints in unit tests.
49+
50+
---
51+
52+
## Project Structure
53+
54+
```
55+
src/
56+
├─ index.ts # entry point — createAuth0Client() factory + re-exports
57+
├─ Auth0Client.ts # main client; orchestrates PKCE authorization-code flow
58+
├─ global.ts # public types (Auth0ClientOptions, etc.)
59+
├─ api.ts # token endpoint calls + Auth0-Client telemetry header
60+
├─ cache/ # ICache + InMemoryCache / LocalStorageCache
61+
├─ transaction-manager.ts # PKCE verifier + app state across redirects
62+
├─ dpop/ # DPoP proof generation (RFC 9449)
63+
├─ mfa/ # MFA client (wraps @auth0/auth0-auth-js)
64+
├─ fetcher.ts # HTTP wrapper: auth header + DPoP injection
65+
└─ worker/token.worker.ts # refreshes tokens off the main thread
66+
__tests__/ # Jest unit specs (mirror src/) cypress/ # e2e
67+
docs/ # generated TypeDoc output (do not hand-edit)
68+
```
69+
70+
Key files: `src/index.ts` (entry), `src/Auth0Client.ts` (core), `src/api.ts` (telemetry header lives here).
71+
72+
---
73+
74+
## Code Style
75+
76+
- **Linter:** ESLint (`npm run lint` over `src/`); a separate security config runs via `npm run lint:security` (eslint-plugin-security).
77+
- **Naming:** `PascalCase` types/classes (`Auth0Client`, `CacheManager`), `camelCase` members; public options are TS interfaces in `global.ts`.
78+
- **Bundle discipline:** code must stay ES2017-clean (`test:es-check` enforces it) and tree-shakeable — avoid pulling heavy deps into the browser bundle.
79+
80+
Dominant patterns: a `createAuth0Client()` async factory over the `Auth0Client` class; pluggable `ICache` storage backends; `@auth0/auth0-auth-js` wrapped for OAuth/MFA primitives.
81+
82+
---
83+
84+
## Git Workflow
85+
86+
- **Commits:** Conventional Commits — enforced by commitlint (`commitlint.config.mjs`) and a PR-title lint check.
87+
- **PRs:** satisfy the PR template; unit tests, lint, CodeQL, and cross-browser checks must pass.
88+
- **Changelog:** `CHANGELOG.md`.
89+
90+
---
91+
92+
## Boundaries
93+
94+
### ✅ Always Do
95+
- Make surgical changes — touch only what the request requires. Don't refactor, reformat, or "improve" adjacent code that isn't broken; match the existing style. Every changed line should trace directly to the request.
96+
- Run `npm test` and `npm run lint` before committing
97+
- Add Jest specs for new behavior; keep code ES2017-clean (`npm run test:es-check`) and tree-shakeable
98+
- Update `README.md` and `EXAMPLES.md` in the same PR when changing the public API, options, or supported integration patterns
99+
- Update `MIGRATION_GUIDE.md` in the same PR when making a breaking change
100+
- When adding a **new request path to Auth0** (not every feature — most ride on the shared transport), route it through the existing `src/api.ts` fetch layer so it carries the `Auth0-Client` header (base64 `{name,version,env}`) — don't create a separate HTTP client. Since this SDK wraps `@auth0/auth0-auth-js`, preserve the `auth0Client` wrapping (this SDK's name/version, the wrapped lib under `env`).
101+
102+
### ⚠️ Ask First
103+
- Adding/bumping runtime dependencies (they ship in the browser bundle — watch bundle size)
104+
- Modifying the public API on `Auth0Client` / `createAuth0Client` / `global.ts` (breaking → major bump)
105+
- Changes to token storage, DPoP proof generation, PKCE, or the web-worker refresh path
106+
- Changes to `.github/workflows/` or the Rollup build config
107+
108+
### 🚫 Never Do
109+
- Commit secrets, API keys, or tokens
110+
- Log or expose `access_token` / `refresh_token` / `id_token` — especially not to the main thread when the web worker is in use
111+
- Disable PKCE, or weaken DPoP proofs
112+
- Hand-edit `dist/` or `docs/` (generated build/TypeDoc output)
113+
- Remove or skip failing tests instead of fixing them
114+
- Break backward compatibility without a major bump, approval, and a `MIGRATION_GUIDE.md` entry
115+
116+
---
117+
118+
## Security Considerations
119+
120+
- **PKCE:** always used for the authorization-code flow — never expose an option to disable it.
121+
- **Token storage:** in-memory by default (`InMemoryCache`); `LocalStorageCache` is opt-in and documented as higher-risk. With refresh tokens + in-memory cache, refresh happens in a **web worker** (`src/worker/token.worker.ts`) to keep tokens off the main thread.
122+
- **DPoP:** `src/dpop/` binds tokens to a key pair (RFC 9449); `fetcher.ts` attaches the proof. Don't bypass it when DPoP is enabled.
123+
- **Silent auth:** hidden-iframe `prompt=none` needs a custom domain to survive third-party-cookie restrictions.
124+
125+
---
126+
127+
## Common Pitfalls
128+
129+
1. **Web-worker token exposure.** Refresh-token + in-memory-cache mode refreshes in a web worker specifically so tokens never touch the main thread — don't "simplify" this back onto the main thread.
130+
2. **Silent auth vs. third-party cookies.** Iframe `prompt=none` silently fails without a custom domain in browsers that block third-party cookies; refresh tokens are the robust path.
131+
3. **Bundle size / ES level.** New code must pass `test:es-check` (ES2017) and stay tree-shakeable; a heavy runtime dep bloats every consumer's bundle.
132+
4. **DPoP online mode constraints.** `createAuth0Client` enforces `useRefreshTokens: true` + `useDpop: true` for online mode at compile time and again at runtime — keep both checks in sync.
133+
5. **Wrapping `@auth0/auth0-auth-js`.** OAuth/MFA primitives come from that lib; telemetry must nest its version under `env` rather than reporting only this SDK.
134+
135+
---
136+
137+
## Docs Update Rules
138+
139+
> A PR that changes public API, configuration, or supported patterns is **not complete** until the relevant docs are updated in the same PR.
140+
141+
### Tracked Docs
142+
143+
| Doc | Covers |
144+
|-----|--------|
145+
| `README.md` | Install, getting started, configuration, common usage |
146+
| `EXAMPLES.md` | Detailed usage — refresh tokens, DPoP, organizations, custom cache |
147+
| `MIGRATION_GUIDE.md` | Breaking changes and upgrade steps |
148+
149+
### When You Change Code, Update These Docs
150+
151+
| When this changes | Update |
152+
|-------------------|--------|
153+
| Public API on `Auth0Client` / `createAuth0Client` / `global.ts` options | `README.md` (usage), `EXAMPLES.md` (affected samples) |
154+
| Public API removed or renamed | `README.md` + `EXAMPLES.md` — update every reference |
155+
| Install / package requirements | `README.md` (installation) |
156+
| Token storage, cache, DPoP, or refresh behavior | `EXAMPLES.md` (relevant section) |
157+
| New integration pattern (framework, org, provider) | `EXAMPLES.md` (new section) |
158+
| Any breaking change | `MIGRATION_GUIDE.md` |
159+
160+
> When you touch code that maps to a doc above, update that doc **in the same PR** — do not defer.

0 commit comments

Comments
 (0)