0%
balqalam Logo
balqalam
FeaturesCommunityPricingDocumentation
Login
  • Introduction
  • Pitch
  • Hogwarts
  • Live Demo
  • MVP
  • Roadmap
  • Launch Sprint
  • PRD
  • Get Started
  • Localhost
  • Architecture
  • Structure
  • Pattern
  • Page
  • Layout
  • Content
  • Types
  • Config
  • Actions
  • Queries
  • Authorization
  • Validation
  • Form
  • Table
  • Detail
  • Card
  • Util
  • Hooks
  • List Params
  • Views
  • README.md
  • ISSUE.md
  • Technology Stack
  • Database
  • File
  • CDN Assets
  • Entry Points
  • Dashboard
  • Authentication
  • Credentials
  • OAuth
  • Flow Diagrams
  • Multi-Tenancy
  • Offline
  • Onboarding
  • Onboarding Videos
  • Add Values
  • Admission
  • Application
  • Attendance
  • Compliance
  • Profile
  • Exams
  • Exam Wizard
  • Timetable
  • Classrooms
  • Notifications
  • Conference
  • LMS (Lumos)
Finance
  • Finance
  • Fee Management
  • Invoice
  • Wallet
  • Salary
  • Payroll
  • Timesheet
  • Expenses
  • Budget
  • Receipt
  • Accounts
  • Banking
  • Reports
  • Dashboard
  • Permissions
  • Messages
  • Integration Flow
  • Provision
  • AI Document Processing
  • Document Intelligence
  • Internationalization
  • Translation
  • Translation Guide
  • Icons
  • Docs Factory
  • Inspiration
  • Listings
  • Teachers
  • Students
  • Catalog
  • Library
  • Contributing
  • Code of conduct
  • GitHub Workflow
  • Database Seeds
  • Database Safety
  • Test Accounts
  • Playwright
  • Prettier
  • Block Rebound
Sales & GTM
  • Marketing Brief
  • Sales
  • Go-to-market
  • Marketing
  • Admission — Feature Spotlight
  • Pilot Program
  • Leads
  • Proposal
  • Outreach Templates
  • Case Study
  • Competitors
  • Landing-page teardown
  • Competitor FAQ
  • Business model
  • Shared economy
  • Traction
Fundraising & Ecosystem
  • Get Support
  • Investor Deck
  • Data Room
  • Investors
  • Accelerators
  • Incubators
  • Grants
  • Sponsors
  • Partners
  • Competitions & Hackathons
  • Universities & Training Centers

Authentication

PreviousNext

Multi-tenant authentication built on Auth.js v5 — sessions, redirects, route protection, and tenant resolution.

Authentication runs on Next.js App Router with Auth.js (NextAuth v5). Users authenticate via OAuth (Google, Facebook) or credentials, with optional 2FA, email verification, and password reset. Sessions are JWTs scoped via cookies on .databayt.org for cross-subdomain SSO.

For provider-specific detail see credentials, oauth, and flow diagrams.

Entry points

#EntryTriggerPost-login redirect
1Marketing headerLogin icon on ed.databayt.orgDEVELOPER → /dashboard, school user → {school}.databayt.org/dashboard, USER → /
2Get StartedMarketing CTA/login?callbackUrl=/onboarding then 15-step wizard
3School subdomain{school}.databayt.org/loginSame as #1, scoped to school
4Protected routeDirect URL/login?callbackUrl={original_url}, returns after auth

USER role redirects to /{locale} (homepage), not /onboarding. Onboarding is reachable only via explicit callbackUrl.

Redirect priority

Decision chain in src/auth.ts redirect callback and src/components/auth/login/action.ts:

  1. Callback URL — cookie / URL params / baseUrl params (preserved across OAuth via httpOnly cookie)
  2. Explicit relative path from signIn({ redirectTo })
  3. Subdomain detection — on a school subdomain → that school's dashboard
  4. Smart redirect — decode JWT, look up school, redirect to school dashboard
  5. Fallback — main domain dashboard

