fix: code review findings — auth-settings HTTP method, authorization, redirect

- Change auth-settings endpoint from PUT to PATCH (matches partial update semantics and frontend hook)
- Add @PreAuthorize("SCOPE_tenant:manage") to updateAuthSettings endpoint
- Consolidate MFA/passkey 403 redirect handling in API client

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-27 09:01:23 +02:00
parent 60a800f757
commit 43a1058f33
2 changed files with 8 additions and 8 deletions

View File

@@ -5,6 +5,7 @@ import net.siegeln.cameleer.saas.certificate.TenantCaCertService;
import net.siegeln.cameleer.saas.config.TenantContext;
import net.siegeln.cameleer.saas.tenant.TenantService;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.web.bind.annotation.DeleteMapping;
@@ -239,7 +240,8 @@ public class TenantPortalController {
return ResponseEntity.ok(portalService.getAuthSettings());
}
@PutMapping("/auth-settings")
@PreAuthorize("hasAuthority('SCOPE_tenant:manage')")
@PatchMapping("/auth-settings")
public ResponseEntity<Void> updateAuthSettings(@RequestBody Map<String, Object> updates) {
portalService.updateTenantSettings(updates);
return ResponseEntity.ok().build();

View File

@@ -65,13 +65,11 @@ async function apiFetch<T>(path: string, options: RequestInit = {}): Promise<T>
if (response.status === 403) {
const errorHeader = response.headers.get('X-Cameleer-Error');
if (errorHeader === 'APP_MFA_REQUIRED') {
window.location.href = '/platform/tenant/settings?mfa=required';
throw new ApiError(403, '{"message":"MFA enrollment required"}');
}
if (errorHeader === 'APP_PASSKEY_REQUIRED') {
window.location.href = '/platform/tenant/settings?passkey=required';
throw new ApiError(403, '{"message":"Passkey enrollment required"}');
if (errorHeader === 'APP_MFA_REQUIRED' || errorHeader === 'APP_PASSKEY_REQUIRED') {
const param = errorHeader === 'APP_PASSKEY_REQUIRED' ? 'passkey=required' : 'mfa=required';
window.location.href = `/platform/tenant/settings?${param}`;
const msg = errorHeader === 'APP_PASSKEY_REQUIRED' ? 'Passkey enrollment required' : 'MFA enrollment required';
throw new ApiError(403, JSON.stringify({ message: msg }));
}
}