mcpField
C
ce-auth

ce-auth

github.com/commercengineDevelopment035 installsUpdated 9w ago
Repository

About ce-auth

ce-auth documents authentication and user-management patterns for the Commerce Engine SDK. It helps storefront developers implement anonymous sessions, OTP or password access, account operations and logout while distinguishing public reads from session-based flows.

Key features

  1. 01Bootstrap anonymous sessions
  2. 02Email, phone and WhatsApp OTP flows
  3. 03Password login and registration
  4. 04Reset passwords and refresh tokens
  5. 05Manage user profiles and logout

Use cases

  1. 01Add login to a storefront
  2. 02Support passwordless sign-in and account creation
  3. 03Implement account pages and user profile updates
  4. 04Handle session-aware cart and checkout access

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/commercengine/skills --skill ce-auth

After installing, type/ce-authin Claude Code to confirm it loaded.

Bundled files.claude-plugin/plugin.json.cursor-plugin/plugin.json

Details

From the project README

LLM Docs Header: All requests to https://llm-docs.commercengine.io must include the Accept: text/markdown header (or append .md to the URL path). Without it, responses return HTML instead of parseable markdown.

Authentication & User Management

Prerequisite: SDK must be initialized. See setup/ if not done.

When to Implement Auth Directly

If using Hosted Checkout, login and registration are usually handled inside the checkout drawer. Build custom auth UI only when the storefront needs logged-in state outside checkout, for example:

  • account pages
  • saved addresses
  • order history
  • loyalty or wallet pages
  • a persistent signed-in header state

Current Mental Model

  • Public product and category reads can use public() and do not require anonymous auth.
  • Live cart, account, and checkout flows should use the session client.
  • In managed session mode, the SDK can bootstrap anonymous auth automatically on the first token-required request.
  • If you need the anonymous session eagerly, call sdk.ensureAccessToken() once during startup.

Quick Reference

Auth MethodEndpointUse Case
Anonymous bootstrapsdk.ensureAccessToken() or sdk.auth.getAnonymousToken()Start a live session
Email OTPsdk.auth.loginWithEmail() -> sdk.auth.verifyOtp()Passwordless email login
Phone OTPsdk.auth.loginWithPhone() -> sdk.auth.verifyOtp()Passwordless phone login
WhatsApp OTPsdk.auth.loginWithWhatsApp() -> sdk.auth.verifyOtp()Passwordless WhatsApp login
Password loginsdk.auth.loginWithPassword()Traditional login
Password registrationsdk.auth.registerWithPassword() -> OTP verificationPassword sign-up
Forgot passwordsdk.auth.forgotPassword() -> sdk.auth.resetPassword()Reset password with OTP
Token refreshsdk.auth.refreshToken()Renew expired access token

Decision Tree

User Request
    │
    ├─ Public catalog-only page
    │   └─ No auth bootstrap needed; use public()
    │
    ├─ New visitor starting a live session
    │   └─ sdk.ensureAccessToken()
    │
    ├─ "Login" / "Sign in"
    │   ├─ Passwordless → loginWithEmail/Phone/WhatsApp() → verifyOtp()
    │   └─ Password → loginWithPassword()
    │
    ├─ "Register"
    │   └─ registerWithPassword() / registerWithPhonePassword() → verifyOtp()
    │
    ├─ "Forgot password"
    │   └─ forgotPassword() → resetPassword()
    │
    ├─ "Account" / "Profile"
    │   └─ getUserDetails() / updateUserDetails()
    │
    └─ "Token expired" / 401
        └─ refreshToken() or rely on managed session refresh

User States

StateHow CreatedCapabilities
Publicpublic() accessor onlyPublic catalog/store/helper reads
Anonymous sessionsdk.ensureAccessToken() or /auth/anonymousCart, checkout, analytics, session continuity
Logged-in sessionOTP verification, password login, or password reset completionAll anonymous capabilities plus account, orders, addresses, loyalty

User ID vs Customer ID

For most stores, user_id and customer_id are the same value — one user = one customer. In B2B storefronts, one customer can have multiple users (e.g., a company account with multiple employees).

