qnote/docs/API.md
2025-04-10 22:31:09 +03:00

4.4 KiB

Overview of the API endpoint routing

The common prefix for all API routes is /api. All resource IDs are of type UUIDv4. Any routes utilizing pagination have the defaults of 50 for limit and 0 for offset.

Auth

Unprotected endpoints:

  • POST /auth/signup: Create a new user with username and password -> Created user's username and ID
  • POST /auth/login: Login to an existing user with username and password -> Cookie with refresh token and response with access token (including user data if includeUser URL parameter is true)

Endpoints protected with requireAccessToken middleware:

  • GET /auth/me: Get own user's data -> userResponse DTO (user ID, username, admin status, and timestamps of creation and last update)
  • POST /auth/logout: Logout the current user -> Cookie that replaces the refresh token with one that expires immediately
  • PUT /auth/owner/: Update password of the current user with old_password and new_password -> HTTP 204 response
  • DELETE /auth/owner/: Delete the current user (as the owner) with password -> HTTP 204 response
  • GET /auth/admin/all: As an administrator, list all users stored in the system (adjustable with pagination URL parameters) -> Array of userResponse DTOs
  • DELETE /auth/admin/{userID}: As an administrator, delete a specific user -> HTTP 204 response

Endpoints protected with requireRefreshToken and gorilla/csrf middlewares:

  • GET /auth/cookie/csrf: Get new CSRF token -> HTTP 204 response with the token set in the X-CSRF-Token response header
  • POST /auth/cookie/refresh: Perform token rotation (revokes the old refresh token server-side) -> Cookie with new refresh token and response with access token

Notes

All notes related endpoints are protected with requireAccessToken middleware, which means that Bearer <JWT_AT> must be included into the Authorization header of each request. The middleware automatically attaches JWT's user claims into the request's context.

  • POST /notes: Create a new note -> Placeholder contents (title and content)
  • GET /notes: List the metadata of all owned notes -> Array of data.ListNoteRows (note ID, owner ID, title, and timestamp of last update)
  • GET /notes/{noteID}: Get the full representation of a specific note -> data.GetFullNoteRow (metadata + current version's title and content)
  • DELETE /notes/{noteID}: Delete a specific note -> HTTP 204 response
  • GET /notes/{noteID}/versions: Get version metadata history of a specific note (adjustable with pagination URL parameters) -> Array of data.GetVersionHistoryRow (version ID, title, version number, and timestamp of creation)
  • POST /notes/{noteID}/versions: Create a new version for a specific note with title and content -> HTTP 204 response
  • GET /notes/{noteID}/{versionID}: Get the full representation of a specific version of a specific note -> data.GetVersionRow (metadata + the version's content)

Practical client usage

Auth sequence

Sequence diagram of the authentication flow

  • Store access and CSRF tokens in memory (never in localStorage)
  • Automatically handle 401 responses by attempting token refresh
  • Queue pending requests during token refresh, if necessary
  • Clear local tokens on logout (POST /auth/logout)

Flow of accessing protected resources

Flowchart of accessing a protected resource

Flow of accessing versioned notes

Flowchart of perfoming actions for versioned note

Admin resources

  • Verification of the presence of isAdmin tag before rendering
  • Graceful handling of 403 errors
  • Automatic refresh of locally cached users list (if any) after admin actions (e.g. deleting users)

Error cases

  • Invalid token (401):
    • While using access token -> Automatically attempt refresh
    • While using refresh token -> Redirect to login page
  • Insufficient permissions (403): Don't render the corresponding route
  • Resource not found (404): Render a dedicated 404 view

State management

  • Authentication state
  • Resource state (current note)
  • Pagination state (current page, page size, and total locally cached items)

Necessary client interceptors

  • Requests: Add Authorization header with either access_token or request_token
  • Responses: Handle 401 -> Attempt to automatically rotate the tokens
  • Errors: Handle network errors + aforementioned API error formats