Files
AutoGPT/autogpt_platform/frontend/src/components/RoleBasedAccess.tsx
Ubbe fb18ddf95d feat(frontend): handle cross-tab login/logout + auth architecture refactor (#10150)
## 🏗️ Changes 

### 🧢 Authentication improvements
- Updates for [CASA compliance](https://appdefensealliance.dev/casa)
  - implemented cross-tab login/logout
  - logout now triggers cross-device logout 
  - forgot password triggers cross-device logout
- we are already able to revoke sessions given Supabase stores sessions
🙌🏽

### 📙 Cross-tab login/logout implementation

I implemented some session validation debouncing ( _2-second cooldown_ )
to prevent excessive API calls when switching tabs fast ( _more of an
edge-case but could happen_ ). Cross tab implementation is done via
`localStorage` and `window.visibility` events.

### Refactor and cleanup

Smol things to improve our auth logic on the Frontend:
- created `helpers.ts` with utilities for protected page detection,
admin page routing, and cross-tab communication
- added `STORAGE_KEYS`, `PROTECTED_PAGES`, and `ADMIN_PAGES` constants
for better organization
- refactored server-side Supabase utilities and middleware
- updated import paths to use named exports

## Checklist 📋

### For code changes:
- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] I have tested my changes according to the test plan:
  - [x] Cross-tab logout synchronization works correctly
  - [x] Session validation debouncing prevents excessive API calls
  - [x] Protected page redirects function properly
  - [x] Authentication state persists correctly across tabs
  - [x] Role-based access controls work as expected
  - [x] Cross-device logout is performed after forgot password change

### Cross-tab login/logout 


https://github.com/user-attachments/assets/5dbdd204-faa2-419f-b989-e31f69ddabd6

### Cross-device logout


https://github.com/user-attachments/assets/aac9c97a-beec-4519-a391-f94f988dc7c8
2025-06-13 15:28:03 +00:00

28 lines
567 B
TypeScript

// components/RoleBasedAccess.tsx
import { useSupabase } from "@/lib/supabase/hooks/useSupabase";
import React from "react";
interface RoleBasedAccessProps {
allowedRoles: string[];
children: React.ReactNode;
}
const RoleBasedAccess: React.FC<RoleBasedAccessProps> = ({
allowedRoles,
children,
}) => {
const { user, isUserLoading } = useSupabase();
if (isUserLoading) {
return <div>Loading...</div>;
}
if (!user!.role || !allowedRoles.includes(user!.role)) {
return null;
}
return <>{children}</>;
};
export default RoleBasedAccess;