Skip to content

OAuth & Providers

import { createAuth, google, github, credentials } from "@mountsqli/auth";
const auth = createAuth({
db,
secret: process.env.JWT_SECRET!,
providers: [
google({ clientId: "...", clientSecret: "..." }),
github({ clientId: "...", clientSecret: "..." }),
credentials({
authorize: async ({ email, password }) => {
const user = await lookupUser(email);
if (!user || !verifyPassword(user.password, password)) return null;
return { id: user.id, email: user.email };
},
}),
],
});
Provider Import Config
Google google { clientId, clientSecret, scope? }
GitHub github { clientId, clientSecret, scope? }
Password credentials { authorize: (creds) => User | null }
// Step 1 — redirect the user to the provider
const url = await auth.signIn("google");
// redirect user to url

Sets identifier: state:<random> in authVerificationTokens for CSRF protection (expires 10 minutes).

// Step 2 — handle the callback
const result = await auth.handleCallback("google", {
code: req.query.code,
state: req.query.state,
});
// { user, session, token } | throws ProviderError

The callback validates the state (CSRF), exchanges the code for tokens, fetches user info, and creates or links an account in authAccounts.

The Auth config supports lifecycle callbacks:

createAuth({
db, secret,
providers: [/* ... */],
callbacks: {
onRegister: async (user) => { /* welcome email */ },
onLogin: async (user) => { /* audit log */ },
onLogout: async (session) => { /* cleanup */ },
onSession: async (session) => { /* enrich session data */ },
},
});

The credentials provider lets you authenticate with email + password. Your authorize function receives the form data and returns a User or null.

credentials({
authorize: async ({ email, password }) => {
const user = await db.query(authUsers).where("email", "=", email).findOne();
if (!user?.password) return null;
if (!verifyPassword(password, user.password)) return null;
return { id: user.id, email: user.email };
},
});
  • Scope OAuth providers to the minimum scope your app needs.
  • Use credentials for email/password; use OAuth providers for social login.
  • Validate email is verified on the OAuth provider before creating the user.
  • Expecting handleCallback to accept a response object (it receives params, not res).
  • Forgetting to pass providers in the config — auth.signIn throws ProviderError.