feat: vendor admin management and shared account settings #59
@@ -107,12 +107,8 @@ public class TenantPortalController {
|
||||
@PostMapping("/password")
|
||||
public ResponseEntity<Void> changeOwnPassword(@AuthenticationPrincipal Jwt jwt,
|
||||
@RequestBody PasswordChangeRequest body) {
|
||||
try {
|
||||
portalService.changePassword(jwt.getSubject(), body.password());
|
||||
return ResponseEntity.noContent().build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
portalService.changePassword(jwt.getSubject(), body.password());
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@PostMapping("/team/{userId}/password")
|
||||
@@ -203,23 +199,15 @@ public class TenantPortalController {
|
||||
if (name == null || name.isBlank()) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
try {
|
||||
portalService.renamePasskey(jwt.getSubject(), id, name);
|
||||
return ResponseEntity.noContent().build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
portalService.renamePasskey(jwt.getSubject(), id, name);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@DeleteMapping("/mfa/webauthn/{id}")
|
||||
public ResponseEntity<Void> deletePasskey(@AuthenticationPrincipal Jwt jwt,
|
||||
@PathVariable String id) {
|
||||
try {
|
||||
portalService.deletePasskey(jwt.getSubject(), id);
|
||||
return ResponseEntity.noContent().build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
portalService.deletePasskey(jwt.getSubject(), id);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@PostMapping("/mfa/method-preference")
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.siegeln.cameleer.saas.vendor;
|
||||
|
||||
import net.siegeln.cameleer.saas.account.AccountService;
|
||||
import net.siegeln.cameleer.saas.identity.LogtoManagementClient;
|
||||
import net.siegeln.cameleer.saas.notification.PasswordResetNotificationService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -20,13 +21,16 @@ public class VendorAdminService {
|
||||
private final LogtoManagementClient logtoClient;
|
||||
private final AccountService accountService;
|
||||
private final EmailConnectorService emailConnectorService;
|
||||
private final PasswordResetNotificationService passwordNotificationService;
|
||||
|
||||
public VendorAdminService(LogtoManagementClient logtoClient,
|
||||
AccountService accountService,
|
||||
EmailConnectorService emailConnectorService) {
|
||||
EmailConnectorService emailConnectorService,
|
||||
PasswordResetNotificationService passwordNotificationService) {
|
||||
this.logtoClient = logtoClient;
|
||||
this.accountService = accountService;
|
||||
this.emailConnectorService = emailConnectorService;
|
||||
this.passwordNotificationService = passwordNotificationService;
|
||||
}
|
||||
|
||||
// --- Records ---
|
||||
@@ -107,13 +111,36 @@ public class VendorAdminService {
|
||||
}
|
||||
|
||||
public void resetAdminPassword(String userId, String newPassword) {
|
||||
verifyIsVendorAdmin(userId);
|
||||
accountService.validatePassword(newPassword);
|
||||
logtoClient.updateUserPassword(userId, newPassword);
|
||||
log.info("Reset password for vendor admin {}", userId);
|
||||
|
||||
// Send notification email
|
||||
try {
|
||||
var user = logtoClient.getUser(userId);
|
||||
if (user != null) {
|
||||
String email = String.valueOf(user.getOrDefault("primaryEmail", ""));
|
||||
if (!email.isBlank()) {
|
||||
passwordNotificationService.sendNotification(email);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to send password reset notification: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void resetAdminMfa(String userId) {
|
||||
verifyIsVendorAdmin(userId);
|
||||
logtoClient.deleteAllMfaVerifications(userId);
|
||||
log.info("Reset MFA for vendor admin {}", userId);
|
||||
}
|
||||
|
||||
private void verifyIsVendorAdmin(String userId) {
|
||||
boolean isAdmin = listAdmins().stream()
|
||||
.anyMatch(a -> userId.equals(a.userId()));
|
||||
if (!isAdmin) {
|
||||
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User is not a platform administrator");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user