Files
tenderpilot/public/backup-20260214/auth.js
Peter Foster f969ecae04 feat: visual polish, nav login link, pricing badge fix, cursor fix, button contrast
- Hero mockup: enhanced 3D perspective and shadow
- Testimonials: illustrated SVG avatars
- Growth pricing card: visual prominence (scale, gradient, badge)
- Most Popular badge: repositioned to avoid overlapping heading
- Nav: added Log In link next to Start Free Trial
- Fixed btn-primary text colour on anchor tags (white on blue)
- Fixed cursor: default on all non-interactive elements
- Disabled user-select on non-form content to prevent text caret
2026-02-14 14:17:15 +00:00

111 lines
2.1 KiB
JavaScript

/**
* TenderRadar Authentication Utilities
* Shared auth module for all app pages
*/
/**
* Get JWT token from localStorage
* @returns {string|null} JWT token or null if not found
*/
function getToken() {
return localStorage.getItem('tenderradar_token');
}
/**
* Set JWT token in localStorage
* @param {string} token - JWT token to store
*/
function setToken(token) {
localStorage.setItem('tenderradar_token', token);
}
/**
* Clear JWT token from localStorage
*/
function clearToken() {
localStorage.removeItem('tenderradar_token');
}
/**
* Check if user is authenticated
* @returns {boolean} true if token exists, false otherwise
*/
function isAuthenticated() {
return !!getToken();
}
/**
* Decode JWT payload (simple, does not verify signature)
* @returns {object|null} Decoded payload or null if token invalid
*/
function getUserInfo() {
const token = getToken();
if (!token) return null;
try {
const parts = token.split('.');
if (parts.length !== 3) return null;
const payload = JSON.parse(atob(parts[1]));
return payload;
} catch (e) {
console.error('Failed to decode token:', e);
return null;
}
}
/**
* Redirect to login if not authenticated
*/
function requireAuth() {
if (!isAuthenticated()) {
window.location.href = '/login.html';
}
}
/**
* Fetch with automatic Authorization header
* @param {string} url - API endpoint URL
* @param {object} options - Fetch options
* @returns {Promise<Response>} Fetch response
*/
async function fetchWithAuth(url, options = {}) {
const token = getToken();
const headers = {
'Content-Type': 'application/json',
...options.headers
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
return fetch(url, {
...options,
headers
});
}
/**
* Logout user: clear token and redirect to login
*/
function logout() {
clearToken();
window.location.href = '/login.html';
}
// Export for use as ES module
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
getToken,
setToken,
clearToken,
isAuthenticated,
getUserInfo,
requireAuth,
fetchWithAuth,
logout
};
}