Bunch of updates for temp users and logging securely.
This commit is contained in:
parent
3b88eef397
commit
960bd39e21
@ -215,7 +215,7 @@ The build script automatically creates the following table structure:
|
||||
- `Password` (Single Line Text): User password (required)
|
||||
- `Name` (Single Line Text): User display name
|
||||
- `Admin` (Checkbox): Admin privileges
|
||||
- `UserType` (Single Select): Options: "user" (Blue), "temp" (Orange) - User role type
|
||||
- `UserType` or `User Type` (Single Select): Options: "user" (Blue), "temp" (Orange) - User role type
|
||||
- `ExpiresAt` (DateTime): Expiration date for temporary users
|
||||
- `ExpireDays` (Number): Number of days until temp user expires
|
||||
- `Created At` (DateTime): Account creation timestamp
|
||||
|
||||
@ -52,7 +52,7 @@ class AuthController {
|
||||
}
|
||||
|
||||
// Check if temp user has expired
|
||||
const userType = user.UserType || user.userType || 'user';
|
||||
const userType = user['User Type'] || user.UserType || user.userType || 'user';
|
||||
if (userType === 'temp') {
|
||||
const expiration = user.ExpiresAt || user.expiresAt || user.Expiration || user.expiration;
|
||||
if (expiration) {
|
||||
@ -91,11 +91,23 @@ class AuthController {
|
||||
req.session.userEmail = user.email || user.Email; // Make sure this is set
|
||||
req.session.userName = user.name || user.Name;
|
||||
req.session.isAdmin = user.admin || user.Admin || false;
|
||||
req.session.userType = user.UserType || user.userType || (req.session.isAdmin ? 'admin' : 'user');
|
||||
|
||||
logger.info('User logged in:', {
|
||||
email: req.session.userEmail,
|
||||
admin: req.session.isAdmin
|
||||
// More explicit userType determination with proper fallback - handle both field name variations
|
||||
let sessionUserType = 'user'; // default
|
||||
if (user['User Type']) {
|
||||
sessionUserType = user['User Type'].toLowerCase();
|
||||
} else if (user.UserType) {
|
||||
sessionUserType = user.UserType.toLowerCase();
|
||||
} else if (user.userType) {
|
||||
sessionUserType = user.userType.toLowerCase();
|
||||
} else if (req.session.isAdmin) {
|
||||
sessionUserType = 'admin';
|
||||
}
|
||||
|
||||
req.session.userType = sessionUserType;
|
||||
|
||||
logger.info('User logged in successfully', {
|
||||
userType: req.session.userType
|
||||
});
|
||||
|
||||
// Force session save
|
||||
|
||||
@ -334,6 +334,14 @@ class LocationsController {
|
||||
|
||||
async delete(req, res) {
|
||||
try {
|
||||
// Check if user is temp and deny delete
|
||||
if (req.session?.userType === 'temp') {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
error: 'Temporary users cannot delete locations'
|
||||
});
|
||||
}
|
||||
|
||||
const locationId = req.params.id;
|
||||
|
||||
// Validate ID
|
||||
|
||||
@ -100,6 +100,7 @@ class UsersController {
|
||||
name: name || '',
|
||||
Admin: isAdmin === true,
|
||||
admin: isAdmin === true,
|
||||
'User Type': userType || 'user', // Handle space in field name
|
||||
UserType: userType || 'user',
|
||||
userType: userType || 'user',
|
||||
CreatedAt: new Date().toISOString(),
|
||||
@ -121,6 +122,7 @@ class UsersController {
|
||||
Email: email,
|
||||
Name: name,
|
||||
Admin: isAdmin,
|
||||
'User Type': userType, // Handle space in field name
|
||||
UserType: userType,
|
||||
'Created At': new Date().toISOString(),
|
||||
ExpiresAt: expiresAt
|
||||
|
||||
@ -28,4 +28,30 @@ a.temp-restricted,
|
||||
body.temp-user a[href="/shifts.html"],
|
||||
body.temp-user .mobile-dropdown-item a[href="/shifts.html"] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Hide delete button for temp users - MOST AGGRESSIVE RULES */
|
||||
body.temp-user #delete-location-btn,
|
||||
body.temp-user .delete-location-btn,
|
||||
body.temp-user .btn-danger[id*="delete"],
|
||||
body.temp-user button[id*="delete"],
|
||||
body.temp-user .form-actions .btn-danger,
|
||||
body.temp-user .form-actions button[type="button"].btn-danger,
|
||||
.temp-hidden,
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
opacity: 0 !important;
|
||||
pointer-events: none !important;
|
||||
position: absolute !important;
|
||||
left: -9999px !important;
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
/* Hide move location button for temp users */
|
||||
body.temp-user .move-location-btn,
|
||||
body.temp-user #move-location-btn {
|
||||
display: none !important;
|
||||
}
|
||||
@ -431,7 +431,7 @@
|
||||
<div class="spinner"></div>
|
||||
<p>Authenticating...</p>
|
||||
<p class="loading-patience-message">
|
||||
Loading map for the first time can take several seconds, even up to a minute. Please be patient.
|
||||
Loading map can take several seconds, even up to a minute. Please be patient.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -25,6 +25,27 @@ export async function checkAuth() {
|
||||
currentUser = data.user;
|
||||
currentUser.userType = data.user.userType || 'user'; // Ensure userType is set
|
||||
|
||||
// IMMEDIATE console blocking for all non-admin users - before any other code runs
|
||||
if (currentUser.userType !== 'admin') {
|
||||
const noop = () => {};
|
||||
setTimeout(() => {
|
||||
console.log = noop;
|
||||
console.debug = noop;
|
||||
console.info = noop;
|
||||
console.warn = noop;
|
||||
console.error = noop;
|
||||
console.trace = noop;
|
||||
console.dir = noop;
|
||||
console.dirxml = noop;
|
||||
console.group = noop;
|
||||
console.groupEnd = noop;
|
||||
console.time = noop;
|
||||
console.timeEnd = noop;
|
||||
console.assert = noop;
|
||||
console.profile = noop;
|
||||
}, 1000); // Give 1 second for initialization logs, then block
|
||||
}
|
||||
|
||||
// Authentication successful - show the app
|
||||
document.body.classList.remove('authenticating');
|
||||
document.body.classList.add('authenticated');
|
||||
@ -43,9 +64,19 @@ export async function checkAuth() {
|
||||
export function updateUserInterface() {
|
||||
if (!currentUser) return;
|
||||
|
||||
/* NEW – add a body class we can target with CSS */
|
||||
document.body.classList.toggle('temp-user', currentUser.userType === 'temp');
|
||||
document.body.classList.toggle('admin-user', currentUser.isAdmin === true);
|
||||
// CRITICAL: Add body class for temp users FIRST
|
||||
if (currentUser.userType === 'temp') {
|
||||
document.body.classList.add('temp-user');
|
||||
} else {
|
||||
document.body.classList.remove('temp-user');
|
||||
}
|
||||
|
||||
// Also add admin class for consistency
|
||||
if (currentUser.isAdmin === true) {
|
||||
document.body.classList.add('admin-user');
|
||||
} else {
|
||||
document.body.classList.remove('admin-user');
|
||||
}
|
||||
|
||||
// ----- existing code that manipulates DOM -----
|
||||
// Update user email in both desktop and mobile
|
||||
@ -119,6 +150,21 @@ export function updateUserInterface() {
|
||||
if (currentUser.isAdmin) {
|
||||
addAdminLinks();
|
||||
}
|
||||
|
||||
// CRITICAL: Final check to hide delete buttons for temp users
|
||||
if (currentUser.userType === 'temp') {
|
||||
// Use setTimeout to ensure this runs after all other DOM operations
|
||||
setTimeout(() => {
|
||||
const deleteButtons = document.querySelectorAll('#delete-location-btn, .delete-location-btn, .btn-danger[id*="delete"]');
|
||||
deleteButtons.forEach(btn => {
|
||||
btn.style.display = 'none';
|
||||
btn.style.visibility = 'hidden';
|
||||
btn.disabled = true;
|
||||
btn.classList.add('temp-hidden');
|
||||
btn.setAttribute('hidden', 'true');
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
function addAdminLinks() {
|
||||
|
||||
@ -413,13 +413,26 @@ export function openEditForm(location) {
|
||||
document.getElementById('edit-location-lng').value = location.longitude || '';
|
||||
document.getElementById('edit-geo-location').value = location['Geo-Location'] || '';
|
||||
|
||||
// Show/hide delete button based on user type
|
||||
// Hide delete button for temp users - use multiple approaches
|
||||
const deleteBtn = document.getElementById('delete-location-btn');
|
||||
if (deleteBtn) {
|
||||
if (currentUser?.userType === 'temp') {
|
||||
if (deleteBtn) {
|
||||
// Check both currentUser and body class to ensure restriction
|
||||
const isTemp = currentUser?.userType === 'temp' || document.body.classList.contains('temp-user');
|
||||
|
||||
if (isTemp) {
|
||||
deleteBtn.style.display = 'none';
|
||||
deleteBtn.style.visibility = 'hidden';
|
||||
deleteBtn.disabled = true;
|
||||
deleteBtn.classList.add('temp-hidden');
|
||||
deleteBtn.setAttribute('hidden', 'true');
|
||||
// Remove the button from DOM completely for temp users
|
||||
deleteBtn.remove();
|
||||
} else {
|
||||
deleteBtn.style.display = '';
|
||||
deleteBtn.style.display = 'inline-block';
|
||||
deleteBtn.style.visibility = 'visible';
|
||||
deleteBtn.disabled = false;
|
||||
deleteBtn.classList.remove('temp-hidden');
|
||||
deleteBtn.removeAttribute('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -37,8 +37,8 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
|
||||
console.log('Authentication confirmed, initializing application...');
|
||||
|
||||
// Setup temp user security measures after authentication
|
||||
setupTempUserSecurity();
|
||||
// Setup temp user security measures immediately after authentication
|
||||
await setupUserSecurity();
|
||||
|
||||
// Then initialize the map
|
||||
updateLoadingMessage('Initializing map...');
|
||||
@ -177,63 +177,55 @@ async function initializeUnifiedSearch() {
|
||||
}
|
||||
}
|
||||
|
||||
// Setup security measures for temp users
|
||||
function setupTempUserSecurity() {
|
||||
// Setup security measures for non-admin users
|
||||
async function setupUserSecurity() {
|
||||
// Import currentUser from auth module
|
||||
import('./auth.js').then(authModule => {
|
||||
const { currentUser } = authModule;
|
||||
const { currentUser } = await import('./auth.js');
|
||||
|
||||
if (currentUser?.userType !== 'admin') {
|
||||
// Override console methods for all non-admin users
|
||||
const noop = () => {};
|
||||
console.log = noop;
|
||||
console.debug = noop;
|
||||
console.info = noop;
|
||||
console.warn = noop;
|
||||
console.error = noop;
|
||||
console.trace = noop;
|
||||
console.dir = noop;
|
||||
console.dirxml = noop;
|
||||
console.group = noop;
|
||||
console.groupEnd = noop;
|
||||
console.time = noop;
|
||||
console.timeEnd = noop;
|
||||
console.assert = noop;
|
||||
console.profile = noop;
|
||||
}
|
||||
|
||||
// Additional temp user specific restrictions
|
||||
if (currentUser?.userType === 'temp') {
|
||||
// Disable right-click context menu
|
||||
document.addEventListener('contextmenu', (e) => {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
if (currentUser?.userType === 'temp') {
|
||||
console.log('Applying temp user security measures...');
|
||||
|
||||
// Disable right-click context menu
|
||||
document.addEventListener('contextmenu', (e) => {
|
||||
// Disable common keyboard shortcuts for developer tools
|
||||
document.addEventListener('keydown', (e) => {
|
||||
// F12
|
||||
if (e.keyCode === 123) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Basic developer tools detection
|
||||
const devtools = { open: false };
|
||||
let devtoolsTimer = setInterval(() => {
|
||||
// Detect if developer tools are open by checking window dimensions
|
||||
if (window.outerHeight - window.innerHeight > 200 ||
|
||||
window.outerWidth - window.innerWidth > 200) {
|
||||
if (!devtools.open) {
|
||||
console.clear();
|
||||
console.log('Access to developer tools is restricted for temporary accounts.');
|
||||
console.log('Please contact an administrator for full access.');
|
||||
}
|
||||
devtools.open = true;
|
||||
} else {
|
||||
devtools.open = false;
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// Clear interval on page unload
|
||||
window.addEventListener('beforeunload', () => {
|
||||
if (devtoolsTimer) {
|
||||
clearInterval(devtoolsTimer);
|
||||
}
|
||||
});
|
||||
|
||||
// Disable common keyboard shortcuts for developer tools
|
||||
document.addEventListener('keydown', (e) => {
|
||||
// F12
|
||||
if (e.keyCode === 123) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
// Ctrl+Shift+I, Ctrl+Shift+J, Ctrl+U
|
||||
if (e.ctrlKey && e.shiftKey && (e.keyCode === 73 || e.keyCode === 74)) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
// Ctrl+U (view source)
|
||||
if (e.ctrlKey && e.keyCode === 85) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// Ctrl+Shift+I, Ctrl+Shift+J, Ctrl+U
|
||||
if (e.ctrlKey && e.shiftKey && (e.keyCode === 73 || e.keyCode === 74)) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
// Ctrl+U (view source)
|
||||
if (e.ctrlKey && e.keyCode === 85) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user