UNPKG

universal_authentication

Version:

Seamless and Secure Authentication for Modern Web Applications: Easily integrate OTP-based email verification, Google OAuth, GitHub, Microsoft, and Okta login into your Node.js app. Modular, flexible, and database-agnostic, this package simplifies user au

133 lines (132 loc) 5.77 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.handleOAuthCallback = exports.initiateLogin = void 0; const axios_1 = __importDefault(require("axios")); // function to genrate OAuth url const initiateLogin = (provider, clientId, redirectUri) => { const providerUrls = { google: `https://accounts.google.com/o/oauth2/v2/auth?client_id=${clientId}&redirect_uri=${redirectUri}&response_type=code&scope=profile email`, github: `https://github.com/login/oauth/authorize?client_id=${clientId}`, microsoft: `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=${clientId}&response_type=code&redirect_uri=${redirectUri}&response_mode=query&scope=https://graph.microsoft.com/.default`, okta: `${process.env.OKTA_DOMAIN}/v1/authorize?client_id=${clientId}&response_type=code&scope=openid profile email&redirect_uri=${redirectUri}`, }; return providerUrls[provider]; }; exports.initiateLogin = initiateLogin; //function to handle OAuth callback const handleOAuthCallback = async (code, provider, config) => { try { if (!code) { return { status: 400, message: "Authorization code is missing" }; } // token urls of particular provider and their payloads const tokenUrls = { google: "https://oauth2.googleapis.com/token", github: "https://github.com/login/oauth/access_token", microsoft: "https://login.microsoftonline.com/common/oauth2/v2.0/token", okta: `${process.env.OKTA_DOMAIN}/oauth/token`, }; const tokenPayloads = provider === "google" ? { code, client_id: config.clientId, client_secret: config.clientSecret, redirect_uri: config.redirectUri, grant_type: "authorization_code", } : provider === "github" ? { client_id: config.clientId, client_secret: config.clientSecret, code, } : provider === "microsoft" ? { client_id: config.clientId, client_secret: config.clientSecret, code, redirect_uri: config.redirectUri, grant_type: "authorization_code", } : { grant_type: "authorization_code", code, redirect_uri: config.redirectUri, client_id: config.clientId, client_secret: config.clientSecret, }; // Microsoft-specific header for token exchange const tokenHeaders = provider === "microsoft" ? { "Content-Type": "application/x-www-form-urlencoded" } : { Accept: "application/json" }; //Exchange authorization code for access token const { data: tokenData } = await axios_1.default.post(tokenUrls[provider], tokenPayloads, { headers: tokenHeaders, }); const accessToken = tokenData.access_token; if (!accessToken) { return { status: 400, message: "Failed to get access token" }; } //user profile url to fetch the particular user const userinfoUrls = { google: "https://www.googleapis.com/oauth2/v1/userinfo", github: "https://api.github.com/user", microsoft: "https://graph.microsoft.com/v1.0/me", okta: `${process.env.OKTA_DOMAIN}/v1/userinfo`, }; //fetch user profile from OAuth provider const { data: profileData } = await axios_1.default.get(userinfoUrls[provider], { headers: { Authorization: `Bearer ${accessToken}`, }, }); // extract relevant user details const userData = provider === "google" ? { providerId: profileData.id, name: profileData.name, email: profileData.email, provider, } : provider === "github" ? { providerId: profileData.id, username: profileData.login, name: profileData.name, provider, } : provider === "microsoft" ? { providerId: profileData.id, name: profileData.displayName, email: profileData.mail || profileData.userPrincipalName, provider, } : { providerId: profileData.sub, name: profileData.name, email: profileData.email, provider, }; //check if the user exist const existingUser = await config.findUserById(userData.providerId); if (!existingUser) { const newUser = await config.createUser(userData); return { status: 200, message: "User created successfully", user: newUser, }; } else { return { status: 200, message: "User already exist", user: existingUser }; } } catch (err) { return { status: 500, message: `Failed to get loged in to ${provider}` }; } }; exports.handleOAuthCallback = handleOAuthCallback;