From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Thu, 18 Dec 2025 14:31:25 +0000 (-0800)
Subject: Security: remove safe html pipe
X-Git-Tag: v2.20.3~1^2~3
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bf38ae98f1ac3bae2c6006888a8705e42fbb804f;p=thirdparty%2Fpaperless-ngx.git
Security: remove safe html pipe
---
diff --git a/src-ui/src/app/components/admin/settings/settings.component.spec.ts b/src-ui/src/app/components/admin/settings/settings.component.spec.ts
index 300067d1b9..cc5c966407 100644
--- a/src-ui/src/app/components/admin/settings/settings.component.spec.ts
+++ b/src-ui/src/app/components/admin/settings/settings.component.spec.ts
@@ -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,
diff --git a/src-ui/src/app/components/admin/trash/trash.component.spec.ts b/src-ui/src/app/components/admin/trash/trash.component.spec.ts
index aa5a8af0f6..215b0b253d 100644
--- a/src-ui/src/app/components/admin/trash/trash.component.spec.ts
+++ b/src-ui/src/app/components/admin/trash/trash.component.spec.ts
@@ -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()
diff --git a/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html
index e25ace6121..deee54402c 100644
--- a/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html
+++ b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html
@@ -8,7 +8,7 @@
{{messageBold}}
}
@if (message) {
-
+
}
diff --git a/src-ui/src/app/components/common/permissions-dialog/permissions-dialog.component.spec.ts b/src-ui/src/app/components/common/permissions-dialog/permissions-dialog.component.spec.ts
index 55cbf152a1..e596719212 100644
--- a/src-ui/src/app/components/common/permissions-dialog/permissions-dialog.component.spec.ts
+++ b/src-ui/src/app/components/common/permissions-dialog/permissions-dialog.component.spec.ts
@@ -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,
diff --git a/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html b/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html
index a8627f19cb..67098b55cd 100644
--- a/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html
+++ b/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html
@@ -110,7 +110,9 @@
Loading...
} @else if (totpSettings) {
-
+ @if (qrSvgDataUrl) {
+
+ }
Scan the QR code with your authenticator app and then enter the code below
diff --git a/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts b/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts
index c4a103397f..d6c839f1e0 100644
--- a/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts
+++ b/src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts
@@ -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
diff --git a/src-ui/src/app/components/document-list/document-list.component.spec.ts b/src-ui/src/app/components/document-list/document-list.component.spec.ts
index a64d79e499..f39225f3f0 100644
--- a/src-ui/src/app/components/document-list/document-list.component.spec.ts
+++ b/src-ui/src/app/components/document-list/document-list.component.spec.ts
@@ -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(),
diff --git a/src-ui/src/app/components/manage/mail/mail.component.spec.ts b/src-ui/src/app/components/manage/mail/mail.component.spec.ts
index 38293aca9c..c866160d4e 100644
--- a/src-ui/src/app/components/manage/mail/mail.component.spec.ts
+++ b/src-ui/src/app/components/manage/mail/mail.component.spec.ts
@@ -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,
diff --git a/src-ui/src/app/components/manage/management-list/management-list.component.html b/src-ui/src/app/components/manage/management-list/management-list.component.html
index 23e518f316..8fac6f44f6 100644
--- a/src-ui/src/app/components/manage/management-list/management-list.component.html
+++ b/src-ui/src/app/components/manage/management-list/management-list.component.html
@@ -94,8 +94,14 @@
{{ getDocumentCount(object) }} |
@for (column of extraColumns; track column) {
- @if (column.rendersHtml) {
-
+ @if (column.badgeFn) {
+
+ {{ column.badgeFn.call(null, object)?.text }}
+
} @else if (column.monospace) {
{{ column.valueFn.call(null, object) }}
} @else {
diff --git a/src-ui/src/app/components/manage/management-list/management-list.component.spec.ts b/src-ui/src/app/components/manage/management-list/management-list.component.spec.ts
index 9c64f57309..813c81148c 100644
--- a/src-ui/src/app/components/manage/management-list/management-list.component.spec.ts
+++ b/src-ui/src/app/components/manage/management-list/management-list.component.spec.ts
@@ -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,
],
diff --git a/src-ui/src/app/components/manage/management-list/management-list.component.ts b/src-ui/src/app/components/manage/management-list/management-list.component.ts
index 7cc3eaf4b7..b1af1f1d16 100644
--- a/src-ui/src/app/components/manage/management-list/management-list.component.ts
+++ b/src-ui/src/app/components/manage/management-list/management-list.component.ts
@@ -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
diff --git a/src-ui/src/app/components/manage/storage-path-list/storage-path-list.component.spec.ts b/src-ui/src/app/components/manage/storage-path-list/storage-path-list.component.spec.ts
index 22060bc61e..e59c52789a 100644
--- a/src-ui/src/app/components/manage/storage-path-list/storage-path-list.component.spec.ts
+++ b/src-ui/src/app/components/manage/storage-path-list/storage-path-list.component.spec.ts
@@ -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,
diff --git a/src-ui/src/app/components/manage/storage-path-list/storage-path-list.component.ts b/src-ui/src/app/components/manage/storage-path-list/storage-path-list.component.ts
index 346d956e8d..413ccc33ac 100644
--- a/src-ui/src/app/components/manage/storage-path-list/storage-path-list.component.ts
+++ b/src-ui/src/app/components/manage/storage-path-list/storage-path-list.component.ts
@@ -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,
diff --git a/src-ui/src/app/components/manage/tag-list/tag-list.component.spec.ts b/src-ui/src/app/components/manage/tag-list/tag-list.component.spec.ts
index 0db84182b2..9b1923e432 100644
--- a/src-ui/src/app/components/manage/tag-list/tag-list.component.spec.ts
+++ b/src-ui/src/app/components/manage/tag-list/tag-list.component.spec.ts
@@ -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,
diff --git a/src-ui/src/app/components/manage/tag-list/tag-list.component.ts b/src-ui/src/app/components/manage/tag-list/tag-list.component.ts
index 64ca121dfc..0ba0a0855b 100644
--- a/src-ui/src/app/components/manage/tag-list/tag-list.component.ts
+++ b/src-ui/src/app/components/manage/tag-list/tag-list.component.ts
@@ -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 {
{
key: 'color',
name: $localize`Color`,
- rendersHtml: true,
- valueFn: (t: Tag) => {
- return `${t.color}`
- },
+ 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
index 8ef9a9e47f..0000000000
--- a/src-ui/src/app/pipes/safehtml.pipe.spec.ts
+++ /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 = ' some content '
- 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
index 1001b8dbfc..0000000000
--- a/src-ui/src/app/pipes/safehtml.pipe.ts
+++ /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)
- }
-}
|