Update legal pages with contact details, location handling, and alert channels
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled

- Expand privacy policy with detailed location-use explanations: search-only, shareable links, and saved location
This commit is contained in:
Ovidiu U
2026-06-10 10:55:54 +01:00
parent df4ebdb7c6
commit 1ae2f1396d
2 changed files with 95 additions and 64 deletions

View File

@@ -1,9 +1,9 @@
{{-- DRAFT: Generated {{ date('Y-m-d') }}. Review by UK-qualified solicitor recommended before launch. --}}
<x-layouts.legal
title="Cookie Policy"
heading="Cookie Policy"
lastUpdated="{{ now()->format('j F Y') }}"
metaDescription="The cookies and similar technologies FuelAlert uses, and how to manage them.">
title="Cookie Policy"
heading="Cookie Policy"
lastUpdated="{{ now()->format('j F Y') }}"
metaDescription="The cookies and similar technologies FuelAlert uses, and how to manage them.">
<section class="space-y-3">
<h2 class="font-display text-2xl font-bold text-zinc-900">1. What cookies are</h2>
@@ -27,62 +27,57 @@
For aggregated usage metrics we run our own self-hosted instance of
<strong>Umami Analytics</strong>, which is <strong>cookieless</strong> &mdash; it does
not set any cookies, does not use device fingerprinting, and does not track you across
sites. Because no personal data is collected, no consent is required.
sites. It does not store information that identifies you as an individual, so no consent
is required.
</p>
<div class="overflow-x-auto">
<table class="w-full border-collapse text-left text-sm">
<thead class="bg-zinc-100">
<tr>
<th class="border border-zinc-300 px-3 py-2 font-semibold">Name</th>
<th class="border border-zinc-300 px-3 py-2 font-semibold">Purpose</th>
<th class="border border-zinc-300 px-3 py-2 font-semibold">Duration</th>
<th class="border border-zinc-300 px-3 py-2 font-semibold">Type</th>
</tr>
<tr>
<th class="border border-zinc-300 px-3 py-2 font-semibold">Name</th>
<th class="border border-zinc-300 px-3 py-2 font-semibold">Purpose</th>
<th class="border border-zinc-300 px-3 py-2 font-semibold">Duration</th>
<th class="border border-zinc-300 px-3 py-2 font-semibold">Type</th>
</tr>
</thead>
<tbody>
<tr>
<td class="border border-zinc-300 px-3 py-2 font-mono text-xs">fuel_alert_session</td>
<td class="border border-zinc-300 px-3 py-2">Keeps you signed in and maintains your session state.</td>
<td class="border border-zinc-300 px-3 py-2">Session</td>
<td class="border border-zinc-300 px-3 py-2">Essential</td>
</tr>
<tr>
<td class="border border-zinc-300 px-3 py-2 font-mono text-xs">XSRF-TOKEN</td>
<td class="border border-zinc-300 px-3 py-2">Protects against cross-site request forgery attacks on forms and account actions.</td>
<td class="border border-zinc-300 px-3 py-2">Session</td>
<td class="border border-zinc-300 px-3 py-2">Essential</td>
</tr>
<tr>
<td class="border border-zinc-300 px-3 py-2 font-mono text-xs">remember_web_*</td>
<td class="border border-zinc-300 px-3 py-2">"Remember me" &mdash; keeps you signed in across browser restarts if you tick the box at login.</td>
<td class="border border-zinc-300 px-3 py-2">Up to 5 years</td>
<td class="border border-zinc-300 px-3 py-2">Essential</td>
</tr>
<tr>
<td class="border border-zinc-300 px-3 py-2 font-mono text-xs">fa_location</td>
<td class="border border-zinc-300 px-3 py-2">Stores your most recent postcode search so we can show local prices on return visits without re-querying.</td>
<td class="border border-zinc-300 px-3 py-2">30 days</td>
<td class="border border-zinc-300 px-3 py-2">Essential</td>
</tr>
<tr>
<td class="border border-zinc-300 px-3 py-2 font-mono text-xs">fuel_alert_session</td>
<td class="border border-zinc-300 px-3 py-2">Keeps you signed in and maintains your session state.</td>
<td class="border border-zinc-300 px-3 py-2">Session</td>
<td class="border border-zinc-300 px-3 py-2">Essential</td>
</tr>
<tr>
<td class="border border-zinc-300 px-3 py-2 font-mono text-xs">XSRF-TOKEN</td>
<td class="border border-zinc-300 px-3 py-2">Protects against cross-site request forgery attacks on forms and account actions.</td>
<td class="border border-zinc-300 px-3 py-2">Session</td>
<td class="border border-zinc-300 px-3 py-2">Essential</td>
</tr>
<tr>
<td class="border border-zinc-300 px-3 py-2 font-mono text-xs">remember_web_*</td>
<td class="border border-zinc-300 px-3 py-2">"Remember me" &mdash; keeps you signed in across browser restarts if you tick the box at login.</td>
<td class="border border-zinc-300 px-3 py-2">30 days</td>
<td class="border border-zinc-300 px-3 py-2">Essential</td>
</tr>
</tbody>
</table>
</div>
<p class="text-sm text-zinc-600">
If we add a marketing or advertising tool in future, a Marketing row will be added to the
table above and your consent will be requested before it loads.
If we add a non-essential cookie in future (for example, a marketing or advertising
tool), we will add it to the table above and request your consent before it loads.
</p>
</section>
<section class="space-y-3">
<h2 class="font-display text-2xl font-bold text-zinc-900">3. Your choices</h2>
<p>
Because we currently only use essential cookies, there is nothing to opt in or out of
on FuelAlert at this time. If we add non-essential cookies in future (for example,
analytics or marketing), we will present a consent banner and you will be able to
accept, reject, or customise your choice. We will not set non-essential cookies before
you have given consent.
Because we currently use only essential cookies, there is nothing to opt in or out of
on FuelAlert at this time. If we introduce non-essential cookies in future (for example,
analytics or marketing), we will ask for your consent first and give you a way to accept,
reject, or customise your choice. We will not set non-essential cookies before you have
given consent.
</p>
<p>
All major browsers also let you view, block, or delete cookies. The ICO publishes

