Appearance
Registration & Login
Registration
The platform supports sign-up via Email or Phone. You can also pass a metadata object to store custom client data (e.g., affiliate codes, promo codes).
Note on IP & Device Tracking: The SDK does not send IP addresses or browser agents. These are captured automatically by your backend via standard HTTP headers (req.ip and req.headers['user-agent']).
RegisterPayload
typescript
type SignUpMode = 'EMAIL' | 'PHONE';
interface RegisterPayload {
signUpMode: SignUpMode; // which contact channel the account uses
email?: string; // required when signUpMode = 'EMAIL'
phone?: string; // required when signUpMode = 'PHONE'
password: string; // 10+ chars, letters + numbers; breached passwords rejected
username: string; // unique across the platform
metadata?: Record<string, string | number | boolean>; // client-supplied primitive passthrough
}| Field | Type | Required | Notes |
|---|---|---|---|
signUpMode | 'EMAIL' | 'PHONE' | yes | Selects the required contact field |
email | string | when EMAIL | Valid email format required |
phone | string | when PHONE | E.164 format recommended (e.g. +1234567890) |
password | string | yes | 10+ characters, must contain letters and numbers; passwords known to be compromised (breach-list match) are rejected |
username | string | yes | Unique across the platform |
metadata | Record<string, string | number | boolean> | no | Client-supplied primitive passthrough (affiliate codes, promo codes, etc.); opaque to the SDK |
javascript
// Email Registration
await sdk.auth.register({
signUpMode: 'EMAIL',
email: 'player@casino.com',
password: 'securePassword123',
username: 'HighRoller99',
metadata: { affiliateId: 'AFF_123', preferredCurrency: 'USD' }
});
// Phone Registration
await sdk.auth.register({
signUpMode: 'PHONE',
phone: '+1234567890',
password: 'securePassword123',
username: 'HighRoller99'
});register() returns the logged-in User and starts a session immediately.
Registration errors
Validation is enforced client- and server-side. Branch on the error code; the message is display text only (full table: State & Security § Error Taxonomy):
| Code | Error class | Trigger |
|---|---|---|
AUTH_VALIDATION | AuthValidationError | Malformed email/phone, missing mode-required field, weak or breached password |
AUTH_EMAIL_TAKEN | EmailTakenError | Email (or phone) already registered |
AUTH_USERNAME_TAKEN | UsernameTakenError | Username already registered |
Login
Login accepts a single identifier field. The backend resolves whether the user typed an email, phone, or username.
LoginPayload
typescript
interface LoginPayload {
identifier: string; // email, phone, or username; backend resolves which
password: string;
}| Field | Type | Required |
|---|---|---|
identifier | string | yes |
password | string | yes |
javascript
await sdk.auth.login({ identifier: 'player@casino.com', password: 'securePassword123' });Login errors
| Code | Error class | Trigger |
|---|---|---|
AUTH_INVALID_CREDENTIALS | InvalidCredentialsError | Wrong identifier/password |
AUTH_2FA_REQUIRED | TwoFactorRequiredError | Account has 2FA enabled; not an error to show, a flow signal (see below) |
AUTH_ACCOUNT_LOCKED | AccountLockedError | Temporary lockout after repeated failures (carries retryAfterMs) |
Two-Factor Authentication (2FA) Challenge
If a user has 2FA enabled, login() does not return a session. It throws TwoFactorRequiredError; treat this as a flow signal, not a failure: the error carries a tempToken your frontend uses to complete the challenge.
javascript
try {
const user = await sdk.auth.login({ identifier: 'user', password: 'pass' });
} catch (error) {
if (error.name === 'TwoFactorRequiredError') {
const tempToken = error.tempToken; // single-use, expires after 5 minutes; do NOT persist it
// Show 2FA input screen to the user
}
}
// Once the user provides their 6-digit code:
const user = await sdk.auth.verifyLogin2FA(tempToken, '123456');verifyLogin2FA throws InvalidTwoFactorCodeError (AUTH_2FA_INVALID_CODE) for a wrong code and the common TooManyAttemptsError (TOO_MANY_ATTEMPTS) when the attempt cap is exceeded. See Two-Factor Auth (2FA) and Session Lifecycle.