No description
  • TypeScript 100%
Find a file
Neo Huyghe 2f08ae3fdc
All checks were successful
CI / build (push) Successful in 10s
chore: release 0.1.3
2026-05-27 11:18:04 +02:00
.forgejo/workflows chore: biome auto-format pass + Forgejo CI + publish workflow 2026-05-18 16:55:07 +02:00
examples docs(examples): vanilla, oidc-client-ts SPA, react passkey enrollment snippets 2026-05-18 16:51:14 +02:00
src fix(linked-accounts): merge available() by provider_name 2026-05-27 11:17:38 +02:00
tests fix(linked-accounts): merge available() by provider_name 2026-05-27 11:17:38 +02:00
.gitignore chore: bootstrap @orionauth/account-sdk (tsup, vitest, biome, MIT) 2026-05-18 16:32:15 +02:00
.npmignore chore: bootstrap @orionauth/account-sdk (tsup, vitest, biome, MIT) 2026-05-18 16:32:15 +02:00
biome.json chore: bootstrap @orionauth/account-sdk (tsup, vitest, biome, MIT) 2026-05-18 16:32:15 +02:00
CHANGELOG.md chore: release 0.1.3 2026-05-27 11:18:04 +02:00
LICENSE chore: bootstrap @orionauth/account-sdk (tsup, vitest, biome, MIT) 2026-05-18 16:32:15 +02:00
package-lock.json feat(linked-accounts): begin-link, get-by-id and available helpers 2026-05-26 16:17:52 +02:00
package.json chore: release 0.1.3 2026-05-27 11:18:04 +02:00
README.md chore: bootstrap @orionauth/account-sdk (tsup, vitest, biome, MIT) 2026-05-18 16:32:15 +02:00
tsconfig.json chore: bootstrap @orionauth/account-sdk (tsup, vitest, biome, MIT) 2026-05-18 16:32:15 +02:00
tsup.config.ts build: enable tsup code splitting to dedupe shared modules 2026-05-26 10:58:25 +02:00
vitest.config.ts test: 53 tests covering http, errors, encoding, modules, stepUp, oidc-client-ts integration (89% lines) 2026-05-18 16:49:48 +02:00

@orionauth/account-sdk

TypeScript SDK for the OrionAuth User Account API (/api/v1/me/*). It wraps every self-service endpoint — profile, password, email change, MFA TOTP, passkeys (WebAuthn), sessions, linked accounts, account deletion — plus the step-up re-authentication flow (X-Reauth-Token) and the usernameless passkey login.

npm install @orionauth/account-sdk
# or
pnpm add @orionauth/account-sdk

Quickstart

import { AccountClient } from '@orionauth/account-sdk'

const client = new AccountClient({
  baseUrl: 'https://auth.example.com',
  getAccessToken: async () => yourAccessToken,
})

const profile = await client.profile.get()
await client.profile.update({ displayName: 'Bob' })

await client.passkeys.register({ name: 'My laptop' }) // wraps navigator.credentials.create
const sessions = await client.sessions.list()

Step-up reauthentication

Sensitive endpoints (password change, MFA disable, passkey delete, account deletion, email change, linked-account unlink) require a short-lived reauth token in X-Reauth-Token. The SDK ships two patterns:

Low-level

const { reauth_token } = await client.reauth.withPassword(currentPassword)
await client.password.change(
  { currentPassword, newPassword },
  { reauthToken: reauth_token },
)

High-level

import { withStepUp } from '@orionauth/account-sdk'

await withStepUp(
  () => client.password.change({ currentPassword, newPassword }),
  { method: 'password', getPassword: () => prompt('Confirm your password') },
)

withStepUp intercepts a ReauthRequiredError, issues a fresh reauth token and retries the original call once.

Passkeys

// 1. Enrollment (authenticated)
await client.passkeys.register({ name: 'My phone' })

// 2. Usernameless login (public, no bearer required)
import { passkeyLogin } from '@orionauth/account-sdk'

const { user_id, email } = await passkeyLogin({
  baseUrl: 'https://auth.example.com',
})

Integration with oidc-client-ts

import { UserManager } from 'oidc-client-ts'
import { fromUserManager } from '@orionauth/account-sdk/integrations/oidc-client-ts'

const userManager = new UserManager({ /* … */ })
const client = fromUserManager(userManager, {
  baseUrl: 'https://auth.example.com',
})

The helper binds getAccessToken to userManager.getUser().access_token and automatically calls signinSilent() on a 401 before retrying.

Errors

Every HTTP error throws a typed subclass of AccountError:

import {
  AccountError,
  ConflictError,
  ReauthRequiredError,
  ValidationError,
} from '@orionauth/account-sdk'

try {
  await client.email.requestChange({ newEmail: 'taken@example.com' })
} catch (err) {
  if (err instanceof ConflictError) { /* email already used */ }
  if (err instanceof ReauthRequiredError) { /* surface a reauth modal */ }
}

License

MIT