package jnpf.audit.sdk.aspect; import jnpf.util.JsonUtil; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.List; import java.util.Map; /** Resolves the display-only audit title supplied by the scoped online form request wrapper. */ final class AuditRequestTitleResolver { static final String HEADER_NAME = "X-Audit-Display-Fields"; private static final int MAX_HEADER_LENGTH = 8192; private static final int MAX_FIELDS = 50; private static final int MAX_TITLE_LENGTH = 400; private AuditRequestTitleResolver() { } static String resolveCurrentRequest() { RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); if (!(attributes instanceof ServletRequestAttributes)) { return null; } String encoded = ((ServletRequestAttributes) attributes).getRequest().getHeader(HEADER_NAME); return resolveEncoded(encoded); } static String resolveEncoded(String encoded) { if (encoded == null || encoded.isEmpty() || encoded.length() > MAX_HEADER_LENGTH) { return null; } try { String json = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8); List fields = JsonUtil.getJsonToList(json, Map.class); StringBuilder title = new StringBuilder(); int count = 0; for (Map field : fields) { if (field == null || count++ >= MAX_FIELDS) { break; } String value = clean(field.get("displayValue")); if (value.isEmpty()) { continue; } int separatorLength = title.length() > 0 ? 1 : 0; int remaining = MAX_TITLE_LENGTH - title.length() - separatorLength; if (remaining <= 0) { break; } if (separatorLength > 0) { title.append('/'); } title.append(value, 0, Math.min(value.length(), remaining)); } return title.length() == 0 ? null : title.toString(); } catch (Throwable ignored) { return null; } } private static String clean(Object value) { if (value == null) { return ""; } return String.valueOf(value).replace('\r', ' ').replace('\n', ' ').trim(); } }