Customer auth

AuthClient from @cstar.help/js/auth handles customer signup and login for end-user surfaces: your help center, an embedded portal or a logged-in chat experience. No API key, just teamSlug.

Setup

setup.js
import { AuthClient } from '@cstar.help/js/auth';

const auth = new AuthClient({
  teamSlug: 'acme'
});

Sign up

Signup takes no password. It emails the customer a sign-in link, and the reply is the same for new and existing emails, so your form never reveals who already has an account. Call signup in the browser: it stores a one-time verifier that completeSignIn reads after the click.

signup.js
const result = await auth.signup({
  email: 'jane@example.com',
  name: 'Jane Doe',
  returnUrl: 'https://acme.com/help' // optional, defaults to the current page
});

// Always { success: true, requiresConfirmation: true, message }
showNotice(result.message);

The link returns to returnUrl when its origin is on your team's allowed redirect list (otherwise to the hosted widget page). Finish sign-in on that page:

return-page.js
const session = await auth.completeSignIn();
if (session) {
  console.log('Signed in as', session.customer.email);
}

Running against a non-production baseUrl? Also pass that environment's supabaseUrl and supabaseKey so the email comes from the same project.

Set a password (optional)

A signed-in customer can choose a password so later visits skip the email. Passwords need at least 8 characters. Customers who skip this keep signing in with an emailed link.

set-password.js
// Needs a session from completeSignIn() or login()
await auth.setPassword('SecurePass!123');

This is the same update the hosted widget makes when it offers a password after the first email sign-in, so a password set in either place works for both.

Log in

Password login works once the customer has set a password. Until then, send them through signup again: it emails a fresh sign-in link for existing accounts too.

login.js
const { customer, accessToken, refreshToken } = await auth.login({
  email: 'jane@example.com',
  password: 'SecurePass!123'
});

// The session lives in memory on this AuthClient instance.
// Store it yourself if it must survive a page reload.

Session helpers

session.js
auth.isAuthenticated;        // boolean, true if a session exists
auth.accessToken;            // string | null, the JWT for outbound calls
auth.getCustomer();          // { id, email, name } | null
auth.getSession();           // Full session object with refresh token

Log out

logout.js
auth.logout();
// Clears the session held by this AuthClient instance, and the
// copy a sign-in link or setPassword() kept in browser storage.

Plug into a reactive UI

@cstar.help/react and @cstar.help/svelte don't wrap AuthClient yet. Use it directly next to them and keep its session in your own state.

Next up