diff --git a/server/services/termine/kontext.js b/server/services/termine/kontext.js index c6ebeb3..846864a 100644 --- a/server/services/termine/kontext.js +++ b/server/services/termine/kontext.js @@ -177,14 +177,23 @@ export async function speichereEinstellung(feature, einstellung, { version, by = } /** - * Adresse der Website des Betriebs (Link auf Gaesteseiten): betrieb.websiteUrl oder https:// + erster gespeicherter Host - * des Projekts (analyseHosts); sonst null. + * Adresse der Website des Betriebs (Link auf Gaesteseiten und im Mailfuss), immer die echte Seite statt der Vorschau: + * betrieb.websiteUrl; sonst https:// + Live-Domain des Projekts (wenn project.liveDomain einen gueltigen Host ergibt); + * sonst https:// + .project.webklar.com; sonst die Portal-Adresse (config.publicBaseUrl). */ export function websiteUrl(ctx) { const eigene = ctx?.einstellung?.betrieb?.websiteUrl if (typeof eigene === 'string' && eigene !== '') return eigene - const [host] = ctx?.project ? analyseHosts(ctx.project) : [] - return host ? `https://${host}` : null + const project = ctx?.project + if (project) { + // analyseHosts: [.project.webklar.com, Live-Domain], ungueltige und doppelte Hosts fehlen + const hosts = analyseHosts(project) + const vorschau = project.subdomain ? `${String(project.subdomain).trim().toLowerCase()}.project.webklar.com` : null + const live = project.liveDomain ? hosts.find((host) => host !== vorschau) : undefined + const host = live ?? hosts.find((h) => h === vorschau) + if (host) return `https://${host}` + } + return config.publicBaseUrl } /** Leert den Speicher von kontextPerSiteKey (Tests). */ diff --git a/server/services/termine/mails.js b/server/services/termine/mails.js index ff54d12..6c32f59 100644 --- a/server/services/termine/mails.js +++ b/server/services/termine/mails.js @@ -16,8 +16,8 @@ import { datumKurz, datumLang, uhrzeit } from './zeit.js' * * Regeln fuer alle Mails: * - Genau ein Anrede-Block (sie oder du) je G-Mail, nach einstellung.anrede; K20/K21 sind immer Du-Form ohne diese Bloecke. - * - Leere freiwillige Werte erscheinen als "–". Links auf die Website des Betriebs (Impressum, Datenschutz) fallen auf - * websiteUrl(ctx) und zuletzt auf die Portal-Adresse zurueck (ein href darf nicht "–" sein). + * - Leere freiwillige Werte erscheinen als "–". Links auf Impressum und Datenschutz des Betriebs fallen auf die Website + * des Betriebs zurueck (websiteUrl(ctx), zuletzt die Portal-Adresse; ein href darf nicht "–" sein). * - Person oder Platz (Block person in G02/G05) nur, wenn der Betrieb mehrere Ressourcen hat; K20/K21 zeigen sie immer. * - G01 und G08 enthalten keinen Text, den der Gast eingegeben hat (die Mail geht an eine ungeprueft angegebene Adresse); * in keinem Betreff steht ein Gastname. @@ -136,7 +136,7 @@ function bestaetigungsLink(token) { function betriebsWerte(ctx) { const e = ctx.einstellung const b = e.betrieb - const seite = websiteUrl(ctx) || config.publicBaseUrl + const seite = websiteUrl(ctx) return { farbe: e.farbe, betrieb_name: b.name, diff --git a/test/termineKontext.test.js b/test/termineKontext.test.js index d013fdd..e3a5291 100644 --- a/test/termineKontext.test.js +++ b/test/termineKontext.test.js @@ -402,13 +402,25 @@ test('kontextPerFeature: Modus off => null ohne Anfrage; fehlendes Projekt => pr assert.equal(await zaehleAnfragen(async () => assert.equal(await kontextPerFeature(FEATURE), null)), 0) }) -test('websiteUrl: betrieb.websiteUrl, sonst https:// + erster Host des Projekts, sonst null', () => { - assert.equal(websiteUrl(ctxMit()), 'https://salon.de/') +test('websiteUrl: betrieb.websiteUrl, sonst Live-Domain, sonst Vorschau-Subdomain, sonst Portal-Adresse', () => { + assert.equal(websiteUrl(ctxMit()), 'https://salon.de/', 'Angabe des Betriebs gewinnt auch gegen Live-Domain und Subdomain') + assert.equal(websiteUrl(ctxMit({}, { subdomain: 'salon', liveDomain: 'live.example.com' })), 'https://salon.de/') + const ohneUrl = { betrieb: betriebMit({ websiteUrl: null }) } - assert.equal(websiteUrl(ctxMit(ohneUrl, { subdomain: 'salon', liveDomain: 'www.salon.de' })), 'https://salon.project.webklar.com') - assert.equal(websiteUrl(ctxMit(ohneUrl, { liveDomain: 'https://www.salon.de/start' })), 'https://www.salon.de') - assert.equal(websiteUrl(ctxMit(ohneUrl, { $id: PROJEKT })), null, 'Projekt ohne Hosts') - assert.equal(websiteUrl(ctxMit(ohneUrl, null)), null, 'ohne Projekt') + // Live-Domain vor Subdomain, auch wenn die Subdomain in analyseHosts zuerst steht + assert.equal(websiteUrl(ctxMit(ohneUrl, { subdomain: 'salon', liveDomain: 'www.salon.de' })), 'https://www.salon.de') + assert.equal(websiteUrl(ctxMit(ohneUrl, { subdomain: 'salon', liveDomain: 'https://WWW.Salon.de/start?x=1' })), 'https://www.salon.de', 'Schema, Pfad und Gross-/Kleinschreibung fallen weg') + assert.equal(websiteUrl(ctxMit(ohneUrl, { liveDomain: 'salon.de' })), 'https://salon.de', 'Live-Domain ohne Subdomain') + // keine verwertbare Live-Domain => Vorschau-Subdomain + assert.equal(websiteUrl(ctxMit(ohneUrl, { subdomain: 'salon' })), 'https://salon.project.webklar.com') + assert.equal(websiteUrl(ctxMit(ohneUrl, { subdomain: 'salon', liveDomain: '' })), 'https://salon.project.webklar.com') + assert.equal(websiteUrl(ctxMit(ohneUrl, { subdomain: 'salon', liveDomain: 'kein host!' })), 'https://salon.project.webklar.com', 'ungueltige Live-Domain wird uebersprungen') + assert.equal(websiteUrl(ctxMit(ohneUrl, { subdomain: 'salon', liveDomain: 'salon.project.webklar.com' })), 'https://salon.project.webklar.com', 'Live-Domain gleich Subdomain-Host') + // nichts Brauchbares => Portal-Adresse + assert.equal(websiteUrl(ctxMit(ohneUrl, { $id: PROJEKT })), config.publicBaseUrl, 'Projekt ohne Hosts') + assert.equal(websiteUrl(ctxMit(ohneUrl, null)), config.publicBaseUrl, 'ohne Projekt') + assert.equal(websiteUrl({ einstellung: null, project: null }), config.publicBaseUrl) + assert.equal(websiteUrl(null), config.publicBaseUrl) }) // ---------------------------------------------------------------- Betreffzeilen @@ -664,6 +676,9 @@ test('Impressum und Datenschutz im Fuss: Angaben des Betriebs, sonst dessen Webs assert.equal(web.impressum_url, 'https://salon.de/') assert.equal(web.datenschutz_url, 'https://salon.de/') + const live = werteFuer('G03', ctxMit({ betrieb: betriebMit({ ...ohneLinks, websiteUrl: null }) }, { subdomain: 'salon', liveDomain: 'www.salon.de' }), buchung(), {}).values + assert.equal(live.impressum_url, 'https://www.salon.de', 'ohne Angabe die Live-Domain, nicht die Vorschau') + const nackt = werteFuer('G03', ctxMit({ betrieb: betriebMit({ ...ohneLinks, websiteUrl: null }) }, null), buchung(), {}).values assert.equal(nackt.impressum_url, config.publicBaseUrl) assert.equal(nackt.datenschutz_url, config.publicBaseUrl)