Auth & Sessions

Flow tổng quát

POST /api/auth/login

Gửi email + password. Nhận Set-Cookie: iai_session=... trong response.

Mọi request sau: credentials: "include"

Browser tự gửi cookie. Không cần attach token thủ công.

GET /api/auth/session

Kiểm tra session còn hiệu lực. Dùng trên mọi page load của dash.iai.one.

DELETE /api/auth/session

Logout. Xóa session trong D1. Cookie bị clear.

Endpoints

POST /api/auth/login

POST/api/auth/loginLogin with email + password
Request body
{
  "email": "you@company.com",
  "password": "your-password"
}
Response 200
Set-Cookie: iai_session=<opaque-token>; HttpOnly; Secure; SameSite=None; Path=/; Max-Age=604800

{
  "authenticated": true,
  "user": {
    "id": "usr_abc123",
    "email": "you@company.com",
    "name": "Your Name"
  },
  "workspace": {
    "workspaceId": "ws_xyz",
    "name": "My Workspace",
    "role": "owner"
  }
}
Response 401
{ "error": "Invalid credentials" }

GET /api/auth/session

GET/api/auth/sessionCheck current session
Response 200 — authenticated
{
  "authenticated": true,
  "user": { "id": "usr_...", "email": "...", "name": "..." },
  "workspace": { "workspaceId": "ws_...", "name": "...", "role": "owner" }
}
Response 401 — not authenticated
{ "authenticated": false }

DELETE /api/auth/session

DELETE/api/auth/sessionLogout — invalidate session
Response 200
{ "ok": true }

Cookie bị clear, session bị xóa khỏi D1.

Session details

PropertyValue
Cookie nameiai_session
TTL7 ngày (604800 giây)
StorageD1 database (opaque token)
Password hashPBKDF2-SHA256, 100k iterations
SameSiteNone (required for cross-origin dash.iai.one)
Securetrue (HTTPS only)
HttpOnlytrue (không accessible bởi JS)
Cross-origin: Vì dash.iai.one và api.flow.iai.one là khác domain, cookie cần SameSite=None; Secure. Và client phải gửi credentials: "include" với mọi fetch.

Auth guard pattern (Frontend)

// auth-guard.js — runs on every protected page
async function checkSession() {
  const res = await fetch("https://api.flow.iai.one/api/auth/session", {
    credentials: "include"
  });

  if (res.status !== 200) {
    location.replace("/login/?next=" +
      encodeURIComponent(location.pathname));
    return null;
  }

  const data = await res.json();
  if (!data.authenticated) {
    location.replace("/login/");
    return null;
  }

  return data; // { user, workspace }
}

CORS Requirements

API returns these headers for dash.iai.one and developer.iai.one origins:

Access-Control-Allow-Origin: https://dash.iai.one
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Pattern *.iai.one được allow. Mọi subdomain của iai.one có thể gọi API với credentials.