]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Security: remove safe html pipe
authorshamoon <4887959+shamoon@users.noreply.github.com>
Thu, 18 Dec 2025 14:31:25 +0000 (06:31 -0800)
committershamoon <4887959+shamoon@users.noreply.github.com>
Thu, 18 Dec 2025 14:31:25 +0000 (06:31 -0800)
33 files changed:
src-ui/src/app/components/admin/settings/settings.component.spec.ts
src-ui/src/app/components/admin/trash/trash.component.spec.ts
src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html
src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.spec.ts
src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts
src-ui/src/app/components/common/confirm-dialog/rotate-confirm-dialog/rotate-confirm-dialog.component.html
src-ui/src/app/components/common/confirm-dialog/rotate-confirm-dialog/rotate-confirm-dialog.component.spec.ts
src-ui/src/app/components/common/confirm-dialog/rotate-confirm-dialog/rotate-confirm-dialog.component.ts
src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.spec.ts
src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.spec.ts
src-ui/src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.spec.ts
src-ui/src/app/components/common/input/entries/entries.component.html
src-ui/src/app/components/common/input/file/file.component.html
src-ui/src/app/components/common/input/password/password.component.html
src-ui/src/app/components/common/input/text/text.component.html
src-ui/src/app/components/common/input/text/text.component.ts
src-ui/src/app/components/common/input/textarea/textarea.component.html
src-ui/src/app/components/common/input/textarea/textarea.component.ts
src-ui/src/app/components/common/input/url/url.component.html
src-ui/src/app/components/common/permissions-dialog/permissions-dialog.component.spec.ts
src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html
src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts
src-ui/src/app/components/document-list/document-list.component.spec.ts
src-ui/src/app/components/manage/mail/mail.component.spec.ts
src-ui/src/app/components/manage/management-list/management-list.component.html
src-ui/src/app/components/manage/management-list/management-list.component.spec.ts
src-ui/src/app/components/manage/management-list/management-list.component.ts
src-ui/src/app/components/manage/storage-path-list/storage-path-list.component.spec.ts
src-ui/src/app/components/manage/storage-path-list/storage-path-list.component.ts
src-ui/src/app/components/manage/tag-list/tag-list.component.spec.ts
src-ui/src/app/components/manage/tag-list/tag-list.component.ts
src-ui/src/app/pipes/safehtml.pipe.spec.ts [deleted file]
src-ui/src/app/pipes/safehtml.pipe.ts [deleted file]

index 300067d1b95cd2bcc460fb6f4eafcdbffc0fa6a5..cc5c9664075e554752b1876b7820e602557596b3 100644 (file)
@@ -28,7 +28,6 @@ import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
 import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
 import { PermissionsGuard } from 'src/app/guards/permissions.guard'
 import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { PermissionsService } from 'src/app/services/permissions.service'
 import { GroupService } from 'src/app/services/rest/group.service'
 import { SavedViewService } from 'src/app/services/rest/saved-view.service'
@@ -129,7 +128,6 @@ describe('SettingsComponent', () => {
         ConfirmDialogComponent,
         CheckComponent,
         ColorComponent,
-        SafeHtmlPipe,
         SelectComponent,
         TextComponent,
         NumberComponent,
index aa5a8af0f603134b928c94183032c5f204cdf3ce..215b0b253d405bd57f40f2dc5990c45099ea8879 100644 (file)
@@ -11,7 +11,6 @@ import {
 } from '@ng-bootstrap/ng-bootstrap'
 import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
 import { of, throwError } from 'rxjs'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { ToastService } from 'src/app/services/toast.service'
 import { TrashService } from 'src/app/services/trash.service'
 import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
@@ -53,7 +52,6 @@ describe('TrashComponent', () => {
         TrashComponent,
         PageHeaderComponent,
         ConfirmDialogComponent,
-        SafeHtmlPipe,
       ],
     }).compileComponents()
 
index e25ace61219aa12aa674a3d6c894c4ab2b15bdb9..deee54402c229486c1651911bd5d97a791c21081 100644 (file)
@@ -8,7 +8,7 @@
     <p><b>{{messageBold}}</b></p>
   }
   @if (message) {
-    <p class="mb-0" [innerHTML]="message | safeHtml"></p>
+    <p class="mb-0" [innerHTML]="message"></p>
   }
 </div>
 <div class="modal-footer">
