1+ using Microsoft . AspNetCore . Antiforgery ;
12using Microsoft . AspNetCore . Components ;
23using Microsoft . AspNetCore . Identity ;
34using Microsoft . AspNetCore . Mvc ;
45using Microsoft . Extensions . Options ;
6+ using Passwordless . AdminConsole . Authorization ;
57using Passwordless . AdminConsole . Billing . Configuration ;
68using Passwordless . AdminConsole . Identity ;
79using Passwordless . AdminConsole . Services ;
810using Passwordless . AdminConsole . Services . MagicLinks ;
11+ using Passwordless . AdminConsole . Services . PasswordlessManagement ;
12+ using Passwordless . Common . Models . Authenticators ;
913using Stripe ;
1014using Stripe . Checkout ;
1115using static Microsoft . AspNetCore . Http . Results ;
@@ -17,6 +21,8 @@ public static class ComplimentaryEndpoints
1721 public static void MapComplimentaryEndpoints ( this IEndpointRouteBuilder builder )
1822 {
1923 builder . MapGet ( "/Account/Magic" , AccountMagicEndpoint ) ;
24+ builder . MapPost ( "/app/{appId}/settings/authenticators/manage/api" , ManageAuthenticatorAsync )
25+ . RequireAuthorization ( CustomPolicy . HasAppRole ) ;
2026 }
2127
2228 /// <summary>
@@ -48,4 +54,47 @@ public static async Task<IResult> AccountMagicEndpoint(
4854 // Only allow the url to be a relative url, to prevent open redirect attacks
4955 return LocalRedirect ( returnUrl ) ;
5056 }
57+
58+ public static async Task < IResult > ManageAuthenticatorAsync (
59+ [ FromRoute ] string appId ,
60+ [ FromForm ] AuthenticatorManagementRequest request ,
61+ [ FromServices ] IScopedPasswordlessClient passwordlessClient ,
62+ HttpContext context )
63+ {
64+ try
65+ {
66+ switch ( request . Action ? . ToLowerInvariant ( ) )
67+ {
68+ case "add" :
69+ {
70+ var addRequest = new AddAuthenticatorsRequest ( request . Selected , true ) ;
71+ await passwordlessClient . AddAuthenticatorsAsync ( addRequest ) ;
72+ break ;
73+ }
74+ case "remove" :
75+ {
76+ var removeRequest = new RemoveAuthenticatorsRequest ( request . Selected ) ;
77+ await passwordlessClient . RemoveAuthenticatorsAsync ( removeRequest ) ;
78+ break ;
79+ }
80+ default :
81+ return BadRequest ( new { error = "Invalid action. Must be 'add' or 'remove'." } ) ;
82+ }
83+
84+ return Ok ( new { success = true } ) ;
85+ }
86+ catch ( Exception ex )
87+ {
88+ return Problem (
89+ title : "Error managing authenticator" ,
90+ detail : ex . Message ,
91+ statusCode : 500 ) ;
92+ }
93+ }
94+
95+ public class AuthenticatorManagementRequest
96+ {
97+ public Guid [ ] Selected { get ; set ; } = Array . Empty < Guid > ( ) ;
98+ public string ? Action { get ; set ; }
99+ }
51100}
0 commit comments