@cqaiclub/cqai-account-sdk
v0.1.1
Published
Server-side TypeScript SDK for NewAPI login, account provisioning, tokens, usage, and billing
Downloads
206
Readme
CQAI Account SDK
Server-side TypeScript clients for the NewAPI HTTP interface. NewAPI remains the source of truth for dashboard users, API keys, quota, usage, and billing. This package does not contain an identity provider integration or a local database.
Install
npm install @cqaiclub/cqai-account-sdkBefore the first npm release, install directly from GitHub. The package's
prepare script builds dist during installation:
npm install github:cqai-club/cqai-account-sdkDashboard login and account queries
import { NewApiAuthClient } from '@cqaiclub/cqai-account-sdk'
const auth = new NewApiAuthClient({
baseUrl: process.env.NEW_API_URL!,
// Keep the access token and refresh cookie on a trusted backend.
origin: process.env.NEW_API_ORIGIN,
credentials: 'include',
})
const login = await auth.login({
username: 'alice',
password: process.env.NEW_API_PASSWORD!,
})
if (login.kind === 'two_factor') {
const authenticated = await auth.login2FA(login.flowToken, getTotpCode())
console.log(authenticated.user?.username)
} else {
console.log(login.user?.username)
}
const user = await auth.getSelf()
const tokens = await auth.listTokens({ page: 1, pageSize: 20 })
const fullKey = await auth.getTokenKey(tokens.items[0].id)
// refresh() uses the HttpOnly new_api_refresh cookie captured by the client.
await auth.refresh()
await auth.logout()login() returns a discriminated union. A successful password login stores the
dashboard access token and refresh cookie in the client. When Node's fetch
cannot expose Set-Cookie, pass a custom cookieJar or use a same-origin
browser request with credentials: 'include'.
The login endpoint may require a Cloudflare Turnstile token. Pass it as the
second argument: auth.login(request, { turnstile }). If password encryption
is enabled in NewAPI, provide the caller-encrypted fields
passwordEncrypted and encryptionKeyId; the SDK does not handle private RSA
keys.
Service provisioning and relay usage
Provisioning is server-only and requires the protected NewAPI service token:
import { NewApiClient } from '@cqaiclub/cqai-account-sdk'
const newApi = new NewApiClient({
baseUrl: process.env.NEW_API_URL!,
serviceToken: process.env.NEW_API_INTERNAL_TOKEN!,
})
const binding = await newApi.provision({
issuer: 'https://accounts.example.com',
subject: 'user-123',
platform: 'writer-app',
}, { idempotencyKey: 'writer-app:user-123' })
if (binding.apiKey) {
// Store the key only in the platform backend.
const usage = await newApi.getTokenUsage(binding.apiKey)
const subscription = await newApi.getSubscription(binding.apiKey)
const billing = await newApi.getBillingUsage(binding.apiKey)
console.log(usage.totalAvailable, subscription.accessUntil, billing.totalUsage)
}NEW_API_INTERNAL_TOKEN must exactly match the value configured on NewAPI.
Use a long random value and never expose it through a VITE_* variable or a
browser bundle.
getTokenUsage(), getSubscription(), and getBillingUsage() use a relay
API key. They must not be called with a dashboard access token or the service
token. The token list endpoint intentionally returns a masked key; call
getTokenKey(id) only on a trusted backend when the full key is required.
Provisioning creates or reuses the NewAPI user/key binding. NewAPI-generated
provisioning users do not return a dashboard password, so provisioning is not a
replacement for a user login flow. Existing users can use login() with their
NewAPI credentials, or the product can keep its own login and use provisioning
server-to-server.
API surface
NewApiAuthClient: encryption-key lookup, login, 2FA, registration, refresh, logout, current-user lookup, token CRUD, and full-key retrieval.NewApiClient: protected provisioning plus relay-key usage and billing.MemoryCookieJar: small single-origin cookie jar for Node server processes.AiAccountError: normalized HTTP/business error withstatus,code, and optionalretryAfter.
Do not put serviceToken, dashboard access tokens, user passwords, or full API
keys in browser bundles or logs. For browser applications, use a same-origin
backend proxy when possible; cross-origin refresh depends on cookie, CORS, and
trusted-origin configuration in NewAPI.
Development
npm run typecheck
npm run build