View File

@@ -1,9 +1,9 @@
{{-- DRAFT: Generated {{ date('Y-m-d') }}. Review by UK-qualified solicitor recommended before launch. --}}
<x-layouts.legal
title="Privacy Policy"
heading="Privacy Policy"
lastUpdated="{{ now()->format('j F Y') }}"
metaDescription="How FuelAlert collects, uses and protects your personal data under UK GDPR.">
title="Privacy Policy"
heading="Privacy Policy"
lastUpdated="{{ now()->format('j F Y') }}"
metaDescription="How FuelAlert collects, uses and protects your personal data under UK GDPR.">
<section class="space-y-3">
<h2 class="font-display text-2xl font-bold text-zinc-900">1. Who we are</h2>
@@ -28,11 +28,41 @@
<h3 class="font-semibold text-zinc-900">Account data</h3>
<p>Your email address, a hashed password, and the date you created your account.</p>
<h3 class="font-semibold text-zinc-900">Contact data for alerts</h3>
<p>
If you opt in to WhatsApp or SMS alerts, your mobile phone number. We collect it only to
send the alerts you have requested, and only after you confirm the number through an
opt-in step.
</p>
<h3 class="font-semibold text-zinc-900">Location data</h3>
<p>
Postcodes or place names you search for. With your permission, your device's precise
location to find nearby stations. Derived approximate location used to query our database.
We use location only to show you fuel prices near you, and only when you ask us to. We
never track your location in the background. Location reaches us in the following ways:
</p>
<ul class="list-disc space-y-1 pl-6">
<li>
<strong>Searching nearby (everyone).</strong> When you use "find prices near me",
your browser asks your permission to share your device location. We use the
coordinates to find nearby stations. We do not store your precise coordinates. For
anonymous usage statistics (for example, "stations checked this week") we record
searches only at approximately 1&nbsp;km precision, together with a one-way hashed
version of your IP address that cannot be reversed to identify you.
</li>
<li>
<strong>Shareable search links.</strong> Search results can be shared or bookmarked
as a web link. To make this work, your filters and an approximate location are
included in the link's web address. Location in links is rounded to roughly
street-level precision rather than your exact position. Anyone you share a link with
can see the approximate location it contains.
</li>
<li>
<strong>Saved location (registered users).</strong> If you provide a postcode, we
convert it to approximate coordinates and store this against your account so we can
show your local prices without you re-entering it. You can change or remove it in
your account settings, and it is deleted when you delete your account.
</li>
</ul>
<h3 class="font-semibold text-zinc-900">Payment data</h3>
<p>
@@ -63,9 +93,12 @@
<p>We process your personal data under the following bases of UK GDPR Article 6:</p>
<ul class="list-disc space-y-1 pl-6">
<li><strong>Account creation and service delivery</strong> &mdash; contract (Art. 6(1)(b)).</li>
<li><strong>Sending the alerts you configure, including by email, WhatsApp, SMS or push</strong> &mdash; contract (Art. 6(1)(b)).</li>
<li><strong>Finding stations near you on request (device location)</strong> &mdash; consent (Art. 6(1)(a)), given through your browser's location permission and withdrawable at any time.</li>
<li><strong>Storing your saved location as a registered user</strong> &mdash; contract (Art. 6(1)(b)).</li>
<li><strong>Payment processing</strong> &mdash; contract (Art. 6(1)(b)).</li>
<li><strong>Security and fraud prevention</strong> &mdash; legitimate interests (Art. 6(1)(f)).</li>
<li><strong>Analytics and product improvement</strong> &mdash; legitimate interests, with opt-out via our cookie banner where applicable.</li>
<li><strong>Aggregated, non-identifying analytics and product improvement</strong> &mdash; legitimate interests (Art. 6(1)(f)).</li>
<li><strong>Marketing emails</strong> &mdash; consent (Art. 6(1)(a)). You can withdraw consent at any time.</li>
</ul>
</section>
@@ -74,10 +107,11 @@
<h2 class="font-display text-2xl font-bold text-zinc-900">4. How we use your data</h2>
<ul class="list-disc space-y-1 pl-6">
<li>To create and operate your account (contract).</li>
<li>To deliver fuel price information and alerts you have configured (contract).</li>
<li>To deliver fuel price information and the alerts you have configured (contract).</li>
<li>To find fuel stations near you when you request it (consent).</li>
<li>To process subscription payments via Stripe (contract).</li>
<li>To keep our service secure and prevent abuse (legitimate interests).</li>
<li>To understand which features are used and improve the product (legitimate interests).</li>
<li>To understand which features are used and improve the product, using aggregated, non-identifying data (legitimate interests).</li>
<li>To respond to your support enquiries (contract / legitimate interests).</li>
<li>To send marketing emails if you have opted in (consent).</li>
</ul>
@@ -96,21 +130,22 @@
<li>
<strong>Umami Analytics</strong> &mdash; we run our own self-hosted Umami instance to
collect aggregated, cookieless usage metrics (pages viewed, referrer, country, device
type). No personal data is collected and no analytics data is shared with third
parties.
type). It does not store data that identifies you as an individual, and no analytics
data is shared with third parties.
</li>
<li><strong>Vonage</strong> &mdash; delivers WhatsApp and SMS alerts if you opt in to those channels. Your phone number is shared only to send messages you have requested.</li>
<li><strong>OneSignal</strong> &mdash; delivers web push notifications if you opt in to push alerts.</li>
<li><strong>Vonage</strong> &mdash; delivers WhatsApp and SMS alerts if you opt in to those channels. Your phone number is shared only to send messages you have requested. See <a class="text-accent underline" href="https://www.vonage.co.uk/legal/privacy-policy/" target="_blank" rel="noopener">Vonage's privacy policy</a>.</li>
<li><strong>OneSignal</strong> &mdash; delivers web push notifications if you opt in to push alerts. See <a class="text-accent underline" href="https://onesignal.com/privacy_policy" target="_blank" rel="noopener">OneSignal's privacy policy</a>.</li>
</ul>
</section>
<section class="space-y-3">
<h2 class="font-display text-2xl font-bold text-zinc-900">6. International transfers</h2>
<p>
Some of our processors (notably Stripe) operate outside the UK and EEA, including in the
United States. Where personal data is transferred internationally, we rely on appropriate
safeguards under UK GDPR: the UK International Data Transfer Addendum to the EU Standard
Contractual Clauses, or an equivalent mechanism.
Some of our processors &mdash; including Stripe, Vonage and OneSignal &mdash; operate
outside the UK and EEA, including in the United States. Where personal data is transferred
internationally, we rely on appropriate safeguards under UK GDPR: the UK International Data
Transfer Addendum to the EU Standard Contractual Clauses, the UK Extension to the EU-US
Data Privacy Framework, or an equivalent mechanism, depending on the processor.
</p>
</section>
@@ -118,6 +153,7 @@
<h2 class="font-display text-2xl font-bold text-zinc-900">7. How long we keep data</h2>
<ul class="list-disc space-y-1 pl-6">
<li><strong>Active account data:</strong> for as long as your account is open, plus 12 months after closure.</li>
<li><strong>Saved location (registered users):</strong> while your account is active; deleted when you delete your account.</li>
<li><strong>Payment records:</strong> 6 years, to meet HMRC requirements for self-employed traders.</li>
<li><strong>Marketing data:</strong> until you withdraw consent.</li>
<li><strong>Logs and analytics:</strong> a maximum of 24 months.</li>
@@ -135,7 +171,7 @@
<li><strong>Right to data portability</strong> &mdash; receive your data in a machine-readable format.</li>
<li><strong>Right to object</strong> &mdash; object to processing based on legitimate interests.</li>
<li><strong>Rights related to automated decision-making</strong> &mdash; we do <strong>not</strong> make solely automated decisions with legal or similarly significant effects on you.</li>
<li><strong>Right to withdraw consent</strong> &mdash; where we rely on consent (e.g. marketing).</li>
<li><strong>Right to withdraw consent</strong> &mdash; where we rely on consent (for example, device location or marketing).</li>
</ul>
<p>
To exercise any of these rights, email
@@ -147,8 +183,8 @@
<section class="space-y-3">
<h2 class="font-display text-2xl font-bold text-zinc-900">9. Cookies</h2>
<p>
We use a small number of cookies to operate the service. Full details &mdash; including
categories and how to change your choices &mdash; are in our
We use only a small number of essential cookies to operate the service, and self-hosted,
cookieless analytics. Full details are in our
<a class="text-accent underline" href="{{ route('legal.cookies') }}">Cookie Policy</a>.
</p>
</section>