Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,19 @@ public List<VedtaksbrevValgEntitet> finnNyesteDeaktiverteVedtakbrevValg(Long beh
.setParameter("behandlingId", behandlingId);
return query.getResultList();
}

public Optional<VedtaksbrevValgEntitet> finnNyesteDeaktiverteVedtakbrevValg(Long behandlingId, DokumentMalType dokumentMalType) {
TypedQuery<VedtaksbrevValgEntitet> query = entityManager.createQuery(
"SELECT v FROM VedtaksbrevValgEntitet v WHERE " +
"v.behandlingId = :behandlingId " +
"AND v.aktiv = false " +
"AND v.dokumentMalType = :dokumentMalType " +
"AND v.opprettetTidspunkt = (" +
"SELECT MAX(v2.opprettetTidspunkt) FROM VedtaksbrevValgEntitet v2 WHERE v2.behandlingId = :behandlingId AND v2.aktiv = false AND v2.dokumentMalType = v.dokumentMalType" +
")", VedtaksbrevValgEntitet.class)
.setParameter("behandlingId", behandlingId)
.setParameter("dokumentMalType", dokumentMalType);
return HibernateVerktøy.hentUniktResultat(query);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;

/**
Expand All @@ -22,9 +21,14 @@ public class XhtmlBrevRenser {
.charset(StandardCharsets.UTF_8)
.prettyPrint(false);

private static final List<String> SAFE_TAGS = List.of("b", "em", "i", "strong", "u", "br", "li", "ol", "p", "ul", "h1", "h2", "h3", "a");
private static final Safelist SAFELIST = Safelist.none()
.addTags(
"b", "em", "i", "strong", "u", "br", "li", "ol", "p", "ul", "h1", "h2", "h3", "a"
)
.addAttributes("a", "href", "title")
.addProtocols("a", "href", "http", "https");


private static final Safelist SAFELIST = Safelist.none().addTags(SAFE_TAGS.toArray(new String[0]));

public static String rens(String input) {
Objects.requireNonNull(input, "Input må være satt");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,65 +8,72 @@

class XhtmlBrevRenserTest {

private final XhtmlBrevRenser sanitizer = new XhtmlBrevRenser();

@Test
void skal_gjøre_om_html_breakline_til_xhtml_breakline() {
assertThat(sanitizer.rens("<br>")).isEqualTo("<br />");
assertThat(rens("<br>")).isEqualTo("<br />");
}

@Test
void skal_avslutte_ulukkede_tagger() {
assertThat(sanitizer.rens("<p>")).isEqualTo("<p></p>");
assertThat(sanitizer.rens("</p>")).isEqualTo("<p></p>");
assertThat(sanitizer.rens("0<i>1</p>2</i>3<p>4"))
assertThat(rens("<p>")).isEqualTo("<p></p>");
assertThat(rens("</p>")).isEqualTo("<p></p>");
assertThat(rens("0<i>1</p>2</i>3<p>4"))
.isEqualToIgnoringWhitespace("0 <i>1 <p></p> 2</i> 3 <p>4</p>");
}

@Test
void skal_funke_med_spesialtegn() {
assertThat(sanitizer.rens("&")).isEqualTo("&amp;");
assertThat(sanitizer.rens("<")).isEqualTo("&lt;");
assertThat(sanitizer.rens(">")).isEqualTo("&gt;");
assertThat(sanitizer.rens("[")).isEqualTo("[");
assertThat(sanitizer.rens("]")).isEqualTo("]");
assertThat(sanitizer.rens("&amp;")).isEqualTo("&amp;");
assertThat(sanitizer.rens("&nbsp;")).isEqualTo("&#xa0;");
assertThat(sanitizer.rens(" ")).isEqualTo("&#xa0;");
assertThat(rens("&")).isEqualTo("&amp;");
assertThat(rens("<")).isEqualTo("&lt;");
assertThat(rens(">")).isEqualTo("&gt;");
assertThat(rens("[")).isEqualTo("[");
assertThat(rens("]")).isEqualTo("]");
assertThat(rens("&amp;")).isEqualTo("&amp;");
assertThat(rens("&nbsp;")).isEqualTo("&#xa0;");
assertThat(rens(" ")).isEqualTo("&#xa0;");

sanitizer.rens("!\"#¤%/()=?`§\\;:<>*€¨^ +-;,è");
rens("!\"#¤%/()=?`§\\;:<>*€¨^ +-;,è");
}

@ParameterizedTest
@ValueSource(strings = {"script", "style"})
void skal_fjerne_innhold_og_tagg_i_ikke_støttede_kjente_html_tagger(String tag) {
assertThat(sanitizer.rens("<" + tag + ">tekst inni en tagg</" + tag + ">")).isEqualTo("");
assertThat(sanitizer.rens("<" + tag + ">")).isEqualTo("");
assertThat(sanitizer.rens("</" + tag + ">")).isEqualTo("");
assertThat(rens("<" + tag + ">tekst inni en tagg</" + tag + ">")).isEqualTo("");
assertThat(rens("<" + tag + ">")).isEqualTo("");
assertThat(rens("</" + tag + ">")).isEqualTo("");
}

@Test
void skal_fjerne_tagg_men_beholde_innhold_i_ukjente_tagger() {
String text = "tekst inni en tagg";
assertThat(sanitizer.rens("<FINNESIKKE>" + text + "</FINNESIKKE>")).isEqualTo(text);
assertThat(sanitizer.rens("<![CDATA[" + text + "]]>")).isEqualTo(text);
assertThat(sanitizer.rens("<FINNESIKKE>")).isEqualTo("");
assertThat(sanitizer.rens("</FINNESIKKE>")).isEqualTo("");
assertThat(rens("<FINNESIKKE>" + text + "</FINNESIKKE>")).isEqualTo(text);
assertThat(rens("<![CDATA[" + text + "]]>")).isEqualTo(text);
assertThat(rens("<FINNESIKKE>")).isEqualTo("");
assertThat(rens("</FINNESIKKE>")).isEqualTo("");
}

@Test
void skal_fjerne_attributter_i_tagger() {
assertThat(sanitizer.rens("<h1 class='overskrift' onclick='stealCookies()'>overskrift</h1>"))
assertThat(rens("<h1 class='overskrift' onclick='stealCookies()'>overskrift</h1>"))
.isEqualTo("<h1>overskrift</h1>");
assertThat(sanitizer.rens("<a href=\"https://www.unsecure.com\">www.secure.com</a>"))
.isEqualTo("<a>www.secure.com</a>");
}


@Test
void skal_ikke_fjerne_href_og_title_attributter_for_lenker() {
assertThat(rens("<a href=\"https://www.secure.com\" title=\"tittel\" rel=\"noreferrer\">www.secure.com</a>"))
.isEqualTo("<a href=\"https://www.secure.com\" title=\"tittel\">www.secure.com</a>");
}

@ParameterizedTest
@ValueSource(strings = {"h1", "h2", "p"})
void skal_ikke_fjerne_støttede_tagger(String tag) {
String text = "tekst inni en tagg";
assertThat(sanitizer.rens("<" + tag + ">" + text + "</" + tag + ">"))
assertThat(rens("<" + tag + ">" + text + "</" + tag + ">"))
.isEqualTo("<" + tag + ">" + text + "</" + tag + ">");
}

private static String rens(String input) {
return XhtmlBrevRenser.rens(input);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package no.nav.ung.sak.formidling.vedtak;

import no.nav.ung.sak.kontrakt.formidling.vedtaksbrev.editor.VedtaksbrevSeksjon;
import no.nav.ung.sak.kontrakt.formidling.vedtaksbrev.editor.VedtaksbrevSeksjonType;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.safety.Safelist;
import org.jsoup.select.Elements;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class BrevXhtmlTilSeksjonKonverter {
private static final Safelist SAFELIST = Safelist.none()
.addTags(
"div",
"p",
"h1",
"h2",
"a",
"span",
"section",
"header",
"footer",
"style",
"table",
"tr",
"td"

)
.addAttributes(":all", "class", "id")
.addAttributes("div", "data-hidden", "data-editable")
.addAttributes("a", "href", "title")
.addAttributes("span", "class")
.addAttributes(":all", "style")
.addProtocols("a", "href", "http", "https");



public static List<VedtaksbrevSeksjon> konverter(String html) {
List<VedtaksbrevSeksjon> seksjoner = new ArrayList<>();

// Parse HTML med Jsoup
String clean = Jsoup.clean(html, "", SAFELIST);
Document doc = Jsoup.parse(clean);
doc.outputSettings(new Document.OutputSettings()
.syntax(Document.OutputSettings.Syntax.xml)
.charset(StandardCharsets.UTF_8)
.prettyPrint(false));

// Del 1: Style - Trekk ut style taggen
Element style = doc.selectFirst("style");
if (style == null) {
throw new IllegalArgumentException("Fant ingen styleelement");
}

seksjoner.add(new VedtaksbrevSeksjon(VedtaksbrevSeksjonType.STYLE, style.outerHtml()));

Element header = doc.selectFirst("header");
if (header == null) {
throw new IllegalArgumentException("Fant ingen headerelement");
}
header.select("#nav_logo_container").remove();
seksjoner.add(new VedtaksbrevSeksjon(VedtaksbrevSeksjonType.STATISK, header.outerHtml()));

Element editableDiv = doc.body().selectFirst("div[data-editable]");
if (editableDiv == null) {
throw new IllegalArgumentException("Fant ingen <div data-editable=...> element");
}
seksjoner.add(new VedtaksbrevSeksjon(VedtaksbrevSeksjonType.REDIGERBAR, editableDiv.html()));

Elements footer = editableDiv.nextElementSiblings();
seksjoner.add(new VedtaksbrevSeksjon(VedtaksbrevSeksjonType.STATISK, footer.outerHtml()));

return seksjoner;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package no.nav.ung.sak.formidling.vedtak;

import no.nav.ung.kodeverk.dokument.DokumentMalType;

public record VedtaksbrevForhåndsvisInput(
Long behandlingId,
DokumentMalType dokumentMalType,
Boolean redigertVersjon,
boolean htmlVersjon
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jakarta.inject.Inject;
import no.nav.fpsak.tidsserie.LocalDateTimeline;
import no.nav.ung.kodeverk.KodeverdiSomObjekt;
import no.nav.ung.kodeverk.dokument.DokumentMalType;
import no.nav.ung.sak.behandlingslager.behandling.repository.BehandlingRepository;
import no.nav.ung.sak.behandlingslager.formidling.VedtaksbrevValgEntitet;
import no.nav.ung.sak.behandlingslager.formidling.VedtaksbrevValgRepository;
Expand All @@ -14,10 +15,12 @@
import no.nav.ung.sak.formidling.vedtak.regler.Vedtaksbrev;
import no.nav.ung.sak.formidling.vedtak.regler.VedtaksbrevReglerUng;
import no.nav.ung.sak.formidling.vedtak.resultat.DetaljertResultat;
import no.nav.ung.sak.kontrakt.formidling.vedtaksbrev.VedtaksbrevForhåndsvisRequest;
import no.nav.ung.sak.kontrakt.formidling.vedtaksbrev.VedtaksbrevValg;
import no.nav.ung.sak.kontrakt.formidling.vedtaksbrev.VedtaksbrevValgRequest;
import no.nav.ung.sak.kontrakt.formidling.vedtaksbrev.VedtaksbrevValgResponse;
import no.nav.ung.sak.kontrakt.formidling.vedtaksbrev.editor.VedtaksbrevEditorResponse;
import no.nav.ung.sak.kontrakt.formidling.vedtaksbrev.editor.VedtaksbrevSeksjon;
import no.nav.ung.sak.kontrakt.formidling.vedtaksbrev.editor.VedtaksbrevSeksjonType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -96,7 +99,8 @@ private static VedtaksbrevValg mapVedtaksbrevValg(Vedtaksbrev resultat, Optional
!erAvsluttet && egenskaper.kanOverstyreRediger(),
resultat.forklaring(),
redigertBrevHtml,
tidligereRedigertTekst);
tidligereRedigertTekst,
redigertBrevHtml == null && deaktivertValg.isPresent());
}

private static VedtaksbrevValgResponse mapIngenBrevResponse(BehandlingVedtaksbrevResultat totalResultat) {
Expand All @@ -113,7 +117,8 @@ private static VedtaksbrevValgResponse mapIngenBrevResponse(BehandlingVedtaksbre
false,
it.forklaring(),
null,
null
null,
false
)).toList()
);
}
Expand Down Expand Up @@ -159,7 +164,7 @@ public VedtaksbrevValgEntitet lagreVedtaksbrev(VedtaksbrevValgRequest dto) {

}

public GenerertBrev forhåndsvis(VedtaksbrevForhåndsvisRequest dto) {
public GenerertBrev forhåndsvis(VedtaksbrevForhåndsvisInput dto) {
Long behandlingId = dto.behandlingId();
BehandlingVedtaksbrevResultat totalresultater = vedtaksbrevRegler.kjør(behandlingId);
validerHarBrev(totalresultater);
Expand Down Expand Up @@ -248,5 +253,35 @@ public void ryddVedTilbakeHopp(Long behandlingId) {


}

public VedtaksbrevEditorResponse editor(Long behandlingId, DokumentMalType dokumentMalType) {
GenerertBrev forhåndsvis = forhåndsvis(new VedtaksbrevForhåndsvisInput(
behandlingId,
dokumentMalType,
false,
true
));

List<VedtaksbrevSeksjon> original = BrevXhtmlTilSeksjonKonverter.konverter(forhåndsvis.dokument().html());
List<VedtaksbrevSeksjon> redigert = vedtaksbrevValgRepository.finnVedtakbrevValg(behandlingId, dokumentMalType)
.filter(VedtaksbrevValgEntitet::isRedigert)
.map(it -> erstattRedigerBar(original, it.getRedigertBrevHtml()))
.orElse(null);

List<VedtaksbrevSeksjon> tidligereRedigert = redigert == null ?
vedtaksbrevValgRepository.finnNyesteDeaktiverteVedtakbrevValg(behandlingId, dokumentMalType)
.map(it -> erstattRedigerBar(original, it.getRedigertBrevHtml()))
.orElse(null)
: null;

return new VedtaksbrevEditorResponse(original, redigert, tidligereRedigert);
}

private List<VedtaksbrevSeksjon> erstattRedigerBar(List<VedtaksbrevSeksjon> original, String redigertBrevHtml) {
return original.stream().map(it ->
it.type() == VedtaksbrevSeksjonType.REDIGERBAR ?
new VedtaksbrevSeksjon(VedtaksbrevSeksjonType.REDIGERBAR, redigertBrevHtml) : it)
.toList();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<p>Du finner mer informasjon på <a title="ungdomsprogrammet" href="https://nav.no/ungdomsprogrammet">nav.no/ungdomsprogrammet</a>.
</p>

<p>På <a href="https://nav.no/kontakt">nav.no/kontakt</a> kan du chatte eller skrive til oss. </p>
<p>På <a title="kontakt" href="https://nav.no/kontakt" >nav.no/kontakt</a> kan du chatte eller skrive til oss. </p>

<p>Hvis du ikke finner svar på nav.no kan du ringe oss på telefon 55 55 33 33, hverdager 09:00-15:00.</p>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
</p>

<p>
Du finner mer informasjon om utbetalingen hvis du <a href="https://www.nav.no/min-side">logger inn på Min
Du finner mer informasjon om utbetalingen hvis du <a href="https://www.nav.no/min-side" title="min side">logger inn på Min
side på nav.no</a>.
</p>

Expand Down
Loading