@mostajs/pdf-sign 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +35 -1
- package/dist/cli.js +7 -2
- package/dist/cli.js.map +1 -1
- package/dist/node-signer.d.ts.map +1 -1
- package/dist/node-signer.js +3 -0
- package/dist/node-signer.js.map +1 -1
- package/dist/pyhanko-signer.d.ts.map +1 -1
- package/dist/pyhanko-signer.js +3 -0
- package/dist/pyhanko-signer.js.map +1 -1
- package/dist/sign.d.ts.map +1 -1
- package/dist/sign.js +1 -0
- package/dist/sign.js.map +1 -1
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +3 -1
- package/dist/verify.js.map +1 -1
- package/llms.txt +12 -6
- package/package.json +10 -2
- package/python/sign_with_perms.py +37 -21
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@
|
|
|
4
4
|
|
|
5
5
|
Le format suit [Keep a Changelog](https://keepachangelog.com/fr/) ; versionnage [SemVer](https://semver.org/lang/fr/).
|
|
6
6
|
|
|
7
|
+
## 0.2.0 — 2026-09-21
|
|
8
|
+
|
|
9
|
+
### Ajouté
|
|
10
|
+
- **Mot de passe à l'ouverture** (`SignOptions.openPassword`, CLI `--open-password`). Jusqu'ici le
|
|
11
|
+
pipeline Python forçait `user=""` : le document était chiffré, mais s'ouvrait librement. Les
|
|
12
|
+
permissions n'étaient donc que **déclaratives** — un lecteur complaisant suffisait à les ignorer.
|
|
13
|
+
`openPassword` apporte le seul verrou **dur** du format : sans lui, le document ne s'ouvre pas.
|
|
14
|
+
- `VerifyOptions.openPassword` (CLI `verify --password`) : sans le mot de passe, les signatures d'un
|
|
15
|
+
document verrouillé sont illisibles — la vérification aurait répondu « non signé » sur un document
|
|
16
|
+
parfaitement signé.
|
|
17
|
+
- Un mot de passe **seul** chiffre sans rien restreindre d'autre que l'ouverture. Qui demande une
|
|
18
|
+
clé ne demande pas, par la même occasion, de perdre son imprimante.
|
|
19
|
+
|
|
20
|
+
### Garde-fous
|
|
21
|
+
- `signNode` **lève** si `openPassword` est demandé. Le cœur Node signe mais ne chiffre pas :
|
|
22
|
+
accepter l'option en l'ignorant aurait rendu un document que l'on croit fermé et qui s'ouvre.
|
|
23
|
+
|
|
7
24
|
## [0.1.0] — 2026-07-01
|
|
8
25
|
|
|
9
26
|
### Ajouté
|
package/README.md
CHANGED
|
@@ -70,10 +70,44 @@ console.log(detectEngines());
|
|
|
70
70
|
mosta-pdf-sign sign in.pdf out.pdf --p12 cert.p12 --pass secret \
|
|
71
71
|
--reason "Ordonnance" --name "Dr H. Madani" --location "Alger, DZ"
|
|
72
72
|
mosta-pdf-sign sign in.pdf out.pdf --p12 cert.p12 --pass secret --restrict --engine pyhanko
|
|
73
|
-
mosta-pdf-sign
|
|
73
|
+
mosta-pdf-sign sign in.pdf out.pdf --p12 cert.p12 --pass secret --open-password ouvre-moi
|
|
74
|
+
mosta-pdf-sign verify out.pdf --trust ac-racine.pem [--password ouvre-moi]
|
|
74
75
|
mosta-pdf-sign engines
|
|
75
76
|
```
|
|
76
77
|
|
|
78
|
+
## Permissions, mot de passe — ce qui protège vraiment
|
|
79
|
+
|
|
80
|
+
Deux choses très différentes, et les confondre coûte cher :
|
|
81
|
+
|
|
82
|
+
| | `permissions` | `openPassword` |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| **Effet** | le document **demande** qu'on n'imprime ni ne copie | le document **ne s'ouvre pas** sans le mot de passe |
|
|
85
|
+
| **Qui l'applique** | le lecteur, s'il veut bien | le chiffrement — personne ne le contourne |
|
|
86
|
+
| **Le document s'ouvre** | librement | sur mot de passe seulement |
|
|
87
|
+
| **Moteur** | pyhanko | pyhanko |
|
|
88
|
+
|
|
89
|
+
Les permissions seules sont **déclaratives** : le mot de passe utilisateur reste vide, le document
|
|
90
|
+
s'ouvre, et Acrobat comme tous les lecteurs sérieux respectent les interdits — mais un outil qui
|
|
91
|
+
choisit de les ignorer le peut. C'est le format PDF, pas une faiblesse de ce module. Pour un verrou
|
|
92
|
+
que rien ne contourne, il faut `openPassword`.
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
// Ni impression ni copie, ET fermé à clé.
|
|
96
|
+
await signPdf({
|
|
97
|
+
input: "crh.pdf", output: "crh.signe.pdf", p12: "cert.p12", passphrase: "•••",
|
|
98
|
+
permissions: { extract: false, printLowres: false, printHighres: false },
|
|
99
|
+
openPassword: "ouvre-moi",
|
|
100
|
+
engine: "pyhanko",
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Un mot de passe SEUL : on ferme l'ouverture, on ne restreint rien d'autre.
|
|
104
|
+
await signPdf({ input: "note.pdf", p12: "cert.p12", passphrase: "•••", openPassword: "•••" });
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
> ⚠ Un document verrouillé se vérifie avec sa clé : `verifyPdf({ input, openPassword })`. Sans
|
|
108
|
+
> elle, ses signatures sont illisibles et la réponse serait « non signé » — sur un document
|
|
109
|
+
> parfaitement signé.
|
|
110
|
+
|
|
77
111
|
## Configuration (`.env`)
|
|
78
112
|
|
|
79
113
|
| Clé | Rôle |
|
package/dist/cli.js
CHANGED
|
@@ -22,8 +22,9 @@ const HELP = `mosta-pdf-sign — signature numérique de PDF (moteur hybride Nod
|
|
|
22
22
|
--pass <str> | --pass-file <fichier>
|
|
23
23
|
--engine auto|node|pyhanko (défaut auto)
|
|
24
24
|
--restrict permissions restrictives (PAdES pyhanko requis)
|
|
25
|
+
--open-password <str> mot de passe exigé à l'OUVERTURE (chiffrement, pyhanko requis)
|
|
25
26
|
--reason --name --location --contact
|
|
26
|
-
mosta-pdf-sign verify <pdf> [--trust cert.pem] [--engine ...]
|
|
27
|
+
mosta-pdf-sign verify <pdf> [--trust cert.pem] [--password <str>] [--engine ...]
|
|
27
28
|
mosta-pdf-sign engines état des moteurs disponibles
|
|
28
29
|
`;
|
|
29
30
|
async function main() {
|
|
@@ -53,6 +54,7 @@ async function main() {
|
|
|
53
54
|
passphraseFile: opt(argv, "pass-file"),
|
|
54
55
|
engine: opt(argv, "engine"),
|
|
55
56
|
permissions: flag(argv, "restrict") ? {} : undefined,
|
|
57
|
+
openPassword: opt(argv, "open-password"),
|
|
56
58
|
meta: {
|
|
57
59
|
reason: opt(argv, "reason"), name: opt(argv, "name"),
|
|
58
60
|
location: opt(argv, "location"), contact: opt(argv, "contact"),
|
|
@@ -67,7 +69,10 @@ async function main() {
|
|
|
67
69
|
process.stderr.write("PDF à vérifier manquant.\n");
|
|
68
70
|
process.exit(1);
|
|
69
71
|
}
|
|
70
|
-
const res = verifyPdf({
|
|
72
|
+
const res = verifyPdf({
|
|
73
|
+
input, trustPem: opt(argv, "trust"), openPassword: opt(argv, "password"),
|
|
74
|
+
engine: opt(argv, "engine"),
|
|
75
|
+
});
|
|
71
76
|
console.log(JSON.stringify(res, null, 2));
|
|
72
77
|
return;
|
|
73
78
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,SAAS,GAAG,CAAC,IAAc,EAAE,IAAY;IACvC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACpC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AACD,SAAS,IAAI,CAAC,IAAc,EAAE,IAAY;IACxC,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,IAAI,GAAG
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-signer.d.ts","sourceRoot":"","sources":["../src/node-signer.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE1D,iEAAiE;AACjE,wBAAsB,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"node-signer.d.ts","sourceRoot":"","sources":["../src/node-signer.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE1D,iEAAiE;AACjE,wBAAsB,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA0BrE"}
|
package/dist/node-signer.js
CHANGED
|
@@ -15,6 +15,9 @@ export async function signNode(opts) {
|
|
|
15
15
|
if (opts.permissions) {
|
|
16
16
|
throw new Error("Le cœur Node ne gère pas les permissions/PAdES — utilisez engine:'pyhanko' (python/setup-venv.sh).");
|
|
17
17
|
}
|
|
18
|
+
if (opts.openPassword) {
|
|
19
|
+
throw new Error("Le cœur Node ne chiffre pas — un mot de passe d'ouverture exige engine:'pyhanko' (python/setup-venv.sh).");
|
|
20
|
+
}
|
|
18
21
|
const pdfBuffer = typeof opts.input === "string" ? readFileSync(opts.input) : Buffer.from(opts.input);
|
|
19
22
|
const p12Buffer = typeof opts.p12 === "string" ? readFileSync(opts.p12) : Buffer.from(opts.p12);
|
|
20
23
|
const withPlaceholder = plainAddPlaceholder({
|
package/dist/node-signer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-signer.js","sourceRoot":"","sources":["../src/node-signer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGjE,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAiB;IAC9C,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,oGAAoG,CAAC,CAAC;IACxH,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtG,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEhG,MAAM,eAAe,GAAG,mBAAmB,CAAC;QAC1C,SAAS;QACT,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,WAAW;QACxC,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE;QACrC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE;QAC3B,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE;KACpC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAEjE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC3D,CAAC"}
|
|
1
|
+
{"version":3,"file":"node-signer.js","sourceRoot":"","sources":["../src/node-signer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGjE,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAiB;IAC9C,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,oGAAoG,CAAC,CAAC;IACxH,CAAC;IACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,0GAA0G,CAAC,CAAC;IAC9H,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtG,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEhG,MAAM,eAAe,GAAG,mBAAmB,CAAC;QAC1C,SAAS;QACT,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,WAAW;QACxC,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE;QACrC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE;QAC3B,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE;KACpC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAEjE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC3D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pyhanko-signer.d.ts","sourceRoot":"","sources":["../src/pyhanko-signer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAmB,UAAU,EAAE,MAAM,YAAY,CAAC;AAqB3E,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"pyhanko-signer.d.ts","sourceRoot":"","sources":["../src/pyhanko-signer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAmB,UAAU,EAAE,MAAM,YAAY,CAAC;AAqB3E,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAiCzE"}
|
package/dist/pyhanko-signer.js
CHANGED
|
@@ -45,6 +45,9 @@ export function signPyhanko(opts, python) {
|
|
|
45
45
|
stamp_image: opts.field?.stampImage,
|
|
46
46
|
},
|
|
47
47
|
permissions: perms,
|
|
48
|
+
// Chiffrement à l'ouverture. Transmis par le fichier de configuration, jamais par `argv` :
|
|
49
|
+
// une ligne de commande se lit dans la table des processus de toute la machine.
|
|
50
|
+
open_password: opts.openPassword || undefined,
|
|
48
51
|
};
|
|
49
52
|
const cfgPath = toFile(dir, "config.json", JSON.stringify(cfg));
|
|
50
53
|
execFileSync(python, [SIGN_PY, "sign", inPath, outPath, p12Path, passFile, cfgPath], { stdio: "inherit" });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pyhanko-signer.js","sourceRoot":"","sources":["../src/pyhanko-signer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,SAAS,MAAM,CAAC,GAAW,EAAE,IAAY,EAAE,IAAyB;IAClE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1B,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACvB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,cAAc,CAAC,CAAkB;IACxC,OAAO;QACL,aAAa,EAAE,CAAC,CAAC,aAAa,IAAI,IAAI;QACtC,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK;QAC3B,iBAAiB,EAAE,CAAC,CAAC,gBAAgB,IAAI,KAAK;QAC9C,eAAe,EAAE,CAAC,CAAC,cAAc,IAAI,KAAK;QAC1C,YAAY,EAAE,CAAC,CAAC,WAAW,IAAI,KAAK;QACpC,YAAY,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;QACnC,aAAa,EAAE,CAAC,CAAC,YAAY,IAAI,IAAI;KACtC,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW,CAAC,IAAiB,EAAE,MAAc;IAC3D,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/F,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAEpD,IAAI,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC;QACnC,IAAI,CAAC,QAAQ;YAAE,QAAQ,GAAG,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QAEtE,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzE,MAAM,GAAG,GAAG;YACV,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;YACrB,KAAK,EAAE;gBACL,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI;gBACtB,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC;gBAC3B,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC;gBAC3C,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU;aACpC;YACD,WAAW,EAAE,KAAK;
|
|
1
|
+
{"version":3,"file":"pyhanko-signer.js","sourceRoot":"","sources":["../src/pyhanko-signer.ts"],"names":[],"mappings":"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"}
|
package/dist/sign.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../src/sign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM1D,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../src/sign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM1D,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA+BpE"}
|
package/dist/sign.js
CHANGED
|
@@ -12,6 +12,7 @@ export async function signPdf(opts) {
|
|
|
12
12
|
meta: { ...cfg.meta, ...opts.meta },
|
|
13
13
|
field: { ...cfg.field, ...opts.field },
|
|
14
14
|
permissions: opts.permissions ?? (cfg.restrict ? {} : undefined),
|
|
15
|
+
openPassword: opts.openPassword,
|
|
15
16
|
engine: opts.engine ?? cfg.engine,
|
|
16
17
|
};
|
|
17
18
|
if (!merged.p12)
|
package/dist/sign.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sign.js","sourceRoot":"","sources":["../src/sign.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAiB;IAC7C,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAEhC,MAAM,MAAM,GAAgB;QAC1B,GAAG,IAAI;QACP,GAAG,EAAE,IAAI,CAAC,GAAG,IAAK,GAAG,CAAC,GAAc;QACpC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,GAAG,CAAC,UAAU;QAC7C,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,GAAG,CAAC,cAAc;QACzD,IAAI,EAAE,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE;QACnC,KAAK,EAAE,EAAE,GAAG,GAAG,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE;QACtC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAChE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;KAClC,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAE5F,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;IAErC,IAAI,MAA0B,CAAC;IAC/B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;QACvH,MAAM,GAAG,SAAS,CAAC;IACrB,CAAC;SAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,MAAM,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,yBAAyB;IACxE,CAAC;IAED,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,MAAgB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC/F,CAAC"}
|
|
1
|
+
{"version":3,"file":"sign.js","sourceRoot":"","sources":["../src/sign.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAiB;IAC7C,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAEhC,MAAM,MAAM,GAAgB;QAC1B,GAAG,IAAI;QACP,GAAG,EAAE,IAAI,CAAC,GAAG,IAAK,GAAG,CAAC,GAAc;QACpC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,GAAG,CAAC,UAAU;QAC7C,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,GAAG,CAAC,cAAc;QACzD,IAAI,EAAE,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE;QACnC,KAAK,EAAE,EAAE,GAAG,GAAG,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE;QACtC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAChE,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;KAClC,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAE5F,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;IAErC,IAAI,MAA0B,CAAC;IAC/B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;QACvH,MAAM,GAAG,SAAS,CAAC;IACrB,CAAC;SAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,MAAM,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,yBAAyB;IACxE,CAAC;IAED,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,MAAgB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC/F,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -45,6 +45,14 @@ export interface SignOptions {
|
|
|
45
45
|
field?: SignField;
|
|
46
46
|
/** Restrictions d'édition. `false`/absent = aucune (le cœur Node suffit) ; objet = PAdES pyhanko. */
|
|
47
47
|
permissions?: SignPermissions | false;
|
|
48
|
+
/**
|
|
49
|
+
* Mot de passe exigé à l'OUVERTURE du document (chiffrement AES-256, R=6).
|
|
50
|
+
*
|
|
51
|
+
* C'est le seul verrou DUR du format : sans lui, les permissions ne sont que déclaratives — le
|
|
52
|
+
* document s'ouvre librement et ce sont les lecteurs qui acceptent de les respecter. Requiert le
|
|
53
|
+
* moteur pyhanko. Seul (sans `permissions`), il ne restreint RIEN d'autre que l'ouverture.
|
|
54
|
+
*/
|
|
55
|
+
openPassword?: string;
|
|
48
56
|
/** `auto` (défaut) = pyhanko si dispo sinon Node ; `node` = PKCS#7 ; `pyhanko` = PAdES. */
|
|
49
57
|
engine?: SignEngine;
|
|
50
58
|
}
|
|
@@ -55,6 +63,8 @@ export interface SignResult {
|
|
|
55
63
|
}
|
|
56
64
|
export interface VerifyOptions {
|
|
57
65
|
input: string;
|
|
66
|
+
/** Mot de passe d'ouverture, si le document en porte un — sans lui, ses signatures sont illisibles. */
|
|
67
|
+
openPassword?: string;
|
|
58
68
|
/** Certificat de confiance (PEM) pour la validation pyhanko. */
|
|
59
69
|
trustPem?: string;
|
|
60
70
|
engine?: SignEngine;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,6DAA6D;AAC7D,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,yFAAyF;AACzF,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3B,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,qGAAqG;IACrG,WAAW,CAAC,EAAE,eAAe,GAAG,KAAK,CAAC;IACtC,2FAA2F;IAC3F,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,MAAM,EAAE,SAAS,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,6DAA6D;AAC7D,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,yFAAyF;AACzF,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3B,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,qGAAqG;IACrG,WAAW,CAAC,EAAE,eAAe,GAAG,KAAK,CAAC;IACtC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,uGAAuG;IACvG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,MAAM,EAAE,SAAS,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
package/dist/verify.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI9D,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI9D,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,YAAY,CAuB3D"}
|
package/dist/verify.js
CHANGED
|
@@ -18,7 +18,9 @@ export function verifyPdf(opts) {
|
|
|
18
18
|
const want = opts.engine ?? cfg.engine;
|
|
19
19
|
if (avail.pyhanko && want !== "node") {
|
|
20
20
|
try {
|
|
21
|
-
const args =
|
|
21
|
+
const args = [SIGN_PY, "verify", opts.input, trust ?? ""];
|
|
22
|
+
if (opts.openPassword)
|
|
23
|
+
args.push(opts.openPassword);
|
|
22
24
|
const out = execFileSync(avail.python, args, { encoding: "utf-8" });
|
|
23
25
|
const line = out.trim().split("\n").pop() ?? "{}";
|
|
24
26
|
const parsed = JSON.parse(line);
|
package/dist/verify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,UAAU,SAAS,CAAC,IAAmB;IAC3C,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC;IAEvC,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,UAAU,SAAS,CAAC,IAAmB;IAC3C,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC;IAEvC,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;YAC1D,IAAI,IAAI,CAAC,YAAY;gBAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACpD,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,MAAgB,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YAC9E,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC;YAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAChC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC7F,CAAC;QAAC,MAAM,CAAC;YACP,iCAAiC;QACnC,CAAC;IACH,CAAC;IAED,iFAAiF;IACjF,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,wCAAwC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5F,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACzG,CAAC"}
|
package/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @mostajs/pdf-sign — fiche LLM
|
|
2
|
-
> Signature numérique de PDF, moteur HYBRIDE : cœur Node (PKCS#7 détaché via @signpdf, zéro Python) + bascule pyhanko (PAdES visible + permissions AES-256) quand un venv est disponible. Config 100 % `.env`, CLI + API. Portage générique du pipeline pyhanko+pikepdf éprouvé. IMPLÉMENTÉ 0.1.0.
|
|
2
|
+
> Signature numérique de PDF, moteur HYBRIDE : cœur Node (PKCS#7 détaché via @signpdf, zéro Python) + bascule pyhanko (PAdES visible + permissions AES-256 + MOT DE PASSE d'ouverture) quand un venv est disponible. Config 100 % `.env`, CLI + API. Portage générique du pipeline pyhanko+pikepdf éprouvé. IMPLÉMENTÉ 0.1.0.
|
|
3
3
|
|
|
4
|
-
- Version: 0.
|
|
4
|
+
- Version: 0.2.0 · Licence: AGPL-3.0-or-later · Auteur: Dr Hamid MADANI <drmdh@msn.com>
|
|
5
5
|
- Chemin: mostajs/mosta-pdf-sign-stack/mosta-pdf-sign · UI: ../mosta-pdf-sign-ui
|
|
6
6
|
|
|
7
7
|
## RÔLE
|
|
@@ -19,13 +19,16 @@ La signature PAdES + permissions AES-256 garantit intégrité, authenticité et
|
|
|
19
19
|
## DEUX MOTEURS
|
|
20
20
|
- **node** (défaut si pas de venv) : PKCS#7 détaché, cachet invisible, aucune dépendance Python.
|
|
21
21
|
NE gère PAS permissions/chiffrement/PAdES.
|
|
22
|
-
- **pyhanko** (si venv) : PAdES visible + permissions restrictives (chiffrement AES-256, R=6) via le
|
|
22
|
+
- **pyhanko** (si venv) : PAdES visible + permissions restrictives + mot de passe d'ouverture (chiffrement AES-256, R=6) via le
|
|
23
23
|
script Python embarqué `python/sign_with_perms.py`. Pipeline : pikepdf chiffre → IncrementalPdfFileWriter
|
|
24
24
|
(writer.encrypt(owner)) → append_signature_field → PdfSigner PAdES. Préserve chiffrement ET signature.
|
|
25
25
|
- **auto** : pyhanko si dispo, sinon node.
|
|
26
26
|
|
|
27
27
|
## EXPORTS ("@mostajs/pdf-sign")
|
|
28
28
|
- signPdf(opts): Promise<SignResult> — fusionne opts + `.env`, dispatch node/pyhanko
|
|
29
|
+
· opts.openPassword : mot de passe exigé à l'OUVERTURE (0.2.0). Seul verrou DUR : sans lui les
|
|
30
|
+
permissions ne sont que déclaratives. Exige pyhanko. Seul (sans permissions), ne restreint
|
|
31
|
+
rien d'autre que l'ouverture.
|
|
29
32
|
- verifyPdf(opts): VerifyResult — validation pyhanko complète si dispo, sinon détection Node (/ByteRange)
|
|
30
33
|
- detectEngines(python?): EngineAvailability — { node:true, pyhanko:bool, python }
|
|
31
34
|
- resolvePython / pyhankoAvailable
|
|
@@ -40,8 +43,8 @@ PDF_SIGN_FIELD_PAGE / PDF_SIGN_FIELD_BOX ("x1,y1,x2,y2") · PDF_SIGN_STAMP_IMAGE
|
|
|
40
43
|
PDF_SIGN_TRUST_PEM (certificat de confiance pour la vérification)
|
|
41
44
|
|
|
42
45
|
## CLI
|
|
43
|
-
mosta-pdf-sign sign <in.pdf> [out.pdf] --p12 c.p12 --pass s [--engine …] [--restrict] [--reason …]
|
|
44
|
-
mosta-pdf-sign verify <pdf> [--trust cert.pem] [--engine …]
|
|
46
|
+
mosta-pdf-sign sign <in.pdf> [out.pdf] --p12 c.p12 --pass s [--engine …] [--restrict] [--open-password s] [--reason …]
|
|
47
|
+
mosta-pdf-sign verify <pdf> [--trust cert.pem] [--password s] [--engine …]
|
|
45
48
|
mosta-pdf-sign engines
|
|
46
49
|
|
|
47
50
|
## MOTEUR pyhanko (optionnel)
|
|
@@ -49,7 +52,10 @@ bash python/setup-venv.sh → .venv local → exporter PDF_SIGN_PYTHON=…/.ven
|
|
|
49
52
|
requiert pyhanko>=0.25, pikepdf>=8.
|
|
50
53
|
|
|
51
54
|
## PIÈGES
|
|
52
|
-
- Le cœur Node lève si `permissions` est demandé : le
|
|
55
|
+
- Le cœur Node lève si `permissions` OU `openPassword` est demandé : le chiffrement EXIGE pyhanko.
|
|
56
|
+
- `openPassword` implique le chiffrement même sans `permissions` — et n'impose alors AUCUNE
|
|
57
|
+
restriction (qui demande une clé ne demande pas de perdre son imprimante).
|
|
58
|
+
- vérifier un document verrouillé exige `verifyPdf({ openPassword })`, sinon ses signatures sont illisibles.
|
|
53
59
|
- `engine:'pyhanko'` sans venv → erreur explicite (lancer setup-venv.sh).
|
|
54
60
|
- p12 obligatoire (opts.p12 ou PDF_SIGN_P12) sinon throw.
|
|
55
61
|
- box en points PDF, origine bas-gauche (A4 = 595×842) ; défaut cachet bas-droite [320,40,575,140].
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mostajs/pdf-sign",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Signature numérique de PDF pour @mostajs — moteur HYBRIDE : cœur Node (PKCS#7 via @signpdf) + bascule pyhanko (PAdES + permissions AES-256) si disponible. Config .env, CLI, API. Réutilise le pipeline éprouvé pyhanko+pikepdf.",
|
|
5
5
|
"author": "Dr Hamid MADANI <drmdh@msn.com>",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|
|
@@ -56,5 +56,13 @@
|
|
|
56
56
|
"@mostajs/mjs-unit": "^0.4.1",
|
|
57
57
|
"@types/node": "^22.0.0",
|
|
58
58
|
"typescript": "^5.6.0"
|
|
59
|
+
},
|
|
60
|
+
"mostajs": {
|
|
61
|
+
"niveau": "N0",
|
|
62
|
+
"nature": "primitif",
|
|
63
|
+
"reutilisabilite": "universelle",
|
|
64
|
+
"depend_de": [
|
|
65
|
+
"@mostajs/config"
|
|
66
|
+
]
|
|
59
67
|
}
|
|
60
|
-
}
|
|
68
|
+
}
|
|
@@ -8,7 +8,7 @@ ET la validité cryptographique de la signature.
|
|
|
8
8
|
|
|
9
9
|
Usage :
|
|
10
10
|
sign_with_perms.py sign INPUT.pdf OUTPUT.pdf CERT.p12 PASSFILE CONFIG.json
|
|
11
|
-
sign_with_perms.py verify PDF CERT.pem
|
|
11
|
+
sign_with_perms.py verify PDF [CERT.pem] [MOT_DE_PASSE]
|
|
12
12
|
|
|
13
13
|
Le moteur Node (@mostajs/pdf-sign) écrit CONFIG.json puis appelle ce script.
|
|
14
14
|
|
|
@@ -37,23 +37,33 @@ def do_sign(inp, outp, p12_path, p12_pass_file, config_path):
|
|
|
37
37
|
field_cfg = cfg.get("field", {})
|
|
38
38
|
perms_cfg = cfg.get("permissions") # None => pas de chiffrement/restriction
|
|
39
39
|
|
|
40
|
+
# Mot de passe d'OUVERTURE : le seul verrou dur du format. Vide => le document s'ouvre
|
|
41
|
+
# librement et les permissions ne valent que par la bonne volonte des lecteurs.
|
|
42
|
+
user_pwd = cfg.get("open_password") or ""
|
|
43
|
+
|
|
40
44
|
src_buf = inp
|
|
41
|
-
# --- 1. permissions + chiffrement (optionnel) via pikepdf, en
|
|
45
|
+
# --- 1. permissions + chiffrement (optionnel) via pikepdf, en memoire ---
|
|
42
46
|
owner_pwd = None
|
|
43
|
-
if perms_cfg is not None:
|
|
44
|
-
|
|
47
|
+
if perms_cfg is not None or user_pwd:
|
|
48
|
+
quoi = "mot de passe" if perms_cfg is None else ("permissions + mot de passe" if user_pwd else "permissions")
|
|
49
|
+
print("-- 1/3 %s (chiffrement AES-256) --" % quoi, flush=True)
|
|
45
50
|
owner_pwd = "".join(secrets.choice(string.ascii_letters + string.digits) for _ in range(40))
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
if perms_cfg is None:
|
|
52
|
+
# Mot de passe SEUL : on verrouille l'ouverture, on ne restreint rien d'autre. Qui
|
|
53
|
+
# demande une cle ne demande pas, par la meme occasion, de perdre son imprimante.
|
|
54
|
+
perms = pikepdf.Permissions(modify_form=True)
|
|
55
|
+
else:
|
|
56
|
+
perms = pikepdf.Permissions(
|
|
57
|
+
accessibility=perms_cfg.get("accessibility", True),
|
|
58
|
+
extract=perms_cfg.get("extract", False),
|
|
59
|
+
modify_annotation=perms_cfg.get("modify_annotation", False),
|
|
60
|
+
modify_assembly=perms_cfg.get("modify_assembly", False),
|
|
61
|
+
modify_form=True, # requis pour signer apres chiffrement
|
|
62
|
+
modify_other=perms_cfg.get("modify_other", False),
|
|
63
|
+
print_lowres=perms_cfg.get("print_lowres", True),
|
|
64
|
+
print_highres=perms_cfg.get("print_highres", True),
|
|
65
|
+
)
|
|
66
|
+
encryption = pikepdf.Encryption(user=user_pwd, owner=owner_pwd, R=6, allow=perms)
|
|
57
67
|
buf = io.BytesIO()
|
|
58
68
|
with pikepdf.open(inp) as pdf:
|
|
59
69
|
pdf.save(buf, encryption=encryption)
|
|
@@ -119,7 +129,7 @@ def _cert_name(cert):
|
|
|
119
129
|
return str(cert) if cert else ""
|
|
120
130
|
|
|
121
131
|
|
|
122
|
-
def do_verify(pdf_path, cert_pem):
|
|
132
|
+
def do_verify(pdf_path, cert_pem, open_password=None):
|
|
123
133
|
import logging
|
|
124
134
|
# Silence les logs internes (tracebacks de chaîne de confiance) : on renvoie le verdict en JSON.
|
|
125
135
|
for name in ("pyhanko", "pyhanko_certvalidator"):
|
|
@@ -142,10 +152,14 @@ def do_verify(pdf_path, cert_pem):
|
|
|
142
152
|
# PDF chiffré (permissions restrictives) : s'authentifier avec le mot de passe
|
|
143
153
|
# utilisateur vide (lecture libre) avant d'énumérer les signatures.
|
|
144
154
|
if getattr(r, "encrypted", False):
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
155
|
+
# Le mot de passe d'ouverture d'abord s'il est donne, la chaine vide ensuite : un
|
|
156
|
+
# document non verrouille s'authentifie avec elle, un document verrouille l'exige.
|
|
157
|
+
for essai in ([open_password] if open_password else []) + [""]:
|
|
158
|
+
try:
|
|
159
|
+
r.decrypt(essai)
|
|
160
|
+
break
|
|
161
|
+
except Exception:
|
|
162
|
+
continue
|
|
149
163
|
sigs = r.embedded_signatures
|
|
150
164
|
if not sigs:
|
|
151
165
|
print(json.dumps({"signed": False, "signatures": []}))
|
|
@@ -167,7 +181,9 @@ if __name__ == "__main__":
|
|
|
167
181
|
if len(sys.argv) >= 2 and sys.argv[1] == "sign" and len(sys.argv) == 7:
|
|
168
182
|
do_sign(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])
|
|
169
183
|
elif len(sys.argv) >= 2 and sys.argv[1] == "verify" and len(sys.argv) >= 3:
|
|
170
|
-
do_verify(sys.argv[2],
|
|
184
|
+
do_verify(sys.argv[2],
|
|
185
|
+
sys.argv[3] if len(sys.argv) > 3 and sys.argv[3] else None,
|
|
186
|
+
sys.argv[4] if len(sys.argv) > 4 else None)
|
|
171
187
|
else:
|
|
172
188
|
print(__doc__)
|
|
173
189
|
sys.exit(1)
|