index e0cbd9113906e4a84375fa1a6a44e7c8602f2f61..8a2777c1378b53de600ec181e9930eaf6fb29f73 100644 (file)
@@ -1,7 +1,6 @@
 import { ComponentFixture, TestBed } from '@angular/core/testing'
 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
 import { Subject } from 'rxjs'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { ConfirmDialogComponent } from './confirm-dialog.component'
 
 describe('ConfirmDialogComponent', () => {
@@ -11,8 +10,8 @@ describe('ConfirmDialogComponent', () => {
 
   beforeEach(async () => {
     TestBed.configureTestingModule({
-      providers: [NgbActiveModal, SafeHtmlPipe],
-      imports: [ConfirmDialogComponent, SafeHtmlPipe],
+      providers: [NgbActiveModal],
+      imports: [ConfirmDialogComponent],
     }).compileComponents()
 
     modal = TestBed.inject(NgbActiveModal)
index 191954742e64c51e9e9f704eb142e233652de417..7ef9ccce067490ccd0c34bc46b76b8eabc020018 100644 (file)
@@ -2,14 +2,13 @@ import { DecimalPipe } from '@angular/common'
 import { Component, EventEmitter, Input, Output, inject } from '@angular/core'
 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
 import { Subject } from 'rxjs'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 @Component({
   selector: 'pngx-confirm-dialog',
   templateUrl: './confirm-dialog.component.html',
   styleUrls: ['./confirm-dialog.component.scss'],
-  imports: [DecimalPipe, SafeHtmlPipe],
+  imports: [DecimalPipe],
 })
 export class ConfirmDialogComponent extends LoadingComponentWithPermissions {
   activeModal = inject(NgbActiveModal)
index e996ecb44b74b1cf255a4a8f1f0904e18d360b73..ebd5b1fa83f3c58503e6160bad1668130f399bc3 100644 (file)
 <div class="modal-footer flex-nowrap">
     <div class="col">
         @if (message) {
-            <p [innerHTML]="message | safeHtml"></p>
+            <p>{{message}}</p>
         }
         @if (messageBold) {
-          <p class="mb-0 small"><b [innerHTML]="messageBold | safeHtml"></b></p>
+          <p class="mb-0 small"><b>{{messageBold}}</b></p>
         }
     </div>
     <button type="button" class="btn" [class]="cancelBtnClass" (click)="cancel()" [disabled]="!buttonsEnabled">
index df5819ac73cca53ea5c22857a227af243b09538e..f33f2638c715d02d10b23cccc7963c85ef0dadfd 100644 (file)
@@ -3,7 +3,6 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'
 import { ComponentFixture, TestBed } from '@angular/core/testing'
 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
 import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { RotateConfirmDialogComponent } from './rotate-confirm-dialog.component'
 
 describe('RotateConfirmDialogComponent', () => {
@@ -15,11 +14,9 @@ describe('RotateConfirmDialogComponent', () => {
       imports: [
         NgxBootstrapIconsModule.pick(allIcons),
         RotateConfirmDialogComponent,
-        SafeHtmlPipe,
       ],
       providers: [
         NgbActiveModal,
-        SafeHtmlPipe,
         provideHttpClient(withInterceptorsFromDi()),
         provideHttpClientTesting(),
       ],
index b8b1f3ea36bb55177b8b275c4a940cd4a3ba3879..90d759da30b02b0aa6c9a2d4d418a8fbb184ad5c 100644 (file)
@@ -1,7 +1,6 @@
 import { NgStyle } from '@angular/common'
 import { Component, inject } from '@angular/core'
 import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { DocumentService } from 'src/app/services/rest/document.service'
 import { ConfirmDialogComponent } from '../confirm-dialog.component'
 
@@ -9,7 +8,7 @@ import { ConfirmDialogComponent } from '../confirm-dialog.component'
   selector: 'pngx-rotate-confirm-dialog',
   templateUrl: './rotate-confirm-dialog.component.html',
   styleUrl: './rotate-confirm-dialog.component.scss',
-  imports: [NgStyle, NgxBootstrapIconsModule, SafeHtmlPipe],
+  imports: [NgStyle, NgxBootstrapIconsModule],
 })
 export class RotateConfirmDialogComponent extends ConfirmDialogComponent {
   documentService = inject(DocumentService)
index 4486003dec65630c33b1323c3c18d1cce2f285a3..419fd89bb8d36564b9e0a5a301aaca878988e239 100644 (file)
@@ -10,7 +10,6 @@ import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
 import { CustomFieldDataType } from 'src/app/data/custom-field'
 import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
 import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { SettingsService } from 'src/app/services/settings.service'
 import { SelectComponent } from '../../input/select/select.component'
 import { TextComponent } from '../../input/text/text.component'
@@ -35,7 +34,6 @@ describe('CustomFieldEditDialogComponent', () => {
         IfOwnerDirective,
         SelectComponent,
         TextComponent,
-        SafeHtmlPipe,
       ],
       providers: [
         NgbActiveModal,
index d808caf0c5b5065ae113e829f3520f3f202aff30..af3b4dbd8eca2251c83b148c476ec935584fdf2c 100644 (file)
@@ -11,7 +11,6 @@ import {
 } from 'src/app/data/mail-rule'
 import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
 import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
 import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
 import { MailAccountService } from 'src/app/services/rest/mail-account.service'
@@ -46,7 +45,6 @@ describe('MailRuleEditDialogComponent', () => {
         PermissionsFormComponent,
         NumberComponent,
         TagsComponent,
-        SafeHtmlPipe,
         CheckComponent,
         SwitchComponent,
       ],
index 0736e221507014ceb147b1604dd5e3a28140cd48..aa52592b1e6241f02bba9243201939d2b5348664 100644 (file)
@@ -30,7 +30,6 @@ import {
 } from 'src/app/data/workflow-trigger'
 import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
 import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
 import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
 import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
@@ -105,7 +104,6 @@ describe('WorkflowEditDialogComponent', () => {
         TagsComponent,
         PermissionsUserComponent,
         PermissionsGroupComponent,
-        SafeHtmlPipe,
         ConfirmButtonComponent,
       ],
       providers: [
index c75007c25d927133e3b0ece5a99fb17411e26b18..301ecfa4de7b899e0c135744b3748d6c67c1aae2 100644 (file)
@@ -19,7 +19,7 @@
         </div>
       }
       @if (hint) {
-        <small class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
+        <small class="form-text text-muted" [innerHTML]="hint"></small>
       }
       <div class="invalid-feedback position-absolute top-100">
         {{error}}
index 4e780781c81c9181751f81a252e645025f540b61..b64a5e60e7ea7253e7e0525fd7f1fa0f13a96bee 100644 (file)
@@ -24,7 +24,7 @@
         }
         <input #inputField type="hidden" class="form-control small" [(ngModel)]="value" [disabled]="true">
         @if (hint) {
-            <small class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
+            <small class="form-text text-muted" [innerHTML]="hint"></small>
         }
         <div class="invalid-feedback position-absolute top-100">
             {{error}}
index 1a70ff4f68aae7398c02d15c952a209b97ff9bcc..9daa4be5fd12aef2beb744a112ba88f4b2fbe2f5 100644 (file)
@@ -12,6 +12,6 @@
     {{error}}
   </div>
   @if (hint) {
-    <small class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
+    <small class="form-text text-muted" [innerHTML]="hint"></small>
   }
 </div>
index 29e5698ad06ed716b2d4e39cc5ff832013ac111e..dcc43f72cdfd1335ee96c4f7ecd361a15337b6e7 100644 (file)
@@ -13,7 +13,7 @@
       <div class="position-relative" [class.col-md-9]="horizontal">
         <input #inputField type="text" class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [disabled]="disabled" [autocomplete]="autocomplete" [placeholder]="placeholder">
         @if (hint) {
-          <small class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
+          <small class="form-text text-muted" [innerHTML]="hint"></small>
         }
         <div class="invalid-feedback position-absolute top-100">
           {{error}}
index cc06d5bc01c1f03d39f340ae7cab156b06cc5f0e..283a8eb7137b020c36b1a64b2372097dcd7c8f82 100644 (file)
@@ -5,7 +5,6 @@ import {
   ReactiveFormsModule,
 } from '@angular/forms'
 import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { AbstractInputComponent } from '../abstract-input'
 
 @Component({
@@ -19,12 +18,7 @@ import { AbstractInputComponent } from '../abstract-input'
   selector: 'pngx-input-text',
   templateUrl: './text.component.html',
   styleUrls: ['./text.component.scss'],
-  imports: [
-    FormsModule,
-    ReactiveFormsModule,
-    SafeHtmlPipe,
-    NgxBootstrapIconsModule,
-  ],
+  imports: [FormsModule, ReactiveFormsModule, NgxBootstrapIconsModule],
 })
 export class TextComponent extends AbstractInputComponent<string> {
   @Input()
index d92a8aa4f89dc9302b2ea725c6bffa0776b375b9..60469ff086817e23278a96c38ebfeff20ebbb27d 100644 (file)
@@ -23,7 +23,7 @@
           rows="4">
         </textarea>
         @if (hint) {
-          <small class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
+          <small class="form-text text-muted" [innerHTML]="hint"></small>
         }
         <div class="invalid-feedback position-absolute top-100">
           {{error}}
index 733c3f18aa0211056ded4c2bc5feec05b85a9d58..527afda92545f68814ab572a50f3bc0f528be3fc 100644 (file)
@@ -5,7 +5,6 @@ import {
   ReactiveFormsModule,
 } from '@angular/forms'
 import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { AbstractInputComponent } from '../abstract-input'
 
 @Component({
@@ -19,12 +18,7 @@ import { AbstractInputComponent } from '../abstract-input'
   selector: 'pngx-input-textarea',
   templateUrl: './textarea.component.html',
   styleUrls: ['./textarea.component.scss'],
-  imports: [
-    FormsModule,
-    ReactiveFormsModule,
-    SafeHtmlPipe,
-    NgxBootstrapIconsModule,
-  ],
+  imports: [FormsModule, ReactiveFormsModule, NgxBootstrapIconsModule],
 })
 export class TextAreaComponent extends AbstractInputComponent<string> {
   @Input()
index 0885b3786bca4042469b259908ad91f8ca83b5ba..0fcd76d99954b6b97d18345310cd4aec87c76987 100644 (file)
@@ -19,7 +19,7 @@
         </div>
       </div>
       @if (hint) {
-        <small class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
+        <small class="form-text text-muted" [innerHTML]="hint"></small>
       }
     </div>
   </div>
index 55cbf152a12378dcc7721e9b1e4e8c807c48b651..e596719212de8f180dda5df90fbf82c3a2f30b44 100644 (file)
@@ -5,7 +5,6 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'
 import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
 import { NgSelectModule } from '@ng-select/ng-select'
 import { of } from 'rxjs'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { UserService } from 'src/app/services/rest/user.service'
 import { PermissionsFormComponent } from '../input/permissions/permissions-form/permissions-form.component'
 import { PermissionsGroupComponent } from '../input/permissions/permissions-group/permissions-group.component'
@@ -41,7 +40,6 @@ describe('PermissionsDialogComponent', () => {
         ReactiveFormsModule,
         NgbModule,
         PermissionsDialogComponent,
-        SafeHtmlPipe,
         SelectComponent,
         SwitchComponent,
         PermissionsFormComponent,
index a8627f19cb2afa5bbeff74293726667118a6beb4..67098b55cd94d44ae87f963cb8bd6768590d6f52 100644 (file)
                       <div class="visually-hidden" i18n>Loading...</div>
                     } @else if (totpSettings) {
                       <figure class="figure">
-                        <div class="bg-white d-inline-block" [innerHTML]="totpSettings.qr_svg | safeHtml"></div>
+                        @if (qrSvgDataUrl) {
+                          <img class="bg-white d-inline-block" [src]="qrSvgDataUrl" alt="Authenticator QR code">
+                        }
                         <figcaption class="figure-caption text-end mt-2" i18n>Scan the QR code with your authenticator app and then enter the code below</figcaption>
                       </figure>
                       <p>
index c4a103397f05a22f459d603567ad5c38b83525af..d6c839f1e00d20093356a50550b1c517d56898d2 100644 (file)
@@ -18,7 +18,6 @@ import {
   SocialAccountProvider,
   TotpSettings,
 } from 'src/app/data/user-profile'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { ProfileService } from 'src/app/services/profile.service'
 import { ToastService } from 'src/app/services/toast.service'
 import { setLocationHref } from 'src/app/utils/navigation'
@@ -37,7 +36,6 @@ import { TextComponent } from '../input/text/text.component'
     PasswordComponent,
     FormsModule,
     ReactiveFormsModule,
-    SafeHtmlPipe,
     NgbAccordionModule,
     NgbPopoverModule,
     NgxBootstrapIconsModule,
@@ -89,6 +87,13 @@ export class ProfileEditDialogComponent
   public socialAccounts: SocialAccount[] = []
   public socialAccountProviders: SocialAccountProvider[] = []
 
+  get qrSvgDataUrl(): string | null {
+    if (!this.totpSettings?.qr_svg) {
+      return null
+    }
+    return `data:image/svg+xml;utf8,${encodeURIComponent(this.totpSettings.qr_svg)}`
+  }
+
   ngOnInit(): void {
     this.networkActive = true
     this.profileService
index a64d79e499e478b1bac29fe12739d61324354ede..f39225f3f0643cc3bf52f5d0c09be633c163838e 100644 (file)
@@ -36,7 +36,6 @@ import { PermissionsGuard } from 'src/app/guards/permissions.guard'
 import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
 import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
 import { FilterPipe } from 'src/app/pipes/filter.pipe'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { UsernamePipe } from 'src/app/pipes/username.pipe'
 import { DocumentListViewService } from 'src/app/services/document-list-view.service'
 import { PermissionsService } from 'src/app/services/permissions.service'
@@ -103,7 +102,6 @@ describe('DocumentListComponent', () => {
         DatePipe,
         DocumentTitlePipe,
         UsernamePipe,
-        SafeHtmlPipe,
         PermissionsGuard,
         provideHttpClient(withInterceptorsFromDi()),
         provideHttpClientTesting(),
index 38293aca9ccea83b3f6c13cedb94d16fcbf51e0b..c866160d4e836b1194ac7e3c852eb9e9bc7669cd 100644 (file)
@@ -23,7 +23,6 @@ import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
 import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
 import { PermissionsGuard } from 'src/app/guards/permissions.guard'
 import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { PermissionsService } from 'src/app/services/permissions.service'
 import { MailAccountService } from 'src/app/services/rest/mail-account.service'
 import { MailRuleService } from 'src/app/services/rest/mail-rule.service'
@@ -84,7 +83,6 @@ describe('MailComponent', () => {
         CustomDatePipe,
         ConfirmDialogComponent,
         CheckComponent,
-        SafeHtmlPipe,
         SelectComponent,
         TextComponent,
         PasswordComponent,
index 23e518f3168ab821792cf1240f5c6dac837e03c2..8fac6f44f67e06842d81f53f0ff325089b685d0d 100644 (file)
     <td scope="row">{{ getDocumentCount(object) }}</td>
     @for (column of extraColumns; track column) {
       <td scope="row" [ngClass]="{ 'd-none d-sm-table-cell' : column.hideOnMobile }">
-        @if (column.rendersHtml) {
-          <div [innerHtml]="column.valueFn.call(null, object) | safeHtml"></div>
+        @if (column.badgeFn) {
+          <span
+            class="badge"
+            [style.color]="column.badgeFn.call(null, object)?.textColor"
+            [style.backgroundColor]="column.badgeFn.call(null, object)?.backgroundColor"
+          >
+            {{ column.badgeFn.call(null, object)?.text }}
+          </span>
         } @else if (column.monospace) {
           <span class="font-monospace">{{ column.valueFn.call(null, object) }}</span>
         } @else {
index 9c64f57309e44d6aa1491d0cd2ed01cabf6a2cb7..813c81148c74fc4e123e53a33c5072952b062889 100644 (file)
@@ -33,7 +33,6 @@ import { Tag } from 'src/app/data/tag'
 import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
 import { SortableDirective } from 'src/app/directives/sortable.directive'
 import { PermissionsGuard } from 'src/app/guards/permissions.guard'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { DocumentListViewService } from 'src/app/services/document-list-view.service'
 import {
   PermissionAction,
@@ -93,7 +92,6 @@ describe('ManagementListComponent', () => {
         SortableDirective,
         PageHeaderComponent,
         IfPermissionsDirective,
-        SafeHtmlPipe,
         ConfirmDialogComponent,
         PermissionsDialogComponent,
       ],
index 7cc3eaf4b7773b7765a858453b79ccc5ecc7d05b..b1af1f1d16affe70009d1718a3f9b5a19e0b2c34 100644 (file)
@@ -48,9 +48,13 @@ export interface ManagementListColumn {
 
   name: string
 
-  valueFn: any
+  valueFn?: any
 
-  rendersHtml?: boolean
+  badgeFn?: (object: any) => {
+    text: string
+    textColor?: string
+    backgroundColor?: string
+  }
 
   hideOnMobile?: boolean
 
index 22060bc61e2f7f94452bc01b49d389ed81db7502..e59c52789ac64d48f775d2db509588c5243874ac 100644 (file)
@@ -9,7 +9,6 @@ import { of } from 'rxjs'
 import { StoragePath } from 'src/app/data/storage-path'
 import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
 import { SortableDirective } from 'src/app/directives/sortable.directive'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { StoragePathService } from 'src/app/services/rest/storage-path.service'
 import { PageHeaderComponent } from '../../common/page-header/page-header.component'
 import { StoragePathListComponent } from './storage-path-list.component'
@@ -30,7 +29,6 @@ describe('StoragePathListComponent', () => {
         SortableDirective,
         PageHeaderComponent,
         IfPermissionsDirective,
-        SafeHtmlPipe,
       ],
       providers: [
         DatePipe,
index 346d956e8d426f0e7471d900b03464d7246fbf1d..413ccc33ac2dd0cfa8eef21722cb8ca891f5e547 100644 (file)
@@ -10,7 +10,6 @@ import { FILTER_HAS_STORAGE_PATH_ANY } from 'src/app/data/filter-rule-type'
 import { StoragePath } from 'src/app/data/storage-path'
 import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
 import { SortableDirective } from 'src/app/directives/sortable.directive'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { PermissionType } from 'src/app/services/permissions.service'
 import { StoragePathService } from 'src/app/services/rest/storage-path.service'
 import { StoragePathEditDialogComponent } from '../../common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component'
@@ -26,7 +25,6 @@ import { ManagementListComponent } from '../management-list/management-list.comp
     PageHeaderComponent,
     TitleCasePipe,
     IfPermissionsDirective,
-    SafeHtmlPipe,
     FormsModule,
     ReactiveFormsModule,
     NgClass,
index 0db84182b245893de5db3f441f0a0088c8d999ae..9b1923e43237baaccacf1fa074a2f784e06660eb 100644 (file)
@@ -8,7 +8,6 @@ import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
 import { of } from 'rxjs'
 import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
 import { SortableDirective } from 'src/app/directives/sortable.directive'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { TagService } from 'src/app/services/rest/tag.service'
 import { PageHeaderComponent } from '../../common/page-header/page-header.component'
 import { TagListComponent } from './tag-list.component'
@@ -30,7 +29,6 @@ describe('TagListComponent', () => {
         SortableDirective,
         PageHeaderComponent,
         IfPermissionsDirective,
-        SafeHtmlPipe,
       ],
       providers: [
         DatePipe,
index 64ca121dfc89f1c403c277f1b29c5a848f7ffbed..0ba0a0855b90476dc2ac2e2fe7a40c9b16ec05f7 100644 (file)
@@ -10,7 +10,6 @@ import { FILTER_HAS_TAGS_ALL } from 'src/app/data/filter-rule-type'
 import { Tag } from 'src/app/data/tag'
 import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
 import { SortableDirective } from 'src/app/directives/sortable.directive'
-import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
 import { PermissionType } from 'src/app/services/permissions.service'
 import { TagService } from 'src/app/services/rest/tag.service'
 import { TagEditDialogComponent } from '../../common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component'
@@ -26,7 +25,6 @@ import { ManagementListComponent } from '../management-list/management-list.comp
     PageHeaderComponent,
     TitleCasePipe,
     IfPermissionsDirective,
-    SafeHtmlPipe,
     FormsModule,
     ReactiveFormsModule,
     NgClass,
@@ -49,10 +47,11 @@ export class TagListComponent extends ManagementListComponent<Tag> {
       {
         key: 'color',
         name: $localize`Color`,
-        rendersHtml: true,
-        valueFn: (t: Tag) => {
-          return `<span class="badge" style="color: ${t.text_color}; background-color: ${t.color}">${t.color}</span>`
-        },
+        badgeFn: (t: Tag) => ({
+          text: t.color,
+          textColor: t.text_color,
+          backgroundColor: t.color,
+        }),
       },
     ]
   }
diff --git a/src-ui/src/app/pipes/safehtml.pipe.spec.ts b/src-ui/src/app/pipes/safehtml.pipe.spec.ts
deleted file mode 100644 (file)
index 8ef9a9e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-import { TestBed } from '@angular/core/testing'
-import { BrowserModule, DomSanitizer } from '@angular/platform-browser'
-import { SafeHtmlPipe } from './safehtml.pipe'
-
-describe('SafeHtmlPipe', () => {
-  let pipe: SafeHtmlPipe
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      providers: [SafeHtmlPipe],
-      imports: [BrowserModule],
-    })
-    pipe = TestBed.inject(SafeHtmlPipe)
-  })
-
-  it('should bypass security and trust the url', () => {
-    const html = '<div>some content</div>'
-    const domSanitizer = TestBed.inject(DomSanitizer)
-    const sanitizerSpy = jest.spyOn(domSanitizer, 'bypassSecurityTrustHtml')
-    let safeHtml = pipe.transform(html)
-    expect(safeHtml).not.toBeNull()
-    expect(sanitizerSpy).toHaveBeenCalled()
-  })
-})
diff --git a/src-ui/src/app/pipes/safehtml.pipe.ts b/src-ui/src/app/pipes/safehtml.pipe.ts
deleted file mode 100644 (file)
index 1001b8d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Pipe, PipeTransform, inject } from '@angular/core'
-import { DomSanitizer } from '@angular/platform-browser'
-
-@Pipe({
-  name: 'safeHtml',
-})
-export class SafeHtmlPipe implements PipeTransform {
-  private sanitizer = inject(DomSanitizer)
-
-  transform(html) {
-    return this.sanitizer.bypassSecurityTrustHtml(html)
-  }
-}