chyoo 19b8e40b72
ci/woodpecker/push/woodpecker Pipeline was successful
store profile avatars in R2
2026-07-08 11:40:50 +09:00
2026-07-02 01:43:41 +00:00
2026-07-06 11:45:35 +09:00
2026-07-08 11:40:50 +09:00
2026-07-01 17:36:34 +09:00
2026-07-03 16:45:19 +09:00
2026-07-08 11:40:50 +09:00
2026-07-01 17:36:34 +09:00
2026-07-01 17:36:34 +09:00
2026-07-08 11:40:50 +09:00
2026-07-01 17:36:34 +09:00
2026-07-01 17:36:34 +09:00

ATNMY STDO Auth

Central JWT auth server for Autonomy Studio and launched apps.

Stack

  • Bun
  • Hono
  • PostgreSQL
  • Redis
  • Prisma
  • JWT access tokens
  • Opaque refresh tokens stored in Redis
  • One-time handoff tokens for app SSO stored in Redis

Local Run

cp .env.example .env
docker compose up -d postgres redis
bun install
bun run db:generate
bun run db:migrate
bun run db:seed
bun run dev

Default server:

http://localhost:4100

Default backing services:

PostgreSQL: localhost:5434
Redis: localhost:6380

Default seeded admin:

admin@futuredrive.net / admin1234

Change this before using the service outside local development.

API

Login

POST /auth/login
Content-Type: application/json

{
  "email": "admin@futuredrive.net",
  "password": "admin1234"
}

Returns:

{
  "accessToken": "...",
  "accessTokenExpiresIn": 900,
  "refreshToken": "...",
  "refreshTokenExpiresIn": 2592000,
  "user": {
    "id": "...",
    "email": "admin@futuredrive.net",
    "name": "ATNMY Studio Admin",
    "role": "ADMIN",
    "roles": ["ADMIN"]
  }
}

Current User

GET /auth/me
Authorization: Bearer <accessToken>

Refresh

POST /auth/refresh
Content-Type: application/json

{
  "refreshToken": "<refreshToken>"
}

Refresh tokens are rotated on every use.

Logout

POST /auth/logout
Content-Type: application/json

{
  "refreshToken": "<refreshToken>"
}

Create App Handoff Token

Launcher calls this before launching ADS IDE or another app.

POST /auth/handoff
Authorization: Bearer <launcherAccessToken>
Content-Type: application/json

{
  "audienceApp": "ADS IDE"
}

Returns a short-lived one-time token:

{
  "handoffToken": "...",
  "expiresIn": 60,
  "audienceApp": "ADS IDE"
}

Exchange App Handoff Token

The launched app calls this on startup.

POST /auth/handoff/exchange
Content-Type: application/json

{
  "handoffToken": "...",
  "audienceApp": "ADS IDE"
}

Returns the launched app's own access/refresh token pair.

Launcher Integration Sketch

const handoff = await fetch(`${AUTH_URL}/auth/handoff`, {
  method: 'POST',
  headers: {
    authorization: `Bearer ${accessToken}`,
    'content-type': 'application/json'
  },
  body: JSON.stringify({ audienceApp: 'ADS IDE' })
}).then((r) => r.json())

spawn(execBin, [
  `--url=${encodeURIComponent(url)}`,
  `--handoff-token=${encodeURIComponent(handoff.handoffToken)}`,
  `--auth-url=${encodeURIComponent(AUTH_URL)}`
])

ADS IDE then calls /auth/handoff/exchange and stores the returned session.

S
Description
No description provided
Readme 200 KiB
Languages
TypeScript 99.7%
Dockerfile 0.3%