Skip to main content

Overview

EventPalour uses session-based authentication with support for:
  • Email and password authentication
  • OAuth provider (Google)
  • Two-factor authentication (2FA)
  • WebAuthn/Passkeys
  • Role-based access control

Session Management

Authentication is handled through secure sessions that are validated on every request.

Getting Current User

Retrieve the currently authenticated user:
import { getCurrentUser } from '@/app/actions/auth';

const result = await getCurrentUser();

if (result) {
  const { user, session } = result;
  console.log('User ID:', user.id);
  console.log('Email:', user.email);
  console.log('Platform Role:', user.platform_role);
}

Requiring Authentication

Redirect unauthenticated users to the sign-in page:
import { requireAuth } from '@/app/actions/auth';

const { user, session } = await requireAuth();
// If not authenticated, automatically redirects to /auth/sign-in

Platform Roles

EventPalour has two primary platform roles:
Users who create and manage events:
  • Create workspaces
  • Manage events and tickets
  • Access analytics
  • Require KYC verification for paid events

Requiring Platform Role

import { requireRole } from '@/app/actions/auth';
import { PlatformRole } from '@/lib/db/schema/enums';

// Require organizer role
const { user } = await requireRole(PlatformRole.ORGANIZER);
// Redirects to /no-workspace if user is not an organizer

Workspace Authorization

Workspaces have their own role hierarchy:
RolePermissions
AdminFull workspace control, manage members, billing
ModeratorCreate events, manage tickets, view analytics
MemberView events, basic access

Validating Workspace Access

import { validateWorkspaceAccess } from '@/app/actions/auth';
import { WorkspaceRole } from '@/lib/db/schema/enums';

// Require at least Moderator role
const { user, workspace, role } = await validateWorkspaceAccess(
  workspaceId,
  WorkspaceRole.MODERATOR
);

console.log('User role:', role); // 'admin' or 'moderator'
console.log('Workspace:', workspace.name);
Workspace owners always have admin-level access and cannot be removed from their workspace.

Admin Levels

Platform administrators have hierarchical access levels:
enum AdminLevel {
  SUPER_ADMIN = "super_admin",  // Platform owners
  SUPPORT = "support",            // Customer support
  FINANCE = "finance",            // Finance team
  MODERATOR = "moderator"         // Content moderation
}

Super Admin Verification

Check if a user is a super admin:
curl -X GET https://api.eventpalour.com/api/auth/check-super-admin \
  -H "Cookie: session=your_session_token"
Response:
{
  "isSuperAdmin": true
}
Super admin access is determined by email whitelist in the environment configuration.

OAuth Authentication

EventPalour supports OAuth authentication with Google.

Google OAuth Flow

1

Initiate OAuth

Redirect user to Google OAuth endpoint:
GET /api/auth/oauth/google
2

User Authorizes

User grants permissions on Google’s consent screen.
3

Callback Handling

Google redirects to callback endpoint:
GET /api/auth/oauth/google/callback?code=...
EventPalour exchanges the code for user information and creates/updates the user account.
4

Session Created

User is authenticated and redirected to the dashboard.

API Authentication

API endpoints require authentication via session cookies.

Authenticated Request Example

curl -X POST https://api.eventpalour.com/api/upload \
  -H "Cookie: session=your_session_token" \
  -F "[email protected]" \
  -F "bucket=EVENTS"

Authentication Errors

401 Unauthorized - Missing or invalid session:
{
  "error": "Authentication required"
}
403 Forbidden - Insufficient permissions:
{
  "error": "Only workspace admins can send invitations"
}

User Object

The authenticated user object includes:
interface User {
  id: string;                    // Unique user ID
  email: string;                 // Email address
  name: string;                  // Display name
  platform_role: PlatformRole;   // 'organizer' or 'attendee'
  email_verified: boolean;       // Email verification status
  two_factor_enabled: boolean;   // 2FA status
  created_at: Date;              // Account creation date
}

Getting User Workspaces

Retrieve all workspaces a user has access to:
import { getUserWorkspaces } from '@/app/actions/auth';

const workspaces = await getUserWorkspaces(userId);

workspaces.forEach(({ workspace, role, isOwner }) => {
  console.log(`${workspace.name}: ${role} ${isOwner ? '(Owner)' : ''}`);
});
Response structure:
[
  {
    workspace: {
      id: string;
      name: string;
      description: string;
      // ... other workspace fields
    },
    role: WorkspaceRole;  // 'admin' | 'moderator' | 'member'
    isOwner: boolean;     // true if user created the workspace
  }
]

Security Best Practices

Never trust client-side role checks. Always validate permissions server-side:
// ✅ Good: Server-side validation
const { user, workspace, role } = await validateWorkspaceAccess(
  workspaceId,
  WorkspaceRole.MODERATOR
);

// ❌ Bad: Client-side only
if (userRole === 'admin') {
  // Don't rely on client state
}
Protect server actions and API routes:
export async function deleteEvent(eventId: string) {
  // Require authentication first
  await requireAuth();
  
  // Then validate specific permissions
  const event = await getEventById(eventId);
  await validateWorkspaceAccess(event.workspace_id, WorkspaceRole.MODERATOR);
  
  // Proceed with deletion
  await db.delete(tables.events).where(eq(tables.events.id, eventId));
}
Sessions can expire. Always handle null user gracefully:
const result = await getCurrentUser();

if (!result) {
  // Redirect to login or show error
  redirect('/auth/sign-in');
}

Next Steps

Events API

Create and manage events with proper authorization

Workspaces API

Learn about workspace management

Error Handling

Handle authentication and authorization errors

User Roles

Learn more about the role system

Build docs developers (and LLMs) love