/*
 * This file is part of the TYPO3 CMS project.
 *
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 *
 * The TYPO3 project - inspiring people to share!
 */
import{property as m,state as h,customElement as v}from"lit/decorators.js";import{LitElement as $,html as o,nothing as n}from"lit";import{classMap as R}from"lit/directives/class-map.js";import p from"@typo3/core/ajax/ajax-request.js";import y from"@typo3/core/event/regular-event.js";import{lll as i}from"@typo3/core/lit-helper.js";var a=function(r,e,t,l){var s=arguments.length,c=s<3?e:l===null?l=Object.getOwnPropertyDescriptor(e,t):l,u;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")c=Reflect.decorate(r,e,t,l);else for(var b=r.length-1;b>=0;b--)(u=r[b])&&(c=(s<3?u(c):s>3?u(e,t,c):u(e,t))||c);return s>3&&c&&Object.defineProperty(e,t,c),c},f;(function(r){r.fixable="fixable",r.irrelevant="irrelevant",r.suspicious="suspicious"})(f||(f={}));let d=class extends ${constructor(){super(...arguments),this.selectedScope=null,this.reports=[],this.selectedReport=null,this.suggestions=[],this.previouslyFocusedRow=null}connectedCallback(){super.connectedCallback(),this.fetchReports(),this.peripheralEvent=new y("click",(e,t)=>{t.dataset.cspReportsHandler==="refresh"&&(e.preventDefault(),this.fetchReports())}),this.peripheralEvent.delegateTo(document,"[data-csp-reports-handler]")}disconnectedCallback(){super.disconnectedCallback(),this.peripheralEvent?.release()}updated(e){super.updated(e),e.has("selectedReport")&&this.selectedReport!==null&&this.updateComplete.then(()=>{this.querySelector("#report-details")?.focus()})}createRenderRoot(){return this}render(){return o`<div class="infolist-container infolist-overlay"><div class=infolist><div class=infolist-header>${this.renderNavigation()}</div></div></div><div class=infolist-container><div class=infolist><div class=infolist-content><div class="table-fit mb-0"><table class="table table-striped"><thead><tr><th>${i("label.created")||"Created"}</th><th>${i("label.scope")||"Scope"}</th><th>${i("label.violation")||"Violation"}</th><th>${i("label.uri")||"URI"}</th><th></th></tr></thead><tbody>${this.reports.length===0?o`<tr><td colspan=5>${i("label.label.noEntriesAvailable")||"No entries available."}</td></tr>`:n} ${this.reports.map(e=>o`<tr class=${R({"table-info":this.selectedReport===e})} data-mutation-group=${e.mutationHashes.join("-")} @click=${()=>this.selectReport(e)} @keydown=${t=>this.handleReportKeydown(t,e)} tabindex=0 role=button aria-label=${i("label.showDetails",e.details.effectiveDirective,e.details.blockedUri)||"Show details"}><td>${e.created}</td><td>${e.scope}</td><td><span class="badge badge-warning">${e.count}</span> ${e.details.effectiveDirective}</td><td>${this.shortenUri(e.details.blockedUri)}</td><td>${e.attributes.join(", ")}</td></tr>`)}</tbody></table></div></div><div class=infolist-info${this.selectedReport?" infolist-info-showrecord":""}>${this.renderGuide()} ${this.renderSelectedReport()}</div></div></div>`}renderNavigation(){return o`<div class=btn-toolbar><button type=button class="btn btn-default dropdown-toggle" data-bs-toggle=dropdown aria-expanded=false title=${i("label.scope")||"Scope"}>${this.selectedScope===null?i("label.all")||"ALL":this.selectedScope}</button><ul class=dropdown-menu><button class="dropdown-item dropdown-item-spaced" title=${i("label.all")||"ALL"} @click=${()=>this.selectScope(null)}><span class=${this.selectedScope===null?"text-primary":""}> <typo3-backend-icon identifier=${this.selectedScope===null?"actions-dot":"empty-empty"} size=small></typo3-backend-icon> </span>${i("label.all")||"ALL"}</button> ${this.scopes.map(e=>o`<li><button class="dropdown-item dropdown-item-spaced" title=${e} @click=${()=>this.selectScope(e)}><span class=${e===this.selectedScope?"text-primary":""}> <typo3-backend-icon identifier=${e===this.selectedScope?"actions-dot":"empty-empty"} size=small></typo3-backend-icon> </span>${e}</button></li>`)}</ul><button type=button class="btn btn-danger" title=${i("label.removeAll")||"Remove all"} @click=${()=>this.invokeDeleteReportsAction()}>${i("label.removeAll")||"Remove all"} ${this.selectedScope!==null?o`"${this.selectedScope}"`:n}</button></div>`}renderGuide(){return o`${this.selectedReport?n:o`<div class=infolist-info-norecord><div class="card mb-0"><div class=card-body><p>${i("label.guide.no_record_selected")||"Select a row to see more information."}</p></div></div></div>`}`}renderSelectedReport(){const e=this.selectedReport;return o`${e?o`<div class=infolist-info-record><div class="card mb-0" tabindex=-1 id=report-details @keydown=${t=>this.handleDetailsKeydown(t)}><div class=card-header><h3>${i("label.details")||"Details"}</h3></div><div class=card-body><dl><dt>${i("label.directive")||"Directive"} / ${i("label.disposition")||"Disposition"}</dt><dd>${e.details.effectiveDirective} / ${e.details.disposition}</dd><dt>${i("label.document_uri")||"Document URI"}</dt><dd>${e.details.documentUri} ${this.renderCodeLocation(e)}</dd>${e.details.sourceFile&&e.details.sourceFile!==e.details.documentUri?o`<dt>${i("label.source_file")||"Source File"}</dt><dd>${e.details.sourceFile}</dd>`:n}<dt>${i("label.blocked_uri")||"Blocked URI"}</dt><dd>${e.details.blockedUri}</dd>${e.details.scriptSample?o`<dt>${i("label.sample")||"Sample"}</dt><dd><code>${e.details.scriptSample}</code></dd>`:n} ${e.meta.agent?o`<dt>${i("label.user_agent")||"User Agent"}</dt><dd><code>${e.meta.agent}</code></dd>`:n}<dt>${i("label.uuid")||"UUID"}</dt><dd><code>${e.uuid}</code></dd><dt>${i("label.summary")||"Summary"}</dt><dd><code>${e.summary}</code></dd></dl></div>${this.suggestions.length>0?o`<div class=card-header><h3>${i("label.suggestions")||"Suggestions"}</h3></div>`:n} ${this.suggestions.map(t=>o`<div class=card-body><h4>${t.label||t.identifier}</h4>${t.collection.mutations.map(l=>o`<p><i>${l.mode}</i> <code>${l.directive}: ${l.sources.join(" ")}</code></p>`)} <button class="btn btn-primary" @click=${()=>this.invokeMutateReportAction(e,t)}><typo3-backend-icon identifier=actions-check size=small></typo3-backend-icon>${i("button.apply")||"Apply"}</button></div>`)}<div class=card-footer><button class="btn btn-default" @click=${()=>this.selectReport(null)}><typo3-backend-icon identifier=actions-close size=small></typo3-backend-icon>${i("button.close")||"Close"}</button> <button class="btn btn-default" @click=${()=>this.invokeMuteReportAction(e)}><typo3-backend-icon identifier=actions-ban size=small></typo3-backend-icon>${i("button.mute")||"Mute"}</button> <button class="btn btn-default" @click=${()=>this.invokeDeleteReportAction(e)}><typo3-backend-icon identifier=actions-delete size=small></typo3-backend-icon>${i("button.delete")||"Delete"}</button></div></div></div>`:n}`}renderCodeLocation(e){if(!e.details.lineNumber)return n;const t=[e.details.lineNumber];return e.details.columnNumber&&t.push(e.details.columnNumber),o`(${t.join(":")})`}selectReport(e){this.suggestions=[],e!==null&&this.selectedReport!==e?(this.previouslyFocusedRow=document.activeElement,this.selectedReport=e,this.invokeHandleReportAction(e).then(t=>this.suggestions=t)):(this.selectedReport=null,this.previouslyFocusedRow&&this.updateComplete.then(()=>{this.previouslyFocusedRow?.focus(),this.previouslyFocusedRow=null}))}handleReportKeydown(e,t){if(e.key==="Enter"||e.key==="Space"||e.key===" "){e.preventDefault(),this.selectReport(t);return}const l=e.currentTarget;let s=null;switch(e.key){case"ArrowDown":e.preventDefault(),s=l.nextElementSibling;break;case"ArrowUp":e.preventDefault(),s=l.previousElementSibling;break;case"Home":e.preventDefault(),s=l.parentElement?.firstElementChild;break;case"End":e.preventDefault(),s=l.parentElement?.lastElementChild;break;default:return}s&&s.hasAttribute("tabindex")&&s.focus()}handleDetailsKeydown(e){e.key==="Escape"&&(e.preventDefault(),this.selectReport(null))}focusFirstReportRow(){this.updateComplete.then(()=>{this.querySelector('tbody tr[tabindex="0"]')?.focus()})}selectScope(e){this.selectedScope=e,this.fetchReports()}fetchReports(){this.invokeFetchReportsAction().then(e=>this.reports=e)}filterReports(...e){e.includes(this.selectedReport?.uuid)&&(this.selectedReport=null),this.reports=this.reports.filter(t=>!e.includes(t.uuid))}invokeFetchReportsAction(){return new p(this.controlUri).post({action:"fetchReports",scope:this.selectedScope||""}).then(e=>e.resolve("application/json"))}invokeHandleReportAction(e){return new p(this.controlUri).post({action:"handleReport",uuid:e.uuid}).then(t=>t.resolve("application/json"))}invokeMutateReportAction(e,t){const l=this.reports.filter(s=>s.mutationHashes.includes(t.hash)).map(s=>s.summary);return new p(this.controlUri).post({action:"mutateReport",scope:e.scope,hmac:t.hmac,suggestion:t,summaries:l}).then(s=>s.resolve("application/json")).then(s=>this.filterReports(...s.uuids))}invokeMuteReportAction(e){new p(this.controlUri).post({action:"muteReport",summaries:[e.summary]}).then(t=>t.resolve("application/json")).then(t=>this.filterReports(...t.uuids)).then(()=>this.focusFirstReportRow())}invokeDeleteReportAction(e){new p(this.controlUri).post({action:"deleteReport",summaries:[e.summary]}).then(t=>t.resolve("application/json")).then(t=>this.filterReports(...t.uuids)).then(()=>this.focusFirstReportRow())}invokeDeleteReportsAction(){new p(this.controlUri).post({action:"deleteReports",scope:this.selectedScope||""}).then(e=>e.resolve("application/json")).then(()=>this.fetchReports()).then(()=>this.selectReport(null))}shortenUri(e){if(e==="inline")return e;try{return new URL(e).hostname}catch{return e}}};a([m({type:Array})],d.prototype,"scopes",void 0),a([m({type:String})],d.prototype,"controlUri",void 0),a([h()],d.prototype,"selectedScope",void 0),a([h()],d.prototype,"reports",void 0),a([h()],d.prototype,"selectedReport",void 0),a([h()],d.prototype,"suggestions",void 0),d=a([v("typo3-backend-security-csp-reports")],d);export{d as CspReports};
