diff --git a/Dockerfile b/Dockerfile index 93f5699a..d0e0f409 100644 --- a/Dockerfile +++ b/Dockerfile @@ -81,6 +81,7 @@ ARG BASE_URL # Set this to "true" to disable Nginx listening on IPv6 ENV DISABLE_IPV6=false +ENV PORT=8080 USER root RUN apk upgrade --no-cache diff --git a/Dockerfile.nonroot b/Dockerfile.nonroot index cc64aefa..22f06178 100644 --- a/Dockerfile.nonroot +++ b/Dockerfile.nonroot @@ -74,6 +74,7 @@ ARG BASE_URL ENV PUID=1000 ENV PGID=1000 ENV DISABLE_IPV6=false +ENV PORT=8080 RUN apk upgrade --no-cache && apk add --no-cache su-exec diff --git a/README.md b/README.md index 47ceb839..00387043 100644 --- a/README.md +++ b/README.md @@ -890,7 +890,7 @@ For the full list of editor categories, see the [self-hosting docs](https://bent BentoPDF runs as a non-root user using nginx-unprivileged for enhanced security: - **Non-Root Execution**: Container runs with minimal privileges using nginx-unprivileged -- **Port 8080**: Uses high port number to avoid requiring root privileges +- **Port 8080**: Uses high port number to avoid requiring root privileges (configurable via `PORT` env var) - **Security Best Practices**: Follows Principle of Least Privilege #### Basic Usage @@ -900,6 +900,18 @@ docker build -t bentopdf . docker run -p 8080:8080 bentopdf ``` +#### Custom Port + +By default, BentoPDF listens on port `8080` inside the container. To change this, set the `PORT` environment variable: + +```bash +docker run -p 3000:9090 -e PORT=9090 ghcr.io/alam00000/bentopdf:latest +``` + +| Variable | Description | Default | +| -------- | ------------------------------ | ------- | +| `PORT` | Nginx listen port in container | `8080` | + #### Custom User ID (PUID/PGID) For environments that require running as a specific non-root user (e.g., NAS devices, Kubernetes with security contexts), use the non-root Dockerfile: diff --git a/docs/self-hosting/docker.md b/docs/self-hosting/docker.md index f9835941..298ab847 100644 --- a/docs/self-hosting/docker.md +++ b/docs/self-hosting/docker.md @@ -307,6 +307,20 @@ Use the codes printed by `bash scripts/prepare-airgap.sh --list-ocr-languages`, Set a variable to empty string to disable that module (users must configure manually via Advanced Settings). +## Custom Port + +By default, BentoPDF listens on port `8080` inside the container. To change this, set the `PORT` environment variable at runtime: + +```bash +docker run -p 3000:9090 -e PORT=9090 ghcr.io/alam00000/bentopdf:latest +``` + +| Variable | Description | Default | +| -------- | ------------------------------ | ------- | +| `PORT` | Nginx listen port in container | `8080` | + +This works with both the standard and nonroot Dockerfiles. + ## Custom User ID (PUID/PGID) For environments that require running as a specific non-root user (NAS devices, Kubernetes with security contexts, organizational policies), BentoPDF provides a separate Dockerfile with LSIO-style PUID/PGID support. @@ -333,6 +347,7 @@ docker run -d \ | -------------- | --------------------- | ------- | | `PUID` | User ID to run as | `1000` | | `PGID` | Group ID to run as | `1000` | +| `PORT` | Nginx listen port | `8080` | | `DISABLE_IPV6` | Disable IPv6 listener | `false` | ### Docker Compose diff --git a/entrypoint.sh b/entrypoint.sh index 0a26ae5f..1827e6dd 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -34,6 +34,12 @@ chown -R "$PUID:$PGID" \ /usr/share/nginx/html \ /etc/nginx/nginx.conf +PORT=${PORT:-8080} +if [ "$PORT" != "8080" ]; then + echo "Changing Nginx listen port to $PORT" + sed -i "s/listen 8080/listen $PORT/g; s/listen \[::\]:8080/listen [::]:$PORT/g" /etc/nginx/nginx.conf +fi + if [ "$DISABLE_IPV6" = "true" ]; then echo "Disabling Nginx IPv6 listener" sed -i '/^[[:space:]]*listen[[:space:]]*\[::\]:[0-9]*/s/^/#/' /etc/nginx/nginx.conf diff --git a/nginx-ipv6.sh b/nginx-ipv6.sh index f2a5ee5a..423dfe68 100644 --- a/nginx-ipv6.sh +++ b/nginx-ipv6.sh @@ -9,6 +9,12 @@ entrypoint_log() { fi } +PORT=${PORT:-8080} +if [ "$PORT" != "8080" ]; then + entrypoint_log "Changing Nginx listen port to $PORT" + sed -i "s/listen 8080/listen $PORT/g; s/listen \[::\]:8080/listen [::]:$PORT/g" /etc/nginx/nginx.conf +fi + if [ "$DISABLE_IPV6" = "true" ]; then entrypoint_log "Disabling the Nginx IPv6 listener" sed -i '/^[[:space:]]*listen[[:space:]]*\[::\]:[0-9]*/s/^/#/' /etc/nginx/nginx.conf diff --git a/public/locales/ar/common.json b/public/locales/ar/common.json index 693b1a7e..948480bd 100644 --- a/public/locales/ar/common.json +++ b/public/locales/ar/common.json @@ -5,6 +5,7 @@ "contact": "اتصل بنا", "licensing": "الترخيص", "allTools": "جميع الأدوات", + "docs": "Docs", "openMainMenu": "فتح القائمة الرئيسية", "language": "اللغة" }, diff --git a/public/locales/be/common.json b/public/locales/be/common.json index 67c94ee4..348db347 100644 --- a/public/locales/be/common.json +++ b/public/locales/be/common.json @@ -5,6 +5,7 @@ "contact": "Кантакты", "licensing": "Ліцэнзія", "allTools": "Усе інструменты", + "docs": "Docs", "openMainMenu": "Адкрыць галоўнае меню", "language": "Мова" }, diff --git a/public/locales/da/common.json b/public/locales/da/common.json index 68836e3e..56342d73 100644 --- a/public/locales/da/common.json +++ b/public/locales/da/common.json @@ -5,6 +5,7 @@ "contact": "Kontakt", "licensing": "licensing", "allTools": "Alle værktøjer", + "docs": "Docs", "openMainMenu": "Åbn hovedmenu", "language": "Sprog" }, diff --git a/public/locales/de/common.json b/public/locales/de/common.json index b24e2da7..ec9ebb86 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -5,6 +5,7 @@ "contact": "Kontakt", "licensing": "Lizenzierung", "allTools": "Alle Werkzeuge", + "docs": "Docs", "openMainMenu": "Hauptmenü öffnen", "language": "Sprache" }, diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 0d9b28f1..c22880ed 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -5,6 +5,7 @@ "contact": "Contact", "licensing": "Licensing", "allTools": "All Tools", + "docs": "Docs", "openMainMenu": "Open main menu", "language": "Language" }, diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 039d1aef..4f7419b0 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -5,6 +5,7 @@ "contact": "Contacto", "licensing": "Licencias", "allTools": "Todas las Herramientas", + "docs": "Docs", "openMainMenu": "Abrir menú principal", "language": "Idioma" }, diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json index 16aa178c..7e21edbb 100644 --- a/public/locales/fr/common.json +++ b/public/locales/fr/common.json @@ -5,6 +5,7 @@ "contact": "Contact", "licensing": "Licence", "allTools": "Tous les outils", + "docs": "Docs", "openMainMenu": "Ouvrir le menu principal", "language": "Langue" }, diff --git a/public/locales/id/common.json b/public/locales/id/common.json index 19566878..478abde7 100644 --- a/public/locales/id/common.json +++ b/public/locales/id/common.json @@ -5,6 +5,7 @@ "contact": "Kontak", "licensing": "Lisensi", "allTools": "Semua Alat", + "docs": "Docs", "openMainMenu": "Buka menu utama", "language": "Bahasa" }, diff --git a/public/locales/it/common.json b/public/locales/it/common.json index c72f4d89..e57ef568 100644 --- a/public/locales/it/common.json +++ b/public/locales/it/common.json @@ -5,6 +5,7 @@ "contact": "Contatti", "licensing": "Licenze", "allTools": "Tutti gli strumenti", + "docs": "Docs", "openMainMenu": "Apri il menu principale", "language": "Lingua" }, diff --git a/public/locales/ko/common.json b/public/locales/ko/common.json index 6beed76c..01d815cb 100644 --- a/public/locales/ko/common.json +++ b/public/locales/ko/common.json @@ -5,6 +5,7 @@ "contact": "문의", "licensing": "라이선스", "allTools": "모든 도구", + "docs": "Docs", "openMainMenu": "메인 메뉴 열기", "language": "언어" }, diff --git a/public/locales/nl/common.json b/public/locales/nl/common.json index 30d46a45..61487612 100644 --- a/public/locales/nl/common.json +++ b/public/locales/nl/common.json @@ -5,6 +5,7 @@ "contact": "Contact", "licensing": "Licentie", "allTools": "Alle Tools", + "docs": "Docs", "openMainMenu": "Hoofdmenu openen", "language": "Taal" }, diff --git a/public/locales/pt/common.json b/public/locales/pt/common.json index 0f4ac7da..48aebc1d 100644 --- a/public/locales/pt/common.json +++ b/public/locales/pt/common.json @@ -5,6 +5,7 @@ "contact": "Contato", "licensing": "Licenciamento", "allTools": "Todas as Ferramentas", + "docs": "Docs", "openMainMenu": "Abrir menu principal", "language": "Idioma" }, diff --git a/public/locales/ru/common.json b/public/locales/ru/common.json index ef82a2bc..613ff999 100644 --- a/public/locales/ru/common.json +++ b/public/locales/ru/common.json @@ -5,6 +5,7 @@ "contact": "Контакты", "licensing": "Лицензия", "allTools": "Все инструменты", + "docs": "Docs", "openMainMenu": "Открыть главное меню", "language": "Язык" }, diff --git a/public/locales/sv/common.json b/public/locales/sv/common.json index a6028994..b8b872e2 100644 --- a/public/locales/sv/common.json +++ b/public/locales/sv/common.json @@ -5,6 +5,7 @@ "contact": "Kontakt", "licensing": "Licensiering", "allTools": "Alla verktyg", + "docs": "Docs", "openMainMenu": "Öppna huvudmenyn", "language": "Språk" }, diff --git a/public/locales/tr/common.json b/public/locales/tr/common.json index 3d32b95b..f4f35de7 100644 --- a/public/locales/tr/common.json +++ b/public/locales/tr/common.json @@ -5,6 +5,7 @@ "contact": "İletişim", "licensing": "Lisanslama", "allTools": "Tüm Araçlar", + "docs": "Docs", "openMainMenu": "Ana menüyü aç", "language": "Dil" }, diff --git a/public/locales/vi/common.json b/public/locales/vi/common.json index 3ee1a288..ccb5dbc1 100644 --- a/public/locales/vi/common.json +++ b/public/locales/vi/common.json @@ -5,6 +5,7 @@ "contact": "Liên hệ", "licensing": "Giấy phép", "allTools": "Tất cả công cụ", + "docs": "Docs", "openMainMenu": "Mở menu chính", "language": "Ngôn ngữ" }, diff --git a/public/locales/zh-TW/common.json b/public/locales/zh-TW/common.json index 6d372a8b..cd4ae62a 100644 --- a/public/locales/zh-TW/common.json +++ b/public/locales/zh-TW/common.json @@ -5,6 +5,7 @@ "contact": "聯絡我們", "licensing": "產品授權", "allTools": "所有工具", + "docs": "Docs", "openMainMenu": "開啟主選單", "language": "語言" }, diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json index 8aa25835..67814532 100644 --- a/public/locales/zh/common.json +++ b/public/locales/zh/common.json @@ -5,6 +5,7 @@ "contact": "联系我们", "licensing": "许可", "allTools": "所有工具", + "docs": "Docs", "openMainMenu": "打开主菜单", "language": "语言" }, diff --git a/src/js/logic/add-attachments-page.ts b/src/js/logic/add-attachments-page.ts index e78b4d3a..44aea4b5 100644 --- a/src/js/logic/add-attachments-page.ts +++ b/src/js/logic/add-attachments-page.ts @@ -65,11 +65,9 @@ worker.onmessage = function (e) { if (data.status === 'success' && data.modifiedPDF !== undefined) { hideLoader(); - const originalName = - pageState.file?.name.replace(/\.pdf$/i, '') || 'document'; downloadFile( new Blob([new Uint8Array(data.modifiedPDF)], { type: 'application/pdf' }), - `${originalName}_with_attachments.pdf` + pageState.file?.name || 'document.pdf' ); showAlert( diff --git a/src/js/logic/add-blank-page-page.ts b/src/js/logic/add-blank-page-page.ts index bf286ef5..e6484da8 100644 --- a/src/js/logic/add-blank-page-page.ts +++ b/src/js/logic/add-blank-page-page.ts @@ -178,11 +178,9 @@ async function addBlankPages() { } const newPdfBytes = await newPdf.save(); - const originalName = pageState.file.name.replace(/\.pdf$/i, ''); - downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - `${originalName}_blank-pages-added.pdf` + pageState.file.name ); showAlert( diff --git a/src/js/logic/add-page-labels-page.ts b/src/js/logic/add-page-labels-page.ts index f7d30b14..7c54ff0f 100644 --- a/src/js/logic/add-page-labels-page.ts +++ b/src/js/logic/add-page-labels-page.ts @@ -502,7 +502,7 @@ async function addPageLabels() { downloadFile( new Blob([outputBytes], { type: 'application/pdf' }), - 'page-labels-added.pdf' + pageState.file?.name || 'document.pdf' ); showAlert( translate('common.success', 'Success'), diff --git a/src/js/logic/add-watermark-page.ts b/src/js/logic/add-watermark-page.ts index b61200ca..79c06c64 100644 --- a/src/js/logic/add-watermark-page.ts +++ b/src/js/logic/add-watermark-page.ts @@ -1010,7 +1010,7 @@ async function applyWatermark() { downloadFile( new Blob([new Uint8Array(resultBytes)], { type: 'application/pdf' }), - 'watermarked.pdf' + pageState.file?.name || 'document.pdf' ); showAlert('Success', 'Watermark added successfully!', 'success'); } catch (e: unknown) { diff --git a/src/js/logic/adjust-colors-page.ts b/src/js/logic/adjust-colors-page.ts index 5d36c49d..2ed9e00c 100644 --- a/src/js/logic/adjust-colors-page.ts +++ b/src/js/logic/adjust-colors-page.ts @@ -234,7 +234,7 @@ async function processAllPages(): Promise { const resultBytes = await newPdfDoc.save(); downloadFile( new Blob([new Uint8Array(resultBytes)], { type: 'application/pdf' }), - 'color-adjusted.pdf' + files[0]?.name || 'document.pdf' ); showAlert( 'Success', diff --git a/src/js/logic/background-color-page.ts b/src/js/logic/background-color-page.ts index 30e07730..8ce491ce 100644 --- a/src/js/logic/background-color-page.ts +++ b/src/js/logic/background-color-page.ts @@ -140,7 +140,7 @@ async function changeBackgroundColor() { const newPdfBytes = await newPdfDoc.save(); downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - 'background-changed.pdf' + pageState.file?.name || 'document.pdf' ); showAlert( 'Success', diff --git a/src/js/logic/bates-numbering-page.ts b/src/js/logic/bates-numbering-page.ts index 67204d96..c0d6d3cb 100644 --- a/src/js/logic/bates-numbering-page.ts +++ b/src/js/logic/bates-numbering-page.ts @@ -516,7 +516,7 @@ async function applyBatesNumbers() { fileCounter++; const pdfBytes = await pdfDoc.save(); results.push({ - name: `bates_${entry.file.name}`, + name: entry.file.name, bytes: new Uint8Array(pdfBytes), }); } diff --git a/src/js/logic/bookmark-pdf.ts b/src/js/logic/bookmark-pdf.ts index 19d21460..e7bd2082 100644 --- a/src/js/logic/bookmark-pdf.ts +++ b/src/js/logic/bookmark-pdf.ts @@ -2306,7 +2306,7 @@ downloadBtn?.addEventListener('click', async () => { const blob = new Blob([new Uint8Array(pdfBytes)], { type: 'application/pdf', }); - downloadFile(blob, `${originalFileName}-bookmarked.pdf`); + downloadFile(blob, `${originalFileName}.pdf`); await showAlertModal('Success', 'PDF saved successfully!'); diff --git a/src/js/logic/change-permissions-page.ts b/src/js/logic/change-permissions-page.ts index 784358f5..8c0d2885 100644 --- a/src/js/logic/change-permissions-page.ts +++ b/src/js/logic/change-permissions-page.ts @@ -222,7 +222,7 @@ async function changePermissions() { const blob = new Blob([new Uint8Array(outputFile)], { type: 'application/pdf', }); - downloadFile(blob, `permissions-changed-${pageState.file.name}`); + downloadFile(blob, pageState.file.name); if (loaderModal) loaderModal.classList.add('hidden'); diff --git a/src/js/logic/combine-single-page-page.ts b/src/js/logic/combine-single-page-page.ts index f5307abe..0b0df811 100644 --- a/src/js/logic/combine-single-page-page.ts +++ b/src/js/logic/combine-single-page-page.ts @@ -243,11 +243,9 @@ async function combineToSinglePage() { } const newPdfBytes = await newDoc.save(); - const originalName = pageState.file.name.replace(/\.pdf$/i, ''); - downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - `${originalName}_combined.pdf` + pageState.file.name ); showAlert( diff --git a/src/js/logic/compress-pdf-page.ts b/src/js/logic/compress-pdf-page.ts index 20aa1309..587a4e38 100644 --- a/src/js/logic/compress-pdf-page.ts +++ b/src/js/logic/compress-pdf-page.ts @@ -465,10 +465,7 @@ document.addEventListener('DOMContentLoaded', () => { const savingsPercent = savings > 0 ? ((savings / originalFile.size) * 100).toFixed(1) : 0; - downloadFile( - resultBlob, - originalFile.name.replace(/\.pdf$/i, '') + '_compressed.pdf' - ); + downloadFile(resultBlob, originalFile.name); hideLoader(); @@ -523,8 +520,7 @@ document.addEventListener('DOMContentLoaded', () => { } totalCompressedSize += resultBytes.length; - const baseName = file.name.replace(/\.pdf$/i, ''); - zip.file(`${baseName}_compressed.pdf`, resultBytes); + zip.file(file.name, resultBytes); } const zipBlob = await zip.generateAsync({ type: 'blob' }); diff --git a/src/js/logic/crop-pdf-page.ts b/src/js/logic/crop-pdf-page.ts index aabd964d..6e805158 100644 --- a/src/js/logic/crop-pdf-page.ts +++ b/src/js/logic/crop-pdf-page.ts @@ -288,10 +288,9 @@ async function performCrop() { finalPdfBytes = await performMetadataCrop(finalCropData); } - const fileName = isDestructive ? 'flattened_crop.pdf' : 'standard_crop.pdf'; downloadFile( new Blob([new Uint8Array(finalPdfBytes)], { type: 'application/pdf' }), - fileName + cropperState.file?.name || 'document.pdf' ); showAlert( 'Success', diff --git a/src/js/logic/decrypt-pdf-page.ts b/src/js/logic/decrypt-pdf-page.ts index f289ca1d..3257cf07 100644 --- a/src/js/logic/decrypt-pdf-page.ts +++ b/src/js/logic/decrypt-pdf-page.ts @@ -137,7 +137,7 @@ async function decryptPdf() { const blob = new Blob([decryptedBytes.slice().buffer], { type: 'application/pdf', }); - downloadFile(blob, `unlocked-${file.name}`); + downloadFile(blob, file.name); if (loaderModal) loaderModal.classList.add('hidden'); showAlert( @@ -168,7 +168,7 @@ async function decryptPdf() { password ); - zip.file(`unlocked-${file.name}`, decryptedBytes, { binary: true }); + zip.file(file.name, decryptedBytes, { binary: true }); successCount++; } catch (fileError: unknown) { errorCount++; diff --git a/src/js/logic/delete-pages-page.ts b/src/js/logic/delete-pages-page.ts index 2f8102f9..31af8742 100644 --- a/src/js/logic/delete-pages-page.ts +++ b/src/js/logic/delete-pages-page.ts @@ -267,12 +267,11 @@ async function deletePages() { new Uint8Array(srcBytes), deleteState.pagesToDelete ); - const baseName = deleteState.file?.name.replace('.pdf', '') || 'document'; downloadFile( new Blob([new Uint8Array(resultBytes)], { type: 'application/pdf', }), - `${baseName}_pages_removed.pdf` + deleteState.file?.name || 'document.pdf' ); hideLoader(); diff --git a/src/js/logic/deskew-pdf-page.ts b/src/js/logic/deskew-pdf-page.ts index ed7bafb4..67486626 100644 --- a/src/js/logic/deskew-pdf-page.ts +++ b/src/js/logic/deskew-pdf-page.ts @@ -171,8 +171,7 @@ async function processDeskew(): Promise { displayResults(result); - const filename = file.name.replace('.pdf', '_deskewed.pdf'); - downloadFile(resultPdf, filename); + downloadFile(resultPdf, file.name); } hideLoader(); diff --git a/src/js/logic/digital-sign-pdf-page.ts b/src/js/logic/digital-sign-pdf-page.ts index ba1c82dc..82f2459a 100644 --- a/src/js/logic/digital-sign-pdf-page.ts +++ b/src/js/logic/digital-sign-pdf-page.ts @@ -739,10 +739,7 @@ async function processSignature(): Promise { const blob = new Blob([signedPdfBytes.slice().buffer], { type: 'application/pdf', }); - const originalName = state.pdfFile?.name ?? 'document.pdf'; - const signedName = originalName.replace(/\.pdf$/i, '_signed.pdf'); - - downloadFile(blob, signedName); + downloadFile(blob, state.pdfFile?.name ?? 'document.pdf'); hideLoader(); showAlert( diff --git a/src/js/logic/divide-pages-page.ts b/src/js/logic/divide-pages-page.ts index 7b2f53c1..16df79bd 100644 --- a/src/js/logic/divide-pages-page.ts +++ b/src/js/logic/divide-pages-page.ts @@ -177,11 +177,9 @@ async function dividePages() { } const newPdfBytes = await newPdfDoc.save(); - const originalName = pageState.file.name.replace(/\.pdf$/i, ''); - downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - `${originalName}_divided.pdf` + pageState.file.name ); showAlert( diff --git a/src/js/logic/duplicate-organize.ts b/src/js/logic/duplicate-organize.ts index e2a11c87..cfffe86a 100644 --- a/src/js/logic/duplicate-organize.ts +++ b/src/js/logic/duplicate-organize.ts @@ -222,7 +222,7 @@ export async function processAndSave() { const newPdfBytes = await newPdfDoc.save(); downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - 'organized.pdf' + state.files[0]?.name || 'document.pdf' ); } catch (e) { console.error('Save error:', e); diff --git a/src/js/logic/edit-attachments-page.ts b/src/js/logic/edit-attachments-page.ts index c0f7c448..1d56deef 100644 --- a/src/js/logic/edit-attachments-page.ts +++ b/src/js/logic/edit-attachments-page.ts @@ -60,11 +60,9 @@ worker.onmessage = function (e) { } else if (data.status === 'success' && data.modifiedPDF !== undefined) { hideLoader(); - const originalName = - pageState.file?.name.replace(/\.pdf$/i, '') || 'document'; downloadFile( new Blob([new Uint8Array(data.modifiedPDF)], { type: 'application/pdf' }), - `${originalName}_edited.pdf` + pageState.file?.name || 'document.pdf' ); showAlert( diff --git a/src/js/logic/edit-metadata-page.ts b/src/js/logic/edit-metadata-page.ts index f44683aa..775eade0 100644 --- a/src/js/logic/edit-metadata-page.ts +++ b/src/js/logic/edit-metadata-page.ts @@ -351,11 +351,9 @@ async function saveMetadata() { }); const newPdfBytes = await pageState.pdfDoc.save(); - const originalName = pageState.file.name.replace(/\.pdf$/i, ''); - downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - `${originalName}_metadata-edited.pdf` + pageState.file.name ); showAlert( diff --git a/src/js/logic/edit-pdf-page.ts b/src/js/logic/edit-pdf-page.ts index 1996bdc0..3ce15122 100644 --- a/src/js/logic/edit-pdf-page.ts +++ b/src/js/logic/edit-pdf-page.ts @@ -17,6 +17,7 @@ import type { DocManagerPlugin } from '@/types'; let viewerInstance: EmbedPdfContainer | null = null; let docManagerPlugin: DocManagerPlugin | null = null; let isViewerInitialized = false; +let currentFileName = 'document.pdf'; const fileEntryMap = new Map(); function resetViewer() { @@ -128,6 +129,7 @@ async function handleFiles(files: FileList) { if (!isViewerInitialized) { const firstFile = decryptedFiles[0]; + currentFileName = firstFile.name; const firstBuffer = await firstFile.arrayBuffer(); pdfContainer.textContent = ''; @@ -217,7 +219,7 @@ async function handleFiles(files: FileList) { const exportPlugin = registry.getPlugin('export').provides(); const arrayBuffer = await exportPlugin.saveAsCopy().toPromise(); const blob = new Blob([arrayBuffer], { type: 'application/pdf' }); - downloadFile(blob, 'edited-document.pdf'); + downloadFile(blob, currentFileName); } catch (err) { console.error('Error downloading PDF:', err); showAlert('Error', 'Failed to download the edited PDF.'); diff --git a/src/js/logic/encrypt-pdf-page.ts b/src/js/logic/encrypt-pdf-page.ts index dae312f0..72542cfc 100644 --- a/src/js/logic/encrypt-pdf-page.ts +++ b/src/js/logic/encrypt-pdf-page.ts @@ -173,7 +173,7 @@ async function encryptPdf() { const blob = new Blob([new Uint8Array(outputFile)], { type: 'application/pdf', }); - downloadFile(blob, `encrypted-${pageState.file.name}`); + downloadFile(blob, pageState.file.name); if (loaderModal) loaderModal.classList.add('hidden'); diff --git a/src/js/logic/fix-page-size-page.ts b/src/js/logic/fix-page-size-page.ts index 0f774018..0328452c 100644 --- a/src/js/logic/fix-page-size-page.ts +++ b/src/js/logic/fix-page-size-page.ts @@ -135,7 +135,7 @@ async function fixPageSize() { downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - 'standardized.pdf' + pageState.file?.name || 'document.pdf' ); showAlert( 'Success', diff --git a/src/js/logic/flatten-pdf-page.ts b/src/js/logic/flatten-pdf-page.ts index 8e128b2b..a42f1614 100644 --- a/src/js/logic/flatten-pdf-page.ts +++ b/src/js/logic/flatten-pdf-page.ts @@ -174,10 +174,7 @@ async function flattenPdf() { } const flattenedBytes = await pdfDoc.save(); - const zipEntryName = deduplicateFileName( - `flattened_${file.name}`, - usedNames - ); + const zipEntryName = deduplicateFileName(file.name, usedNames); zip.file(zipEntryName, flattenedBytes); processedCount++; } catch (e) { diff --git a/src/js/logic/font-to-outline-page.ts b/src/js/logic/font-to-outline-page.ts index 884188f7..518385d1 100644 --- a/src/js/logic/font-to-outline-page.ts +++ b/src/js/logic/font-to-outline-page.ts @@ -124,8 +124,7 @@ async function processFiles() { if (loaderText) loaderText.textContent = msg; }); - const baseName = file.name.replace(/\.pdf$/i, ''); - downloadFile(resultBlob, `${baseName}_outlined.pdf`); + downloadFile(resultBlob, file.name); if (loaderModal) loaderModal.classList.add('hidden'); } else { if (loaderModal) loaderModal.classList.remove('hidden'); @@ -143,11 +142,7 @@ async function processFiles() { try { const resultBlob = await convertFileToOutlines(file, () => {}); const arrayBuffer = await resultBlob.arrayBuffer(); - const baseName = file.name.replace(/\.pdf$/i, ''); - const zipEntryName = deduplicateFileName( - `${baseName}_outlined.pdf`, - usedNames - ); + const zipEntryName = deduplicateFileName(file.name, usedNames); zip.file(zipEntryName, arrayBuffer); processedCount++; } catch (e) { diff --git a/src/js/logic/form-creator.ts b/src/js/logic/form-creator.ts index 9689e98b..603970bc 100644 --- a/src/js/logic/form-creator.ts +++ b/src/js/logic/form-creator.ts @@ -65,6 +65,7 @@ let pages: PageData[] = []; let currentPageIndex = 0; let uploadedPdfDoc: PDFDocument | null = null; let uploadedPdfjsDoc: PDFDocumentProxy | null = null; +let uploadedFileName: string | null = null; let pageSize: { width: number; height: number } = { width: 612, height: 792 }; let currentScale = 1.333; let pdfViewerOffset = { x: 0, y: 0 }; @@ -2717,7 +2718,7 @@ downloadBtn.addEventListener('click', async () => { const blob = new Blob([new Uint8Array(pdfBytes)], { type: 'application/pdf', }); - downloadFile(blob, 'fillable-form.pdf'); + downloadFile(blob, uploadedFileName || 'document.pdf'); showModal( 'Success', 'Your PDF has been downloaded successfully.', @@ -3141,6 +3142,7 @@ async function handlePdfUpload(file: File) { const arrayBuffer = result.bytes; uploadedPdfjsDoc = result.pdf; uploadedPdfDoc = await loadPdfDocument(arrayBuffer); + uploadedFileName = file.name; // Check for existing fields and update counter existingFieldNames.clear(); diff --git a/src/js/logic/header-footer-page.ts b/src/js/logic/header-footer-page.ts index 191ba11b..d7efe734 100644 --- a/src/js/logic/header-footer-page.ts +++ b/src/js/logic/header-footer-page.ts @@ -242,7 +242,7 @@ async function addHeaderFooter() { const newPdfBytes = await pageState.pdfDoc.save(); downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - 'header-footer-added.pdf' + pageState.file?.name || 'document.pdf' ); showAlert( 'Success', diff --git a/src/js/logic/invert-colors-page.ts b/src/js/logic/invert-colors-page.ts index 0cd6cf5f..4eceb6fe 100644 --- a/src/js/logic/invert-colors-page.ts +++ b/src/js/logic/invert-colors-page.ts @@ -164,7 +164,7 @@ async function invertColors() { const newPdfBytes = await newPdfDoc.save(); downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - 'inverted.pdf' + pageState.file?.name || 'document.pdf' ); showAlert('Success', 'Colors inverted successfully!', 'success', () => { resetState(); diff --git a/src/js/logic/n-up-pdf-page.ts b/src/js/logic/n-up-pdf-page.ts index c17807cc..5b6c527c 100644 --- a/src/js/logic/n-up-pdf-page.ts +++ b/src/js/logic/n-up-pdf-page.ts @@ -200,11 +200,9 @@ async function nUpTool() { } const newPdfBytes = await newDoc.save(); - const originalName = pageState.file.name.replace(/\.pdf$/i, ''); - downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - `${originalName}_${n}-up.pdf` + pageState.file.name ); showAlert( diff --git a/src/js/logic/ocr-pdf-page.ts b/src/js/logic/ocr-pdf-page.ts index f4988831..a4b4f329 100644 --- a/src/js/logic/ocr-pdf-page.ts +++ b/src/js/logic/ocr-pdf-page.ts @@ -461,7 +461,7 @@ document.addEventListener('DOMContentLoaded', function () { new Blob([new Uint8Array(pageState.searchablePdfBytes)], { type: 'application/pdf', }), - 'searchable.pdf' + pageState.file?.name || 'document.pdf' ); } }); diff --git a/src/js/logic/organize-pdf-page.ts b/src/js/logic/organize-pdf-page.ts index ce5bbfa3..9a026c33 100644 --- a/src/js/logic/organize-pdf-page.ts +++ b/src/js/logic/organize-pdf-page.ts @@ -380,10 +380,9 @@ async function saveChanges() { copiedPages.forEach((page) => newPdf.addPage(page)); const pdfBytes = await newPdf.save(); - const baseName = organizeState.file?.name.replace('.pdf', '') || 'document'; downloadFile( new Blob([pdfBytes as BlobPart], { type: 'application/pdf' }), - `${baseName}_organized.pdf` + organizeState.file?.name || 'document.pdf' ); hideLoader(); diff --git a/src/js/logic/overlay-pdf-page.ts b/src/js/logic/overlay-pdf-page.ts index 2308be0a..53e92c00 100644 --- a/src/js/logic/overlay-pdf-page.ts +++ b/src/js/logic/overlay-pdf-page.ts @@ -177,12 +177,9 @@ async function processOverlay() { } const modeLabel = mode.replace('--', ''); - const baseName = pageState.baseFile.name.replace(/\.pdf$/i, ''); - const fileName = `${baseName}_${modeLabel}.pdf`; - downloadFile( new Blob([new Uint8Array(outputFile)], { type: 'application/pdf' }), - fileName + pageState.baseFile.name ); showAlert( diff --git a/src/js/logic/page-numbers-page.ts b/src/js/logic/page-numbers-page.ts index 4d222e93..e478c3e9 100644 --- a/src/js/logic/page-numbers-page.ts +++ b/src/js/logic/page-numbers-page.ts @@ -181,7 +181,7 @@ async function addPageNumbers() { new Blob([resultBytes as unknown as BlobPart], { type: 'application/pdf', }), - 'paginated.pdf' + pageState.file?.name || 'document.pdf' ); showAlert('Success', 'Page numbers added successfully!', 'success', () => { resetState(); diff --git a/src/js/logic/pdf-booklet-page.ts b/src/js/logic/pdf-booklet-page.ts index ffadfe30..30253ffb 100644 --- a/src/js/logic/pdf-booklet-page.ts +++ b/src/js/logic/pdf-booklet-page.ts @@ -524,12 +524,9 @@ async function createBooklet() { } const pdfBytes = await outputDoc.save(); - const originalName = - pageState.file?.name.replace(/\.pdf$/i, '') || 'document'; - downloadFile( new Blob([new Uint8Array(pdfBytes)], { type: 'application/pdf' }), - `${originalName}_booklet.pdf` + pageState.file?.name || 'document.pdf' ); showAlert( diff --git a/src/js/logic/pdf-layers-page.ts b/src/js/logic/pdf-layers-page.ts index 9bd8335d..80ed5255 100644 --- a/src/js/logic/pdf-layers-page.ts +++ b/src/js/logic/pdf-layers-page.ts @@ -423,9 +423,7 @@ document.addEventListener('DOMContentLoaded', () => { const blob = new Blob([new Uint8Array(pdfBytes)], { type: 'application/pdf', }); - const outName = - currentFile!.name.replace(/\.pdf$/i, '') + '_layers.pdf'; - downloadFile(blob, outName); + downloadFile(blob, currentFile!.name); hideLoader(); resetState(); showAlert('Success', 'PDF with layer changes saved!', 'success'); diff --git a/src/js/logic/pdf-to-greyscale-page.ts b/src/js/logic/pdf-to-greyscale-page.ts index 41110506..d170d095 100644 --- a/src/js/logic/pdf-to-greyscale-page.ts +++ b/src/js/logic/pdf-to-greyscale-page.ts @@ -142,7 +142,7 @@ async function convert() { const resultBytes = await newPdfDoc.save(); downloadFile( new Blob([new Uint8Array(resultBytes)], { type: 'application/pdf' }), - 'greyscale.pdf' + files[0]?.name || 'document.pdf' ); showAlert( 'Success', diff --git a/src/js/logic/posterize-page.ts b/src/js/logic/posterize-page.ts index 6233848d..1bc1f80c 100644 --- a/src/js/logic/posterize-page.ts +++ b/src/js/logic/posterize-page.ts @@ -310,7 +310,7 @@ async function posterize() { const newPdfBytes = await newDoc.save(); downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - 'posterized.pdf' + pageState.file?.name || 'document.pdf' ); showAlert('Success', 'Your PDF has been posterized.'); diff --git a/src/js/logic/rasterize-pdf-page.ts b/src/js/logic/rasterize-pdf-page.ts index d9efdd99..1d51ef4f 100644 --- a/src/js/logic/rasterize-pdf-page.ts +++ b/src/js/logic/rasterize-pdf-page.ts @@ -146,8 +146,7 @@ document.addEventListener('DOMContentLoaded', () => { } ); - const outName = file.name.replace(/\.pdf$/i, '') + '_rasterized.pdf'; - downloadFile(rasterizedBlob, outName); + downloadFile(rasterizedBlob, file.name); hideLoader(); showAlert( @@ -177,9 +176,7 @@ document.addEventListener('DOMContentLoaded', () => { quality: 95, }); - const outName = - file.name.replace(/\.pdf$/i, '') + '_rasterized.pdf'; - const zipEntryName = deduplicateFileName(outName, usedNames); + const zipEntryName = deduplicateFileName(file.name, usedNames); zip.file(zipEntryName, rasterizedBlob); completed++; diff --git a/src/js/logic/redact.ts b/src/js/logic/redact.ts index 74467132..25d0ce27 100644 --- a/src/js/logic/redact.ts +++ b/src/js/logic/redact.ts @@ -35,7 +35,7 @@ export async function redact(redactions: RedactionRect[], canvasScale: number) { const redactedBytes = await state.pdfDoc.save(); downloadFile( new Blob([new Uint8Array(redactedBytes)], { type: 'application/pdf' }), - 'redacted.pdf' + state.files[0]?.name || 'document.pdf' ); } catch (e) { console.error(e); diff --git a/src/js/logic/remove-annotations-page.ts b/src/js/logic/remove-annotations-page.ts index 17c77c0d..1fb199fa 100644 --- a/src/js/logic/remove-annotations-page.ts +++ b/src/js/logic/remove-annotations-page.ts @@ -144,7 +144,7 @@ async function processRemoveAnnotations() { const newPdfBytes = await pageState.pdfDoc.save(); downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - 'annotations-removed.pdf' + pageState.file?.name || 'document.pdf' ); showAlert('Success', 'Annotations removed successfully!', 'success', () => { resetState(); diff --git a/src/js/logic/remove-blank-pages-page.ts b/src/js/logic/remove-blank-pages-page.ts index 5af9fc6c..3700226d 100644 --- a/src/js/logic/remove-blank-pages-page.ts +++ b/src/js/logic/remove-blank-pages-page.ts @@ -313,7 +313,7 @@ async function processRemoveBlankPages() { const newPdfBytes = await newPdf.save(); downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - 'blank-pages-removed.pdf' + pageState.file?.name || 'document.pdf' ); showAlert( 'Success', diff --git a/src/js/logic/remove-metadata-page.ts b/src/js/logic/remove-metadata-page.ts index 2573a1bb..ab5a60f8 100644 --- a/src/js/logic/remove-metadata-page.ts +++ b/src/js/logic/remove-metadata-page.ts @@ -158,7 +158,7 @@ async function removeMetadata() { const newPdfBytes = await pdfDoc.save(); downloadFile( new Blob([newPdfBytes as BlobPart], { type: 'application/pdf' }), - 'metadata-removed.pdf' + pageState.file?.name || 'document.pdf' ); showAlert('Success', 'Metadata removed successfully!', 'success', () => { resetState(); diff --git a/src/js/logic/remove-restrictions-page.ts b/src/js/logic/remove-restrictions-page.ts index 1f10924b..1bdfd0a2 100644 --- a/src/js/logic/remove-restrictions-page.ts +++ b/src/js/logic/remove-restrictions-page.ts @@ -153,7 +153,7 @@ async function removeRestrictions() { const blob = new Blob([new Uint8Array(outputFile)], { type: 'application/pdf', }); - downloadFile(blob, `unrestricted-${pageState.file.name}`); + downloadFile(blob, pageState.file.name); if (loaderModal) loaderModal.classList.add('hidden'); diff --git a/src/js/logic/reverse-pages-page.ts b/src/js/logic/reverse-pages-page.ts index a31744a0..7d026ba3 100644 --- a/src/js/logic/reverse-pages-page.ts +++ b/src/js/logic/reverse-pages-page.ts @@ -124,20 +124,16 @@ async function reversePages() { showLoader(`Reversing ${file.name} (${j + 1}/${validFiles.length})...`); const newPdfBytes = await reverseSingleFile(file); - const originalName = file.name.replace(/\.pdf$/i, ''); - const fileName = `${originalName}_reversed.pdf`; - const zipEntryName = deduplicateFileName(fileName, usedNames); + const zipEntryName = deduplicateFileName(file.name, usedNames); zip.file(zipEntryName, newPdfBytes); } if (validFiles.length === 1) { const file = validFiles[0]; const newPdfBytes = await reverseSingleFile(file); - const originalName = file.name.replace(/\.pdf$/i, ''); - downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - `${originalName}_reversed.pdf` + file.name ); } else { const zipBlob = await zip.generateAsync({ type: 'blob' }); diff --git a/src/js/logic/rotate-custom-page.ts b/src/js/logic/rotate-custom-page.ts index 72cf1249..4be3632e 100644 --- a/src/js/logic/rotate-custom-page.ts +++ b/src/js/logic/rotate-custom-page.ts @@ -319,11 +319,9 @@ async function applyRotations() { } const rotatedPdfBytes = await newPdfDoc.save(); - const originalName = pageState.file.name.replace(/\.pdf$/i, ''); - downloadFile( new Blob([new Uint8Array(rotatedPdfBytes)], { type: 'application/pdf' }), - `${originalName}_rotated.pdf` + pageState.file.name ); showAlert( diff --git a/src/js/logic/rotate-pdf-page.ts b/src/js/logic/rotate-pdf-page.ts index a37433f3..654b4042 100644 --- a/src/js/logic/rotate-pdf-page.ts +++ b/src/js/logic/rotate-pdf-page.ts @@ -246,13 +246,11 @@ async function applyRotations() { new Uint8Array(pdfBytes), pageState.rotations ); - const originalName = pageState.file.name.replace(/\.pdf$/i, ''); - downloadFile( new Blob([rotatedPdfBytes as unknown as BlobPart], { type: 'application/pdf', }), - `${originalName}_rotated.pdf` + pageState.file.name ); showAlert( diff --git a/src/js/logic/sanitize-pdf-page.ts b/src/js/logic/sanitize-pdf-page.ts index d7ae9fb6..a758b4f2 100644 --- a/src/js/logic/sanitize-pdf-page.ts +++ b/src/js/logic/sanitize-pdf-page.ts @@ -147,7 +147,7 @@ async function runSanitize() { downloadFile( new Blob([new Uint8Array(result.bytes)], { type: 'application/pdf' }), - 'sanitized.pdf' + pageState.file?.name || 'document.pdf' ); showAlert( 'Success', diff --git a/src/js/logic/scanner-effect-page.ts b/src/js/logic/scanner-effect-page.ts index 5f995fe8..48d5e538 100644 --- a/src/js/logic/scanner-effect-page.ts +++ b/src/js/logic/scanner-effect-page.ts @@ -257,7 +257,7 @@ async function processAllPages(): Promise { const resultBytes = await newPdfDoc.save(); downloadFile( new Blob([new Uint8Array(resultBytes)], { type: 'application/pdf' }), - 'scanned.pdf' + files[0]?.name || 'document.pdf' ); showAlert( 'Success', diff --git a/src/js/logic/sign-pdf-page.ts b/src/js/logic/sign-pdf-page.ts index e2af79db..d2de5caa 100644 --- a/src/js/logic/sign-pdf-page.ts +++ b/src/js/logic/sign-pdf-page.ts @@ -303,10 +303,7 @@ async function applyAndSaveSignatures() { const blob = new Blob([new Uint8Array(flattenedPdfBytes)], { type: 'application/pdf', }); - downloadFile( - blob, - `signed_flattened_${signState.file?.name || 'document.pdf'}` - ); + downloadFile(blob, signState.file?.name || 'document.pdf'); hideLoader(); showAlert('Success', 'Signed PDF saved successfully!', 'success', () => { diff --git a/src/js/logic/table-of-contents.ts b/src/js/logic/table-of-contents.ts index b079e19e..f60406bc 100644 --- a/src/js/logic/table-of-contents.ts +++ b/src/js/logic/table-of-contents.ts @@ -180,10 +180,7 @@ worker.onmessage = (e: MessageEvent) => { const pdfBytes = new Uint8Array(pdfBytesBuffer); const blob = new Blob([pdfBytes], { type: 'application/pdf' }); - downloadFile( - blob, - pdfFile?.name.replace('.pdf', '_with_toc.pdf') || 'output_with_toc.pdf' - ); + downloadFile(blob, pdfFile?.name || 'document.pdf'); showStatus( 'Table of contents generated successfully! Download started.', diff --git a/src/js/logic/text-color-page.ts b/src/js/logic/text-color-page.ts index e6a73822..d184c2a2 100644 --- a/src/js/logic/text-color-page.ts +++ b/src/js/logic/text-color-page.ts @@ -186,7 +186,7 @@ async function changeTextColor() { const newPdfBytes = await newPdfDoc.save(); downloadFile( new Blob([new Uint8Array(newPdfBytes)], { type: 'application/pdf' }), - 'text-color-changed.pdf' + pageState.file?.name || 'document.pdf' ); showAlert('Success', 'Text color changed successfully!', 'success', () => { resetState(); diff --git a/src/js/logic/timestamp-pdf-page.ts b/src/js/logic/timestamp-pdf-page.ts index 97b8d690..4ee591d8 100644 --- a/src/js/logic/timestamp-pdf-page.ts +++ b/src/js/logic/timestamp-pdf-page.ts @@ -227,14 +227,10 @@ async function processTimestamp(): Promise { try { const timestampedBytes = await timestampPdf(state.pdfBytes, tsaUrl); - const outputFilename = state.pdfFile.name.replace( - /\.pdf$/i, - '_timestamped.pdf' - ); const blob = new Blob([new Uint8Array(timestampedBytes)], { type: 'application/pdf', }); - downloadFile(blob, outputFilename); + downloadFile(blob, state.pdfFile.name); showAlert( 'Success', diff --git a/src/partials/navbar.html b/src/partials/navbar.html index ae540cff..6470c9b7 100644 --- a/src/partials/navbar.html +++ b/src/partials/navbar.html @@ -30,10 +30,10 @@ >Licensing All ToolsDocs Licensing All ToolsDocs