Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Formatted with oxfmt when the repository moved off Biome.
8a5c1e02656c306843248b38d42474819417f977
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ jobs:
- run: pnpm add --global @antelopejs/core
- run: pnpm prepack
- run: pnpm lint
- run: pnpm format:check
- run: pnpm knip
- run: pnpm test
8 changes: 4 additions & 4 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: 'Close stale issues'
name: "Close stale issues"

on:
schedule:
- cron: '30 * * * *'
- cron: "30 * * * *"
workflow_dispatch:

permissions:
Expand All @@ -17,8 +17,8 @@ jobs:
- uses: actions/stale@v9
with:
exempt-issue-labels: pending
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.'
close-issue-message: 'This issue was closed because it has been stalled for 30 days with no activity.'
stale-issue-message: "This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days."
close-issue-message: "This issue was closed because it has been stalled for 30 days with no activity."
days-before-stale: 60
days-before-close: 30
operations-per-run: 200
Expand Down
18 changes: 9 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
| --------------------- | --------------------------------------------------------------------------------------- |
| English only | All code must be in English: variable names, function names, comments |
| PNPM only | Always use pnpm, never npm or yarn |
| NO COMMENTS | Code must be self-documenting through clear naming. TSDoc is allowed for public APIs |
| NO COMMENTS | Code must be self-documenting through clear naming. TSDoc is allowed for public APIs |
| NO switch/case | Use objects, maps, or arrays instead |
| NO inline types | Define proper interfaces/types, never use anonymous types like `{a: string, b: number}` |
| Functions ≤ 40 lines | Split into subfunctions if longer |
Expand All @@ -35,23 +35,23 @@ Never use `switch/case` or `if param === 'XXX'` chains. Instead:
// BAD
function getStatus(code: string) {
switch (code) {
case 'A':
return 'Active';
case 'I':
return 'Inactive';
case "A":
return "Active";
case "I":
return "Inactive";
default:
return 'Unknown';
return "Unknown";
}
}

// GOOD
const STATUS_MAP: Record<string, string> = {
A: 'Active',
I: 'Inactive',
A: "Active",
I: "Inactive",
};

function getStatus(code: string) {
return STATUS_MAP[code] ?? 'Unknown';
return STATUS_MAP[code] ?? "Unknown";
}
```

Expand Down
3 changes: 0 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Changelog


## v0.0.6

[compare changes](https://github.com/AntelopeJS/interface-auth/compare/v0.0.5...v0.0.6)
Expand Down Expand Up @@ -64,7 +63,6 @@

## v0.0.2


### 🚀 Enhancements

- Initial interface-auth package ([b7ec0d9](https://github.com/AntelopeJS/interface-auth/commit/b7ec0d9))
Expand All @@ -85,4 +83,3 @@

- Antony Rizzitelli <upd4ting@gmail.com>
- Glastis ([@Glastis](http://github.com/Glastis))

56 changes: 0 additions & 56 deletions biome.json

This file was deleted.

12 changes: 8 additions & 4 deletions docs/2.authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ A typical authentication flow consists of four steps:

```typescript
import { SignRaw, Authentication } from "@antelopejs/interface-auth";
import { Controller, Post, Get, JSONBody, HTTPResult } from "@antelopejs/interface-api";
import {
Controller,
Post,
Get,
JSONBody,
HTTPResult,
} from "@antelopejs/interface-api";

class UserController extends Controller("/users") {
@Post("login")
Expand Down Expand Up @@ -153,9 +159,7 @@ const AdminOnly = CreateAuthDecorator({
The `AuthValidator` type signature is:

```typescript
type AuthValidator<T = unknown, R = unknown> = (
data: T,
) => Promise<R> | R;
type AuthValidator<T = unknown, R = unknown> = (data: T) => Promise<R> | R;
```

## Authentication pipeline
Expand Down
54 changes: 27 additions & 27 deletions docs/3.token-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ console.log(token); // Signed token string

The function accepts two arguments:

| Argument | Type | Description |
| --------- | -------------------------------- | ------------------------------ |
| `data` | `string \| Buffer \| object` | The data to sign |
| `options` | `SignOptions` (optional) | Signing configuration options |
| Argument | Type | Description |
| --------- | ---------------------------- | ----------------------------- |
| `data` | `string \| Buffer \| object` | The data to sign |
| `options` | `SignOptions` (optional) | Signing configuration options |

`SignRaw` returns a `Promise<string>` that resolves to the signed token.

### `SignOptions`

The `SignOptions` interface configures token generation.

| Property | Type | Description |
| ----------- | ------------------ | ---------------------------------------------------------------------- |
| Property | Type | Description |
| ----------- | ------------------ | ---------------------------------------------------------------------------- |
| `expiresIn` | `string \| number` | Token expiration time as seconds or a timespan string (e.g., `"1h"`, `"2d"`) |
| `notBefore` | `string \| number` | Duration before which the token is not valid |
| `notBefore` | `string \| number` | Duration before which the token is not valid |

### `SignServerResponse`

Expand All @@ -59,28 +59,28 @@ async function login(res: ServerResponse) {

The function accepts four arguments:

| Argument | Type | Description |
| --------------- | ----------------------------- | ---------------------------------- |
| `res` | `ServerResponse` | The HTTP response object |
| `data` | `string \| Buffer \| object` | The data to sign |
| `signOptions` | `SignOptions` (optional) | Signing configuration options |
| `cookieOptions` | `CookieOptions` (optional) | Cookie configuration options |
| Argument | Type | Description |
| --------------- | ---------------------------- | ----------------------------- |
| `res` | `ServerResponse` | The HTTP response object |
| `data` | `string \| Buffer \| object` | The data to sign |
| `signOptions` | `SignOptions` (optional) | Signing configuration options |
| `cookieOptions` | `CookieOptions` (optional) | Cookie configuration options |

The cookie is set with the name `ANTELOPEJS_AUTH` and the signed token as its value. The function returns a `Promise<ServerResponse>` that resolves to the same response object once the cookie header has been set.

### `CookieOptions`

The `CookieOptions` interface configures the authentication cookie.

| Property | Type | Description |
| ---------- | --------- | ---------------------------------------------------------- |
| `maxAge` | `number` | Maximum age in milliseconds |
| `signed` | `boolean` | Whether the cookie should be signed |
| `expires` | `Date` | Specific date when the cookie expires |
| `httpOnly` | `boolean` | Prevents client-side JavaScript from accessing the cookie |
| `path` | `string` | URL path for which the cookie is valid |
| `domain` | `string` | Domain for which the cookie is valid |
| `secure` | `boolean` | Only sends the cookie over HTTPS |
| Property | Type | Description |
| ---------- | --------- | --------------------------------------------------------- |
| `maxAge` | `number` | Maximum age in milliseconds |
| `signed` | `boolean` | Whether the cookie should be signed |
| `expires` | `Date` | Specific date when the cookie expires |
| `httpOnly` | `boolean` | Prevents client-side JavaScript from accessing the cookie |
| `path` | `string` | URL path for which the cookie is valid |
| `domain` | `string` | Domain for which the cookie is valid |
| `secure` | `boolean` | Only sends the cookie over HTTPS |

## Token validation

Expand All @@ -101,9 +101,9 @@ try {

The function accepts two arguments:

| Argument | Type | Description |
| --------- | --------------- | -------------------------------- |
| `token` | `string` (optional) | The signed token to verify |
| Argument | Type | Description |
| --------- | -------------------------- | -------------------------- |
| `token` | `string` (optional) | The signed token to verify |
| `options` | `VerifyOptions` (optional) | Verification configuration |

### `VerifyOptions`
Expand All @@ -112,8 +112,8 @@ The `VerifyOptions` interface configures token validation.

| Property | Type | Description |
| ------------------ | ------------------ | ---------------------------------------------------- |
| `ignoreExpiration` | `boolean` | If `true`, expired tokens are still considered valid |
| `ignoreNotBefore` | `boolean` | If `true`, tokens not yet valid are accepted |
| `ignoreExpiration` | `boolean` | If `true`, expired tokens are still considered valid |
| `ignoreNotBefore` | `boolean` | If `true`, tokens not yet valid are accepted |
| `maxAge` | `string \| number` | Maximum allowed age of the token |

### Example with verify options
Expand Down
20 changes: 10 additions & 10 deletions docs/4.parameter-decoration.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ export const ApiKeyAuth = CreateAuthDecorator({

The function accepts an object with the following properties:

| Property | Type | Description |
| ---------------------- | --------------------- | -------------------------------------------------------- |
| Property | Type | Description |
| ---------------------- | --------------------- | --------------------------------------------------------------- |
| `source` | `AuthSource` | Extracts the token from the request (defaults to header/cookie) |
| `authenticator` | `AuthVerifier<T>` | Verifies the token and returns the payload |
| `authenticatorOptions` | `VerifyOptions` | Options passed to the authenticator |
| `validator` | `AuthValidator<T, R>` | Validates and transforms the authenticated data |
| `authenticator` | `AuthVerifier<T>` | Verifies the token and returns the payload |
| `authenticatorOptions` | `VerifyOptions` | Options passed to the authenticator |
| `validator` | `AuthValidator<T, R>` | Validates and transforms the authenticated data |

All properties are optional. When omitted, the default behavior is used.

Expand Down Expand Up @@ -165,8 +165,8 @@ class UserController extends Controller("/users") {

The `@Authentication` decorator (and any custom decorator created with `CreateAuthDecorator`) can be applied at three levels:

| Scope | Effect |
| ----------- | ------------------------------------------------------------------- |
| Parameter | Injects the verified payload into a single handler parameter |
| Property | Populates a class property with the verified payload for all handlers |
| Class | Requires authentication for every route in the controller |
| Scope | Effect |
| --------- | --------------------------------------------------------------------- |
| Parameter | Injects the verified payload into a single handler parameter |
| Property | Populates a class property with the verified payload for all handlers |
| Class | Requires authentication for every route in the controller |
14 changes: 14 additions & 0 deletions knip.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { antelopeKnipConfig } from "@antelopejs/tooling-configs/knip";

export default antelopeKnipConfig({
entry: [
// `ajs module test` runs the compiled suites out of this tree, and reads
// src/antelope.test.ts (package.json antelopeJs.test) to build the test
// project; the preset only knows the `src/test/` spelling.
"src/tests/**/*.test.ts",
"src/antelope.test.ts",
],
// `ajs` comes from @antelopejs/core, which CI installs globally rather than
// pulling the whole CLI into every module's dependency tree.
ignoreBinaries: ["ajs"],
});
7 changes: 7 additions & 0 deletions oxfmt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { antelopeFmtPreset } from "@antelopejs/tooling-configs/oxc/fmt";

export default antelopeFmtPreset({
// Drop once tooling-configs ships the shared ignore (AntelopeJS/tooling-configs#5):
// these are Markdown templates with a .yml extension, which oxfmt cannot parse.
ignorePatterns: [".github/ISSUE_TEMPLATE/**"],
});
7 changes: 7 additions & 0 deletions oxlint.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from "oxlint";
import { antelopePreset } from "@antelopejs/tooling-configs/oxc/lint";

export default defineConfig({
extends: [antelopePreset()],
options: { typeAware: true },
});
Loading