UNPKG

payloadcms_otp_plugin

Version:

A comprehensive One-Time Password (OTP) authentication plugin for Payload CMS that enables secure passwordless authentication via SMS and email

201 lines (200 loc) 6.44 kB
'use server'; import { cookies, headers } from "next/headers.js"; import { jwtDecode } from "jwt-decode"; async function getBaseUrl() { // Try to get the base URL from environment variable first if (process.env.NEXT_PUBLIC_SERVER_URL) { return process.env.NEXT_PUBLIC_SERVER_URL; } // Fallback to constructing from headers try { const headersList = await headers(); const host = headersList.get('host'); const protocol = headersList.get('x-forwarded-proto') || 'http'; if (host) { return `${protocol}://${host}`; } } catch (error) { // console.error('Error getting headers:', error); } // Final fallback for development return 'http://localhost:3000'; } export async function resetToken() { try { const appCookies = await cookies(); const token = appCookies.get("payload-token")?.value; if (token) { appCookies.set("otp-token", token); appCookies.delete("payload-token"); await sendOtp(); return token; } } catch (error) { // console.error('Error resetting token:', error); } return undefined; } export async function sendOtp() { try { const appCookies = await cookies(); const token = appCookies.get("otp-token")?.value; if (!token) { return { success: false, message: "No authentication token found" }; } // Decode JWT token to get user credentials let decodedToken; try { decodedToken = jwtDecode(token); } catch (decodeError) { return { success: false, message: "Invalid authentication token" }; } // Check if token is expired const currentTime = Math.floor(Date.now() / 1000); if (decodedToken.exp < currentTime) { return { success: false, message: "Authentication token has expired" }; } // Prepare credentials for OTP sending const credentials = {}; if (decodedToken.email) { credentials.email = decodedToken.email; } if (decodedToken.mobile) { credentials.mobile = decodedToken.mobile; } if (!credentials.email && !credentials.mobile) { return { success: false, message: "No email or mobile found in token" }; } const body = JSON.stringify(credentials); // Send OTP request const baseUrl = await getBaseUrl(); const response = await fetch(`${baseUrl}/api/otp/send`, { method: "POST", headers: { "Content-Type": "application/json" }, body: body }); const result = await response.json(); return { success: result.code === 200 && !result.error, message: result.message }; } catch (error) { // console.error('Error sending OTP:', error); return { success: false, message: "Failed to send OTP. Please try again." }; } } export async function submitOtp(code) { try { if (!code || code.trim().length === 0) { return { success: false, message: "OTP code is required" }; } const appCookies = await cookies(); const token = appCookies.get("otp-token")?.value; if (!token) { return { success: false, message: "No authentication token found" }; } // Decode JWT token to get user credentials let decodedToken; try { decodedToken = jwtDecode(token); } catch (decodeError) { return { success: false, message: "Invalid authentication token" }; } // Check if token is expired const currentTime = Math.floor(Date.now() / 1000); if (decodedToken.exp < currentTime) { return { success: false, message: "Authentication token has expired" }; } // Prepare credentials for OTP verification const credentials = { otp: code.trim() }; if (decodedToken.email) { credentials.email = decodedToken.email; } if (decodedToken.mobile) { credentials.mobile = decodedToken.mobile; } if (!credentials.email && !credentials.mobile) { return { success: false, message: "No email or mobile found in token" }; } // Submit OTP for verification const baseUrl = await getBaseUrl(); const response = await fetch(`${baseUrl}/api/otp/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(credentials) }); const result = await response.json(); if (result.code === 200 && !result.error && result.data?.token) { // Set new authentication token appCookies.set("payload-token", result.data.token); appCookies.delete("otp-token"); return { success: true, message: result.message, token: result.data.token }; } return { success: false, message: result.message || "OTP verification failed" }; } catch (error) { // console.error('Error submitting OTP:', error); return { success: false, message: "Failed to verify OTP. Please try again." }; } } export async function resendOtp() { // Resend OTP is the same as sending OTP return await sendOtp(); } export async function getOtpConfig() { const baseUrl = await getBaseUrl(); const response = await fetch(`${baseUrl}/api/otp/config`); if (response.ok) { const result = await response.json(); // console.log('response ', result) return result.data || undefined; } // Return undefined for failed requests return undefined; } //# sourceMappingURL=index.js.map