Datenschutz (Entwurf): Übermittlung an UptimeRobot, Bestellungen im Portal, Formulare, Tests
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
a2c1f0d81c
commit
6f7daf757f
3 files changed
+52
-18
No files matched your search
+47
-15
@@ -203,30 +203,62 @@ test('Alle internen Links und Querverweise treffen', () => {
|
||||
|
||||
// --- Datenschutzerklärung (Plan 2, Task 2) ---
|
||||
|
||||
test('Datenschutz: Abos, UptimeRobot, Stand wie termsVersion', () => {
|
||||
const ds = strip(read('public/datenschutz.html'))
|
||||
const DS = 'public/datenschutz.html'
|
||||
// Ein Satz ab seinem Anfang bis zum nächsten Satzende (in den geprüften Sätzen kommt kein "Art. 6" o. ä. vor)
|
||||
const sentence = (s, start) => between(s, start, '. ') + '.'
|
||||
|
||||
test('Datenschutz: Abos, produktneutral, Stand wie termsVersion', () => {
|
||||
const ds = strip(read(DS))
|
||||
for (const s of ['Abos und Zahlung über Stripe', 'UptimeRobot s. r. o.', 'Obchodná 507/2', '811 06 Bratislava',
|
||||
'Standardvertragsklauseln', 'im Rahmen unserer Abos']) assert.ok(ds.includes(s), s)
|
||||
// Produktneutral: keine Formulierung mehr, die nur das Wartungs-Abo meint, wo beide Abos gemeint sind
|
||||
// Produktneutral; keine Zusage einer Ereignisansicht (Plan 2 baut keine); UptimeRobot ist kein Unterauftragsverarbeiter
|
||||
for (const s of ['insbesondere das Wartungs-Abo', 'Schließen Sie das Wartungs-Abo', 'im Rahmen des Wartungs-Abos',
|
||||
'für das Wartungs-Abo über Stripe']) assert.ok(!ds.includes(s), `noch da: ${s}`)
|
||||
// Abschnitt 3 und 12: Überwachung der Erreichbarkeit durch UptimeRobot, Drittland auf Grundlage von SCC
|
||||
const hosting = between(ds, '3. Hosting', '4. Cookies')
|
||||
for (const s of ['UptimeRobot s. r. o., Obchodná 507/2, 811 06 Bratislava (Slowakei)', 'Art. 46 Abs. 2 lit. c DSGVO',
|
||||
'Auftragsverarbeitung', 'Nutzungsbedingungen']) assert.ok(hosting.includes(s), `Abschnitt 3: ${s}`)
|
||||
assert.ok(between(ds, '12. Empfänger im Überblick', '13. Ihre Rechte').includes('UptimeRobot'))
|
||||
// Abschnitt 7: Nachweisdaten auch bei Wechsel und Zusatzspeicher, Aufbewahrung wie bisher
|
||||
const abos = between(ds, '7. Abos und Zahlung über Stripe', '8. E-Mail')
|
||||
for (const s of ['Wechsel', 'Zusatzspeicher', 'Kündigung', 'Widerruf', 'Version der Vertragsbedingungen',
|
||||
'drei Jahre nach Vertragsende']) assert.ok(abos.includes(s), `Abschnitt 7: ${s}`)
|
||||
// Stand der Erklärung = Datum aus termsVersion (JJJJ-MM-TT-v4); das Freigabedatum kommt erst beim Livegang (Task 20)
|
||||
const [, y, mo, d] = /^(\d{4})-(\d{2})-(\d{2})-v4$/.exec(config.abo.termsVersion)
|
||||
'für das Wartungs-Abo über Stripe', 'Sie sehen diese Ereignisse', 'Unterauftragsverarbeiter']) assert.ok(!ds.includes(s), `noch da: ${s}`)
|
||||
// Stand = Datum aus termsVersion (JJJJ-MM-TT-v4). Die Kopplung gilt bis zum Livegang: Task 20 trägt in beiden das
|
||||
// Freigabedatum ein. Danach darf sie gelockert werden, sobald die Erklärung unabhängig von den Bedingungen geändert wird.
|
||||
const m = /^(\d{4})-(\d{2})-(\d{2})-v4$/.exec(config.abo.termsVersion)
|
||||
assert.ok(m, `termsVersion nicht im Format JJJJ-MM-TT-v4: ${config.abo.termsVersion}`)
|
||||
const [, y, mo, d] = m
|
||||
const stand = /Stand (\d{2}\.\d{2}\.\d{4})/.exec(ds)
|
||||
assert.ok(stand, 'Stand fehlt')
|
||||
assert.equal(stand[1], `${d}.${mo}.${y}`)
|
||||
assert.ok(read('scripts/build-legal-pdfs.sh').includes('pdf public/datenschutz.html docs/WEBklar-Datenschutzerklaerung.pdf'))
|
||||
})
|
||||
|
||||
test('Datenschutz Abschnitt 3 und 12: UptimeRobot, Drittland USA, SCC im AVV mit Kopie', () => {
|
||||
const ds = strip(read(DS))
|
||||
// Nur die UptimeRobot-Absätze (nach dem Hetzner-Absatz), damit "Auftragsverarbeitung" wirklich UptimeRobot meint
|
||||
const robot = between(ds, 'Ob unsere Websites', '4. Cookies')
|
||||
for (const s of ['UptimeRobot s. r. o., Obchodná 507/2, 811 06 Bratislava (Slowakei)', 'Adressen (URLs)', 'Daten der Besucher',
|
||||
'Auftragsverarbeitung', 'außerhalb der EU', 'insbesondere in den USA', 'Standardvertragsklauseln', 'Art. 46 Abs. 2 lit. c DSGVO',
|
||||
'uptimerobot.com/dpa', 'Kopie', 'lit. b', 'lit. f', 'entfernen wir']) assert.ok(robot.includes(s), `UptimeRobot: ${s}`)
|
||||
const empfaenger = between(ds, '12. Empfänger im Überblick', '13. Ihre Rechte')
|
||||
assert.ok(empfaenger.includes('UptimeRobot s. r. o.'))
|
||||
assert.ok(empfaenger.includes('(insbesondere USA)'))
|
||||
})
|
||||
|
||||
test('Datenschutz Abschnitt 7: Nachweisdaten je Bestellung, Vertragsereignisse, Kündigungs- und Widerrufsseite', () => {
|
||||
const abos = between(strip(read(DS)), '7. Abos und Zahlung über Stripe', '8. E-Mail')
|
||||
// Nachweisdaten (mit IP und Browser) für Abschluss, Wechsel und Zusatzspeicher-Bestellung, im Portal und bei Stripe
|
||||
const nachweis = between(abos, 'Um Ihre Bestellungen nachweisen', 'Außerdem')
|
||||
for (const s of ['Version der Vertragsbedingungen', 'gegebenenfalls Ihre Angaben zum Leistungsbeginn', 'IP-Adresse', 'Browserkennung',
|
||||
'bei Stripe', 'Abschluss eines Abos', 'Wechsel', 'Zusatzspeicher']) assert.ok(nachweis.includes(s), `Nachweis: ${s}`)
|
||||
// Ereignis-Satz nennt Kündigung und Widerruf als Ereignisse (eine "Kündigungsbestätigung" genügt nicht)
|
||||
const ereignisse = sentence(abos, 'Außerdem halten wir')
|
||||
for (const re of [/[ :,]Abschluss[ ,.]/, /[ :,]Wechsel[ ,.]/, /[ :,]Zusatzspeicher[ ,.]/, /[ :,]Verringerungen[ ,.]/,
|
||||
/[ :,]Kündigung[ ,.]/, /[ :,]Widerruf[ ,.]/]) assert.match(ereignisse, re)
|
||||
// Verringerung, Kündigung, Widerruf: nur Zeitpunkt und Status (Task 8 speichert beim Minus keine IP/Browserkennung)
|
||||
assert.ok(abos.includes('nur Zeitpunkt und Status, keine IP-Adresse und Browserkennung'))
|
||||
assert.ok(abos.includes('Den Stand Ihrer Bestellungen, etwa laufende Widerrufsfristen und die Einrichtung von Zusatzspeicher, sehen Sie im Kundenportal unter „Verträge“.'))
|
||||
assert.ok(abos.includes('Aufgabenliste, um Änderungen am Zusatzspeicher umzusetzen'))
|
||||
assert.ok(sentence(abos, 'Diese Angaben löschen wir').includes('drei Jahre nach Vertragsende'))
|
||||
// Öffentliche Kündigungs- und Widerrufsseite (§§ 312k, 356a BGB): Daten, Zweck, Rechtsgrundlage, IP nur zur Begrenzung
|
||||
const formulare = between(abos, 'kuendigen.html', 'Abschnitt 9')
|
||||
for (const s of ['widerrufen.html', 'ohne Anmeldung', 'Namen', 'E-Mail-Adresse', 'Kundennummer', 'Eingang', 'Bestätigung', 'Team',
|
||||
'Art. 6 Abs. 1 lit. c DSGVO', '§§ 312k, 356a BGB', 'lit. b', 'IP-Adresse', 'Arbeitsspeicher', 'zehn',
|
||||
'drei Jahre nach Vertragsende']) assert.ok(formulare.includes(s), `Formulare: ${s}`)
|
||||
})
|
||||
|
||||
// --- Übernahmegutschrift, Prüftexte, Leitfaden (Plan 2, Task 3) ---
|
||||
|
||||
test('Übernahmegutschrift und Leitfaden: produktneutral', () => {
|
||||
|
||||
Reference in new issue
Block a user