Authentication

Add user authentication to your apps. Supports email/password, OAuth providers (Google, GitHub, Okta, OIDC), session management, and user administration.

import { getPlatform } from '@maravilla-labs/platform';
const platform = getPlatform();

const session = await platform.auth.login({
  email: 'jane@example.com',
  password: 'securePassword123'
});
// session.access_token — short-lived JWT
// session.refresh_token — single-use refresh token

Quick Start

1. Enable Auth in project settings on Maravilla Cloud.

2. Use hosted pages — every project gets branded login pages at /_auth/login and /_auth/register. No code needed.

Or build your own UI using the platform.auth API:

// SvelteKit example: src/routes/login/+page.server.ts
import { redirect, fail } from '@sveltejs/kit';
import { getPlatform } from '@maravilla-labs/platform';

export const actions = {
  default: async ({ request, cookies }) => {
    const platform = getPlatform();
    const data = await request.formData();

    try {
      const session = await platform.auth.login({
        email: data.get('email'),
        password: data.get('password')
      });
      cookies.set('__session', session.access_token, {
        httpOnly: true, secure: true, sameSite: 'lax', path: '/', maxAge: 60 * 60 * 24 * 30
      });
      throw redirect(303, '/');
    } catch (e) {
      if (e instanceof Response) throw e;
      return fail(401, { error: 'Invalid credentials' });
    }
  }
};

3. Protect routes with withAuth or manual validation:

// Middleware helper — extracts token from Authorization header or __session cookie
export default {
  fetch: platform.auth.withAuth(async (request) => {
    // request.user is guaranteed
    return Response.json({ hello: request.user.email });
  })
};

Hosted Login Pages

Customizable through Auth Settings > Branding:

  • Layouts — Centered, split-left, split-right, fullscreen
  • Theming — Colors, logo, dark mode, Google Fonts, background image/gradient
  • Legal — Terms and privacy policy links

OAuth / OIDC

Configure providers in Auth Settings > OAuth Providers. Hosted login pages automatically show provider buttons.

ProviderSetup
GoogleClient ID + Secret from Google Cloud Console
GitHubClient ID + Secret from GitHub Developer Settings
OktaClient ID + Secret + Issuer URL
Custom OIDCClient ID + Secret + Discovery URL

For custom UIs, start the OAuth flow programmatically:

const { auth_url } = await platform.auth.getOAuthUrl('google');
return Response.redirect(auth_url);
// User authenticates with provider → redirected back with session cookie

When an OAuth email matches an existing account, the user is prompted to confirm linking.

API Reference

Registration & Login

MethodDescription
register({ email, password, profile? })Create account. Returns AuthUser
login({ email, password })Authenticate. Returns AuthSession
validate(accessToken)Verify token. Returns AuthUser or throws
refresh(refreshToken)New token pair. Returns AuthSession
logout(sessionId)Revoke session

OAuth

MethodDescription
getOAuthUrl(provider, options?)Get authorization URL for redirect
handleOAuthCallback(provider, { code, state })Exchange code for session

Email & Password

MethodDescription
sendVerification(userId)Returns { token } — you deliver it
verifyEmail(token)Mark email as verified
sendPasswordReset(email)Returns { token }
resetPassword(token, newPassword)Reset password, invalidate sessions
changePassword(userId, old, new)Change with current password

User Management

MethodDescription
getUser(userId)Get user or null
listUsers(filter?)Paginated list. Filter by status, email_contains, group_id
updateUser(userId, { email?, status?, profile? })Update user
deleteUser(userId)Delete user and sessions
getFieldConfig()Get configured registration fields

withAuth(handler)

Middleware that validates the token and sets request.user. Returns 401 if unauthenticated.

Types

interface AuthUser {
  id: string;
  email: string;
  email_verified: boolean;
  status: 'active' | 'suspended' | 'deactivated';
  provider: string;      // "email", "google", "github", etc.
  groups: string[];
  created_at: number;
  updated_at: number;
  last_login_at?: number;
}

interface AuthSession {
  access_token: string;  // short-lived JWT (default 15 min)
  refresh_token: string; // single-use (default 30 days)
  expires_in: number;
  user: AuthUser;
}

Framework Examples

React Router 7:

// app/routes/login.tsx
export async function action({ request }) {
  const formData = await request.formData();
  const session = await getPlatform().auth.login({
    email: formData.get('email'), password: formData.get('password')
  });
  return redirect('/', {
    headers: { 'Set-Cookie': `__session=${session.access_token}; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=2592000` }
  });
}

Nuxt 3:

// server/api/login.post.ts
export default defineEventHandler(async (event) => {
  const { email, password } = await readBody(event);
  const session = await getPlatform().auth.login({ email, password });
  setCookie(event, '__session', session.access_token, {
    httpOnly: true, secure: true, sameSite: 'lax', path: '/', maxAge: 60 * 60 * 24 * 30
  });
  return { user: session.user };
});

Security

  • Passwords are hashed with industry-standard algorithms and never stored in plaintext
  • Tokens are short-lived and automatically rotated on refresh
  • OAuth flows use PKCE and verify provider ID tokens cryptographically
  • Client secrets are encrypted at rest
  • Session limits and password policies are configurable per project

Next Steps

  • Authorization — Decide what signed-in users can do with per-resource policies
  • KV Store — Store session data and user preferences
  • Database — Query and store application data per user
  • Storage — Upload and manage user files
  • Channels — Real-time pub/sub and presence
  • Deployment — Deploy your app with auth enabled