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
- issuer:
- 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.