payloadcms_otp_plugin
Version:
A comprehensive One-Time Password (OTP) authentication plugin for Payload CMS that enables secure passwordless authentication via SMS and email
76 lines (75 loc) • 3.29 kB
JavaScript
import { baseOtpTranslation } from '../translation/index.js';
/**
* Parse Accept-Language header and return the best matching supported language
* @param acceptLanguageHeader - The Accept-Language header value
* @returns The best matching supported language, defaults to 'en'
*/ export function parseAcceptLanguage(acceptLanguageHeader) {
if (!acceptLanguageHeader) {
return 'en';
}
// Parse Accept-Language header format: "en-US,en;q=0.9,ar;q=0.8"
const languages = acceptLanguageHeader.split(',').map((lang)=>{
const [code, qValue] = lang.trim().split(';');
const quality = qValue ? parseFloat(qValue.split('=')[1]) : 1.0;
return {
code: code.split('-')[0].toLowerCase(),
quality
};
}).sort((a, b)=>b.quality - a.quality) // Sort by quality (preference)
;
// Find the first supported language
for (const lang of languages){
if (lang.code === 'ar' || lang.code === 'en') {
return lang.code;
}
}
// Default to English if no supported language found
return 'en';
}
/**
* Get translated message based on language and key path
* @param language - The target language
* @param keyPath - Dot notation path to the translation key (e.g., "otp.expired_message")
* @param fallbackMessage - Fallback message if translation not found
* @returns Translated message or fallback
*/ export function getTranslation(language, keyPath, fallbackMessage) {
const translations = baseOtpTranslation[language];
if (!translations) {
return fallbackMessage || keyPath;
}
// Navigate through nested object using dot notation
const keys = keyPath.split('.');
let current = translations;
for (const key of keys){
if (current && typeof current === 'object' && key in current) {
current = current[key];
} else {
return fallbackMessage || keyPath;
}
}
return typeof current === 'string' ? current : fallbackMessage || keyPath;
}
/**
* Get translated message from request headers
* @param headers - Request headers containing Accept-Language
* @param keyPath - Dot notation path to the translation key
* @param fallbackMessage - Fallback message if translation not found
* @returns Translated message
*/ export function getTranslationFromHeaders(headers, keyPath, fallbackMessage) {
const acceptLanguage = headers instanceof Headers ? headers.get('Accept-Language') : headers['accept-language'] || headers['Accept-Language'];
const language = parseAcceptLanguage(acceptLanguage || undefined);
return getTranslation(language, keyPath, fallbackMessage);
}
/**
* Create a translation helper bound to specific request headers
* @param headers - Request headers containing Accept-Language
* @returns Translation helper function
*/ export function createTranslationHelper(headers) {
const acceptLanguage = headers instanceof Headers ? headers.get('Accept-Language') : headers['accept-language'] || headers['Accept-Language'];
const language = parseAcceptLanguage(acceptLanguage || undefined);
return {
language,
t: (keyPath, fallbackMessage)=>getTranslation(language, keyPath, fallbackMessage)
};
}
//# sourceMappingURL=translation.js.map