Session and JWT

// JWT (jwt callback)
token = {
  id: string
  role: UserRole
  schoolId: string | null
  provider: string
  providerAccountId: string
  sessionToken: string
  updatedAt: number
  hash: string
  exp: number
}
 
// Session (session callback)
session.user = {
  id: string
  email: string
  role: UserRole          // Effective role — preview if active
  schoolId: string | null
  isPreviewMode: boolean
}

Session config: strategy: "jwt", maxAge: 24 * 60 * 60 (24h), updateAge: 5 * 60 (5 min in production).

Tenant context

import { getTenantContext } from "@/lib/tenant-context"
 
const { schoolId, requestId, role, isPlatformAdmin } = await getTenantContext()
// Priority: impersonation cookie → x-subdomain header → session

Two-tier subdomain → schoolId cache: Upstash Redis (5 min, shared) → in-memory Map (1 min, max 100 entries, per-instance fallback). Redis optional. Full detail in multi-tenancy.

Roles

enum UserRole {
  DEVELOPER   // 8 - platform admin (cross-school)
  ADMIN       // 7 - school administrator
  TEACHER     // 6 - teaching staff
  ACCOUNTANT  // 5 - finance staff
  STAFF       // 4 - general staff
  GUARDIAN    // 3 - parent / guardian
  STUDENT     // 2 - enrolled student
  USER        // 1 - default
}

Eight roles total. Hierarchy in src/lib/school-access.ts; must stay in sync with roleRoutes in src/routes.ts. See authorization for feature-level permission checks.

Route protection

Edge middleware decodes JWT, checks roleRoutes, detects subdomain (custom domain → Redis lookup), sets x-subdomain header for downstream consumers.

// Server component
import { auth } from "@/auth"
 
export default async function ProtectedPage() {
  const session = await auth()
  if (!session) redirect("/login")
  return <Dashboard schoolId={session.user.schoolId} />
}
"use client"
 
import { RoleGate } from "@/components/auth/role-gate"
import { useCurrentRole } from "@/components/auth/use-current-role"
import { useCurrentUser } from "@/components/auth/use-current-user"
 
;<RoleGate allowedRole={UserRole.ADMIN}>
  <AdminPanel />
</RoleGate>

Registration paths

OptionMethodStatus
Self-registrationOAuth (Google/Facebook)Working
Bulk creationAdmin imports CSV with pre-assigned rolesWorking
Join codes6-char codes (ABCDEFGHJKMNPQRSTUVWXYZ2345679) — 481M combinationsWorking
InvitationsEmail invite links with rolePartial

Self-enrollment toggle: SchoolBranding.allowSelfEnrollment — enabled gives instant join, disabled creates a pending MembershipRequest.

Preview mode

Lets admins see the UI as another role without changing their actual role. Uses preview-mode and preview-role cookies; session callback overrides role and sets isPreviewMode: true.

HookReturns
useEffectiveRoleUserRole — preview if active, else actual
useIsPreviewModeboolean
useRoleInfo{ actual, preview, effective, isPreviewMode }

Impersonation

DEVELOPERs can impersonate school contexts for debugging. Cookie impersonate_schoolId is httpOnly, secure, 1-hour maxAge. IMPERSONATION_STARTED and IMPERSONATION_STOPPED events are audit-logged. Impersonation takes priority over all other tenant resolution methods.

See also

  • Credentials
  • OAuth — providers, multi-tenant adapter, cross-subdomain cookies
  • Flow diagrams
  • Onboarding
  • Multi-tenancy
DashboardCredentials

On This Page

Entry pointsRedirect prioritySession and JWTTenant contextRolesRoute protectionRegistration pathsPreview modeImpersonationSee also

Built by Databayt ·

Welcome to balqalam.

A great journey is about to begin.