UNPKG

authrix

Version:

Lightweight, flexible authentication library for Node.js and TypeScript.

2 lines 4.28 kB
'use strict';var c={AUTH:"https://accounts.google.com/o/oauth2/v2/auth",TOKEN:"https://oauth2.googleapis.com/token",USER_INFO:"https://www.googleapis.com/oauth2/v3/userinfo",TOKEN_INFO:"https://oauth2.googleapis.com/tokeninfo",REVOKE:"https://oauth2.googleapis.com/revoke"},f=["openid","profile","email"],a=null;function g(){if(a)return a;let t=process.env.GOOGLE_CLIENT_ID,e=process.env.GOOGLE_CLIENT_SECRET,o=process.env.GOOGLE_REDIRECT_URI||process.env.GOOGLE_OAUTH_REDIRECT_URI;if(!t||!e||!o){let n=[];throw t||n.push("GOOGLE_CLIENT_ID"),e||n.push("GOOGLE_CLIENT_SECRET"),o||n.push("GOOGLE_REDIRECT_URI"),new Error(`Missing Google OAuth environment variables: ${n.join(", ")}. These are required when using Google OAuth functionality. Visit https://console.cloud.google.com/apis/credentials to obtain these values.`)}return a={clientId:t,clientSecret:e,redirectUri:o},a}function p(t){try{let[,e]=t.split(".");if(!e)return null;let o=e+"=".repeat((4-e.length%4)%4),n=atob(o.replace(/-/g,"+").replace(/_/g,"/"));return JSON.parse(n)}catch{return null}}function h(t={}){let e=g(),o=new URLSearchParams({client_id:e.clientId,redirect_uri:t.redirectUri||e.redirectUri,response_type:"code",scope:(t.scopes||f).join(" "),access_type:t.accessType||"online",prompt:t.prompt||"select_account",include_granted_scopes:String(t.includeGrantedScopes??true)});return t.state&&o.set("state",t.state),t.loginHint&&o.set("login_hint",t.loginHint),`${c.AUTH}?${o.toString()}`}async function m(t,e={}){let o=g();try{let n=await fetch(c.TOKEN,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:new URLSearchParams({code:t,client_id:o.clientId,client_secret:o.clientSecret,redirect_uri:e.redirectUri||o.redirectUri,grant_type:"authorization_code"}).toString()});if(!n.ok){let l=await n.text();throw new Error(`Token exchange failed: ${n.status} - ${l}`)}let r=await n.json();if(!r.id_token)throw new Error("No ID token received from Google");let s=p(r.id_token);if(!s)throw new Error("Failed to decode ID token");if(s.aud!==o.clientId)throw new Error("Token audience mismatch");if(s.iss!=="https://accounts.google.com"&&s.iss!=="accounts.google.com")throw new Error("Invalid token issuer");let d=Math.floor(Date.now()/1e3);if(s.exp<d)throw new Error("ID token has expired");let i;if(r.access_token){let l=await fetch(c.USER_INFO,{headers:{Authorization:`Bearer ${r.access_token}`,Accept:"application/json"}});l.ok?i=await l.json():i=s;}else i=s;if(!e.skipEmailVerification&&i.email_verified!==!0)throw new Error("Email address is not verified");let u={id:i.sub,email:i.email,name:i.name,avatar:i.picture,provider:"google",emailVerified:i.email_verified,metadata:{givenName:i.given_name,familyName:i.family_name,locale:i.locale}};return e.includeTokens?{...u,tokens:{access:r.access_token,refresh:r.refresh_token,idToken:r.id_token}}:u}catch(n){throw n instanceof Error?n.message.includes("fetch")?new Error("Network error during Google authentication. Please try again."):n.message.includes("audience")||n.message.includes("issuer")?new Error("Security validation failed. Please try again."):new Error(`Google authentication failed: ${n.message}`):new Error("An unexpected error occurred during Google authentication.")}}async function _(t){try{return (await fetch(c.REVOKE,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({token:t}).toString()})).ok}catch{return false}}async function E(t){try{let e=await fetch(`${c.TOKEN_INFO}?id_token=${t}`);if(!e.ok)return null;let o=await e.json(),n=g();if(o.aud!==n.clientId)return null;let r=Math.floor(Date.now()/1e3);return o.exp<r?null:o}catch{return null}}function w(t){let e=crypto.getRandomValues(new Uint8Array(32)),o=Array.from(e,n=>n.toString(16).padStart(2,"0")).join("");if(t){let n=JSON.stringify(t),r=btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"");return `${o}.${r}`}return o}function O(t){let e=t.split(".");if(e.length===1)return {token:e[0]};try{let o=e[1],n=o+"=".repeat((4-o.length%4)%4),r=atob(n.replace(/-/g,"+").replace(/_/g,"/")),s=JSON.parse(r);return {token:e[0],data:s}}catch{return {token:e[0]}}}function k(){a=null;} exports.a=h;exports.b=m;exports.c=_;exports.d=E;exports.e=w;exports.f=O;exports.g=k;