Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/frontend/nginx-security-headers.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=()" always;
# Script 'unsafe-inline' is needed by the inline theme script and Angular's inline loaders.
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://cloudflareinsights.com https://www.googletagmanager.com https://www.google-analytics.com https://*.google-analytics.com https://*.analytics.google.com; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://cloudflareinsights.com; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'" always;
3 changes: 0 additions & 3 deletions src/frontend/src/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { ChangeDetectionStrategy, Component, afterNextRender, effect, inject, un
import { RouterOutlet } from '@angular/router';
import { ToastComponent } from './shared/components/toast/toast';
import { ConfirmModalComponent } from './shared/components/confirm-modal/confirm-modal.component';
import { AnalyticsService } from './core/services/analytics.service';
import { RouteLoaderComponent } from './shared/components/route-loader/route-loader';
import { PackageService } from './core/services/package.service';
import { SignalrService } from './core/services/signalr.service';
Expand All @@ -22,8 +21,6 @@ export class App {
private liveUpdates = inject(LiveUpdatesService);

constructor() {
inject(AnalyticsService).init();

afterNextRender(() => {
this.loadLiveUpdates();
this.signalr.startConnection().catch(() => undefined);
Expand Down
56 changes: 0 additions & 56 deletions src/frontend/src/app/core/services/analytics.service.ts

This file was deleted.

47 changes: 32 additions & 15 deletions src/frontend/src/app/features/cookies/cookies.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ <h1 class="text-3xl font-bold tracking-tight text-[#111418] dark:text-white mb-2
<section>
<h2 class="text-lg font-semibold text-[#111418] dark:text-white mb-3">1. Overview</h2>
<p>
{{ appName }} uses browser local storage to enhance your user experience. We do not use
third-party cookies or tracking technologies. This policy explains what we store locally
in your browser and why.
{{ appName }} sets no cookies and uses no tracking technologies. It keeps a few preferences in
your browser's local storage so the site remembers them. This policy lists exactly what is
stored and why.
</p>
</section>

<section>
<h2 class="text-lg font-semibold text-[#111418] dark:text-white mb-3">2. What We Store</h2>
<p class="mb-4">
All data is stored locally in your browser using localStorage. Nothing is sent to
external servers except when explicitly requested by your actions (e.g., package searches).
These entries live only in your browser (localStorage, or sessionStorage where noted). They are
never sent to our servers or to anyone else.
</p>

<div class="overflow-x-auto border border-gray-200 dark:border-gray-700 rounded-lg">
Expand All @@ -47,6 +47,12 @@ <h2 class="text-lg font-semibold text-[#111418] dark:text-white mb-3">2. What We
<td class="py-3 px-4 text-gray-500 dark:text-gray-400">Essential</td>
<td class="py-3 px-4 text-gray-500 dark:text-gray-400">Token lifetime</td>
</tr>
<tr>
<td class="py-3 px-4 font-mono text-xs">lastSelectedRegistry</td>
<td class="py-3 px-4">The registry you last selected on the home page</td>
<td class="py-3 px-4 text-gray-500 dark:text-gray-400">Functional</td>
<td class="py-3 px-4 text-gray-500 dark:text-gray-400">Persistent</td>
</tr>
<tr>
<td class="py-3 px-4 font-mono text-xs">recentRegistries</td>
<td class="py-3 px-4">Recent registry selections for quick access</td>
Expand All @@ -55,25 +61,37 @@ <h2 class="text-lg font-semibold text-[#111418] dark:text-white mb-3">2. What We
</tr>
<tr>
<td class="py-3 px-4 font-mono text-xs">pkgdiff-cookie-consent</td>
<td class="py-3 px-4">Your cookie consent choice</td>
<td class="py-3 px-4">Remembers that you dismissed the privacy notice</td>
<td class="py-3 px-4 text-gray-500 dark:text-gray-400">Essential</td>
<td class="py-3 px-4 text-gray-500 dark:text-gray-400">Persistent</td>
</tr>
<tr>
<td class="py-3 px-4 font-mono text-xs">pkgdiff-linkedin-oauth-state</td>
<td class="py-3 px-4">Protects the LinkedIn sign-in flow (admin only, sessionStorage)</td>
<td class="py-3 px-4 text-gray-500 dark:text-gray-400">Essential</td>
<td class="py-3 px-4 text-gray-500 dark:text-gray-400">Until the flow completes</td>
</tr>
</tbody>
</table>
</div>

<p class="mt-4 text-xs text-gray-500 dark:text-gray-500">
All items marked as "Functional" or "Essential" are necessary for the Service to operate
correctly. We do not use analytics, advertising, or tracking cookies.
"Essential" entries are needed for the Service to work; "Functional" entries only remember your
choices. None of them identify or track you, so they need no consent.
</p>
</section>

<section>
<h2 class="text-lg font-semibold text-[#111418] dark:text-white mb-3">3. Third-Party Cookies</h2>
<h2 class="text-lg font-semibold text-[#111418] dark:text-white mb-3">3. Analytics and Third Parties</h2>
<p class="mb-3">
We count visits with Cloudflare Web Analytics, which sets no cookies, stores nothing in your
browser and does not track you across sites or visits.
</p>
<p>
{{ appName }} does not integrate with any third-party services that set cookies or track
users. All functionality is self-contained within our application.
No third-party service sets cookies on {{ appName }}. Your browser does contact Google Fonts and
GitHub to load fonts and images; see the
<a href="/privacy" title="Privacy Policy" class="text-primary hover:underline">Privacy Policy</a>
for what they receive.
</p>
</section>

Expand All @@ -88,17 +106,16 @@ <h2 class="text-lg font-semibold text-[#111418] dark:text-white mb-3">4. Managin
<li><strong>Safari:</strong> Preferences → Privacy → Manage Website Data → pkgdiff.dev → Remove</li>
</ul>
<p class="mt-3">
Clearing local storage will reset your theme preference and consent choice. Essential
functional data (like auth tokens) will also be removed, logging you out if applicable.
Clearing it resets your theme and registry choices and shows the privacy notice again.
Administrators are also signed out.
</p>
</section>

<section>
<h2 class="text-lg font-semibold text-[#111418] dark:text-white mb-3">5. Changes to This Policy</h2>
<p>
We may update this Cookie Policy from time to time. Changes will be posted on this page
with an updated "Last updated" date. Continued use of {{ appName }} after changes
constitutes acceptance of the updated policy.
with an updated "Last updated" date.
</p>
</section>

Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/app/features/cookies/cookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class CookiesComponent implements OnInit {
private seo = inject(SeoService);
appName = APP_CONFIG.name;
contactEmail = APP_CONFIG.contact.email;
lastUpdated = 'February 9, 2026';
lastUpdated = 'October 19, 2026';

ngOnInit() {
this.seo.updateMeta({
Expand Down
Loading