feat: vendor admin management and shared account settings #59
@@ -0,0 +1,114 @@
|
||||
package net.siegeln.cameleer.saas.account;
|
||||
|
||||
import net.siegeln.cameleer.saas.account.AccountService.*;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/account")
|
||||
public class AccountController {
|
||||
|
||||
private final AccountService accountService;
|
||||
|
||||
public AccountController(AccountService accountService) {
|
||||
this.accountService = accountService;
|
||||
}
|
||||
|
||||
// --- Profile ---
|
||||
|
||||
@GetMapping("/profile")
|
||||
public ProfileData getProfile(@AuthenticationPrincipal Jwt jwt) {
|
||||
return accountService.getProfile(jwt.getSubject());
|
||||
}
|
||||
|
||||
@PatchMapping("/profile")
|
||||
public ResponseEntity<Void> updateProfile(@AuthenticationPrincipal Jwt jwt,
|
||||
@RequestBody Map<String, String> body) {
|
||||
String name = body.get("name");
|
||||
accountService.updateDisplayName(jwt.getSubject(), name);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
// --- Password ---
|
||||
|
||||
record PasswordChangeRequest(String currentPassword, String newPassword) {}
|
||||
|
||||
@PostMapping("/password")
|
||||
public ResponseEntity<Void> changePassword(@AuthenticationPrincipal Jwt jwt,
|
||||
@RequestBody PasswordChangeRequest request) {
|
||||
accountService.changePassword(jwt.getSubject(), request.currentPassword(), request.newPassword());
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
// --- MFA ---
|
||||
|
||||
@GetMapping("/mfa/status")
|
||||
public MfaStatusData getMfaStatus(@AuthenticationPrincipal Jwt jwt) {
|
||||
return accountService.getMfaStatus(jwt.getSubject());
|
||||
}
|
||||
|
||||
@PostMapping("/mfa/totp/setup")
|
||||
public MfaSetupData setupTotp(@AuthenticationPrincipal Jwt jwt) {
|
||||
return accountService.setupTotp(jwt.getSubject());
|
||||
}
|
||||
|
||||
record TotpVerifyRequest(String secret, String code) {}
|
||||
|
||||
@PostMapping("/mfa/totp/verify")
|
||||
public Map<String, Boolean> verifyTotp(@AuthenticationPrincipal Jwt jwt,
|
||||
@RequestBody TotpVerifyRequest request) {
|
||||
boolean ok = accountService.verifyTotpCode(request.secret(), request.code());
|
||||
return Map.of("verified", ok);
|
||||
}
|
||||
|
||||
@PostMapping("/mfa/backup-codes")
|
||||
public BackupCodesData generateBackupCodes(@AuthenticationPrincipal Jwt jwt) {
|
||||
return accountService.generateBackupCodes(jwt.getSubject());
|
||||
}
|
||||
|
||||
@DeleteMapping("/mfa/totp")
|
||||
public ResponseEntity<Void> removeTotp(@AuthenticationPrincipal Jwt jwt) {
|
||||
accountService.removeMfa(jwt.getSubject());
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
// --- Passkeys ---
|
||||
|
||||
@GetMapping("/mfa/webauthn")
|
||||
public List<PasskeyCredential> listPasskeys(@AuthenticationPrincipal Jwt jwt) {
|
||||
return accountService.listPasskeys(jwt.getSubject());
|
||||
}
|
||||
|
||||
@PatchMapping("/mfa/webauthn/{id}/name")
|
||||
public ResponseEntity<Void> renamePasskey(@AuthenticationPrincipal Jwt jwt,
|
||||
@PathVariable String id,
|
||||
@RequestBody Map<String, String> body) {
|
||||
String name = body.get("name");
|
||||
if (name == null || name.isBlank()) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
accountService.renamePasskey(jwt.getSubject(), id, name.trim());
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@DeleteMapping("/mfa/webauthn/{id}")
|
||||
public ResponseEntity<Void> deletePasskey(@AuthenticationPrincipal Jwt jwt,
|
||||
@PathVariable String id) {
|
||||
accountService.deletePasskey(jwt.getSubject(), id);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
// --- MFA Preference ---
|
||||
|
||||
@PostMapping("/mfa/method-preference")
|
||||
public ResponseEntity<Void> setMfaPreference(@AuthenticationPrincipal Jwt jwt,
|
||||
@RequestBody Map<String, String> body) {
|
||||
accountService.setMfaMethodPreference(jwt.getSubject(), body.get("preference"));
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user