fix(v5): MakeMKV-Installer aus dem Internet Archive nur nach Rückfrage, mit Größe und SHA-256
WAS: makemkvInstallerHolen fragt vor der Archiv-Quelle über eine Freigabe-Funktion; ohne Freigabe wird das Archiv übersprungen und im Bericht genannt. Der Kern stellt die Frage ans Fenster (beschaffung-status mit `frage`), die MakeMKV-Karte zeigt sie mit „Archiv-Kopie laden" / „Lieber nicht" (beschaffung-antwort); ohne Antwort in zehn Minuten gilt Nein. Die geladene Datei wird mit Größe und SHA-256 gemeldet. WARUM: Durchsicht 12.09.2026, Fund F16 (Commander-Entscheid: Archiv nur nach Rückfrage) — eine unsignierte EXE von fremder Hand, die mit Adminrechten läuft, entscheidet der Nutzer, nicht Rippy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3dacd7cb4f
commit
ae82d8c0fd
@@ -15,6 +15,9 @@ export class WerkzeugDienst {
|
||||
schluesselStand: SchluesselStand | null = null
|
||||
private beschaffungLaeuft = false
|
||||
private installerAntwort: ((fehler: string | null) => void) | null = null
|
||||
/** 5.7.0 (F16): Die offene Ja/Nein-Frage der Beschaffung — null, wenn keine. */
|
||||
private frageAntwort: ((ja: boolean) => void) | null = null
|
||||
private letzterBeschaffungsText = ''
|
||||
|
||||
constructor(
|
||||
private readonly kontext: KernKontext,
|
||||
@@ -115,9 +118,40 @@ export class WerkzeugDienst {
|
||||
this.installerAntwort = null
|
||||
}
|
||||
|
||||
private beschaffungMelden(text: string, anteil: number | null, laeuft: boolean, fehler = false): void {
|
||||
this.kontext.anFenster({ art: 'beschaffung-status', stand: { werkzeug: 'makemkv', laeuft, text, anteil, fehler } })
|
||||
this.kontext.protokoll.schreiben(`MakeMKV-Update: ${text}`)
|
||||
private beschaffungMelden(text: string, anteil: number | null, laeuft: boolean, fehler = false, frage?: string): void {
|
||||
this.letzterBeschaffungsText = text
|
||||
this.kontext.anFenster({ art: 'beschaffung-status', stand: { werkzeug: 'makemkv', laeuft, text, anteil, fehler, ...(frage !== undefined ? { frage } : {}) } })
|
||||
this.kontext.protokoll.schreiben(`MakeMKV-Update: ${text}${frage !== undefined ? ` — FRAGE: ${frage}` : ''}`)
|
||||
}
|
||||
|
||||
/** Antwort des Fensters auf eine offene Frage (beschaffung-antwort). */
|
||||
beschaffungAntwort(ja: boolean): void {
|
||||
const antwort = this.frageAntwort
|
||||
this.frageAntwort = null
|
||||
if (antwort === null) {
|
||||
this.kontext.hinweis('Es ist keine Frage der MakeMKV-Beschaffung offen.')
|
||||
return
|
||||
}
|
||||
antwort(ja)
|
||||
}
|
||||
|
||||
/** Eine Ja/Nein-Frage ans Fenster; ohne Antwort in zehn Minuten gilt Nein. */
|
||||
private frage(text: string): Promise<boolean> {
|
||||
return new Promise((fertig) => {
|
||||
this.frageAntwort = (ja) => {
|
||||
clearTimeout(zeiger)
|
||||
this.beschaffungMelden(ja ? 'Freigegeben — die Archiv-Kopie wird geladen.' : 'Nicht freigegeben.', null, true)
|
||||
fertig(ja)
|
||||
}
|
||||
const zeiger = setTimeout(() => {
|
||||
if (this.frageAntwort === null) return
|
||||
this.frageAntwort = null
|
||||
this.beschaffungMelden('Keine Antwort — die Archiv-Kopie wird nicht geladen.', null, true)
|
||||
fertig(false)
|
||||
}, 10 * 60_000)
|
||||
zeiger.unref()
|
||||
this.beschaffungMelden(this.letzterBeschaffungsText, null, true, false, text)
|
||||
})
|
||||
}
|
||||
|
||||
// ── MakeMKV-Update (§ 9): holen, prüfen, installieren lassen ────────────
|
||||
@@ -168,8 +202,25 @@ export class WerkzeugDienst {
|
||||
const alteExe = this.makemkvcon()
|
||||
const alteVersion = alteExe.length > 0 ? versionsangaben(alteExe).version : ''
|
||||
|
||||
const ergebnis = await makemkvInstallerHolen(neueste, (text, anteil) => this.beschaffungMelden(text, anteil, true))
|
||||
this.beschaffungMelden(`Geprüft (Quelle: ${ergebnis.quelle}) — der Installer wird gestartet …`, null, true)
|
||||
const ergebnis = await makemkvInstallerHolen(
|
||||
neueste,
|
||||
(text, anteil) => this.beschaffungMelden(text, anteil, true),
|
||||
'',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
// F16: Das Archiv liefert eine unsignierte EXE, die gleich mit
|
||||
// Adminrechten läuft — das entscheidet der Nutzer, nicht Rippy.
|
||||
(quelle) =>
|
||||
this.frage(
|
||||
`makemkv.com antwortet nicht. Soll Rippy den MakeMKV-Installer ${neueste} aus dem ${quelle} laden? Das ist eine Kopie von fremder Hand, geprüft wird nur, dass sie ein MakeMKV-Programm ist — er läuft danach mit Adminrechten. Wer sicher gehen will, lädt später selbst von makemkv.com.`,
|
||||
),
|
||||
)
|
||||
this.beschaffungMelden(
|
||||
`Geprüft (Quelle: ${ergebnis.quelle}, ${(ergebnis.bytes / 1024 ** 2).toFixed(1)} MB, SHA-256 ${ergebnis.sha256}) — der Installer wird gestartet …`,
|
||||
null,
|
||||
true,
|
||||
)
|
||||
|
||||
const startFehler = await new Promise<string | null>((fertig) => {
|
||||
this.installerAntwort = fertig
|
||||
|
||||
Reference in New Issue
Block a user