mirror of
https://github.com/Oak-and-Sprout/sprout-track.git
synced 2026-04-29 11:39:16 -05:00
cleaned up sysadmin usage streamlined slug flow
This commit is contained in:
+26
-18
@@ -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
@@ -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('/');
|
||||
|
||||
Reference in New Issue
Block a user