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]
|
[project]
|
||||||
name = "tesm-license"
|
name = "tesm-license"
|
||||||
version = "2.6.1"
|
version = "2.7.0"
|
||||||
description = "TESM-Lizenzserver -- Kunden, Tickets, Lizenzen, Aktivierung"
|
description = "TESM-Lizenzserver -- Kunden, Tickets, Lizenzen, Aktivierung"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "tesm-core"
|
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"
|
description = "Gemeinsames Anwendungsgeruest (Auth, RBAC, Navigation, Design-System, Migrationen) fuer TESM und TESM-Lizenzserver"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ def create_base_app(
|
|||||||
#: Wortmarke, ohne Zeile darunter; die Marke selbst zeigen beide
|
#: Wortmarke, ohne Zeile darunter; die Marke selbst zeigen beide
|
||||||
#: Anwendungen.
|
#: Anwendungen.
|
||||||
auth_tagline: str = "",
|
auth_tagline: str = "",
|
||||||
app_version: str = "2.6.1",
|
app_version: str = "2.7.0",
|
||||||
built_in_trusted_keys: tuple[str, ...] = (),
|
built_in_trusted_keys: tuple[str, ...] = (),
|
||||||
enable_license: bool = True,
|
enable_license: bool = True,
|
||||||
template_folder: str | None = None,
|
template_folder: str | None = None,
|
||||||
|
|||||||
@@ -1458,3 +1458,50 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 3;
|
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 anteilY = (event.clientY - rechteck.top) / rechteck.height;
|
||||||
const seite = await dokument.getPage(nummer);
|
const seite = await dokument.getPage(nummer);
|
||||||
const blick = seite.getViewport({ scale: 1 });
|
const blick = seite.getViewport({ scale: 1 });
|
||||||
const breite = Math.min(170, blick.width * 0.35);
|
// Ein menschliches Mass: rund fuenf Zentimeter breit, hoechstens knapp
|
||||||
const hoehe =
|
// zwei hoch. Ohne die Hoehengrenze wird aus einem hohen Gekritzel ein
|
||||||
(wartendeUnterschrift.hoehe / wartendeUnterschrift.breite) * breite;
|
// 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 = {
|
const eintrag = {
|
||||||
...wartendeUnterschrift,
|
...wartendeUnterschrift,
|
||||||
seite: nummer,
|
seite: nummer,
|
||||||
@@ -700,6 +709,7 @@ export function initFilePreview(wurzel = document) {
|
|||||||
const nameFeld = stueck("name");
|
const nameFeld = stueck("name");
|
||||||
const ersetzenFeld = stueck("ersetzen");
|
const ersetzenFeld = stueck("ersetzen");
|
||||||
const ersetzenKasten = stueck("ersetzenfeld");
|
const ersetzenKasten = stueck("ersetzenfeld");
|
||||||
|
const pruefzeile = stueck("pruefung");
|
||||||
const jetzt = stueck("jetzt");
|
const jetzt = stueck("jetzt");
|
||||||
const abbrechen = stueck("abbrechen");
|
const abbrechen = stueck("abbrechen");
|
||||||
const modusFeld = stueck("modus");
|
const modusFeld = stueck("modus");
|
||||||
@@ -761,6 +771,7 @@ export function initFilePreview(wurzel = document) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const aufraeumen = () => {
|
const aufraeumen = () => {
|
||||||
|
pruefungZuruecksetzen();
|
||||||
bild.removeAttribute("src");
|
bild.removeAttribute("src");
|
||||||
bilder.zuruecksetzen();
|
bilder.zuruecksetzen();
|
||||||
rahmen.src = "about:blank";
|
rahmen.src = "about:blank";
|
||||||
@@ -778,6 +789,52 @@ export function initFilePreview(wurzel = document) {
|
|||||||
aktuell = null;
|
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) => {
|
const oeffnen = async (ausloeser) => {
|
||||||
aufraeumen();
|
aufraeumen();
|
||||||
const art = ausloeser.dataset.fillKind || "text";
|
const art = ausloeser.dataset.fillKind || "text";
|
||||||
@@ -793,6 +850,7 @@ export function initFilePreview(wurzel = document) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (hinweis) hinweis.textContent = "PDF wird geladen ...";
|
if (hinweis) hinweis.textContent = "PDF wird geladen ...";
|
||||||
|
pruefen(ausloeser.dataset.fillPruefung || "");
|
||||||
try {
|
try {
|
||||||
pdf = await pdfBetrachter(pdfScroll, pdfSeiten, quelle, basis, {
|
pdf = await pdfBetrachter(pdfScroll, pdfSeiten, quelle, basis, {
|
||||||
formulare: rumpf.dataset.viewerFormulare === "1",
|
formulare: rumpf.dataset.viewerFormulare === "1",
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "tesm-licensing-server"
|
name = "tesm-licensing-server"
|
||||||
version = "2.6.1"
|
version = "2.7.0"
|
||||||
description = "Serverhaelfte des TESM-Lizenzprotokolls: ausstellen, erneuern, antworten"
|
description = "Serverhaelfte des TESM-Lizenzprotokolls: ausstellen, erneuern, antworten"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dependencies = ["tesm-licensing==2.6.1", "cryptography>=41"]
|
dependencies = ["tesm-licensing==2.7.0", "cryptography>=41"]
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
where = ["src"]
|
where = ["src"]
|
||||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "tesm-licensing"
|
name = "tesm-licensing"
|
||||||
version = "2.6.1"
|
version = "2.7.0"
|
||||||
description = "Ed25519-basiertes Lizenz- und Aktivierungsprotokoll fuer TESM und TESM-Lizenzserver"
|
description = "Ed25519-basiertes Lizenz- und Aktivierungsprotokoll fuer TESM und TESM-Lizenzserver"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dependencies = ["cryptography>=42"]
|
dependencies = ["cryptography>=42"]
|
||||||
|
|||||||
Reference in new issue
Block a user