"@daywalker/auth (browser)"

The framework-agnostic browser client used by the React package.

Use this directly with Vue, Svelte, vanilla JS or anything else that runs in a browser.

ts
import { createAuthClient } from "@daywalker/auth";

const auth = createAuthClient({
  publishableKey: "pk_test_…",
  frontendApi: "https://users.daywalker.dev",
});

await auth.load(); // find out if someone is signed in
auth.subscribe((state) => render(state)); // { isLoaded, user, sessionId }

Methods

Method Description
load() Fetches the current session. Call once on startup.
subscribe(fn) Calls fn on every state change. Returns an unsubscribe function.
state Current { isLoaded, user, sessionId }
signIn({ email, password }) Resolves { status: "complete", user } or { status: "needs_second_factor" }
completeSecondFactor(code) Finishes a 2FA sign-in with an authenticator or backup code
startTotpSetup() / confirmTotpSetup(code) Turn on 2FA; confirm returns backup codes
disableTwoFactor(code?) / regenerateBackupCodes(code?) Manage 2FA; both need a current code, or call confirmWithSecurityKey() first and pass none
startSmsSetup(phone, code?) / confirmSmsSetup(code) / removeSmsPhone(code?) SMS as a second factor (when the app allows it)
addSecurityKey({ name?, currentCode? }) / listSecurityKeys() / renameSecurityKey(id, name) / removeSecurityKey(id, code?) Security keys (YubiKey and similar) as a second factor
completeSecondFactorWithSecurityKey() Finishes a 2FA sign-in by touching a key
confirmWithSecurityKey() Confirms one sensitive change (add/remove a factor, turn 2FA off, new backup codes) with a key instead of a code, for two minutes
signUp({ email, password, firstName?, lastName? }) Creates the account and signs in
setOrganizationTwoFactor(orgId, required) Admins: require two-step verification for an organization's members
signOut({ redirectUrl?, singleLogout? }) Ends the session here and in other tabs. For a company SSO sign-in with single logout on, then goes via the identity provider to redirectUrl. Resolves { redirecting }
getToken({ force? }) A valid session token, or null
authFetch(url, init) fetch plus Authorization: Bearer <token>
sendVerificationCode() / verifyEmail(code) Email verification
requestPasswordReset(email) / resetPassword({ email, code, password }) Password reset
signInWithOAuth(provider, redirectUrl?) Redirect to a social provider (google, github, microsoft, apple, discord, gitlab, oidc); returns signed in. See Social sign-in.
getEnvironment() { name, oauthProviders, passwordMinLength }, for building your own sign-in UI
updateProfile({ firstName?, lastName? }) Edit the user's name (null clears a field)
changePassword({ currentPassword, newPassword }) Signs out all other sessions
getSecurity() { hasPassword, twoFactorEnabled, backupCodesRemaining, connectedAccounts }
listSessions() / revokeSession(id) / revokeOtherSessions() Manage signed-in devices
passkeysSupported() / signInWithPasskey() Detect support; usernameless passkey sign-in. See Passkeys.
registerPasskey(name?) / listPasskeys() / renamePasskey(id, name) / deletePasskey(id) Manage passkeys
hostedUrl(page, redirectUrl?) URL of "sign-in", "sign-up", "forgot-password" or "account"

Options

Option Default Description
publishableKey required Your pk_… key
frontendApi required URL of the auth service
syncCookie true Mirror the token into the __dw_session cookie so your server can read it on page loads

Where things are stored

What Where Readable by JS?
Refresh token HttpOnly cookie on the auth domain No
Session token Memory, plus the __dw_session cookie on your domain (60 s) Yes, by design. It's short-lived.
"Was signed in" flag __dw_active cookie on your domain Yes. Contains no secret.

Nothing is ever written to localStorage or sessionStorage.

Organizations

Method Notes
listOrganizations() Orgs you belong to, with your role
createOrganization(name) You become admin
renameOrganization(orgId, name) / deleteOrganization(orgId) Admins only
listOrgMembers(orgId) Any member
changeOrgRole(orgId, userId, "admin" | "member") Admins only; the last admin can't be demoted
removeOrgMember(orgId, userId) Admins remove others; pass your own ID (or "me") to leave
inviteToOrg(orgId, email, role?) / listOrgInvitations(orgId) / revokeOrgInvitation(orgId, id) Admins only
previewInvitation(token) / acceptInvitation(token) The hosted /accept-invite page uses these
setActiveOrganization(orgId | null) Refreshes the JWT so org_id / org_role update

See the Organizations guide.