{"id":50908209,"url":"https://github.com/aniketc068/atick-node","last_synced_at":"2026-06-16T07:04:12.851Z","repository":{"id":364991557,"uuid":"1269852844","full_name":"Aniketc068/ATick-Node","owner":"Aniketc068","description":"Standalone PDF digital-signature library for Node.js — PAdES/CMS signing (PFX/PEM, deferred eSign/HSM/token), RFC-3161 timestamps, LTV, green-tick appearance. Prebuilt native addon, cross-platform, npm install.","archived":false,"fork":false,"pushed_at":"2026-06-15T10:46:45.000Z","size":20104,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-15T12:26:06.434Z","etag":null,"topics":["digital-signature","esign","javascript","nodejs","npm","pades","pdf","typescript"],"latest_commit_sha":null,"homepage":"https://atick-node.readthedocs.io/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Aniketc068.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-15T06:49:19.000Z","updated_at":"2026-06-15T10:46:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Aniketc068/ATick-Node","commit_stats":null,"previous_names":["aniketc068/atick-node"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Aniketc068/ATick-Node","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aniketc068%2FATick-Node","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aniketc068%2FATick-Node/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aniketc068%2FATick-Node/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aniketc068%2FATick-Node/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Aniketc068","download_url":"https://codeload.github.com/Aniketc068/ATick-Node/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aniketc068%2FATick-Node/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34393306,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["digital-signature","esign","javascript","nodejs","npm","pades","pdf","typescript"],"created_at":"2026-06-16T07:04:11.928Z","updated_at":"2026-06-16T07:04:12.829Z","avatar_url":"https://github.com/Aniketc068.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-Node/main/assets/atick_logo.png\" alt=\"ATick\" width=\"260\"/\u003e\n\n# ATick for Node.js\n\n**Standalone PDF digital-signature library for Node.js — PAdES / CMS signing with no external services.**\n\n[![npm](https://img.shields.io/npm/v/atick?color=2ea44f\u0026label=npm)](https://www.npmjs.com/package/atick)\n[![Node](https://img.shields.io/badge/node-10%2B-339933?logo=node.js\u0026logoColor=white)](https://nodejs.org/)\n[![PAdES](https://img.shields.io/badge/PAdES-B--B%20%7C%20B--T%20%7C%20B--LT%20%7C%20B--LTA-success)](#pades-levels)\n[![Cross-platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-brightgreen)](#compatibility--one-package-everywhere)\n[![License: AGPL v3](https://img.shields.io/badge/license-AGPL--3.0-blue)](LICENSE)\n[![Also for Python](https://img.shields.io/badge/also%20for-Python-3776AB?logo=python\u0026logoColor=white)](https://github.com/Aniketc068/ATick-Python)\n[![Also for Java](https://img.shields.io/badge/also%20for-Java-007396?logo=openjdk\u0026logoColor=white)](https://github.com/Aniketc068/ATick-Java)\n[![Also for .NET](https://img.shields.io/badge/also%20for-.NET-512BD4?logo=dotnet\u0026logoColor=white)](https://github.com/Aniketc068/ATick-DotNet)\n[![Also for PHP](https://img.shields.io/badge/also%20for-PHP-777BB4?logo=php\u0026logoColor=white)](https://github.com/Aniketc068/ATick-PHP)\n\n\u003c/div\u003e\n\n**Also available in other languages** — the same ATick engine, the same API, native to each ecosystem:\n\n| Language | Install | Source · Docs |\n|---|---|---|\n| **Python** | `pip install atick` | [ATick-Python](https://github.com/Aniketc068/ATick-Python) · [docs](https://atick.readthedocs.io/) |\n| **Java** | `io.github.aniketc068:atick` (Maven) | [ATick-Java](https://github.com/Aniketc068/ATick-Java) · [docs](https://atick-java.readthedocs.io/) |\n| **.NET** | `dotnet add package ATick` | [ATick-DotNet](https://github.com/Aniketc068/ATick-DotNet) · [docs](https://atick-dotnet.readthedocs.io/) |\n| **PHP** | `composer require aniketc068/atick` | [ATick-PHP](https://github.com/Aniketc068/ATick-PHP) · [docs](https://atick-php.readthedocs.io/) |\n\n---\n\nATick signs PDFs the way Adobe Acrobat and the EU DSS do — **PAdES baseline** signatures with\ntimestamps and long-term validation. It ships a **prebuilt native addon** (N-API), so there is **no\nbuild step**, **no external service** and **nothing to compile** — `npm install atick` and you are done.\n\n```js\nconst atick = require(\"atick\");\nconst fs = require(\"fs\");\n\nconst pdf = fs.readFileSync(\"doc.pdf\");\nconst pfx = fs.readFileSync(\"my.pfx\");\n\nconst signed = atick.signPfx(pdf, pfx, JSON.stringify({\n  password: \"••••\", cn: \"Aniket Chaturvedi\", reason: \"Approved\",\n  green_tick: true, page: 1, rect: [300, 55, 575, 175],\n  pades: true, timestamp: true, ltv: true,           // PAdES-B-LT\n}));\n\nfs.writeFileSync(\"signed.pdf\", signed);\n```\n\n\u003e **Runs server-side** (Node runtime) — Next.js API routes / server actions, Express, NestJS,\n\u003e serverless functions, CLI tools. It is a native module, so it does **not** run in the browser.\n\n---\n\n## The green tick your readers trust\n\nATick draws a verified-signature appearance with a green tick. When the certificate is valid and\ntrusted, Adobe Reader / Acrobat shows **“Signed and all signatures are valid.”**\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-Node/main/assets/valid_signature_adobe.png\" alt=\"Adobe — signed and all signatures are valid\" width=\"560\"/\u003e\n\u003c/div\u003e\n\n\u003ctable align=\"center\"\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-Node/main/assets/signature_appearance.png\" width=\"190\"/\u003e\u003cbr/\u003e\u003cb\u003eValid \u0026amp; trusted\u003c/b\u003e\u003cbr/\u003egreen tick\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-Node/main/assets/sig_unknown.png\" width=\"190\"/\u003e\u003cbr/\u003e\u003cb\u003eValidity unknown\u003c/b\u003e\u003cbr/\u003eyellow “?”\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-Node/main/assets/sig_notverified.png\" width=\"190\"/\u003e\u003cbr/\u003e\u003cb\u003eNot verified\u003c/b\u003e\u003cbr/\u003e“?” not validated\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-Node/main/assets/sig_invalid.png\" width=\"190\"/\u003e\u003cbr/\u003e\u003cb\u003eInvalid\u003c/b\u003e\u003cbr/\u003ered cross\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n## Install\n\n```bash\nnpm install atick\n```\n\nThe prebuilt native addon for your platform comes with the package — no `node-gyp`, no compiler,\nno `postinstall` build.\n\n---\n\n## Quick start (TypeScript)\n\n```ts\nimport * as atick from \"atick\";\nimport { readFileSync, writeFileSync } from \"fs\";\n\nconst signed = atick.signPfx(\n  readFileSync(\"doc.pdf\"),\n  readFileSync(\"my.pfx\"),\n  JSON.stringify({ password: \"••••\", cn: \"Aniket\", pades: true, page: 1, rect: [300, 55, 575, 175] }),\n);\nwriteFileSync(\"signed.pdf\", signed);\n```\n\nFull TypeScript types ship in the package (`index.d.ts`).\n\n---\n\n## Features (A → Z)\n\n| Feature | How |\n|---|---|\n| **Sign with a `.pfx` / `.p12` / `.pem`** | `atick.signPfx(pdf, pfx, options)` — PKCS#12 or PEM (key + certs), auto-detected |\n| **PAdES levels** B-B / B-T / B-LT / B-LTA | `\"pades\":true` + `\"timestamp\":true` + `\"ltv\":true` + `\"lta\":true` |\n| **Hash algorithm** | `\"hash_algo\":\"sha256\" \\| \"sha384\" \\| \"sha512\"` |\n| **Timestamp authority** | built in — or your own with `\"tsa_url\":\"…\"` (and `\"tsa_auth\":[\"user\",\"pass\"]`) |\n| **Long-term validation (LTV)** | `\"ltv\":true` embeds the chain + revocation (CRL/OCSP) |\n| **Multi-page / custom coordinates** | `\"placements\":[[page,[x1,y1,x2,y2]], …]` |\n| **Signature layout** | `\"mode\":\"single\"` (one signature on many pages) · `\"mode\":\"shared\"` (many fields, same value) |\n| **Multi-signatory** | sign an already-signed PDF again — each signature is its own revision, all stay valid |\n| **Certification (DocMDP)** | `\"certify\":1` (no changes) · `2` (form filling) · `3` (form filling + annotations) |\n| **Field locking (FieldMDP)** | `\"lock_fields\":[\"*\"]` or `[\"FieldA\", …]` |\n| **Pre-sign checks** | `\"verify_expiry\":true`, `\"verify_crl\":true`, `\"verify_ocsp\":true` (or `\"verify\":true`) |\n| **Document metadata** | `atick.setMetadata(pdf, options)` |\n| **Password protection** | `\"encrypt_password\"` (+ `\"owner_password\"`) for output; `\"open_password\"` for input; `atick.decrypt(pdf, pw)` |\n| **Appearance** | options `cn, org, ou, location, reason, text, date, dn, body, heading, image` — auto-fit text, transparent logo |\n| **The mark** | the `?` (Adobe greens it), an always-green tick, or nothing — see [The mark](#the-mark) |\n| **CN on the left** (Adobe-style) | `\"image\":\"cn\"` |\n| **Distinguished name** | `\"dn\":\"CN=…, O=…, C=IN\"` |\n| **Custom-text-only appearance** | `\"body\":\"*APPROVED*\\nby *Aniket*\"` — `\\n` = line, `*x*` = bold |\n| **Invisible signature** | `\"placements\":[]` |\n| **Sign an already-signed PDF** | sign again (incremental) — existing signatures stay valid; use a fresh `\"field_name\"` |\n| **Container only** | `atick.prepareFields(pdf, options)` |\n| **Document timestamp** | `\"lta\":true` while signing; `atick.addDocTimestamp(pdf, options)` afterwards (PAdES-B-LTA) |\n| **Fast signing** | revocation cache (ON by default) — `atick.setFastSigning(false)` to disable |\n| **Deferred / eSign (2-step)** | `atick.prepare(pdf, options)` → external CMS → `atick.embed(prepared, cms)` |\n| **Detached CMS** | `atick.cmsPfx(data, pfx, options)` |\n\n---\n\n## The API\n\n```js\natick.signPfx(pdf, pfx, optionsJson)         // sign with a .pfx / .p12 / .pem (auto-detected)\natick.prepare(pdf, optionsJson)              // deferred / eSign: returns { prepared, bytesToSign }\natick.cmsPfx(data, pfx, optionsJson)         // detached CMS over data\natick.embed(prepared, cms)                   // embed a detached CMS into a prepared PDF\natick.prepareFields(pdf, optionsJson)        // make an empty signature field (template)\natick.signField(pdf, pfx, optionsJson)       // sign an existing empty field\natick.setMetadata(pdf, optionsJson)          // Title / Author / Subject / Keywords / …\natick.addDocTimestamp(pdf, optionsJson)      // archive DocTimeStamp (PAdES-B-LTA)\natick.setFastSigning(true | false)           // revocation-cache toggle\natick.decrypt(pdf, password)                 // decrypt a password-protected PDF\natick.version()                              // engine version\n```\n\nAll buffers are Node `Buffer`s; all options are a JSON **string**. Any failure throws an `Error`\nwhose `.message` is the reason.\n\n### Options (JSON)\n\n`cn, org, ou, location, reason, text, date, dn, body, heading, show_mark, green_tick, always_check,\nmark_color (hex / name / [r,g,b]), mark_gradient, mark_scale, text_color, bg_color, border, font_size,\nwidth, height, page, rect, placements ([[page,[x1,y1,x2,y2]], …]), mode (single/shared), field_name,\npades, hash_algo (sha256/384/512), timestamp, tsa_url, tsa_auth, ltv, lta, certify, lock_fields,\nverify, verify_expiry, verify_crl, verify_ocsp, open_password, encrypt_password, owner_password,\ncontents_size`.\n\n---\n\n## The mark\n\n```js\n\"{… ,\\\"green_tick\\\":true}\"      // the \"?\" mark — Adobe paints it GREEN for valid+trusted, RED if invalid\n\"{… ,\\\"always_check\\\":true}\"    // the green-tick graphic as the base\n\"{… ,\\\"green_tick\\\":false}\"     // no mark — a plain signature\n```\n\nColour it: `\"mark_color\":\"#E53935\"`, `\"blue\"`, `[255,140,0]` — or a gradient `\"mark_gradient\":[\"red\",\"orange\",\"yellow\"]`.\n\n---\n\n## Deferred signing \u0026 Indian eSign (two-step)\n\nWhen the private key lives elsewhere (a token / HSM / smart-card, or an eSign ESP):\n\n```js\nconst { prepared, bytesToSign } = atick.prepare(pdf, JSON.stringify({\n  cn: \"DS TEST\", reason: \"eSign\", placements: [[1, [300, 55, 575, 175]]], contents_size: 16384,\n}));\n\n// the eSign InputHash is the SHA-256 of bytesToSign:\nconst crypto = require(\"crypto\");\nconst inputHash = crypto.createHash(\"sha256\").update(bytesToSign).digest(\"hex\");\n// ... sign with your provider / eSign ESP, get back a detached CMS ...\n\nconst signed = atick.embed(prepared, cms);\n```\n\n---\n\n## PAdES levels\n\n```js\natick.signPfx(pdf, pfx, \"{… ,\\\"pades\\\":true}\")                                       // B-B\natick.signPfx(pdf, pfx, \"{… ,\\\"pades\\\":true,\\\"timestamp\\\":true}\")                    // B-T\natick.signPfx(pdf, pfx, \"{… ,\\\"pades\\\":true,\\\"timestamp\\\":true,\\\"ltv\\\":true}\")       // B-LT\natick.signPfx(pdf, pfx, \"{… ,\\\"pades\\\":true,\\\"timestamp\\\":true,\\\"lta\\\":true}\")       // B-LTA\n```\n\n---\n\n## Compatibility — one package everywhere\n\n- **Node 10.16 → the latest** — the prebuilt addon uses N-API (ABI-stable), so one binary works\n  across every Node version, no rebuild.\n- **Every OS/arch** — a prebuilt addon ships for each platform:\n\n  | platform-arch | Covers |\n  |---|---|\n  | `win32-x64` / `win32-ia32` | **Windows 7 → 11**, 64 / 32-bit |\n  | `win32-arm64` | Windows on ARM64 |\n  | `linux-x64` / `linux-arm64` / `linux-arm` / `linux-ia32` | Linux x64 / ARM64 / ARM / 32-bit (glibc 2.17+, every distro) |\n  | `darwin-x64` / `darwin-arm64` | macOS Intel / Apple Silicon |\n\n---\n\n## Errors\n\n```js\ntry {\n  atick.signPfx(pdf, pfx, JSON.stringify({ password: \"wrong\" }));\n} catch (e) {\n  console.error(\"signing failed:\", e.message);\n}\n```\n\n---\n\n## License\n\nATick is **dual-licensed** — free for personal \u0026 open use, paid if you sell:\n\n- **Free under [GNU AGPL-3.0](LICENSE)** — personal projects, learning, internal use, and\n  open-source projects (released publicly under AGPL-3.0).\n- **Commercial license (paid)** — if you **build a product with ATick and sell it**, or use it in a\n  **closed-source / commercial** product, you must buy a commercial license first. Contact\n  **aniketc.pro@gmail.com** for a quote.\n\nSee [LICENSING.md](LICENSING.md) for details. © 2026 Aniket Chaturvedi.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faniketc068%2Fatick-node","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faniketc068%2Fatick-node","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faniketc068%2Fatick-node/lists"}