Authentication API
Relevant source files
The following files were used as context for generating this wiki page:
The Authentication API provides a security layer for the web-archive server, protecting sensitive endpoints from unauthorized access. It is a token-based system centered around a single admin user. The core functionality includes user login, logout, session verification, and middleware for protecting API routes.
Authentication is managed through JSON Web Tokens (JWT) which are generated upon successful login and verified on subsequent requests to protected routes. The system supports a first-time setup flow where the initial valid password provided becomes the administrator's password.
Authentication Flow
The authentication process begins when a user attempts to log in. The server validates the provided password, and upon success, generates a JWT. This token is then sent to the client, which must include it in the Authorization header for all subsequent requests to protected endpoints.
Login Sequence
The following diagram illustrates the sequence of events during a user login.
First-Time Setup
The system has a special flow for the first time an administrator logs in.
- The
verifyAdminTokenfunction checks if anADMIN_TOKENkey exists in thestorestable. - If it does not exist, the first password provided (at least 8 characters long) is hashed (SHA256) and stored as the
ADMIN_TOKEN. The login status is returned as'new'. - If an
ADMIN_TOKENalready exists, the provided password is a hashed and compared against the stored value.
Sources: packages/server/src/model/store.ts:15-32
Core Components
Authentication Endpoints
The authentication logic is exposed via the /api/auth route.
Sources: packages/server/src/api/auth.ts, packages/server/src/server.ts:31
| Method | Endpoint | Description | Request Body | Response |
|---|---|---|---|---|
POST | /login | Authenticates the user. On success, signs a JWT and sets it in an HTTP-only cookie named token. The status can be 'new' for first-time setup or 'accept' for normal login. | { "token": "..." } | 200 OK with `{ status: 'new' |
POST | /logout | Clears the token cookie, effectively logging the user out. | (empty) | 200 OK with { success: true }. |
GET | /check | Verifies if the current user has a valid session by checking the JWT provided in the Authorization header. This endpoint is protected by the tokenMiddleware. | (empty) | 200 OK with { success: true } if authenticated, 401 Unauthorized otherwise. |
Token Middleware
A crucial component is the tokenMiddleware, which protects specified API routes. It intercepts incoming requests, extracts the JWT from the Authorization header, and verifies its validity.
Sources: packages/server/src/middleware/token.ts, packages/server/src/server.ts:29
Middleware Logic Flow
This diagram shows how the middleware processes each request to a protected route.
JWT Structure
The JWT is signed using the JWT_SECRET environment variable. The payload contains a single claim identifying the user.
- Payload:
{ user: 'admin' } - Signing Algorithm: HS256 (default for
hono/jwt)
Sources: packages/server/src/middleware/token.ts:26
Database Interaction
Authentication state, specifically the admin password hash, is persisted in the D1 database in the stores table.
Sources: packages/server/src/model/store.ts
Key Functions
verifyAdminToken(DB, token): The core verification logic.- Validates the token is a string of at least 8 characters.
- Hashes the token using
sha256. - Checks if a matching
ADMIN_TOKENexists in the database. - If it matches, returns
'accept'. - If no
ADMIN_TOKENexists, it sets the provided token as the new admin token and returns'new'. - If it doesn't match, returns
'reject'.
hashToken(token): A utility function that computes the SHA256 hash of the provided password string.
Sources: packages/server/src/model/store.ts:4-13, packages/server/src/model/store.ts:15-32
Client-Side Handling (Browser Plugin)
The browser plugin is a primary consumer of the authentication API. It manages the token and includes it in requests to the server.
Sources: [packages/plugin/background/background.ts]
Request Helper
A request function in the plugin's background script automatically appends the authentication token to every API call.
// packages/plugin/background/background.ts:20-32
async function appendAuthHeader(options?: RequestInit) {
const { token } = await Browser.storage.local.get('token') ?? {}
if (!options) {
return {
headers: {
Authorization: `Bearer ${token}`,
},
}
}
options.headers = Object.assign(options?.headers ?? {}, {
Authorization: `Bearer ${token}`,
})
return options
}
Sources: packages/plugin/background/background.ts:20-32
The plugin listens for messages like login, logout, and check-auth from its UI components and interacts with the server's /api/auth endpoints accordingly. Upon successful login, the token received from the server (via the cookie set on the server URL) is stored in the browser's local storage for use in subsequent Authorization headers.