Username
Official plugin — username + password sign-up and sign-in under /auth, plugged onto gate.auth.
username() lets people register and sign in with a username instead of email. It adds two public
Flows under /auth and contributes the oke_usernames table.
The one rule
Enable gate.auth first, then .plug(username()). The plugin .needs("auth") and joins the HTTP
router via Bindings — not registry metadata alone.
Quick start
Plug it
import { oke } from "okengine";
import { username } from "okengine/plugins";
export const app = oke({
name: "shop",
env: "dev",
gate: { auth: {} },
}).plug(username());Sign up
const { data, error } = await api.auth.signUpUsername({
username: "ali",
password: "CorrectHorse1",
});POST /auth/sign-up/username — usernames are normalized to lowercase; allowed pattern
[a-z0-9._-]{3,64}.
Sign in
const { data } = await api.auth.signInUsername({
username: "ali",
password: "CorrectHorse1",
});
// data: accessToken, refreshToken, accessExpiresAt, userIdUnknown username and bad password both return AuthFailed with
reason: "invalid_credentials" (enumeration-safe).
Options
| Option | Type | Default | Meaning |
|---|---|---|---|
secret | string | active* | HMAC secret (*from gate.auth when plugged after oke()) |
sessions | SessionStore | active* | Session store shared with Gate auth |
now | () => number | Date.now | Injectable clock |
usernames | UsernameStore | new map | Shared in-memory credential store |
Surfaces
| Flow | Path | Gate |
|---|---|---|
auth.signUpUsername | POST /auth/sign-up/username | gate.public + sign-up rate |
auth.signInUsername | POST /auth/sign-in/username | gate.public + sign-in rate |
Troubleshooting
Set oke({ gate: { auth: { … } } }) before .plug(username()).
Username taken, or it fails the [a-z0-9._-]{3,64} pattern after lowercasing. Same error shape
on purpose — do not treat it as "exists" in the UI.
Learn more
- Gate —
gate.authand posture - Plugins — all auth method plugins
- Client · Auth —
createClient+memorySession