cleaned up sysadmin usage streamlined slug flow

This commit is contained in:
John Overton
2025-12-15 20:25:01 -06:00
parent f6fe84018f
commit 639194760e
2 changed files with 59 additions and 31 deletions
+26 -18
View File
@@ -316,20 +316,22 @@ function AppContent({ children }: { children: React.ReactNode }) {
const authToken = localStorage.getItem('authToken');
const unlockTime = localStorage.getItem('unlockTime');
// Check if user is authenticated via account
// Check if user is authenticated via account or is a system admin
let isAccountAuth = false;
let isSysAdmin = false;
if (authToken) {
try {
const payload = authToken.split('.')[1];
const decodedPayload = JSON.parse(atob(payload));
isAccountAuth = decodedPayload.isAccountAuth || false;
isSysAdmin = decodedPayload.isSysAdmin || false;
} catch (error) {
// Ignore parsing errors
}
}
const isAuthenticated = authToken && (isAccountAuth || unlockTime);
const isAuthenticated = authToken && (isAccountAuth || isSysAdmin || unlockTime);
// Only fetch data if authenticated or not on root slug page
// Root slug page handles its own data fetching for login
if (!isRootSlugPage || isAuthenticated) {
@@ -363,20 +365,22 @@ function AppContent({ children }: { children: React.ReactNode }) {
const isRootSlugPage = pathname === `/${familySlug}` || pathname === `/${familySlug}/`;
const authToken = localStorage.getItem('authToken');
const unlockTime = localStorage.getItem('unlockTime');
let isAccountAuth = false;
let isSysAdmin = false;
if (authToken) {
try {
const payload = authToken.split('.')[1];
const decodedPayload = JSON.parse(atob(payload));
isAccountAuth = decodedPayload.isAccountAuth || false;
isSysAdmin = decodedPayload.isSysAdmin || false;
} catch (error) {
// Ignore parsing errors
}
}
const isAuthenticated = authToken && (isAccountAuth || unlockTime);
const isAuthenticated = authToken && (isAccountAuth || isSysAdmin || unlockTime);
if (family?.id && (!isRootSlugPage || isAuthenticated)) {
fetchData();
}
@@ -427,22 +431,24 @@ function AppContent({ children }: { children: React.ReactNode }) {
const authToken = localStorage.getItem('authToken');
const unlockTime = localStorage.getItem('unlockTime');
// Check if user is authenticated via account
// Check if user is authenticated via account or is a system admin
let isAccountAuth = false;
let isSysAdmin = false;
if (authToken) {
try {
const payload = authToken.split('.')[1];
const decodedPayload = JSON.parse(atob(payload));
isAccountAuth = decodedPayload.isAccountAuth || false;
isSysAdmin = decodedPayload.isSysAdmin || false;
} catch (error) {
console.error('Error parsing JWT token for account auth check:', error);
}
}
// Account holders don't need unlockTime, PIN-based users do
// Account holders and system admins don't need unlockTime, PIN-based users do
// If not authenticated and on a sub-route, redirect to root slug page
if (!authToken || (!isAccountAuth && !unlockTime)) {
if (!authToken || (!isAccountAuth && !isSysAdmin && !unlockTime)) {
// If we're on a sub-route, redirect to root slug page to show login
if (familySlug && pathname && pathname.startsWith(`/${familySlug}/`)) {
router.push(`/${familySlug}`);
@@ -576,21 +582,23 @@ function AppContent({ children }: { children: React.ReactNode }) {
const checkUnlockStatus = () => {
const authToken = localStorage.getItem('authToken');
const unlockTime = localStorage.getItem('unlockTime');
// Check if user is authenticated via account
// Check if user is authenticated via account or is a system admin
let isAccountAuth = false;
let isSysAdmin = false;
if (authToken) {
try {
const payload = authToken.split('.')[1];
const decodedPayload = JSON.parse(atob(payload));
isAccountAuth = decodedPayload.isAccountAuth || false;
isSysAdmin = decodedPayload.isSysAdmin || false;
} catch (error) {
console.error('Error parsing JWT token for unlock status:', error);
}
}
// Account holders are automatically unlocked, PIN-based users need unlockTime
const newUnlockState = !!(authToken && (isAccountAuth || unlockTime));
// Account holders and system admins are automatically unlocked, PIN-based users need unlockTime
const newUnlockState = !!(authToken && (isAccountAuth || isSysAdmin || unlockTime));
setIsUnlocked(newUnlockState);
// Extract user information from JWT token
+33 -13
View File
@@ -80,21 +80,23 @@ function FamilySlugPageContent() {
useEffect(() => {
// Don't check auth until slug is validated
if (!slugValidated) return;
setIsCheckingAuth(true);
const checkAuth = () => {
const authToken = localStorage.getItem('authToken');
const unlockTime = localStorage.getItem('unlockTime');
// Check if user is authenticated via account
// Check if user is authenticated via account or is a system admin
let isAccountAuth = false;
let isSysAdmin = false;
if (authToken) {
try {
const payload = authToken.split('.')[1];
const decodedPayload = JSON.parse(atob(payload));
isAccountAuth = decodedPayload.isAccountAuth || false;
isSysAdmin = decodedPayload.isSysAdmin || false;
// Check if token has expired
if (decodedPayload.exp && decodedPayload.exp * 1000 < Date.now()) {
// Token expired, clear it
@@ -116,23 +118,26 @@ function FamilySlugPageContent() {
return;
}
}
// Account holders don't need unlockTime, PIN-based users do
if (authToken && (isAccountAuth || unlockTime)) {
// Account holders and system admins don't need unlockTime, PIN-based users do
if (authToken && (isAccountAuth || isSysAdmin || unlockTime)) {
setIsAuthenticated(true);
// Redirect authenticated users to log-entry (one-time redirect)
if (!hasRedirectedRef.current) {
if (!hasRedirectedRef.current && familySlug) {
hasRedirectedRef.current = true;
router.push(`/${familySlug}/log-entry`);
const targetUrl = `/${familySlug}/log-entry`;
console.log('Redirecting authenticated user to log-entry:', targetUrl);
// Use window.location for a hard navigation to ensure it works
window.location.href = targetUrl;
}
} else {
setIsAuthenticated(false);
hasRedirectedRef.current = false; // Reset if not authenticated
}
setIsCheckingAuth(false);
};
// Only check once when slug is validated, not continuously
checkAuth();
}, [slugValidated]); // Only depend on slugValidated to prevent loops
@@ -141,7 +146,22 @@ function FamilySlugPageContent() {
useEffect(() => {
// Only check after slug is validated and family context has finished loading
if (!slugValidated || familyLoading) return;
// Don't redirect system admins - they can access any family
const authToken = localStorage.getItem('authToken');
if (authToken) {
try {
const payload = authToken.split('.')[1];
const decodedPayload = JSON.parse(atob(payload));
if (decodedPayload.isSysAdmin) {
// System admins can access any family, don't redirect
return;
}
} catch (error) {
// Ignore parsing errors
}
}
if (family && family.isActive === false) {
// Family exists but is inactive - redirect to root
router.push('/');