nuxt-users
Version:
A comprehensive user management module for Nuxt 3 and Nuxt 4 applications with authentication, authorization, database support, and CLI tools
69 lines (68 loc) • 3.24 kB
JavaScript
import { defineEventHandler, sendRedirect, getQuery, setCookie } from "h3";
import { useRuntimeConfig } from "#imports";
import {
createGoogleOAuth2Client,
getGoogleUserFromCode,
findOrCreateGoogleUser,
createAuthTokenForUser
} from "../../../../utils/google-oauth.js";
export default defineEventHandler(async (event) => {
const { nuxtUsers } = useRuntimeConfig();
const options = nuxtUsers;
const query = getQuery(event);
if (!options.auth.google) {
return sendRedirect(event, "/login?error=oauth_not_configured");
}
if (query.error) {
console.error("[Nuxt Users] Google OAuth error:", query.error);
const errorRedirect = options.auth.google.errorRedirect || "/login?error=oauth_failed";
return sendRedirect(event, errorRedirect);
}
if (!query.code || typeof query.code !== "string") {
console.error("[Nuxt Users] Missing authorization code in OAuth callback");
const errorRedirect = options.auth.google.errorRedirect || "/login?error=oauth_failed";
return sendRedirect(event, errorRedirect);
}
try {
const baseUrl = getRequestURL(event).origin;
const callbackPath = options.auth.google.callbackUrl || `${options.apiBasePath}/auth/google/callback`;
const callbackUrl = `${baseUrl}${callbackPath}`;
const oauth2Client = createGoogleOAuth2Client(options.auth.google, callbackUrl);
const googleUser = await getGoogleUserFromCode(oauth2Client, query.code);
const user = await findOrCreateGoogleUser(googleUser, options);
if (!user) {
console.warn(`[Nuxt Users] User not registered attempted Google OAuth login: ${googleUser.email}`);
const errorRedirect = options.auth.google.errorRedirect || "/login?error=user_not_registered";
return sendRedirect(event, errorRedirect);
}
if (!user.active) {
console.warn(`[Nuxt Users] Inactive user attempted Google OAuth login: ${user.email}`);
const errorRedirect = options.auth.google.errorRedirect || "/login?error=account_inactive";
return sendRedirect(event, errorRedirect);
}
const token = await createAuthTokenForUser(user, options, true);
const cookieOptions = {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
path: "/",
maxAge: 60 * 60 * 24 * (options.auth.rememberMeExpiration || 30)
// 30 days default
};
setCookie(event, "auth_token", token, cookieOptions);
console.log(`[Nuxt Users] Google OAuth login successful for user: ${user.email}`);
const successRedirect = options.auth.google.successRedirect || "/";
const redirectUrl = successRedirect.includes("?") ? `${successRedirect}&oauth_success=true` : `${successRedirect}?oauth_success=true`;
return sendRedirect(event, redirectUrl);
} catch (error) {
console.error("[Nuxt Users] Google OAuth callback error:", error);
const errorRedirect = options.auth.google?.errorRedirect || "/login?error=oauth_failed";
return sendRedirect(event, errorRedirect);
}
});
const getRequestURL = (event) => {
const headers = event.node.req.headers;
const host = headers.host || headers[":authority"];
const protocol = headers["x-forwarded-proto"] || "https";
return new URL(`${protocol}://${host}`);
};