mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 03:16:10 -06:00 
			
		
		
		
	Fix: correct download filename in 2.15.0 (#9599)
--------- Co-authored-by: Trenton H <797416+stumpylog@users.noreply.github.com>
This commit is contained in:
		@@ -1,5 +1,5 @@
 | 
				
			|||||||
import { AsyncPipe, NgTemplateOutlet } from '@angular/common'
 | 
					import { AsyncPipe, NgTemplateOutlet } from '@angular/common'
 | 
				
			||||||
import { HttpClient } from '@angular/common/http'
 | 
					import { HttpClient, HttpResponse } from '@angular/common/http'
 | 
				
			||||||
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'
 | 
					import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  FormArray,
 | 
					  FormArray,
 | 
				
			||||||
@@ -995,44 +995,48 @@ export class DocumentDetailComponent
 | 
				
			|||||||
      this.documentId,
 | 
					      this.documentId,
 | 
				
			||||||
      original
 | 
					      original
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    this.http.get(downloadUrl, { responseType: 'blob' }).subscribe({
 | 
					    this.http
 | 
				
			||||||
      next: (blob) => {
 | 
					      .get(downloadUrl, { observe: 'response', responseType: 'blob' })
 | 
				
			||||||
        this.downloading = false
 | 
					      .subscribe({
 | 
				
			||||||
        const blobParts = [blob]
 | 
					        next: (response: HttpResponse<Blob>) => {
 | 
				
			||||||
        const file = new File(
 | 
					          const filename = response.headers
 | 
				
			||||||
          blobParts,
 | 
					            .get('Content-Disposition')
 | 
				
			||||||
          original
 | 
					            ?.split(';')
 | 
				
			||||||
            ? this.document.original_file_name
 | 
					            ?.find((part) => part.trim().startsWith('filename='))
 | 
				
			||||||
            : this.document.archived_file_name,
 | 
					            ?.split('=')[1]
 | 
				
			||||||
          {
 | 
					            ?.replace(/['"]/g, '')
 | 
				
			||||||
            type: original ? this.document.mime_type : 'application/pdf',
 | 
					          const blob = new Blob([response.body], {
 | 
				
			||||||
          }
 | 
					            type: response.body.type,
 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        if (
 | 
					 | 
				
			||||||
          !this.deviceDetectorService.isDesktop() &&
 | 
					 | 
				
			||||||
          navigator.canShare &&
 | 
					 | 
				
			||||||
          navigator.canShare({ files: [file] })
 | 
					 | 
				
			||||||
        ) {
 | 
					 | 
				
			||||||
          navigator.share({
 | 
					 | 
				
			||||||
            files: [file],
 | 
					 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
        } else {
 | 
					          this.downloading = false
 | 
				
			||||||
          const url = URL.createObjectURL(blob)
 | 
					          const file = new File([blob], filename, {
 | 
				
			||||||
          const a = document.createElement('a')
 | 
					            type: response.body.type,
 | 
				
			||||||
          a.href = url
 | 
					          })
 | 
				
			||||||
          a.download = this.document.title
 | 
					          if (
 | 
				
			||||||
          a.click()
 | 
					            !this.deviceDetectorService.isDesktop() &&
 | 
				
			||||||
          URL.revokeObjectURL(url)
 | 
					            navigator.canShare &&
 | 
				
			||||||
        }
 | 
					            navigator.canShare({ files: [file] })
 | 
				
			||||||
      },
 | 
					          ) {
 | 
				
			||||||
      error: (error) => {
 | 
					            navigator.share({
 | 
				
			||||||
        this.downloading = false
 | 
					              files: [file],
 | 
				
			||||||
        this.toastService.showError(
 | 
					            })
 | 
				
			||||||
          $localize`Error downloading document`,
 | 
					          } else {
 | 
				
			||||||
          error
 | 
					            const url = URL.createObjectURL(blob)
 | 
				
			||||||
        )
 | 
					            const a = document.createElement('a')
 | 
				
			||||||
      },
 | 
					            a.href = url
 | 
				
			||||||
    })
 | 
					            a.download = filename
 | 
				
			||||||
 | 
					            a.click()
 | 
				
			||||||
 | 
					            URL.revokeObjectURL(url)
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        error: (error) => {
 | 
				
			||||||
 | 
					          this.downloading = false
 | 
				
			||||||
 | 
					          this.toastService.showError(
 | 
				
			||||||
 | 
					            $localize`Error downloading document`,
 | 
				
			||||||
 | 
					            error
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  hasNext() {
 | 
					  hasNext() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2376,9 +2376,13 @@ def serve_file(*, doc: Document, use_archive: bool, disposition: str):
 | 
				
			|||||||
    # RFC 5987 addresses this issue
 | 
					    # RFC 5987 addresses this issue
 | 
				
			||||||
    # see https://datatracker.ietf.org/doc/html/rfc5987#section-4.2
 | 
					    # see https://datatracker.ietf.org/doc/html/rfc5987#section-4.2
 | 
				
			||||||
    # Chromium cannot handle commas in the filename
 | 
					    # Chromium cannot handle commas in the filename
 | 
				
			||||||
    filename_normalized = normalize("NFKD", filename.replace(",", "_")).encode(
 | 
					    filename_normalized = (
 | 
				
			||||||
        "ascii",
 | 
					        normalize("NFKD", filename.replace(",", "_"))
 | 
				
			||||||
        "ignore",
 | 
					        .encode(
 | 
				
			||||||
 | 
					            "ascii",
 | 
				
			||||||
 | 
					            "ignore",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .decode("ascii")
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    filename_encoded = quote(filename)
 | 
					    filename_encoded = quote(filename)
 | 
				
			||||||
    content_disposition = (
 | 
					    content_disposition = (
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -565,6 +565,10 @@ if DEBUG:
 | 
				
			|||||||
    # Allow access from the angular development server during debugging
 | 
					    # Allow access from the angular development server during debugging
 | 
				
			||||||
    CORS_ALLOWED_ORIGINS.append("http://localhost:4200")
 | 
					    CORS_ALLOWED_ORIGINS.append("http://localhost:4200")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CORS_EXPOSE_HEADERS = [
 | 
				
			||||||
 | 
					    "Content-Disposition",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ALLOWED_HOSTS = __get_list("PAPERLESS_ALLOWED_HOSTS", ["*"])
 | 
					ALLOWED_HOSTS = __get_list("PAPERLESS_ALLOWED_HOSTS", ["*"])
 | 
				
			||||||
if ALLOWED_HOSTS != ["*"]:
 | 
					if ALLOWED_HOSTS != ["*"]:
 | 
				
			||||||
    # always allow localhost. Necessary e.g. for healthcheck in docker.
 | 
					    # always allow localhost. Necessary e.g. for healthcheck in docker.
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user