JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 17
  • Score
    100M100P100Q63554F
  • License ISC

Auth toolkit: Firebase JWKS verify + Supabase user ensure for Next.js Edge runtime

Package Exports

  • @al-hamoud/authx

Readme

@al-hamoud/authx

Auth toolkit for Firebase Supabase in Edge environments (Next.js friendly).

  • Verify Firebase ID tokens using Google JWKS (JOSE)
  • Ensure a Supabase user exists (service role admin) and tag roles/metadata
  • Drop-in Next.js Edge route handler

Install

npm install @al-hamoud/authx

(This package bundles jose and @supabase/supabase-js as dependencies.)

Quick start

Verify a Firebase ID token

import { verifyFirebaseIdToken } from '@al-hamoud/authx'

const projectId = process.env.FIREBASE_PROJECT_ID!
const payload = await verifyFirebaseIdToken(idToken, projectId)

console.log(payload.sub, payload.phone_number, payload.email)

Ensure a Supabase user exists

import { makeAdminClient, ensureSupabaseUser } from '@al-hamoud/authx'

const admin = makeAdminClient({
  url: process.env.SUPABASE_URL!,
  serviceRoleKey: process.env.SUPABASE_SERVICE_ROLE_KEY!,
})

const user = await ensureSupabaseUser(admin, payload)
console.log('Supabase user id:', user.id)

Next.js Edge route (drop-in)

// app/api/auth/verify-id-token/route.ts
export const runtime = 'edge'

import { buildVerifyRouteHandler } from '@al-hamoud/authx'

const handler = buildVerifyRouteHandler({
  projectId: process.env.FIREBASE_PROJECT_ID!,
  supabaseUrl: process.env.SUPABASE_URL!,
  supabaseServiceRoleKey: process.env.SUPABASE_SERVICE_ROLE_KEY!,
})

export async function POST(req: Request) {
  return handler(req)
}

Request contract:

  • Method: POST
  • Body: { idToken: string }

Response (200):

{
  "ok": true,
  "uid": "...",
  "phoneNumber": "+44...",
  "email": null,
  "supabaseUserId": "...",
  "note": "Verified Firebase token and ensured Supabase user exists."
}

Environment variables

  • FIREBASE_PROJECT_ID (server)
  • SUPABASE_URL (server)
  • SUPABASE_SERVICE_ROLE_KEY (server; keep secret)

Client Firebase config (NEXT_PUBLIC_...) is handled by your app’s Firebase SDK; this library validates server-side.

Types

import type { FirebaseIdTokenPayload } from '@al-hamoud/authx'

UI Component

The package also includes a React component for phone authentication:

import { Authx } from '@al-hamoud/authx'

<Authx 
  verifyEndpoint="/api/auth/verify-id-token"
  initialCountry="GB"
/>

Custom Countries Configuration

You can customize the available countries in the phone number picker:

import { Authx, COUNTRIES } from '@al-hamoud/authx'

// Use only specific countries (v1.2.1+)
const customCountries = {
  GB: COUNTRIES.GB,
  US: COUNTRIES.US,
}

<Authx countries={customCountries} />
// Add your own custom countries
const extendedCountries = {
  ...COUNTRIES,
  CA: { name: 'Canada', dial: '+1', flag: 'πŸ‡¨πŸ‡¦', min: 10, max: 10 },
  AU: { name: 'Australia', dial: '+61', flag: 'πŸ‡¦πŸ‡Ί', min: 9, max: 9 },
}

<Authx countries={extendedCountries} />

New in v1.2.1:

  • βœ… Flexible Types: No TypeScript errors when using partial country lists
  • βœ… Auto-fallback: Gracefully handles missing countries with fallback to defaults
  • βœ… Better DX: No type assertions needed

Available countries by default:

  • πŸ‡¬πŸ‡§ GB: United Kingdom (+44)
  • πŸ‡ΊπŸ‡Έ US: United States (+1)
  • πŸ‡¦πŸ‡ͺ AE: UAE (+971)
  • πŸ‡ΈπŸ‡¦ SA: Saudi Arabia (+966)
  • πŸ‡©πŸ‡ͺ DE: Germany (+49)
  • πŸ‡«πŸ‡· FR: France (+33)

Security notes

  • JWKS validation enforces issuer and audience:
    • issuer: https://securetoken.google.com/${projectId}
    • audience: projectId
  • Keep the Supabase service role key server-side only.
  • Consider origin checks and rate limiting on the verify route.

Made for Next.js Edge. Works in standard Node runtimes as well.