01 Software

Customer Authentication

Customer registration, login, token management, password reset, and email verification

Customer Authentication

The SDK provides client.customer for storefront customer authentication — separate from the admin/tenant authentication system.

Customer auth is available on BrowserClient only. For server-side customer data management, use client.from('customers') with ServerClient.

Setup

lib/client.ts
import { createBrowserClient } from '@01.software/sdk'

export const client = createBrowserClient({
  clientKey: process.env.NEXT_PUBLIC_SOFTWARE_CLIENT_KEY!,
  customer: { persist: true },
})

The persist option automatically saves/restores the token in localStorage (SSR-safe). You can also use a custom storage key:

customer: { persist: 'my-app-token' }  // custom localStorage key

For full control, use token and onTokenChange instead:

customer: {
  token: getTokenFromCookie(),
  onTokenChange: (token) => setTokenCookie(token),
}
OptionTypeDescription
persistboolean | stringAuto-persist in localStorage. true uses key 'customer-token', string for custom key
tokenstringInitial token (e.g. from SSR cookie). Ignored when persist is set
onTokenChange(token: string | null) => voidCalled on login/logout. Ignored when persist is set

Register

const { customer } = await client.customer.register({
  name: 'John Doe',
  email: 'john@example.com',
  password: 'securepassword',
  phone: '010-1234-5678',   // optional
})

Registration does not automatically log in. Call login() after registration.

Login

const { token, customer } = await client.customer.login({
  email: 'john@example.com',
  password: 'securepassword',
})

// Token is stored internally and onTokenChange is called

The returned customer object:

{
  id: string | number
  name: string
  email: string
  phone?: string
  isVerified: boolean
}

Profile

const profile = await client.customer.me()

if (!profile) {
  // Not authenticated or token expired
}

Returns null if not authenticated. Automatically clears the token on 401.

Logout

client.customer.logout()
// Token cleared, onTokenChange called with null

Password Reset

1. Request reset email

await client.customer.forgotPassword('john@example.com')
// Always succeeds (prevents email enumeration)

2. Reset with token

The reset email contains a link with a token. Use it to set a new password:

await client.customer.resetPassword(token, 'newpassword')

Change Password

Requires authentication:

await client.customer.changePassword('currentPassword', 'newPassword')

Email Verification

await client.customer.verifyEmail(token)

Token Management

// Check authentication status
client.customer.isAuthenticated()  // boolean

// Get current token
client.customer.getToken()  // string | null

// Set token manually (e.g. from SSR)
client.customer.setToken(token)

Guest vs Registered

GuestRegistered
Creationclient.from('customers').create({ ... }) via ServerClientclient.customer.register({ ... })
LoginNot possibleclient.customer.login()
Cartcustomer field omitted or linkedLinked to customer ID
Order historyLookup by email/order numberclient.customer.me() + scoped queries
Address bookNot availableFull CRUD

Error Handling

import { ApiError } from '@01.software/sdk'

try {
  await client.customer.login({ email, password })
} catch (error) {
  if (error instanceof ApiError) {
    switch (error.status) {
      case 401:
        // Invalid credentials
        break
      case 429:
        // Rate limited
        break
    }
  }
}

On this page