@@ -82,12 +82,12 @@ export const LoginButton: FC<{ text?: string }> = ({ text }) => {
8282export const LoginLink : FC < {
8383 text ?: string ;
8484 color ?:
85- | "primary"
86- | "foreground"
87- | "secondary"
88- | "success"
89- | "warning"
90- | "danger" ;
85+ | "primary"
86+ | "foreground"
87+ | "secondary"
88+ | "success"
89+ | "warning"
90+ | "danger" ;
9191} > = ( { text, color } ) => {
9292 const { isAuthenticated, loginWithRedirect } = useAuth0 ( ) ;
9393 const { t } = useTranslation ( ) ;
@@ -185,12 +185,12 @@ interface LogoutLinkProps extends LogoutButtonProps {
185185 * Button color
186186 */
187187 color ?:
188- | "primary"
189- | "foreground"
190- | "secondary"
191- | "success"
192- | "warning"
193- | "danger" ;
188+ | "primary"
189+ | "foreground"
190+ | "secondary"
191+ | "success"
192+ | "warning"
193+ | "danger" ;
194194}
195195/**
196196 * Renders a logout link for Auth0 authentication.
@@ -572,6 +572,209 @@ export const useSecuredApi = () => {
572572 postJson,
573573 deleteJson,
574574 hasPermission,
575+ // Auth0 Management helpers
576+ getAuth0ManagementToken : async ( ) => {
577+ try {
578+ const tokenResp = await postJson (
579+ `${ import . meta. env . API_BASE_URL } /__auth0/token` ,
580+ { } ,
581+ ) ;
582+ return tokenResp ;
583+ } catch ( error ) {
584+ console . error ( "Failed to get Auth0 management token:" , error ) ;
585+ throw error ;
586+ }
587+ } ,
588+ listAuth0Users : async ( managementToken : string ) => {
589+ try {
590+ const resp = await fetch (
591+ `https://${ import . meta. env . AUTH0_DOMAIN } /api/v2/users?per_page=100` ,
592+ {
593+ method : "GET" ,
594+ headers : {
595+ Authorization : `Bearer ${ managementToken } ` ,
596+ "Content-Type" : "application/json" ,
597+ } ,
598+ } ,
599+ ) ;
600+ return await resp . json ( ) ;
601+ } catch ( error ) {
602+ console . error ( "Failed to list Auth0 users:" , error ) ;
603+ throw error ;
604+ }
605+ } ,
606+ listAuth0Roles : async ( managementToken : string ) => {
607+ try {
608+ const resp = await fetch ( `https://${ import . meta. env . AUTH0_DOMAIN } /api/v2/roles` , {
609+ method : "GET" ,
610+ headers : {
611+ Authorization : `Bearer ${ managementToken } ` ,
612+ "Content-Type" : "application/json" ,
613+ } ,
614+ } ) ;
615+ return await resp . json ( ) ;
616+ } catch ( error ) {
617+ console . error ( "Failed to list Auth0 roles:" , error ) ;
618+ throw error ;
619+ }
620+ } ,
621+ getUserRoles : async ( managementToken : string , userId : string ) => {
622+ try {
623+ const resp = await fetch (
624+ `https://${ import . meta. env . AUTH0_DOMAIN } /api/v2/users/${ encodeURIComponent ( userId ) } /roles` ,
625+ {
626+ method : "GET" ,
627+ headers : {
628+ Authorization : `Bearer ${ managementToken } ` ,
629+ "Content-Type" : "application/json" ,
630+ } ,
631+ } ,
632+ ) ;
633+ return await resp . json ( ) ;
634+ } catch ( error ) {
635+ console . error ( "Failed to get user roles:" , error ) ;
636+ throw error ;
637+ }
638+ } ,
639+ addUserToRole : async ( managementToken : string , roleId : string , userId : string ) => {
640+ try {
641+ const resp = await fetch (
642+ `https://${ import . meta. env . AUTH0_DOMAIN } /api/v2/roles/${ encodeURIComponent ( roleId ) } /users` ,
643+ {
644+ method : "POST" ,
645+ headers : {
646+ Authorization : `Bearer ${ managementToken } ` ,
647+ "Content-Type" : "application/json" ,
648+ } ,
649+ body : JSON . stringify ( { users : [ userId ] } ) ,
650+ } ,
651+ ) ;
652+ return await resp . json ( ) ;
653+ } catch ( error ) {
654+ console . error ( "Failed to add user to role:" , error ) ;
655+ throw error ;
656+ }
657+ } ,
658+ removeUserFromRole : async ( managementToken : string , roleId : string , userId : string ) => {
659+ try {
660+ const resp = await fetch (
661+ `https://${ import . meta. env . AUTH0_DOMAIN } /api/v2/roles/${ encodeURIComponent ( roleId ) } /users` ,
662+ {
663+ method : "DELETE" ,
664+ headers : {
665+ Authorization : `Bearer ${ managementToken } ` ,
666+ "Content-Type" : "application/json" ,
667+ } ,
668+ body : JSON . stringify ( { users : [ userId ] } ) ,
669+ } ,
670+ ) ;
671+ return await resp . json ( ) ;
672+ } catch ( error ) {
673+ console . error ( "Failed to remove user from role:" , error ) ;
674+ throw error ;
675+ }
676+ } ,
677+ patchAuth0User : async ( managementToken : string , userId : string , body : any ) => {
678+ try {
679+ const resp = await fetch ( `https://${ import . meta. env . AUTH0_DOMAIN } /api/v2/users/${ encodeURIComponent ( userId ) } ` , {
680+ method : "PATCH" ,
681+ headers : {
682+ Authorization : `Bearer ${ managementToken } ` ,
683+ "Content-Type" : "application/json" ,
684+ } ,
685+ body : JSON . stringify ( body ) ,
686+ } ) ;
687+ return await resp . json ( ) ;
688+ } catch ( error ) {
689+ console . error ( "Failed to patch Auth0 user:" , error ) ;
690+ throw error ;
691+ }
692+ } ,
693+ deleteAuth0User : async ( managementToken : string , userId : string ) => {
694+ try {
695+ const resp = await fetch ( `https://${ import . meta. env . AUTH0_DOMAIN } /api/v2/users/${ encodeURIComponent ( userId ) } ` , {
696+ method : "DELETE" ,
697+ headers : {
698+ Authorization : `Bearer ${ managementToken } ` ,
699+ "Content-Type" : "application/json" ,
700+ } ,
701+ } ) ;
702+ return await resp . json ( ) ;
703+ } catch ( error ) {
704+ console . error ( "Failed to delete Auth0 user:" , error ) ;
705+ throw error ;
706+ }
707+ } ,
708+ getUserPermissions : async ( managementToken : string , userId : string ) => {
709+ try {
710+ const resp = await fetch (
711+ `https://${ import . meta. env . AUTH0_DOMAIN } /api/v2/users/${ encodeURIComponent ( userId ) } /permissions` ,
712+ {
713+ method : "GET" ,
714+ headers : {
715+ Authorization : `Bearer ${ managementToken } ` ,
716+ "Content-Type" : "application/json" ,
717+ } ,
718+ } ,
719+ ) ;
720+ return await resp . json ( ) ;
721+ } catch ( error ) {
722+ console . error ( "Failed to get user permissions:" , error ) ;
723+ throw error ;
724+ }
725+ } ,
726+ addPermissionToUser : async ( managementToken : string , userId : string , permissionName : string ) => {
727+ try {
728+ const resp = await fetch (
729+ `https://${ import . meta. env . AUTH0_DOMAIN } /api/v2/users/${ encodeURIComponent ( userId ) } /permissions` ,
730+ {
731+ method : "POST" ,
732+ headers : {
733+ Authorization : `Bearer ${ managementToken } ` ,
734+ "Content-Type" : "application/json" ,
735+ } ,
736+ body : JSON . stringify ( {
737+ permissions : [
738+ {
739+ resource_server_identifier : import . meta. env . AUTH0_AUDIENCE ,
740+ permission_name : permissionName ,
741+ } ,
742+ ] ,
743+ } ) ,
744+ } ,
745+ ) ;
746+ return await resp . json ( ) ;
747+ } catch ( error ) {
748+ console . error ( "Failed to add permission to user:" , error ) ;
749+ throw error ;
750+ }
751+ } ,
752+ removePermissionFromUser : async ( managementToken : string , userId : string , permissionName : string ) => {
753+ try {
754+ const resp = await fetch (
755+ `https://${ import . meta. env . AUTH0_DOMAIN } /api/v2/users/${ encodeURIComponent ( userId ) } /permissions` ,
756+ {
757+ method : "DELETE" ,
758+ headers : {
759+ Authorization : `Bearer ${ managementToken } ` ,
760+ "Content-Type" : "application/json" ,
761+ } ,
762+ body : JSON . stringify ( {
763+ permissions : [
764+ {
765+ resource_server_identifier : import . meta. env . AUTH0_AUDIENCE ,
766+ permission_name : permissionName ,
767+ } ,
768+ ] ,
769+ } ) ,
770+ } ,
771+ ) ;
772+ return await resp . json ( ) ;
773+ } catch ( error ) {
774+ console . error ( "Failed to remove permission from user:" , error ) ;
775+ throw error ;
776+ }
777+ } ,
575778 } ;
576779} ;
577780
0 commit comments