diff --git a/infrastructure/web/api/routes/account.api.md b/infrastructure/web/api/routes/account.api.md index 6d1214c..b46e730 100644 --- a/infrastructure/web/api/routes/account.api.md +++ b/infrastructure/web/api/routes/account.api.md @@ -7,13 +7,13 @@ Manage user accounts, forwarding emails, locked inboxes, and API tokens. ## Endpoints -### GET `/api/account/` +### GET `/api/v1/account/` Get account info and stats for the authenticated user. - **Auth:** Required - **Response:** - `userId`, `username`, `createdAt`, `lastLogin`, `verifiedEmails`, `lockedInboxes`, `apiToken` -### POST `/api/account/verify-email` +### POST `/api/v1/account/verify-email` Add a forwarding email (triggers verification). - **Auth:** Required - **Body:** @@ -21,13 +21,13 @@ Add a forwarding email (triggers verification). - **Response:** - Success or error -### DELETE `/api/account/verify-email/:id` +### DELETE `/api/v1/account/verify-email/:id` Remove a forwarding email by ID. - **Auth:** Required - **Response:** - Success or error -### POST `/api/account/change-password` +### POST `/api/v1/account/change-password` Change account password. - **Auth:** Required - **Body:** @@ -35,25 +35,25 @@ Change account password. - **Response:** - Success or error -### DELETE `/api/account/` +### DELETE `/api/v1/account/` Delete the user account. - **Auth:** Required - **Response:** - Success or error -### GET `/api/account/token` +### GET `/api/v1/account/token` Get API token info (not the token itself). - **Auth:** Required - **Response:** - `hasToken`, `createdAt`, `lastUsed` -### POST `/api/account/token` +### POST `/api/v1/account/token` Generate or regenerate API token. - **Auth:** Required - **Response:** - Success or error -### DELETE `/api/account/token` +### DELETE `/api/v1/account/token` Revoke API token. - **Auth:** Required - **Response:** diff --git a/infrastructure/web/api/routes/auth.api.md b/infrastructure/web/api/routes/auth.api.md index 5dbcf1a..88bdb7e 100644 --- a/infrastructure/web/api/routes/auth.api.md +++ b/infrastructure/web/api/routes/auth.api.md @@ -7,7 +7,7 @@ User registration, login, logout, and session management. ## Endpoints -### POST `/api/auth/register` +### POST `/api/v1/auth/register` Register a new user. - **Body:** - `username`: string (3-20 chars, alphanumeric/underscore) @@ -17,7 +17,7 @@ Register a new user. - **Errors:** - `VALIDATION_ERROR`, `REGISTRATION_FAILED`, `AUTH_DISABLED` -### POST `/api/auth/login` +### POST `/api/v1/auth/login` Login user. - **Body:** - `username`, `password` @@ -26,12 +26,12 @@ Login user. - **Errors:** - `VALIDATION_ERROR`, `AUTH_DISABLED` -### POST `/api/auth/logout` +### POST `/api/v1/auth/logout` Logout user. - **Response:** - Success or error -### GET `/api/auth/session` +### GET `/api/v1/auth/session` Get current session info. - **Response:** - `userId`, `username`, `isAuthenticated`, `createdAt` diff --git a/infrastructure/web/api/routes/config.api.md b/infrastructure/web/api/routes/config.api.md index 940b013..278443a 100644 --- a/infrastructure/web/api/routes/config.api.md +++ b/infrastructure/web/api/routes/config.api.md @@ -7,20 +7,20 @@ Public endpoints for configuration, domains, limits, and features. ## Endpoints -### GET `/api/config/domains` +### GET `/api/v1/config/domains` Get allowed email domains. - **Response:** - `domains`: array of strings -### GET `/api/config/limits` +### GET `/api/v1/config/limits` Get rate limits and constraints. - **Response:** - `api.rateLimit`, `email.purgeTime`, `email.purgeUnit`, `email.maxForwardedPerRequest`, `user.maxVerifiedEmails`, `user.maxLockedInboxes`, `user.lockReleaseHours` -### GET `/api/config/features` +### GET `/api/v1/config/features` Get enabled features. - **Response:** - - `authentication`, `forwarding`, `statistics`, `inboxLocking` + - `authentication`, `forwarding`, `statistics` --- diff --git a/infrastructure/web/api/routes/inbox.api.md b/infrastructure/web/api/routes/inbox.api.md index 0cf5e1e..0063c9f 100644 --- a/infrastructure/web/api/routes/inbox.api.md +++ b/infrastructure/web/api/routes/inbox.api.md @@ -7,13 +7,13 @@ Endpoints for listing emails, retrieving full/raw emails, and downloading attach ## Endpoints -### GET `/api/inbox/:address` +### GET `/api/v1/inbox/:address` List mail summaries for an inbox. - **Auth:** Optional - **Response:** - Array of mail summary objects -### GET `/api/inbox/:address/:uid` +### GET `/api/v1/inbox/:address/:uid` Get full email by UID. - **Auth:** Optional - **Response:** @@ -21,7 +21,7 @@ Get full email by UID. - **Errors:** - `VALIDATION_ERROR`, `NOT_FOUND` -### GET `/api/inbox/:address/:uid/raw` +### GET `/api/v1/inbox/:address/:uid/raw` Get raw email source. - **Auth:** Optional - **Response:** @@ -29,7 +29,7 @@ Get raw email source. - **Errors:** - `VALIDATION_ERROR`, `NOT_FOUND` -### GET `/api/inbox/:address/:uid/attachment/:checksum` +### GET `/api/v1/inbox/:address/:uid/attachment/:checksum` Download attachment by checksum. - **Auth:** Optional - **Response:** diff --git a/infrastructure/web/api/routes/locks.api.md b/infrastructure/web/api/routes/locks.api.md index 12c7ef8..904c243 100644 --- a/infrastructure/web/api/routes/locks.api.md +++ b/infrastructure/web/api/routes/locks.api.md @@ -7,7 +7,7 @@ APIs for managing locked inboxes for users. All responses include a `templateCon ## Endpoints -### GET `/api/locks/` +### GET `/api/v1/locks/` List all inboxes locked by the authenticated user. - **Auth:** Required - **Response:** @@ -15,7 +15,7 @@ List all inboxes locked by the authenticated user. - `data`: array of locked inboxes - `templateContext`: `{ userId, config: { maxLockedInboxes } }` -### POST `/api/locks/` +### POST `/api/v1/locks/` Lock an inbox for the authenticated user. - **Auth:** Required - **Body:** @@ -32,7 +32,7 @@ Lock an inbox for the authenticated user. - Locked by other: `LOCKED_BY_OTHER` - All errors include `templateContext` -### DELETE `/api/locks/:address` +### DELETE `/api/v1/locks/:address` Unlock/release a locked inbox. - **Auth:** Required - **Response:** @@ -42,7 +42,7 @@ Unlock/release a locked inbox. - **Errors:** - Not found/unauthorized: `NOT_FOUND` (includes `templateContext`) -### GET `/api/locks/:address/status` +### GET `/api/v1/locks/:address/status` Check if an inbox is locked and if owned by the user. - **Auth:** Optional - **Response:** diff --git a/infrastructure/web/api/routes/mail.api.md b/infrastructure/web/api/routes/mail.api.md index fa20c2c..2c35919 100644 --- a/infrastructure/web/api/routes/mail.api.md +++ b/infrastructure/web/api/routes/mail.api.md @@ -7,7 +7,7 @@ Endpoints for deleting emails and forwarding mail. ## Endpoints -### DELETE `/api/mail/inbox/:address/:uid` +### DELETE `/api/v1/mail/inbox/:address/:uid` Delete a single email by UID. - **Auth:** Optional - **Response:** @@ -15,7 +15,7 @@ Delete a single email by UID. - **Errors:** - `VALIDATION_ERROR`, `NOT_FOUND` -### DELETE `/api/mail/inbox/:address` +### DELETE `/api/v1/mail/inbox/:address` Delete all emails in an inbox (requires `?confirm=true`). - **Auth:** Optional - **Response:** @@ -23,7 +23,7 @@ Delete all emails in an inbox (requires `?confirm=true`). - **Errors:** - `CONFIRMATION_REQUIRED`, `NOT_FOUND` -### POST `/api/mail/forward` +### POST `/api/v1/mail/forward` Forward a single email. - **Auth:** Required - **Body:** @@ -33,7 +33,7 @@ Forward a single email. - **Errors:** - `VALIDATION_ERROR`, `NOT_FOUND`, `FORWARD_FAILED` -### POST `/api/mail/forward-all` +### POST `/api/v1/mail/forward-all` Forward all emails in an inbox. - **Auth:** Required - **Body:** diff --git a/infrastructure/web/api/routes/stats.api.md b/infrastructure/web/api/routes/stats.api.md index 07481ed..d01d51c 100644 --- a/infrastructure/web/api/routes/stats.api.md +++ b/infrastructure/web/api/routes/stats.api.md @@ -7,12 +7,12 @@ Endpoints for retrieving statistics and historical data. ## Endpoints -### GET `/api/stats/` +### GET `/api/v1/stats/` Get lightweight statistics (no historical analysis). - **Response:** - `currentCount`, `allTimeTotal`, `last24Hours` (object with `receives`, `deletes`, `forwards`, `timeline`) -### GET `/api/stats/enhanced` +### GET `/api/v1/stats/enhanced` Get full statistics with historical data and predictions. - **Response:** - `currentCount`, `allTimeTotal`, `last24Hours`, `historical`, `prediction`, `enhanced` diff --git a/infrastructure/web/web.js b/infrastructure/web/web.js index 7785676..559be3a 100644 --- a/infrastructure/web/web.js +++ b/infrastructure/web/web.js @@ -153,6 +153,18 @@ app.use((req, res, next) => { next() }) +// Redirect /api/* to /api/v1/* if version is missing +app.use((req, res, next) => { + // Only match /api/ (not /api/v1/ or /api/v2/ etc.) + const apiMatch = req.path.match(/^\/api\/(?!v\d+\/)([^/?#]+)(.*)/) + if (apiMatch) { + // Redirect to latest stable version (v1) + const rest = apiMatch[1] + (apiMatch[2] || '') + return res.redirect(307, `/api/v1/${rest}`) + } + next() +}) + // Mount API router (v1) app.use('/api/v1', (req, res, next) => { const apiTokenRepository = req.app.get('apiTokenRepository')