PdfFinalBoss is a web app for unlocking and locking PDFs and converting common document formats to PDF. It has a React and Vite frontend and an Express API that uses qpdf for PDF encryption operations.
- π Live application: pdf-final-boss.vercel.app
- π» Source repository: github.com/ashishgit4/PdfFinalBoss
- β Support: Ko-fi
The interface includes day and night themes, password strength feedback, a random password generator, and a support page with Ko-fi and UPI options.
Unlock password-protected PDFs when you have the correct open password, or remove restrictions from PDFs that do not require an open password.
Protect a PDF with a password using qpdf's AES-256 encryption. The password form includes a strength indicator, a random password generator, and an optional hint.
Convert supported Word, Excel, PowerPoint, image, text, CSV, HTML, and Markdown files into PDFs. Conversion can run in the browser or on the backend depending on the file type and conversion path.
Save a password in the browser and match it to the PDF's SHA-256 hash so the app can offer it again for the same file. See the security note below before enabling this feature.
Switch between the app's day and night appearances.
Support links are available through Ko-fi and UPI.
The server accepts files up to 100 MB. Uploaded and generated files are stored under backend/uploads while processing and are removed after 24 hours; files left from a previous server run are cleared when the backend starts.
Password vault detail: The current frontend stores the opted-in password as plain text in the browser's
localStorage. It is not encrypted by the backend crypto helpers. Anyone with access to that browser profile or its developer tools may be able to read it. Do not use the vault on a shared or untrusted device.
- Open the application and choose Unlock, Lock, or Convert.
- Select or drop a file. PDFs are required for lock and unlock; conversion accepts the listed document formats. The maximum file size is 100 MB.
- For an encrypted PDF, enter its password to unlock it. To lock a PDF, choose a password and optionally add a hint, then download the resulting file.
- To convert a document, upload it in Convert mode and download the generated PDF when processing finishes.
- The optional password vault can offer a saved password again when the same PDF is uploaded. See the vault security note above before enabling it.
unlockpdf/
βββ backend/
β βββ bin/ # Bundled qpdf binary for Windows
β βββ cryptoHelper.js # SHA-256, AES-256-GCM and PBKDF2 helper functions
β βββ cryptoHelper.test.js # Backend unit tests
β βββ server.js # Express API and conversion logic
β βββ .env.example
β βββ package.json
βββ frontend/
β βββ src/
β β βββ components/ # React UI
β β βββ pages/ # Home and support pages
β β βββ services/ # API and document conversion code
β βββ .env.example
β βββ package.json
βββ Dockerfile
βββ package.json # Convenience scripts
βββ vercel.json # Vercel frontend configuration
- Node.js 20 or later and npm. The Docker image uses Node 20; use that version for local development.
- qpdf on Linux/macOS, available on
PATH. On Windows, the backend uses the qpdf binary included inbackend/bin. - LibreOffice on the backend host for server-side conversion of Office and other supported formats. The Dockerfile installs LibreOffice. DOCX may use a remote Gotenberg-compatible converter as a fallback.
- Frontend: React 19, TypeScript, Vite, Tailwind CSS 4, React Router, Framer Motion, Lucide React, and Sonner.
- Backend: Node.js, Express, Multer, qpdf, LibreOffice, Helmet, CORS, and express-rate-limit.
- PDF and document handling: qpdf and pdf-lib on the backend; Mammoth, JSZip, html2pdf.js, and pdf-lib in browser-side conversion code.
- Project support: Ko-fi and UPI links.
- Tests and quality tools: Node.js test runner, TypeScript, ESLint, and Prettier.
Run commands from the repository root unless a command says otherwise.
-
Install frontend and backend dependencies:
npm ci --prefix frontend npm ci --prefix backend
-
Create local environment files from the examples.
macOS/Linux:
cp backend/.env.example backend/.env cp frontend/.env.example frontend/.env
PowerShell:
Copy-Item backend/.env.example backend/.env Copy-Item frontend/.env.example frontend/.env
-
Start the API in one terminal:
npm run dev --prefix backend
The API listens on
http://localhost:3000by default. Confirm it is running athttp://localhost:3000/api/health. -
Start the web app in another terminal:
npm run dev --prefix frontend
Open the local URL printed by Vite, usually
http://localhost:5173. Vite proxies/apirequests to the local backend.
To run the production frontend build locally:
npm run build --prefix frontend
npm run preview --prefix frontendAll variables are optional for basic local development. Copy the example files, then set only the values you need.
| Variable | Default | Purpose |
|---|---|---|
PORT |
3000 |
Port used by the Express API. |
GOTENBERG_URL |
Unset | Base URL of a Gotenberg-compatible service used as a DOCX conversion fallback when local LibreOffice conversion fails. DOCX_CONVERTER_API_URL is also accepted. |
| Variable | Default | Purpose |
|---|---|---|
VITE_API_URL |
Production API fallback | Base URL for the backend API. Set to http://localhost:3000 for local development. Vite's dev proxy is used for /api requests. |
Vite variables are included in browser code. Never put secrets in frontend/.env or in a VITE_* variable.
Run these from the repository root:
| Command | What it does |
|---|---|
npm run dev --prefix frontend |
Start the Vite development server. |
npm run dev --prefix backend |
Start the API with nodemon. |
npm start --prefix backend |
Start the API without nodemon. |
npm run build --prefix frontend |
Type-check and build the frontend. |
npm run lint --prefix frontend |
Run ESLint on the frontend. |
npm run typecheck --prefix frontend |
Run the frontend TypeScript check. |
npm test --prefix backend |
Run backend tests with Node's test runner. |
The backend exposes these main routes:
| Method | Route | Purpose |
|---|---|---|
GET |
/api/health |
Health check. |
POST |
/api/upload |
Upload a PDF for unlock/lock workflows. |
POST |
/api/unlock |
Unlock an uploaded PDF. |
POST |
/api/lock |
Encrypt an uploaded PDF. |
POST |
/api/convert |
Convert a supported document to PDF. |
POST |
/api/download-converted |
Download a converted PDF. |
Uploads and conversion requests are limited to 30 per IP per 15 minutes; API requests are limited to 100 per IP per 15 minutes. The API currently enables CORS for browser clients.
The browser sends PDF lock/unlock operations and backend conversions to the API. DOCX and PPTX also have frontend conversion code; conversion output and fidelity can differ by file and conversion path. The backend helper module contains AES-256-GCM password encryption and PBKDF2 hashing functions, but the current frontend vault does not use those helpers.
The conversion endpoint accepts .doc, .docx, .xls, .xlsx, .ppt, .pptx, .jpg, .jpeg, .png, .txt, .csv, .html, .htm, and .md files. Office, CSV, HTML, and Markdown conversion uses LibreOffice on the backend. Images and plain text also have built-in converters. Conversion fidelity depends on the source document and installed fonts.
The repository includes a Dockerfile that installs qpdf and LibreOffice on Debian. The backend package also references the repository root as a local npm package (file:..), so a container build must include the root package.json in the image before running npm install. Review the Dockerfile and build context before using it for deployment. For persistent upload storage, mount a volume at /app/backend/uploads; note that backend startup clears files already in that directory.
- The root
vercel.jsonconfigures a Vite frontend build and SPA fallback. SetVITE_API_URLin the frontend deployment environment to the publicly reachable backend URL. - Deploy the backend separately on a host that can run the Dockerfile or install Node.js, qpdf, and LibreOffice. Configure
PORTif the platform requires it. - If using the DOCX fallback, set
GOTENBERG_URLon the backend. Documents sent to this service leave the backend host, so configure a service you trust.
-
Create a branch for your change.
-
Install dependencies and configure the relevant environment file(s).
-
Start the backend and frontend, then make and review your change in the browser.
-
Before opening a pull request, run the relevant checks:
npm run build --prefix frontend npm run lint --prefix frontend npm test --prefix backend -
Include a short summary, screenshots for visible UI changes, and any configuration or deployment notes in the pull request.
- Frontend cannot reach the API: Make sure the backend is running on port 3000. Check
VITE_API_URLif you are not using Vite's local proxy. - PDF operations fail on Linux/macOS: Install qpdf and ensure
qpdfis onPATH. - Office conversion fails: Install LibreOffice and ensure
sofficeis onPATH. For DOCX, configureGOTENBERG_URLif local LibreOffice is unavailable. - Upload is rejected: Confirm the PDF is a valid PDF, or that the conversion file extension is supported, and that the file is below 100 MB.
- API reports the file expired: Uploads are temporary and are removed after 24 hours or when the backend restarts.
This project is licensed under the GNU General Public License v3.0. See the GPL-3.0 license text.
Developed by Ashish Sharma. Support the project on Ko-fi.