Repository navigation
docs: add AGENTS.md and .aiignore #509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # An .aiignore file follows the same syntax as a .gitignore file. | ||
| # .gitignore documentation: https://git-scm.com/docs/gitignore | ||
|
|
||
| # Dependencies and repository metadata | ||
| node_modules/ | ||
| .git/ | ||
|
|
||
| # Local secrets and credentials | ||
| .env | ||
| .env.* | ||
| .npmrc | ||
| *.pem | ||
| *.key | ||
|
|
||
| # Local IDE and operating-system files | ||
| .idea/ | ||
| .vscode/ | ||
| *.iml | ||
| .DS_Store | ||
|
|
||
| # Logs and temporary files | ||
| *.log | ||
| *.tmp | ||
|
|
||
| # Build output | ||
| dist/ | ||
| build/ | ||
| out/ | ||
|
|
||
| # Coverage output (nyc/Istanbul) | ||
| coverage/ | ||
| .nyc_output/ | ||
| lib-cov/ | ||
|
|
||
| # Generated documentation and VitePress output; edit source JSDoc and guides instead | ||
| /docs/api/ | ||
| /docs/_build/ | ||
| /docs/.vitepress/cache/ | ||
| /docs/.vitepress/dist/ | ||
| # Generated by docs:setup; read /CONTRIBUTING.md instead | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, take or leave:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I didn't know that symlinks can be commited. In that case I would keep line 41 and rename line 40 to something that will not burn tokens by looking up any build steps when reading this file. However, I think the missing key element is, that
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, git can track symlinks (it stores the target path). Untracking it makes sense since |
||
| /docs/guide/contributing.md | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,178 @@ | ||
| # AGENTS.md | ||
|
|
||
| ## Scope | ||
|
|
||
| These instructions apply only to the `node-oauth2-server` repository, the framework-agnostic OAuth 2.0 server library | ||
| published as `@node-oauth/oauth2-server`. | ||
|
|
||
| The sibling `express-oauth-server` repository is outside this file’s scope. Release CI checks out the Express adapter | ||
| as an external integration-test target; it is not a runtime dependency of this package. Changes to the adapter’s code, | ||
| documentation, security policy, and release process are outside this scope. | ||
|
|
||
| Run package commands from the `node-oauth2-server` repository root; do not expect a parent workspace-level install or | ||
| test command. Before changing the package, check `README.md`, `CONTRIBUTING.md`, `SECURITY.md`, and `package.json`. | ||
|
|
||
| ## AI context exclusions | ||
|
|
||
| Before exploring the repository, read [`.aiignore`](./.aiignore) and apply its patterns using gitignore syntax, | ||
| relative to this repository root. Agents must follow these exclusions explicitly: exclude matching paths from routine | ||
| file listings, searches, reads, and manual edits, including when using tools that do not honor `.aiignore` themselves. | ||
| Access an excluded path only when the user’s task specifically requires it. Build, test, coverage, and documentation | ||
| commands may create or update excluded output; use the source files when making changes to generated content. | ||
|
|
||
| ## Project priorities | ||
|
|
||
| - Preserve OAuth 2.0 interoperability and security. Review behavior against the relevant standards, especially RFC 6749, | ||
| RFC 6750, RFC 7636, RFC 8252, and the threat-model guidance in RFC 6819. | ||
| - Keep `node-oauth2-server` framework-agnostic. Framework-specific behavior belongs in adapters maintained separately | ||
| from this repository. | ||
| - Treat authentication, authorization, token, grant, PKCE, parsing, and error-handling changes as security-sensitive. | ||
| Avoid weakening validation or disclosure of credentials and tokens in logs, errors, tests, or documentation. | ||
| - The public API includes JavaScript entry points and TypeScript declarations. Update `index.d.ts` when a public API or | ||
| type contract changes. | ||
| - The package uses CommonJS entry points and Promise/`async`-oriented APIs. Preserve existing public behavior unless a | ||
| change is intentional, documented, and tested. | ||
|
|
||
| ## Repository layout | ||
|
|
||
| - Runtime code: `index.js` and `lib/` | ||
| - Type declarations: `index.d.ts` | ||
| - Tests: `test/` (Mocha files matching `test/**/*_test.js`) | ||
| - Test suites: `test/unit/`, `test/integration/`, and `test/compliance/`; shared fixtures/helpers: `test/helpers/` | ||
| - Mocha configuration: `.mocharc.yml`; shared Chai assertions: `test/assertions.js` | ||
| - Hand-authored documentation: `docs/guide/` and the VitePress home/configuration files | ||
| - Generated API documentation: `docs/api/` | ||
| - Formatting and linting: Biome, configured in `biome.json` | ||
| - CI and release validation: `.github/workflows/` | ||
|
|
||
| ## Library architecture | ||
|
|
||
| The library implements OAuth workflows without owning HTTP routing, a database, user sessions, or a consent UI. | ||
| Applications and framework adapters supply those pieces. The main flow is: adapter creates `Request`/`Response` | ||
| instances, calls `OAuth2Server`, and sends the populated response; handlers delegate persistence and policy to the | ||
| application’s model. | ||
|
|
||
| - **Public facade:** `index.js` exports the `OAuth2Server` constructor, `Request`, `Response`, `AbstractGrantType`, and | ||
| error classes. `lib/server.js` exposes `authenticate()`, `authorize()`, and `token()`. Each call merges method | ||
| defaults, constructor options, and per-call options in that order, creates a handler, and returns its Promise. | ||
| `index.d.ts` describes the public TypeScript contracts. | ||
| - **HTTP boundary:** `lib/request.js` wraps already-parsed headers, method, query, and body; `lib/response.js` holds | ||
| status, headers, and body. Headers are normalized to lowercase. Handlers require these wrapper instances and mutate | ||
| the response without sending it. The caller must handle both the resolved result or rejected error and the response | ||
| state, including redirects and authentication headers. | ||
| - **Resource authentication:** `lib/handlers/authenticate-handler.js` extracts a bearer token, rejects conflicting | ||
| token sources, calls `model.getAccessToken()`, checks expiry, and calls `model.verifyScope()` when scopes are | ||
| requested. It returns the stored token object and manages scope and `WWW-Authenticate` headers. | ||
| - **Authorization endpoint:** `lib/handlers/authorize-handler.js` validates the client, redirect URI, state, and scope, | ||
| obtains the user through a supplied `authenticateHandler` (or bearer authentication by default), and saves an | ||
| authorization code through the model. `lib/response-types/code-response-type.js` builds the code redirect. Only the | ||
| `code` response type is registered; `token-response-type.js` is an unimplemented placeholder. | ||
| - **Token endpoint:** `lib/handlers/token-handler.js` validates form-encoded POST requests, obtains client credentials, | ||
| delegates client authentication to `model.getClient()`, checks the client’s allowed grants, and dispatches by | ||
| `grant_type`. The saved token data is returned to the caller; `lib/models/token-model.js` validates and prepares it | ||
| for `lib/token-types/bearer-token-type.js` to serialize into the OAuth response, with cache-prevention headers. | ||
| Internal scopes are arrays; the token response converts them to a space-delimited string. Bearer is the issued token | ||
| type; `mac-token-type.js` is an unimplemented placeholder. | ||
| - **Grant implementations:** `lib/grant-types/` contains authorization-code, client-credentials, password, and | ||
| refresh-token workflows. `AbstractGrantType` shares token generation, expiration, and scope handling. Grants obtain | ||
| users and credentials through the model and persist results through `saveToken()`. Custom grant constructors are | ||
| registered through `extendedGrantTypes` and implement `handle(request, client)`; the exported base class provides | ||
| reusable helpers. Client-specific token lifetimes override server defaults. | ||
| - **Storage and policy boundary:** `options.model` is an application-supplied object whose required methods depend on | ||
| the selected workflow. Hooks cover client/user lookup, token/code lookup and persistence, revocation, scope policy, | ||
| redirect validation, and optional token/code generation. Hooks may return plain values or Promises. `lib/model.js` | ||
| documents this contract and provides throwing stubs and a `Model.from()` helper; it is not a persistence layer and | ||
| is not exported by the package entry point. In particular, `getClient()` must enforce per-client secret policy; | ||
| PKCE and grant-level secret-presence options do not replace confidential-client authentication. | ||
| - **Security-sensitive sequencing:** authorization-code exchange validates the stored code and client, revokes the | ||
| code, then checks PKCE and redirect binding before issuing tokens. A failed PKCE attempt therefore consumes the code. | ||
| Refresh exchange validates token ownership, expiry, and requested scope before revocation; scopes cannot expand, | ||
| and refresh-token rotation is enabled by default. Preserve these orderings when modifying grant logic. | ||
| - **Shared protocol support:** `lib/pkce/pkce.js` and `lib/utils/` provide PKCE, cryptographic token generation, scope | ||
| parsing, and date/string helpers. Default token generation uses Node’s cryptographic random bytes; model hooks may | ||
| override it. PKCE defaults to `S256`, allows `plain` only when explicitly enabled, and can be required through | ||
| `requirePKCE`. `lib/errors/` defines the `OAuthError` hierarchy with OAuth names and HTTP status codes; handlers | ||
| translate errors into endpoint-specific bodies, redirects, or headers and reject the operation. Token and | ||
| authorization handlers normalize caught programming/configuration errors to `ServerError`. | ||
|
|
||
| ## Setup and validation | ||
|
|
||
| Use the lockfile and install dependencies from the repository root: | ||
|
|
||
| ```bash | ||
| npm ci | ||
| ``` | ||
|
jankapunkt marked this conversation as resolved.
|
||
|
|
||
| If you change dependencies, regenerate `package-lock.json` with npm 11 (the version CI uses), including when resolving merge conflicts. Older npm versions drop the cross-platform optional dependencies, and `npm ci` then fails in CI even though it works locally. | ||
|
|
||
| Validation commands: | ||
|
|
||
| ```bash | ||
| npm test # pretest runs Biome check, then Mocha runs all three test suites | ||
| npm run lint | ||
| npm run format | ||
| npm run test:coverage | ||
| npm run docs:build # for documentation or public JSDoc changes | ||
| ``` | ||
|
|
||
| Code style is enforced by the Biome linter and formatter configured in `biome.json`. Both `npm run lint` and | ||
| `npm run format` must pass before every commit, along with `npm test`. Use `npm run lint:fix` and `npm run format:fix` | ||
| only when you intend to apply automated changes. The configured formatter uses single quotes, spaces, trailing | ||
| commas, and a 120-column line width for JavaScript. | ||
|
|
||
| Biome currently checks `index.js`, `lib/**/*.js`, and `test/**/*.js`. A passing Biome check does not validate Markdown, | ||
| TypeScript declarations, documentation tooling, or workflow files; review those changes separately. | ||
|
|
||
| Write tests with Mocha and Chai, using Chai’s `should` style assertions. Use Sinon for stubbing, and restore stubs and | ||
| fake timers after each test so they cannot affect other tests. Reuse the existing test helpers and shared assertions. | ||
|
|
||
| Run focused tests during iteration, but run the full package test, lint, and format commands before submitting a | ||
| change. Add or update tests for every bug fix and feature. Include regression coverage for security-sensitive | ||
| behavior and boundary cases. | ||
|
|
||
| For a focused run, use `npm test -- --grep 'suite or test name'`; this retains the Biome `pretest` check. | ||
|
|
||
| Measure test coverage with nyc (Istanbul) via `npm run test:coverage`. Strive for the highest possible test coverage | ||
| across statements, branches, functions, and lines, including error paths and boundary cases. The test workflows | ||
| currently enforce a minimum coverage of 98% using `coverage/lcov.info`. The coverage command does not run the | ||
| `pretest` hook, so it does not replace the required Biome checks. | ||
|
|
||
| `package.json` is the source of truth for supported Node.js versions. Follow its `engines.node` declaration when | ||
| developing, rather than prescribing a separate version policy here. If a change relies on a newer Node.js feature, | ||
| verify it against that declaration and document any intentional compatibility change. Development tools may require a | ||
| newer Node.js version than the library’s runtime minimum; check their engine requirements if setup fails without | ||
| changing the library’s support policy merely to match the local toolchain. | ||
|
|
||
| ## Source and documentation workflow | ||
|
|
||
| - Add or update JSDoc for new or changed public APIs and keep `index.d.ts` in sync. | ||
| - Do not manually edit files under `docs/api/`. Update source JSDoc in `lib/`, then run `npm run docs:api` from the | ||
| repository root. | ||
| - Edit the guide under `docs/guide/` directly. `npm run docs:setup` creates the contribution-guide link used by the docs | ||
| build; edit the root `CONTRIBUTING.md` rather than `docs/guide/contributing.md`. | ||
| - Use the `docs:*` scripts in `package.json`; the `npm run docs` example in `CONTRIBUTING.md` is outdated. | ||
| - Keep README, API documentation, migration notes, and type declarations aligned with behavior. Do not update generated | ||
| output without checking whether the corresponding source change is present. | ||
| - Do not edit `CHANGELOG.md` or bump release versions for ordinary feature or bug-fix pull requests; maintainers handle | ||
| release bookkeeping. | ||
|
|
||
| ## Contributions and Git workflow | ||
|
|
||
| Follow [`CONTRIBUTING.md`](./CONTRIBUTING.md) for the established contribution process, including opening or discussing | ||
| an issue before an ordinary feature or bug-fix pull request. Follow the private reporting process below for security | ||
| issues. The branching policy below takes precedence over the guide’s outdated `development` instructions. | ||
|
|
||
| Use trunk-based development with `master` as the trunk. The `development` branch is deprecated. Create feature or fix | ||
| branches from `master`, keep them closely aligned with it, and target pull requests to `master`. The `master` name is | ||
| retained for historical continuity. | ||
|
|
||
| Follow the commit message convention in [`CONTRIBUTING.md`](./CONTRIBUTING.md). | ||
|
|
||
| Keep commits focused, avoid unrelated dependency updates, describe test/reproduction steps in pull requests, and do not | ||
| include secrets or real credentials in fixtures, examples, logs, or documentation. | ||
|
|
||
| ## Security reporting | ||
|
|
||
| Never report a suspected vulnerability in a public issue, pull request, or discussion. Follow | ||
| [`SECURITY.md`](./SECURITY.md), which directs reports to GitHub private vulnerability reporting. Before releasing a | ||
| security fix, the policy requires the full test suite and dependency audits to pass. | ||
Uh oh!
There was an error while loading. Please reload this page.