The SDK exposes helpers to fetch both:

const userId = await sdk.getUserId();
const customerId = await sdk.getCustomerId();

Most SDK methods that require a user or customer ID have parameterless overloads that auto-resolve from the current session. For example, sdk.cart.getUserCart() (no params) fetches the cart for the logged-in user automatically. Only pass IDs explicitly when operating on behalf of a different user (admin scenarios).

Key Patterns

Start a live anonymous session
const sdk = storefront.session();
await sdk.ensureAccessToken();

Call this once during startup if you want eager bootstrap. Do not repeat it before ordinary session-aware cart, order, or customer calls.

OTP Login Flow (Email)
const { data, error } = await sdk.auth.loginWithEmail({
  email: "[email protected]",
  register_if_not_exists: true,
});

if (error) throw error;

const { otp_token, otp_action } = data!;

const { error: verifyError } = await sdk.auth.verifyOtp({
  otp: "123456",
  otp_token,
  otp_action,
});

if (verifyError) throw verifyError;
Password Login
const { data, error } = await sdk.auth.loginWithPassword({
  email: "[email protected]",
  password: "securepassword",
});

if (error) throw error;
Password Registration

Password registration is OTP-first in the latest contract.

const { data, error } = await sdk.auth.registerWithPassword({
  email: "[email protected]",
  password: "securepassword",
  confirm_password: "securepassword",
});

if (error) throw error;

await sdk.auth.verifyOtp({
  otp: "123456",
  otp_token: data!.otp_token,
  otp_action: data!.otp_action,
});
Forgot Password
const { data, error } = await sdk.auth.forgotPassword({
  email: "[email protected]",
});

if (error) throw error;

await sdk.auth.resetPassword({
  otp: "123456",
  otp_token: data!.otp_token,
  new_password: "newPass123",
  confirm_password: "newPass123",
});
User Profile

Auth client methods require explicit IDs (no parameterless overloads). Use sdk.getUserId() to get the current user's ID:

const userId = await sdk.getUserId();

const { data: userData } = await sdk.auth.getUserDetails({ id: userId! });

await sdk.auth.updateUserDetails({ id: userId! }, {
  first_name: "Jane",
  last_name: "Doe",
});

Key Feature: register_if_not_exists

Setting register_if_not_exists: true on login endpoints eliminates separate login and sign-up entry points. If the user does not exist, Commerce Engine creates the account and continues the OTP flow.

This is also the recommended approach for checkout auth — there is no separate "guest checkout" flow. The user provides their email or phone, gets verified via OTP, and the account is created if needed. This path of least resistance ensures address verification and order attribution. Hosted Checkout handles this entire flow automatically.

Logout

The SDK exposes sdk.auth.logout() for custom logout buttons:

const { data, error } = await sdk.auth.logout();

logout() does not clear tokens — it returns new tokens with reduced privileges. The session continues with full continuity (same cart, same analytics trail), but the user is no longer in a logged-in state. The SDK's onTokensUpdated callback fires with the new tokens, and the two-way sync with Hosted Checkout (when using authMode: "provided") propagates them automatically — no manual token clearing or updateTokens("", "") needed.

Common Pitfalls

LevelIssueSolution
CRITICALUsing public() for auth or account operationsUse the session client
CRITICALAssuming every page needs anonymous authPublic reads do not; only live session flows do
HIGHBuilding separate login and sign-up flows by defaultPrefer register_if_not_exists: true where appropriate
HIGHForgetting otp_token and otp_action between stepsPersist both and pass them to verifyOtp()
HIGHStoring tokens insecurely or with the wrong storage for the runtimeUse managed session storage appropriate to the environment
MEDIUMIgnoring { data, error }Always check error before using data

See Also

  • setup/ - SDK installation and session storage
  • cart-checkout/ - Checkout flows and Hosted Checkout
  • orders/ - Logged-in order flows
  • ssr-patterns/ - Server Actions/functions for auth mutations (Next.js, TanStack Start)

Documentation

Comments

Markdown supported