@mostajs/pdf-sign-ui 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 +15 -0
- package/llms.txt +10 -2
- package/package.json +31 -6
- package/src/headless.js +13 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@
|
|
|
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
|
+
- `buildSignRequest` transmet **`openPassword`** (mot de passe à l'ouverture, `@mostajs/pdf-sign`
|
|
11
|
+
0.2.0). Le jeu de clés recopié est **fermé** : l'option y disparaissait sans erreur, et le
|
|
12
|
+
document sortait déverrouillé alors que l'appelant le croyait fermé.
|
|
13
|
+
- `validateSignForm` refuse `openPassword` quand le moteur ne peut pas chiffrer, avec un message
|
|
14
|
+
**qui le nomme** — renvoyer celui des permissions envoyait chercher la panne du côté des cases
|
|
15
|
+
à cocher, qui n'y sont pour rien.
|
|
16
|
+
- `buildEngineViewModel` expose `canLock`.
|
|
17
|
+
|
|
18
|
+
### Modifié (RUPTURE d'installation)
|
|
19
|
+
- `peerDependencies["@mostajs/pdf-sign"]` : `^0.1.0` → `^0.2.0`. La 0.1.0 refusait le moteur 0.2.0
|
|
20
|
+
et faisait **échouer `npm install`** (ERESOLVE) chez tout consommateur des deux modules.
|
|
21
|
+
|
|
7
22
|
## [0.1.0] — 2026-07-01
|
|
8
23
|
|
|
9
24
|
### Ajouté
|
package/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @mostajs/pdf-sign-ui — fiche LLM
|
|
2
|
-
> Couche de PRÉSENTATION de @mostajs/pdf-sign : logique HEADLESS (validation du formulaire de signature, préréglages de documents officiels/SIH, view-models moteur & vérification, contrôleur orchestrant un `service` injecté). Framework-agnostique, zéro dépendance, testable sans navigateur. IMPLÉMENTÉ 0.
|
|
2
|
+
> Couche de PRÉSENTATION de @mostajs/pdf-sign : logique HEADLESS (validation du formulaire de signature, préréglages de documents officiels/SIH, view-models moteur & vérification, contrôleur orchestrant un `service` injecté). Framework-agnostique, zéro dépendance, testable sans navigateur. IMPLÉMENTÉ 0.2.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 · Moteur: ../mosta-pdf-sign
|
|
6
6
|
|
|
7
7
|
## RÔLE
|
|
@@ -41,3 +41,11 @@ Composants en React.createElement (pas de JSX à transpiler ; bundler pour les .
|
|
|
41
41
|
- box = [x1,y1,x2,y2] nombres finis ; sinon rejet. t (i18n) optionnel → identité.
|
|
42
42
|
- Composants React sans build JSX (React.createElement) : Node natif ne charge pas .jsx → test via loader (test:react) ; en prod un bundler résout .jsx.
|
|
43
43
|
- field.stampImage propagé par buildSignRequest (cachet image, moteur pyhanko).
|
|
44
|
+
|
|
45
|
+
## 0.2.0 — MOT DE PASSE D'OUVERTURE
|
|
46
|
+
- buildSignRequest transmet `openPassword` (jeu de clés FERMÉ : avant 0.2.0 il le PERDAIT en
|
|
47
|
+
silence — document réputé verrouillé, et ouvrable).
|
|
48
|
+
- validateSignForm refuse `openPassword` sans pyhanko / avec engine node, avec un message QUI LE
|
|
49
|
+
NOMME (et non celui des permissions).
|
|
50
|
+
- buildEngineViewModel expose `canLock`.
|
|
51
|
+
- peerDependency @mostajs/pdf-sign passe à ^0.2.0 (l'option n'existe pas avant).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mostajs/pdf-sign-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Couche de présentation de @mostajs/pdf-sign — logique headless (validation du formulaire de signature, préréglages de documents officiels/SIH, view-models de vérification, contrôleur). Framework-agnostique, zéro dépendance.",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"author": "Dr Hamid MADANI <drmdh@msn.com>",
|
|
@@ -10,19 +10,44 @@
|
|
|
10
10
|
".": "./src/index.js",
|
|
11
11
|
"./react": "./src/react/index.js"
|
|
12
12
|
},
|
|
13
|
-
"files": [
|
|
13
|
+
"files": [
|
|
14
|
+
"src",
|
|
15
|
+
"README.md",
|
|
16
|
+
"llms.txt",
|
|
17
|
+
"CHANGELOG.md"
|
|
18
|
+
],
|
|
14
19
|
"scripts": {
|
|
15
20
|
"test": "node test-scripts/headless.test.mjs",
|
|
16
21
|
"test:react": "node --experimental-loader ./test-scripts/jsx-loader.mjs test-scripts/react.test.mjs",
|
|
17
22
|
"example": "node examples/verify-viewmodel.mjs"
|
|
18
23
|
},
|
|
19
24
|
"peerDependencies": {
|
|
20
|
-
"@mostajs/pdf-sign": "^0.
|
|
25
|
+
"@mostajs/pdf-sign": "^0.2.0",
|
|
21
26
|
"react": ">=18"
|
|
22
27
|
},
|
|
23
28
|
"peerDependenciesMeta": {
|
|
24
|
-
"@mostajs/pdf-sign": {
|
|
25
|
-
|
|
29
|
+
"@mostajs/pdf-sign": {
|
|
30
|
+
"optional": true
|
|
31
|
+
},
|
|
32
|
+
"react": {
|
|
33
|
+
"optional": true
|
|
34
|
+
}
|
|
26
35
|
},
|
|
27
|
-
"keywords": [
|
|
36
|
+
"keywords": [
|
|
37
|
+
"mostajs",
|
|
38
|
+
"pdf",
|
|
39
|
+
"signature",
|
|
40
|
+
"ui",
|
|
41
|
+
"headless",
|
|
42
|
+
"sih",
|
|
43
|
+
"pades"
|
|
44
|
+
],
|
|
45
|
+
"mostajs": {
|
|
46
|
+
"niveau": "N2",
|
|
47
|
+
"nature": "compose",
|
|
48
|
+
"reutilisabilite": "multi-domaine",
|
|
49
|
+
"depend_de": [
|
|
50
|
+
"@mostajs/pdf-sign"
|
|
51
|
+
]
|
|
52
|
+
}
|
|
28
53
|
}
|
package/src/headless.js
CHANGED
|
@@ -12,7 +12,7 @@ const IDENTITY = (s) => s;
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Valide le formulaire de signature.
|
|
15
|
-
* @param {object} data { input, p12, passphrase, passphraseFile, engine, box, page, permissions, preset }
|
|
15
|
+
* @param {object} data { input, p12, passphrase, passphraseFile, engine, box, page, permissions, openPassword, preset }
|
|
16
16
|
* @param {object} [opts] { engines?: {node,pyhanko}, t?: (k)=>string }
|
|
17
17
|
* @returns {{ valid: boolean, errors: Record<string,string> }}
|
|
18
18
|
*/
|
|
@@ -37,6 +37,13 @@ export function validateSignForm(data = {}, opts = {}) {
|
|
|
37
37
|
if (engine === "node") errors.permissions = t("Le cœur Node ne gère pas les permissions — choisir pyhanko.");
|
|
38
38
|
else if (!engines.pyhanko) errors.permissions = t("Permissions restrictives indisponibles : moteur pyhanko requis.");
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
// Le mot de passe d'ouverture est un CHIFFREMENT, et il a son propre message : renvoyer celui
|
|
42
|
+
// des permissions à qui n'a saisi qu'une clé l'enverrait chercher du côté des cases à cocher.
|
|
43
|
+
if (data.openPassword) {
|
|
44
|
+
if (engine === "node") errors.openPassword = t("Le cœur Node ne chiffre pas — choisir pyhanko pour un mot de passe d'ouverture.");
|
|
45
|
+
else if (!engines.pyhanko) errors.openPassword = t("Mot de passe d'ouverture indisponible : moteur pyhanko requis.");
|
|
46
|
+
}
|
|
40
47
|
if (engine === "pyhanko" && !engines.pyhanko) {
|
|
41
48
|
errors.engine = t("Moteur pyhanko indisponible sur ce serveur.");
|
|
42
49
|
}
|
|
@@ -88,6 +95,10 @@ export function buildSignRequest(data = {}) {
|
|
|
88
95
|
}),
|
|
89
96
|
field: prune({ page: numOrUndef(data.page), box: isBox(data.box) ? data.box : undefined, stampImage: data.stampImage }),
|
|
90
97
|
permissions,
|
|
98
|
+
// ⚠️ Ce jeu de clés est FERMÉ : une option que `buildSignRequest` ignore disparaît en silence,
|
|
99
|
+
// et le document sort sans elle — sans erreur. `openPassword` a été perdu ainsi jusqu'en
|
|
100
|
+
// 0.2.0 : le document s'ouvrait alors que l'appelant le croyait verrouillé.
|
|
101
|
+
openPassword: data.openPassword || undefined,
|
|
91
102
|
};
|
|
92
103
|
return prune(req);
|
|
93
104
|
}
|
|
@@ -114,6 +125,7 @@ export function buildEngineViewModel(availability = { node: true, pyhanko: false
|
|
|
114
125
|
pyhanko,
|
|
115
126
|
canRestrict: pyhanko,
|
|
116
127
|
canPades: pyhanko,
|
|
128
|
+
canLock: pyhanko, // mot de passe à l'ouverture (chiffrement) — même moteur
|
|
117
129
|
label: pyhanko ? t("PAdES + permissions (pyhanko)") : t("PKCS#7 (Node)"),
|
|
118
130
|
hint: pyhanko
|
|
119
131
|
? t("Signature avancée et permissions restrictives disponibles.")
|