Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

signpdf

A privacy-first, in-browser document signer. Upload a document, add your signature, download the signed PDF — your file never leaves your browser.

License: MIT Client-side Privacy-first PRs Welcome

English · العربية


English

What it does

  • Upload anything — PDF, Word, Excel, PowerPoint, images, or text files. Non-PDF office files are converted to PDF by a small, optional, self-hosted LibreOffice service.
  • Add a signature — either:
    • Upload an image of your signature — a smart, luminance-based background remover strips the paper background, with a live-preview threshold slider, or
    • Draw it directly on a signature pad.
  • Place it — drag, resize, and position the signature anywhere on any page.
  • Download — get the signed PDF instantly.

The UI is bilingual-friendly (Arabic RTL first) and uses icons rather than emojis.

Privacy

All signing happens inside your browser. Rendering (pdf.js), signature stamping, and saving (pdf-lib) are done entirely client-side — the document is never uploaded to any server.

The only optional server component is the Office→PDF conversion step (convert.py), needed only for Word/Excel/PowerPoint/text inputs — and you host that yourself. PDFs and images never touch it. The converter keeps nothing: each request runs in a private temp directory that is deleted immediately after conversion.

Architecture

Piece Role
index.html The whole app — UI, pdf.js rendering, signature tools, pdf-lib stamping/saving. Pure static file.
vendor/ Offline-vendored libraries (pdf.js, pdf-lib) — works with no internet access.
convert.py Optional Flask microservice (127.0.0.1:8000): converts office/text files to PDF via LibreOffice headless. Hardened: size limits, extension allowlist, isolated per-job profiles, hard timeouts with process-group kill, concurrency cap, and no shell.

Quick start

Just signing PDFs and images? No server needed at all:

# open index.html directly, or serve the folder statically:
python3 -m http.server 8080
# -> http://localhost:8080

Want Word/Excel/PowerPoint support too? Run the converter beside it:

sudo apt install libreoffice python3-flask fonts-noto   # or your distro's equivalents
python3 convert.py                                      # listens on 127.0.0.1:8000

Then have your web server proxy /convert to 127.0.0.1:8000 (nginx example):

location /convert {
    proxy_pass http://127.0.0.1:8000/convert;
    client_max_body_size 64m;
}

That's it — static files + one optional endpoint.

Contributing

PRs are welcome! Keep the core principle intact: no document data may leave the browser (the converter is the single, explicit exception, and it must remain stateless).

License

MIT © 2026 Ahmed. Bundled third-party libraries are listed in THIRD-PARTY.md.


العربية

ما هو؟

أداة توقيع مستندات تحترم خصوصيتك — كل شيء يجري داخل متصفّحك.

  • ارفع أي ملف — PDF أو Word أو Excel أو PowerPoint أو صورة أو ملف نصي. الملفات المكتبية غير الـPDF تُحوَّل إلى PDF عبر خدمة LibreOffice صغيرة اختيارية تستضيفها بنفسك.
  • أضف توقيعك — إمّا:
    • رفع صورة لتوقيعك، مع إزالة خلفية ذكية (تعتمد على الإضاءة/اللمعان) وشريط ضبط بمعاينة حيّة، أو
    • رسمه مباشرة بلوحة رسم.
  • ضعه على الورقة — اسحبه وكبّره وحرّكه على أي صفحة.
  • نزّل — احصل على الـPDF الموقّع فوراً.

الواجهة عربية RTL أولاً، وتستخدم أيقونات بدل الإيموجي.

الخصوصية

كل عملية التوقيع تتم داخل المتصفّح. العرض (pdf.js) وختم التوقيع والحفظ (pdf-lib) كلها على جهازك — المستند لا يُرفع إلى أي سيرفر.

الاستثناء الوحيد الاختياري هو خطوة تحويل ملفات أوفيس إلى PDF (convert.py)، وتلزم فقط لملفات Word/Excel/PowerPoint/النصوص — وأنت من يستضيفها. ملفات PDF والصور لا تمرّ بها إطلاقاً. والمحوّل لا يحتفظ بشيء: كل طلب يعمل في مجلد مؤقت خاص يُحذف فور انتهاء التحويل.

البنية

الجزء الدور
index.html التطبيق كاملاً — الواجهة، عرض pdf.js، أدوات التوقيع، الختم والحفظ بـpdf-lib. ملف ثابت بحت.
vendor/ المكتبات مضمّنة محلياً (pdf.js وpdf-lib) — يعمل بلا إنترنت.
convert.py خدمة Flask اختيارية (127.0.0.1:8000): تحويل الملفات المكتبية/النصية إلى PDF عبر LibreOffice headless. محصّنة: حد حجم، قائمة امتدادات مسموحة، ملف تعريف معزول لكل مهمة، مهلة صارمة تقتل مجموعة العملية بالكامل، حدّ للتزامن، وبلا shell.

التشغيل السريع

توقيع PDF وصور فقط؟ لا تحتاج أي سيرفر:

# افتح index.html مباشرة، أو قدّم المجلد كملفات ثابتة:
python3 -m http.server 8080
# -> http://localhost:8080

تبي دعم Word/Excel/PowerPoint؟ شغّل المحوّل بجانبها:

sudo apt install libreoffice python3-flask fonts-noto
python3 convert.py     # يستمع على 127.0.0.1:8000

ثم وجّه مسار /convert من خادم الويب إلى 127.0.0.1:8000 (مثال nginx موجود في القسم الإنجليزي أعلاه).

المساهمة

المساهمات مرحّب بها! حافظ على المبدأ الأساسي: لا تخرج بيانات المستند من المتصفّح (المحوّل هو الاستثناء الوحيد الصريح، ويجب أن يبقى بلا حالة/تخزين).

الرخصة

MIT © 2026 Ahmed. المكتبات المضمّنة موثّقة في THIRD-PARTY.md.

About

Privacy-first, in-browser document signer: convert any Office/PDF/image to PDF, sign it (draw or upload with smart background removal), place & download — nothing leaves your browser. Bilingual AR/EN.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages