Version 2.7.0: Pruefung beim Oeffnen, Unterschrift in menschlichem Mass
This commit is contained in:
1 parent
de9c0d4fbd
commit
37a200e983
7 files changed
+114
-9
No files matched your search
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "tesm-core"
|
||||
version = "2.6.1"
|
||||
version = "2.7.0"
|
||||
description = "Gemeinsames Anwendungsgeruest (Auth, RBAC, Navigation, Design-System, Migrationen) fuer TESM und TESM-Lizenzserver"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
|
||||
@@ -148,7 +148,7 @@ def create_base_app(
|
||||
#: Wortmarke, ohne Zeile darunter; die Marke selbst zeigen beide
|
||||
#: Anwendungen.
|
||||
auth_tagline: str = "",
|
||||
app_version: str = "2.6.1",
|
||||
app_version: str = "2.7.0",
|
||||
built_in_trusted_keys: tuple[str, ...] = (),
|
||||
enable_license: bool = True,
|
||||
template_folder: str | None = None,
|
||||
|
||||
@@ -1458,3 +1458,50 @@
|
||||
pointer-events: none;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
/* -- Ergebnis der Signaturpruefung ---------------------------------------- */
|
||||
/* Der Schleier liegt ueber der Seite und nimmt keine Klicks an: ein
|
||||
unterschriebenes Dokument ist flach, aber bei einem Irrtum soll die
|
||||
Kennzeichnung nicht auch noch die Bedienung blockieren. */
|
||||
|
||||
.viewer__pdf--unveraendert {
|
||||
box-shadow: inset 0 0 0 3px var(--success);
|
||||
}
|
||||
|
||||
.viewer__pdf--unveraendert::after,
|
||||
.viewer__pdf--veraendert::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.viewer__pdf--unveraendert::after {
|
||||
background: rgba(47, 158, 68, 0.1);
|
||||
}
|
||||
|
||||
.viewer__pdf--veraendert {
|
||||
box-shadow: inset 0 0 0 3px var(--danger);
|
||||
}
|
||||
|
||||
.viewer__pdf--veraendert::after {
|
||||
background: rgba(201, 42, 42, 0.08);
|
||||
}
|
||||
|
||||
.viewer__pruefung {
|
||||
margin: 0;
|
||||
padding: 6px 12px;
|
||||
font-size: var(--fs-xs);
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.viewer__pruefung--gut {
|
||||
color: var(--success);
|
||||
background: rgba(47, 158, 68, 0.12);
|
||||
}
|
||||
|
||||
.viewer__pruefung--schlecht {
|
||||
color: var(--danger);
|
||||
background: rgba(201, 42, 42, 0.12);
|
||||
}
|
||||
@@ -601,9 +601,18 @@ async function pdfBetrachter(behaelter, seiten, url, basis, { formulare = true }
|
||||
const anteilY = (event.clientY - rechteck.top) / rechteck.height;
|
||||
const seite = await dokument.getPage(nummer);
|
||||
const blick = seite.getViewport({ scale: 1 });
|
||||
const breite = Math.min(170, blick.width * 0.35);
|
||||
const hoehe =
|
||||
(wartendeUnterschrift.hoehe / wartendeUnterschrift.breite) * breite;
|
||||
// Ein menschliches Mass: rund fuenf Zentimeter breit, hoechstens knapp
|
||||
// zwei hoch. Ohne die Hoehengrenze wird aus einem hohen Gekritzel ein
|
||||
// Stempel, der die halbe Seite einnimmt -- das Seitenverhaeltnis kommt ja
|
||||
// aus dem Zuschnitt, nicht aus der Vorlage.
|
||||
const MAX_BREITE = 150;
|
||||
const MAX_HOEHE = 50;
|
||||
let breite = Math.min(MAX_BREITE, blick.width * 0.3);
|
||||
let hoehe = (wartendeUnterschrift.hoehe / wartendeUnterschrift.breite) * breite;
|
||||
if (hoehe > MAX_HOEHE) {
|
||||
breite *= MAX_HOEHE / hoehe;
|
||||
hoehe = MAX_HOEHE;
|
||||
}
|
||||
const eintrag = {
|
||||
...wartendeUnterschrift,
|
||||
seite: nummer,
|
||||
@@ -700,6 +709,7 @@ export function initFilePreview(wurzel = document) {
|
||||
const nameFeld = stueck("name");
|
||||
const ersetzenFeld = stueck("ersetzen");
|
||||
const ersetzenKasten = stueck("ersetzenfeld");
|
||||
const pruefzeile = stueck("pruefung");
|
||||
const jetzt = stueck("jetzt");
|
||||
const abbrechen = stueck("abbrechen");
|
||||
const modusFeld = stueck("modus");
|
||||
@@ -761,6 +771,7 @@ export function initFilePreview(wurzel = document) {
|
||||
};
|
||||
|
||||
const aufraeumen = () => {
|
||||
pruefungZuruecksetzen();
|
||||
bild.removeAttribute("src");
|
||||
bilder.zuruecksetzen();
|
||||
rahmen.src = "about:blank";
|
||||
@@ -778,6 +789,52 @@ export function initFilePreview(wurzel = document) {
|
||||
aktuell = null;
|
||||
};
|
||||
|
||||
/* Unterschrieben und unveraendert? Die Antwort kommt aus dem
|
||||
Aenderungsprotokoll: dort steht die Pruefsumme der abgelegten Fassung.
|
||||
Stimmt sie, bekommt die Seite einen gruenen Schleier -- man soll es sehen,
|
||||
bevor man liest, nicht danach. */
|
||||
|
||||
const pruefungZuruecksetzen = () => {
|
||||
pdfBehaelter.classList.remove("viewer__pdf--unveraendert", "viewer__pdf--veraendert");
|
||||
if (pruefzeile) {
|
||||
pruefzeile.hidden = true;
|
||||
pruefzeile.textContent = "";
|
||||
pruefzeile.className = "viewer__pruefung";
|
||||
}
|
||||
};
|
||||
|
||||
const pruefen = async (adresse) => {
|
||||
pruefungZuruecksetzen();
|
||||
if (!adresse) return;
|
||||
try {
|
||||
const stand = await window.tesm.api(adresse);
|
||||
if (stand.status === "unveraendert") {
|
||||
pdfBehaelter.classList.add("viewer__pdf--unveraendert");
|
||||
if (pruefzeile) {
|
||||
pruefzeile.hidden = false;
|
||||
pruefzeile.className = "viewer__pruefung viewer__pruefung--gut";
|
||||
const namen = (stand.namen || []).join(", ");
|
||||
pruefzeile.textContent =
|
||||
`Unveraendert seit der Unterschrift${namen ? ` von ${namen}` : ""}` +
|
||||
` -- Pruefsumme stimmt mit dem Aenderungsprotokoll ueberein.`;
|
||||
}
|
||||
} else if (stand.status === "veraendert") {
|
||||
pdfBehaelter.classList.add("viewer__pdf--veraendert");
|
||||
if (pruefzeile) {
|
||||
pruefzeile.hidden = false;
|
||||
pruefzeile.className = "viewer__pruefung viewer__pruefung--schlecht";
|
||||
pruefzeile.textContent =
|
||||
"Diese Datei wurde nach der Unterschrift veraendert -- die Pruefsumme " +
|
||||
"weicht vom Aenderungsprotokoll ab.";
|
||||
}
|
||||
}
|
||||
} catch (fehler) {
|
||||
// Keine Aussage ist besser als eine falsche: ohne Antwort bleibt die
|
||||
// Seite schlicht ungekennzeichnet.
|
||||
console.error("Signaturpruefung", fehler);
|
||||
}
|
||||
};
|
||||
|
||||
const oeffnen = async (ausloeser) => {
|
||||
aufraeumen();
|
||||
const art = ausloeser.dataset.fillKind || "text";
|
||||
@@ -793,6 +850,7 @@ export function initFilePreview(wurzel = document) {
|
||||
return;
|
||||
}
|
||||
if (hinweis) hinweis.textContent = "PDF wird geladen ...";
|
||||
pruefen(ausloeser.dataset.fillPruefung || "");
|
||||
try {
|
||||
pdf = await pdfBetrachter(pdfScroll, pdfSeiten, quelle, basis, {
|
||||
formulare: rumpf.dataset.viewerFormulare === "1",
|
||||
|
||||
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "tesm-licensing-server"
|
||||
version = "2.6.1"
|
||||
version = "2.7.0"
|
||||
description = "Serverhaelfte des TESM-Lizenzprotokolls: ausstellen, erneuern, antworten"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = ["tesm-licensing==2.6.1", "cryptography>=41"]
|
||||
dependencies = ["tesm-licensing==2.7.0", "cryptography>=41"]
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "tesm-licensing"
|
||||
version = "2.6.1"
|
||||
version = "2.7.0"
|
||||
description = "Ed25519-basiertes Lizenz- und Aktivierungsprotokoll fuer TESM und TESM-Lizenzserver"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = ["cryptography>=42"]
|
||||
|
||||
Reference in new issue
Block a user