UNPKG

login-auth-services

Version:

Authentication services for Google, GitHub, Microsoft, okta and multi-factor authentication using OTP.

80 lines (68 loc) 2.78 kB
import bcrypt from "bcrypt"; import jwt from "jsonwebtoken"; import nodemailer from "nodemailer"; import crypto from "crypto"; import { DatabaseService } from "./databaseService"; import type { User } from "../entities/User"; const dbService = DatabaseService.getInstance(); const OTPs: Record<string, string> = {}; const transporter = nodemailer.createTransport({ service: "gmail", auth: { user: process.env.EMAIL_USER, pass: process.env.EMAIL_PASSWORD, }, }); export const hashPassword = async (password: string, saltRounds = 10): Promise<string> => { const salt = await bcrypt.genSalt(saltRounds); return await bcrypt.hash(password, salt); }; export const validatePassword = async (password: string, hashedPassword: string): Promise<boolean> => { return await bcrypt.compare(password, hashedPassword); }; export const generateToken = (userId: string | number, email: string): string => { const payload = { id: userId, email }; return jwt.sign(payload, process.env.SECRET_KEY || "default_secret_key", { expiresIn: "1h" }); }; export const registerUser = async (username: string, email: string, password: string): Promise<User> => { const existingUser = await dbService.findUserByEmail(email); if (existingUser) { throw new Error("User already exists"); } const hashedPassword = await hashPassword(password); return await dbService.createUser({ username, email, password: hashedPassword }); }; export const loginUser = async (email: string, password: string): Promise<{ user: User; token: string } | null> => { const user = await dbService.findUserByEmail(email); if (user && (await validatePassword(password, user.password))) { const token = generateToken(user.id, user.email); return { user, token }; } return null; }; export const initiateLoginWithEmail = async (email: string): Promise<{ message: string; success: boolean }> => { const user = await dbService.findUserByEmail(email); if (user) { const otp = crypto.randomInt(100000, 999999).toString(); OTPs[email] = otp; await transporter.sendMail({ from: process.env.EMAIL_USER, to: email, subject: "Your OTP for Login", text: `Your OTP is: ${otp}`, }); return { message: "OTP sent to your email", success: true }; } return { message: "User not found", success: false }; }; export const validateOTP = async (email: string, otp: string): Promise<{ user: User; token: string } | null> => { if (OTPs[email] === otp) { delete OTPs[email]; const user = await dbService.findUserByEmail(email); if (user) { const token = generateToken(user.id, user.email); return { user, token }; } } return null; };