@@ -46,7 +46,7 @@ interface JwtPayload {
4646 */
4747const handleSuperAdminAccess = (
4848 userAuthClaims : string [ ]
49- ) : boolean => userAuthClaims . includes ( ROLES . SUPER_ADMIN ) ;
49+ ) : boolean => userAuthClaims . includes ( ROLES . SUPER_ADMIN ) || userAuthClaims . includes ( ROLES . SUPER_ADMIN_PLUS ) ;
5050
5151/**
5252 * Helper: handles global privileged access rules for VolunteerAdmin.
@@ -802,7 +802,7 @@ export const requireFaqLocationAccess = (req: Request, res: Response, next: Next
802802
803803 // If LocationKey is 'general', only SuperAdmin and VolunteerAdmin can access
804804 if ( locationId === 'general' || locations . includes ( 'general' ) ) {
805- if ( userAuthClaims . includes ( ROLES . SUPER_ADMIN ) || userAuthClaims . includes ( ROLES . VOLUNTEER_ADMIN ) ) {
805+ if ( userAuthClaims . includes ( ROLES . SUPER_ADMIN ) || userAuthClaims . includes ( ROLES . SUPER_ADMIN_PLUS ) || userAuthClaims . includes ( ROLES . VOLUNTEER_ADMIN ) ) {
806806 return next ( ) ;
807807 }
808808 return sendForbidden ( res , 'Access to general advice is restricted to SuperAdmin and VolunteerAdmin' ) ;
@@ -846,7 +846,7 @@ export const requireUserCreationAccess = asyncHandler(async (req: Request, res:
846846 }
847847
848848 // SuperAdmin has access to everything.
849- if ( userAuthClaims . includes ( ROLES . SUPER_ADMIN ) ) {
849+ if ( userAuthClaims . includes ( ROLES . SUPER_ADMIN ) || userAuthClaims . includes ( ROLES . SUPER_ADMIN_PLUS ) ) {
850850 return next ( ) ;
851851 }
852852
@@ -878,7 +878,7 @@ export const requireUserCreationAccess = asyncHandler(async (req: Request, res:
878878 // Validate that they're not trying to assign SuperAdmin role or VolunteerAdmin roles or CityAdmin roles
879879 const requestBody = req . body ;
880880 if ( requestBody . AuthClaims && Array . isArray ( requestBody . AuthClaims ) ) {
881- if ( requestBody . AuthClaims . includes ( ROLES . SUPER_ADMIN ) || requestBody . AuthClaims . includes ( ROLES . VOLUNTEER_ADMIN ) || requestBody . AuthClaims . includes ( ROLES . CITY_ADMIN ) ) {
881+ if ( requestBody . AuthClaims . includes ( ROLES . SUPER_ADMIN ) || requestBody . AuthClaims . includes ( ROLES . SUPER_ADMIN_PLUS ) || requestBody . AuthClaims . includes ( ROLES . VOLUNTEER_ADMIN ) || requestBody . AuthClaims . includes ( ROLES . CITY_ADMIN ) ) {
882882 return sendForbidden ( res , 'OrgAdmin cannot assign SuperAdmin, VolunteerAdmin or CityAdmin roles' ) ;
883883 }
884884 }
@@ -889,7 +889,7 @@ export const requireUserCreationAccess = asyncHandler(async (req: Request, res:
889889 // CityAdmin can create CityAdmin, SwepAdmin, and OrgAdmin users
890890 if ( userAuthClaims . includes ( ROLES . CITY_ADMIN ) ) {
891891 // Validate that they're not trying to assign SuperAdmin or VolunteerAdmin role
892- if ( newUserClaims . includes ( ROLES . SUPER_ADMIN ) || newUserClaims . includes ( ROLES . VOLUNTEER_ADMIN ) ) {
892+ if ( newUserClaims . includes ( ROLES . SUPER_ADMIN ) || newUserClaims . includes ( ROLES . SUPER_ADMIN_PLUS ) || newUserClaims . includes ( ROLES . VOLUNTEER_ADMIN ) ) {
893893 return sendForbidden ( res , 'CityAdmin cannot assign SuperAdmin or VolunteerAdmin roles' ) ;
894894 }
895895
@@ -978,7 +978,7 @@ export const requireDeletionUserAccess = asyncHandler(async (req: Request, res:
978978 }
979979
980980 // 1. SuperAdmin can delete everything
981- if ( userAuthClaims . includes ( ROLES . SUPER_ADMIN ) ) {
981+ if ( userAuthClaims . includes ( ROLES . SUPER_ADMIN ) || userAuthClaims . includes ( ROLES . SUPER_ADMIN_PLUS ) ) {
982982 return next ( ) ;
983983 }
984984
@@ -994,7 +994,7 @@ export const requireDeletionUserAccess = asyncHandler(async (req: Request, res:
994994 // 2. CityAdmin can delete specific roles within their city
995995 if ( userAuthClaims . includes ( ROLES . CITY_ADMIN ) ) {
996996 // Cannot delete SuperAdmin or VolunteerAdmin
997- if ( targetUserClaims . includes ( ROLES . SUPER_ADMIN ) || targetUserClaims . includes ( ROLES . VOLUNTEER_ADMIN ) ) {
997+ if ( targetUserClaims . includes ( ROLES . SUPER_ADMIN ) || targetUserClaims . includes ( ROLES . SUPER_ADMIN_PLUS ) || targetUserClaims . includes ( ROLES . VOLUNTEER_ADMIN ) ) {
998998 return sendForbidden ( res , 'CityAdmin cannot delete/deactivate/activate SuperAdmin or VolunteerAdmin users' ) ;
999999 }
10001000
@@ -1105,7 +1105,7 @@ export const requireUserAccess = asyncHandler(async (req: Request, res: Response
11051105 const userId = req . params . id ;
11061106
11071107 // 1. SuperAdmin can do everything
1108- if ( userAuthClaims . includes ( ROLES . SUPER_ADMIN ) ) {
1108+ if ( userAuthClaims . includes ( ROLES . SUPER_ADMIN ) || userAuthClaims . includes ( ROLES . SUPER_ADMIN_PLUS ) ) {
11091109 // For updates, validate role structure
11101110 if ( method === HTTP_METHODS . PUT || method === HTTP_METHODS . PATCH ) {
11111111 const requestBody = req . body ;
@@ -1197,14 +1197,14 @@ export const requireUserAccess = asyncHandler(async (req: Request, res: Response
11971197
11981198 if ( method === HTTP_METHODS . PUT || method === HTTP_METHODS . PATCH ) {
11991199 // CityAdmin cannot update SuperAdmin or VolunteerAdmin users
1200- if ( targetUserClaims . includes ( ROLES . SUPER_ADMIN ) || targetUserClaims . includes ( ROLES . VOLUNTEER_ADMIN ) ) {
1200+ if ( targetUserClaims . includes ( ROLES . SUPER_ADMIN ) || targetUserClaims . includes ( ROLES . SUPER_ADMIN_PLUS ) || targetUserClaims . includes ( ROLES . VOLUNTEER_ADMIN ) ) {
12011201 return sendForbidden ( res , 'CityAdmin cannot update SuperAdmin or VolunteerAdmin users' ) ;
12021202 }
12031203
12041204 // Validate that they're not trying to assign SuperAdmin or VolunteerAdmin role
12051205 const requestBody = req . body ;
12061206 if ( requestBody . AuthClaims && Array . isArray ( requestBody . AuthClaims ) ) {
1207- if ( requestBody . AuthClaims . includes ( ROLES . SUPER_ADMIN ) || requestBody . AuthClaims . includes ( ROLES . VOLUNTEER_ADMIN ) ) {
1207+ if ( requestBody . AuthClaims . includes ( ROLES . SUPER_ADMIN ) || requestBody . AuthClaims . includes ( ROLES . SUPER_ADMIN_PLUS ) || requestBody . AuthClaims . includes ( ROLES . VOLUNTEER_ADMIN ) ) {
12081208 return sendForbidden ( res , 'CityAdmin cannot assign SuperAdmin or VolunteerAdmin roles' ) ;
12091209 }
12101210
@@ -1688,3 +1688,36 @@ export const locationLogosGetAuth = [
16881688 authenticate ,
16891689 requireLocationLogoByFiltersAccess
16901690] ;
1691+
1692+ /**
1693+ * Helper: handles access rules for SuperAdminPlus.
1694+ * - SuperAdminPlus: access for organisation removal
1695+ * Returns true if user has SuperAdminPlus role, otherwise false.
1696+ */
1697+ const handleSuperAdminPlusAccess = (
1698+ userAuthClaims : string [ ]
1699+ ) : boolean => userAuthClaims . includes ( ROLES . SUPER_ADMIN_PLUS ) ;
1700+
1701+ /**
1702+ * Middleware to require SuperAdminPlus role for organisation deletion
1703+ */
1704+ export const requireSuperAdminPlusAccess = ( req : Request , res : Response , next : NextFunction ) => {
1705+ if ( ensureAuthenticated ( req , res ) ) { return ; }
1706+
1707+ const userAuthClaims = req . user ?. AuthClaims || [ ] ;
1708+
1709+ // Only SuperAdminPlus can delete organisations
1710+ if ( handleSuperAdminPlusAccess ( userAuthClaims ) ) {
1711+ return next ( ) ;
1712+ }
1713+
1714+ return sendForbidden ( res , 'Only SuperAdminPlus role can perform this action' ) ;
1715+ } ;
1716+
1717+ /**
1718+ * Combined middleware for organisation deletion endpoint
1719+ */
1720+ export const organisationDeleteAuth = [
1721+ authenticate ,
1722+ requireSuperAdminPlusAccess
1723+ ] ;
0 commit comments