<seva-auth>
The <seva-auth> component renders a complete authentication UI. It supports email/password sign-in, account creation, forgot password, magic link, SMS OTP, and Google OAuth — all in a single element.
Overview
Section titled “Overview”When the user is not authenticated, the component displays a sign-in form with links to alternate auth methods. After successful authentication, it shows the user’s name, email, and a sign-out button. Auth state is persisted in localStorage and restored on page load.
Quick Example
Section titled “Quick Example”<script type="module" src="YOUR_COMPONENTS_URL/seva-auth.js"></script>
<seva-auth tenant-slug="my-club" api-url="https://api.seva.tools"></seva-auth>
<script> const auth = document.querySelector('seva-auth'); auth.addEventListener('seva:authenticated', (e) => { console.log('User:', e.detail.user); console.log('Token:', e.detail.token); });</script>Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
tenant-slug | string | '' | Required. Your organization’s tenant slug. |
api-url | string | 'https://api.seva.tools' | Base URL of the Seva API. |
view | AuthView | 'sign-in' | Initial view. One of: 'sign-in', 'sign-up', 'forgot-password', 'sms-otp', 'magic-link'. |
theme | 'light' | 'dark' | 'light' | Color theme. Set via JavaScript property. |
hide-sign-up | boolean | false | When present, hides the “Sign up” link and sign-up form. Useful when the component is embedded inside <seva-event-register>. |
Events
Section titled “Events”| Event | Payload | When it fires |
|---|---|---|
seva:authenticated | { user: AuthUser, token: string } | User successfully signs in or signs up. |
seva:signed-out | {} | User signs out (via UI or signOut() method). |
seva:error | { message: string } | An auth error occurs (bad credentials, network failure, etc.). |
seva:view-changed | { view: AuthView } | The component switches between views (sign-in, sign-up, etc.). |
seva:pending | { message: string } | Sign-up succeeded but the account requires admin approval. |
AuthUser type
Section titled “AuthUser type”interface AuthUser { id: string; email: string; name: string;}AuthView type
Section titled “AuthView type”type AuthView = 'sign-in' | 'sign-up' | 'forgot-password' | 'sms-otp' | 'magic-link';Methods
Section titled “Methods”| Method | Signature | Description |
|---|---|---|
getToken() | () => string | null | Returns the current session token, or null if not authenticated. |
getUser() | () => AuthUser | null | Returns the current user object, or null if not authenticated. |
signOut() | () => void | Clears auth state and fires seva:signed-out. |
setView(view) | (view: AuthView) => void | Programmatically switch to a different auth view. |
Auth flows
Section titled “Auth flows”Email / Password
Section titled “Email / Password”The default view. The user enters email and password. On success, seva:authenticated fires.
Sign Up
Section titled “Sign Up”Available unless hide-sign-up is set. Collects first name, last name, email, and password. If the tenant requires approval, the component shows a pending message and fires seva:pending instead.
Forgot Password
Section titled “Forgot Password”Sends a password-reset email. Always shows a success message regardless of whether the email exists (to prevent email enumeration).
Magic Link
Section titled “Magic Link”Sends a sign-in link to the user’s email. When the user clicks the link, they are redirected back with a seva-token query parameter. The component detects this automatically, validates the token, and fires seva:authenticated.
SMS OTP
Section titled “SMS OTP”Two-step flow: (1) user enters phone number and receives a code, (2) user enters the code. On successful verification, seva:authenticated fires.
Google OAuth
Section titled “Google OAuth”Opens a popup window for Google sign-in. The popup communicates back via postMessage. If popups are blocked, an error is shown.
Full Example
Section titled “Full Example”<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sign In</title> <script type="module" src="YOUR_COMPONENTS_URL/seva-auth.js"></script> <style> body { font-family: system-ui, sans-serif; max-width: 400px; margin: 2rem auto; } #status { margin-top: 1rem; padding: 0.75rem; border-radius: 0.5rem; font-size: 0.875rem; } .signed-in { background: #dcfce7; color: #166534; } .signed-out { background: #fef3c7; color: #92400e; } </style></head><body> <seva-auth id="auth" tenant-slug="my-club" api-url="https://api.seva.tools"> </seva-auth>
<div id="status" class="signed-out">Not signed in</div>
<script> const auth = document.getElementById('auth'); const status = document.getElementById('status');
auth.addEventListener('seva:authenticated', (e) => { status.textContent = 'Signed in as ' + e.detail.user.name; status.className = 'signed-in'; });
auth.addEventListener('seva:signed-out', () => { status.textContent = 'Not signed in'; status.className = 'signed-out'; });
auth.addEventListener('seva:error', (e) => { console.error('Auth error:', e.detail.message); }); </script></body></html>