diff --git a/.github/workflows/uptime.yml b/.github/workflows/uptime.yml index 0820b59..3779892 100644 --- a/.github/workflows/uptime.yml +++ b/.github/workflows/uptime.yml @@ -4,8 +4,6 @@ on: push: branches: - master - schedule: - - cron: "*/15 * * * *" workflow_dispatch: permissions: diff --git a/Petabit.Tests/ApplicationTests.cs b/Petabit.Tests/ApplicationTests.cs index 17565c5..b1d75d4 100644 --- a/Petabit.Tests/ApplicationTests.cs +++ b/Petabit.Tests/ApplicationTests.cs @@ -96,6 +96,34 @@ public async Task PrivacyPageLoadsGlobalReadableContentStyles() Assert.Contains("body.dark-mode .table", styles); } + [Theory] + [InlineData("en", "Cookie policy", "Manage analytics cookies")] + [InlineData("hr", "Politika kolačića", "Upravljaj analitičkim kolačićima")] + [InlineData("de", "Cookie-Richtlinie", "Analyse-Cookies verwalten")] + public async Task PrivacyCookieDetailsUseRequestedLanguage(string culture, string heading, string manageText) + { + using var request = new HttpRequestMessage(HttpMethod.Get, "/Home/Privacy"); + request.Headers.AcceptLanguage.ParseAdd(culture); + + var response = await _client.SendAsync(request); + var body = await response.Content.ReadAsStringAsync(); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Contains($"", body); + Assert.Contains(heading, body); + Assert.Contains(manageText, body); + } + + [Fact] + public async Task BooksPageUsesRealPublisherLinks() + { + var body = await _client.GetStringAsync("/Home/Books"); + + Assert.DoesNotContain("example.com", body); + Assert.Contains("informit.com/store/clean-code", body); + Assert.Contains("store.pragprog.com/titles/tpp20", body); + } + [Fact] public async Task ContentSecurityPolicyMatchesEveryInlineScriptNonce() { diff --git a/Petabit/Resources/Views.Home.Privacy.de.resx b/Petabit/Resources/Views.Home.Privacy.de.resx index 42ea295..3694eb5 100644 --- a/Petabit/Resources/Views.Home.Privacy.de.resx +++ b/Petabit/Resources/Views.Home.Privacy.de.resx @@ -171,4 +171,24 @@ Da wir keine personenbezogenen Daten sammeln, haben Sie keine Anfragen zum Zugriff, zur Berichtigung oder Löschung personenbezogener Daten. Wenn Sie Fragen zum Datenschutz haben, kontaktieren Sie uns bitte. + Cookie-Richtlinie + Petabit verwendet nur notwendige funktionale Technologien und, mit Ihrer Einwilligung, Analyse-Cookies. Die Analyse ist für die Nutzung der Website nicht erforderlich. + Notwendige funktionale Technologien + Name + Zweck + Dauer + Speichert die ausgewählte Sprache der Website. + 1 Jahr + Speichert die Entscheidung zu Analyse-Cookies lokal im Browser. + Bis Sie Ihre Entscheidung ändern oder die Browserdaten löschen + Analyse-Cookies – Google Analytics 4 + Google Analytics wird erst geladen, nachdem Sie Akzeptieren ausgewählt haben. Es erfasst zusammengefasste Daten wie Benutzer- und Sitzungszahlen, ungefähren Standort, Browser, Gerät und Zugriffsquelle. Wir verwenden es nicht, um Besucher direkt zu identifizieren. + Unterscheidet einzelne Benutzer. + Speichert den Sitzungsstatus für Google Analytics 4. + Bis zu 2 Jahre + Mehr über GA4-Cookies: + Google-Analytics-Dokumentation + Einwilligung verwalten + Sie können Analyse-Cookies beim ersten Besuch akzeptieren oder ablehnen. Sie können Ihre Entscheidung jederzeit ändern. + Analyse-Cookies verwalten diff --git a/Petabit/Resources/Views.Home.Privacy.en.resx b/Petabit/Resources/Views.Home.Privacy.en.resx index 4b00013..c48c352 100644 --- a/Petabit/Resources/Views.Home.Privacy.en.resx +++ b/Petabit/Resources/Views.Home.Privacy.en.resx @@ -171,4 +171,24 @@ Since we do not collect personal data, you have no requests for access, correction, or deletion of personal data. If you have privacy-related questions, feel free to contact us. + Cookie policy + Petabit uses only necessary functional technologies and, with your consent, analytics cookies. Analytics is not required to use the site. + Necessary functional technologies + Name + Purpose + Duration + Remembers the selected site language. + 1 year + Stores the analytics-cookie choice locally in the browser. + Until you change your choice or clear browser data + Analytics cookies – Google Analytics 4 + Google Analytics loads only after you select Accept. It collects aggregate data such as user and session counts, approximate location, browser, device, and traffic source. We do not use it to directly identify visitors. + Distinguishes unique users. + Stores session state for Google Analytics 4. + Up to 2 years + More about GA4 cookies: + Google Analytics documentation + Consent management + You can accept or reject analytics cookies on your first visit. You can change your choice at any time. + Manage analytics cookies diff --git a/Petabit/Resources/Views.Home.Privacy.hr.resx b/Petabit/Resources/Views.Home.Privacy.hr.resx index ae23bfe..cd3a82d 100644 --- a/Petabit/Resources/Views.Home.Privacy.hr.resx +++ b/Petabit/Resources/Views.Home.Privacy.hr.resx @@ -173,4 +173,24 @@ Budući da ne prikupljamo osobne podatke, nemate zahtjeve za pristup, ispravak ili brisanje osobnih podataka. + Politika kolačića + Petabit koristi samo nužne funkcionalne tehnologije i, uz vašu privolu, analitičke kolačiće. Analitika nije potrebna za korištenje stranice. + Nužne funkcionalne tehnologije + Naziv + Svrha + Trajanje + Pamti odabrani jezik stranice. + 1 godina + Lokalna pohrana odluke o analitičkim kolačićima u pregledniku. + Dok ne promijenite odluku ili ne obrišete podatke preglednika + Analitički kolačići – Google Analytics 4 + Google Analytics učitava se samo nakon odabira Prihvaćam. Prikuplja zbirne podatke kao što su broj korisnika i sesija, približna lokacija, preglednik, uređaj i izvor dolaska. Ne koristimo ga za izravno utvrđivanje identiteta posjetitelja. + Razlikuje jedinstvene korisnike. + Čuva stanje sesije za Google Analytics 4. + Do 2 godine + Više o GA4 kolačićima: + Google Analytics dokumentacija + Upravljanje privolom + Analitičke kolačiće možete prihvatiti ili odbiti pri prvom posjetu. Svoju odluku možete promijeniti u bilo kojem trenutku. + Upravljaj analitičkim kolačićima diff --git a/Petabit/Views/Home/Books.cshtml b/Petabit/Views/Home/Books.cshtml index 291354b..30cc9ce 100644 --- a/Petabit/Views/Home/Books.cshtml +++ b/Petabit/Views/Home/Books.cshtml @@ -10,10 +10,10 @@

📚 @Localizer["LearnWithBooks"]

diff --git a/Petabit/Views/Home/Privacy.cshtml b/Petabit/Views/Home/Privacy.cshtml index 6503a24..6ca4af2 100644 --- a/Petabit/Views/Home/Privacy.cshtml +++ b/Petabit/Views/Home/Privacy.cshtml @@ -24,40 +24,40 @@
  • @Localizer["CookiesPoint2"]
  • -

    Politika kolačića

    -

    Petabit koristi samo nužne funkcionalne tehnologije i, uz vašu privolu, analitičke kolačiće. Analitika nije potrebna za korištenje stranice.

    +

    @Localizer["CookiePolicy"]

    +

    @Localizer["CookiePolicyIntro"]

    -

    Nužne funkcionalne tehnologije

    +

    @Localizer["NecessaryTechnologies"]

    - + - - + +
    NazivSvrhaTrajanje
    @Localizer["Name"]@Localizer["Purpose"]@Localizer["Duration"]
    .AspNetCore.CulturePamti odabrani jezik stranice.1 godina
    petabit-analytics-consentLokalna pohrana odluke o analitičkim kolačićima u pregledniku.Dok ne promijenite odluku ili ne obrišete podatke preglednika
    .AspNetCore.Culture@Localizer["CulturePurpose"]@Localizer["OneYear"]
    petabit-analytics-consent@Localizer["ConsentPurpose"]@Localizer["ConsentDuration"]
    -

    Analitički kolačići – Google Analytics 4

    -

    Google Analytics učitava se samo nakon odabira Prihvaćam. Prikuplja zbirne podatke kao što su broj korisnika i sesija, približna lokacija, preglednik, uređaj i izvor dolaska. Ne koristimo ga za izravno utvrđivanje identiteta posjetitelja.

    +

    @Localizer["AnalyticsCookies"]

    +

    @Localizer["AnalyticsDescription"]

    - + - - + +
    NazivSvrhaTrajanje
    @Localizer["Name"]@Localizer["Purpose"]@Localizer["Duration"]
    _gaRazlikuje jedinstvene korisnike.Do 2 godine
    _ga_W5Z2EDHVY4Čuva stanje sesije za Google Analytics 4.Do 2 godine
    _ga@Localizer["GaPurpose"]@Localizer["UpToTwoYears"]
    _ga_W5Z2EDHVY4@Localizer["GaSessionPurpose"]@Localizer["UpToTwoYears"]
    -

    Više o GA4 kolačićima: Google Analytics dokumentacija.

    +

    @Localizer["GaMoreInfo"] @Localizer["GaDocumentation"].

    -

    Upravljanje privolom

    -

    Analitičke kolačiće možete prihvatiti ili odbiti pri prvom posjetu. Svoju odluku možete promijeniti u bilo kojem trenutku.

    - +

    @Localizer["ConsentManagement"]

    +

    @Localizer["ConsentManagementText"]

    +

    @Localizer["DataSecurity"]

    @Localizer["DataSecurityText"]

    diff --git a/README.md b/README.md index 0b4ad3e..3e62ed3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ [![CI](https://github.com/ChevCellios/Petabit/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ChevCellios/Petabit/actions/workflows/ci.yml) [![Security](https://github.com/ChevCellios/Petabit/actions/workflows/security.yml/badge.svg?branch=master)](https://github.com/ChevCellios/Petabit/actions/workflows/security.yml) -[![Production](https://github.com/ChevCellios/Petabit/actions/workflows/uptime.yml/badge.svg?branch=master)](https://github.com/ChevCellios/Petabit/actions/workflows/uptime.yml) +[![Production smoke test](https://github.com/ChevCellios/Petabit/actions/workflows/uptime.yml/badge.svg?branch=master)](https://github.com/ChevCellios/Petabit/actions/workflows/uptime.yml) +[![Station status freshness](https://github.com/ChevCellios/Petabit/actions/workflows/station-status-freshness.yml/badge.svg?branch=master)](https://github.com/ChevCellios/Petabit/actions/workflows/station-status-freshness.yml) +[![Monitored by Better Stack](https://img.shields.io/badge/uptime-Better%20Stack-5B45FF)](https://betterstack.com/uptime) ![.NET](https://img.shields.io/badge/.NET-10.0-blueviolet) ![Language](https://img.shields.io/badge/language-C%23-orange) ![Localization](https://img.shields.io/badge/i18n-HR%20%7C%20EN%20%7C%20DE-green) @@ -64,7 +66,7 @@ Izvori podataka: - timeout, retry i circuit breaker za vanjski ISS servis - `/health/live` provjera procesa i `/health/ready` provjera dostupnosti ISS servisa - post-deployment smoke test nakon svakog pusha u `master` -- uptime provjera produkcije svakih 15 minuta +- Better Stack provjera produkcijskih liveness, readiness i ISS API endpointova svake 3 minute - tjedna provjera starosti kuriranih podataka o ISS posadi i letjelicama - smoke test početne stranice, readiness endpointa i ISS trackera - strukturirani JSON logovi u produkciji