# Hamshift auth.md

## Service and agent audience

Resource: `https://hmshift.ir/api`.

This document is for automated clients acting with an authorized Hamshift user's account. Hamshift uses the same hospital, role, and ward permissions for automated clients as for its web app. It does not currently provide OAuth authorization servers, bearer access tokens, client credentials, or a separate autonomous agent-registration endpoint.

Discovery: [API catalog](https://hmshift.ir/.well-known/api-catalog), [OpenAPI specification](https://hmshift.ir/api/openapi.json), and [API documentation](https://hmshift.ir/api/docs).

## Supported registration and provisioning methods

Supported methods are **manager provisioning** and **manager-issued invitation acceptance**. These create ordinary Hamshift user accounts. Use only an account or invitation explicitly provided for your authorized work. Reading this document does not authorize registration. Registration changes service state; passive discovery clients must only read discovery documents and must not submit or probe registration requests.

### Agent registration discovery

This self-contained `agent_auth` block describes the existing enrollment endpoints. It is documentation for this service's session-cookie API, not OAuth Authorization Server metadata. Both methods require prior authorization from the hospital's manager; there is no unrestricted enrollment.

```json
{
  "agent_auth": {
    "skill": "https://hmshift.ir/auth.md",
    "register_uri": "https://hmshift.ir/api/employees",
    "registration_methods": [
      {
        "name": "manager_provisioning",
        "register_uri": "https://hmshift.ir/api/employees",
        "http_method": "POST",
        "content_type": "application/json",
        "authorization_required": "Existing manager session in the nobat_sid cookie",
        "required_fields": ["name", "username", "password"],
        "response_fields": ["id", "username"],
        "credential_types_supported": ["username_password", "session_cookie"],
        "credential_use": "The provisioned account signs in at /api/auth/login and retains the nobat_sid cookie; an initial password change may be required."
      },
      {
        "name": "manager_issued_invitation",
        "register_uri": "https://hmshift.ir/api/invite/{token}/accept",
        "http_method": "POST",
        "content_type": "application/json",
        "authorization_required": "Valid single-use invitation token supplied by an authorized manager",
        "required_fields": ["name", "username", "password"],
        "response_fields": ["user"],
        "credential_types_supported": ["username_password", "session_cookie"],
        "credential_use": "Acceptance sets the nobat_sid cookie; retain it for subsequent API calls."
      }
    ]
  }
}
```

### Manager provisioning

Provisioning endpoint: `POST https://hmshift.ir/api/employees`.

An existing, signed-in manager provisions a staff account in the selected ward. The request requires the manager's `nobat_sid` session cookie and `Content-Type: application/json`. Required JSON fields are `name`, `username`, and `password`; optional fields include `email`, `category`, and `title`. The response is an object containing `id` and `username`.

The manager provides the credentials to the account owner. A manager-created account normally requires changing its initial password before using protected workflows. After signing in, if `user.mustChangePassword` is true, submit `POST https://hmshift.ir/api/account/password` using the session cookie and JSON fields `current` and `next`. The new password must differ from the initial password. Until then, the account may read `/api/me`, change its password, or sign out.

### Invitation acceptance

Invitation issuance endpoint: `POST https://hmshift.ir/api/invites` (requires a signed-in manager). For a staff invitation, send JSON with `role: "staff"`; optional fields include `wardId`, `name`, `category`, and `days` (1–30, default 7). Only a super admin may issue a head-nurse invitation. Issuance returns `invite`, `token`, and `url`; the manager supplies that invitation to the account owner.

Invitation metadata endpoint: `GET https://hmshift.ir/api/invite/{token}`. Replace `{token}` with the supplied invitation token, URL-encoded as a path segment. This read-only response identifies the ward, role, expiry, and inviter. Invalid invitations return HTTP 404; used, expired, or revoked invitations return HTTP 410.

Registration endpoint: `POST https://hmshift.ir/api/invite/{token}/accept`. With an authorized, valid invitation, send `Content-Type: application/json` and required JSON fields `name`, `username`, and `password`. Optional field: `gender`. No existing session is required. Acceptance consumes the single-use invitation, creates the user in the invitation's ward and role, returns `{ "user": ... }`, and sets the `nobat_sid` session cookie. Preserve that cookie for subsequent API calls.

Public self-registration is closed after initial setup. `/api/auth/setup` is exclusively for the first human administrator of an empty installation, not ongoing agent enrollment.

## Authentication and credential use

Supported credential method for automated HTTP clients: **username/password followed by a session cookie**.

1. Use an existing, authorized account or complete one of the provisioning methods above.
2. Sign in with `POST https://hmshift.ir/api/auth/login`, `Content-Type: application/json`, and JSON fields `username` and `password`. Success returns `{ "user": ... }` and a `Set-Cookie` header for the HttpOnly `nobat_sid` cookie.
3. Keep the cookie in a cookie jar and send it in the `Cookie` header to the same service. Do not use `Authorization: Bearer`; this service does not issue bearer tokens. Sessions currently expire after 30 days and can be revoked earlier.
4. Check the current identity with `GET https://hmshift.ir/api/me`. For ward-scoped operations, optionally send `X-Ward` with the authorized ward's numeric ID, or use the `ward` query parameter. Without one, the user's home ward is selected.
5. Sign out using `POST https://hmshift.ir/api/auth/logout`, the session cookie, `Content-Type: application/json`, and an empty JSON object. This revokes the current session and clears its cookie.

Passkey sign-in is also available in the interactive web app and requires a WebAuthn authenticator ceremony. It is not an unattended registration or credential-issuance method.

All state-changing API calls require `Content-Type: application/json`. Usernames must be unique. Passwords currently accept 6–200 characters; use a strong unique password. Keep account credentials, invitation tokens, and session cookies private and use HTTPS.

HTTP 401 means credentials are incorrect or sign-in is required. HTTP 403 means the account is inactive, its role or ward is unauthorized, or it needs a password change. Login can return HTTP 429 after too many failed attempts. JSON errors include a human-readable `error` (usually Persian) and may include a machine-readable `code`, such as `must_change_password` or `ward_forbidden`.

## OAuth and identity-assertion discovery

OAuth Protected Resource Metadata and OAuth Authorization Server metadata are not published because no OAuth server or bearer-token flow is implemented. Only the two account-provisioning methods and session-cookie authentication described above are supported. An email profile field does not establish email-based authentication.

## Revocation

An authenticated account can list its sessions with `GET https://hmshift.ir/api/account/sessions`, revoke a selected session using `DELETE https://hmshift.ir/api/account/sessions/{id}`, or revoke other sessions using `POST https://hmshift.ir/api/account/sessions/revoke-others`. State-changing requests require JSON content type. Changing a password revokes other sessions. Logout revokes the current session. There is no agent revocation event stream or OAuth token revocation endpoint.

## Session compatibility

Sessions use Better Auth with a signed opaque `nobat_sid` cookie. Retain the entire cookie exactly as returned. Sessions expire 30 days after creation; password changes revoke other devices and password resets revoke all devices. Existing usernames, passwords, and passkeys remain supported. No email login, public signup, email recovery, or OAuth token endpoints are exposed.
