Merge pull request #190 from christianlouis/copilot/manage-token-timeouts
Add English privacy policy, Terms of Service, and legal footer links for Google OAuth verification
This commit is contained in:
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
<!-- version list -->
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- **English Privacy Policy** (`/privacy`): comprehensive public privacy policy in English including a Google API Services Limited Use Disclosure, explaining how `gmail.insert`, `gmail.labels`, and `gmail.readonly` scopes are used. Required for Google OAuth consent screen verification.
|
||||
- **Terms of Service** (`/terms`): full English terms of service covering acceptable use, Google API compliance, data, liability, and governing law.
|
||||
- **Home page footer legal links**: Privacy Policy, Terms of Service, Impressum, and Datenschutz links added to the public landing page footer — directly resolves the Google verification rejection ("homepage does not contain a link to your privacy policy").
|
||||
- **Login page footer**: now includes Privacy Policy and Terms of Service links alongside the existing Impressum / Datenschutz links.
|
||||
- **Register page consent text**: "By creating an account you agree to our Terms of Service and Privacy Policy" notice added below the sign-up form.
|
||||
- **Datenschutz cross-link**: German privacy page now links to the English `/privacy` page in section 2 and the bottom footer bar.
|
||||
|
||||
## v0.6.5 (2026-04-07)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -4,6 +4,8 @@ Comprehensive task breakdown for repository improvements and production readines
|
||||
|
||||
## ✅ Recently Completed
|
||||
|
||||
- [x] **Google OAuth consent screen legal compliance**: Added English Privacy Policy (`/privacy`) with Google API Limited Use Disclosure, Terms of Service (`/terms`), legal footer links on the home page (resolves Google's "homepage has no privacy policy link" verification rejection), login page, and register page (consent text). Cross-link from `/datenschutz` to `/privacy` added.
|
||||
|
||||
- [x] **Fix Pydantic V2 deprecation warnings**: Replaced `.dict()` with `.model_dump()` in `admin.py` and `notifications.py`. Fixed `RuntimeWarning: coroutine never awaited` for `db.add()` in test mocks (`test_tasks.py`, `test_config_service.py`).
|
||||
|
||||
- [x] **Expanded backend test coverage**: Added 150 new unit tests across 10 new test files, increasing the backend test count from 361 to 511. New coverage includes `core/gdpr.py`, `utils/gmail_labels.py`, `services/notification_service.py`, `services/auth_service.py`, and API endpoints for auth, users, notifications, processing-runs/logs, app-settings, and version.
|
||||
|
||||
@@ -83,7 +83,7 @@ export default function DatenschutzPage() {
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
2. Geltungsbereich dieser Datenschutzerklärung
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
<p className="text-gray-700 mb-3">
|
||||
Dieser Hinweis gilt für die {APP_NAME}-Webanwendung. Er gilt
|
||||
für alle Nutzer weltweit, einschließlich derjenigen in der
|
||||
Europäischen Union (EU), dem Europäischen Wirtschaftsraum (EWR),
|
||||
@@ -91,6 +91,14 @@ export default function DatenschutzPage() {
|
||||
Ukraine, den Vereinigten Staaten (US), Kanada, Lateinamerika,
|
||||
dem asiatisch-pazifischen Raum und Japan.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
Eine englischsprachige Fassung dieser Datenschutzerklärung ist
|
||||
verfügbar unter:{' '}
|
||||
<Link href="/privacy" className="text-blue-600 hover:text-blue-500">
|
||||
/privacy
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="section-3" className="mb-8">
|
||||
@@ -372,7 +380,13 @@ export default function DatenschutzPage() {
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div className="border-t border-gray-200 pt-4 flex gap-4 text-sm text-gray-500">
|
||||
<div className="border-t border-gray-200 pt-4 flex flex-wrap gap-4 text-sm text-gray-500">
|
||||
<Link href="/privacy" className="hover:text-blue-600">
|
||||
Privacy Policy (EN)
|
||||
</Link>
|
||||
<Link href="/terms" className="hover:text-blue-600">
|
||||
Terms of Service
|
||||
</Link>
|
||||
<Link href="/impressum" className="hover:text-blue-600">
|
||||
Impressum
|
||||
</Link>
|
||||
|
||||
@@ -151,6 +151,12 @@ export default function LoginPage() {
|
||||
</form>
|
||||
|
||||
<div className="mt-6 flex justify-center gap-4 text-xs text-gray-400">
|
||||
<Link href="/privacy" className="hover:text-gray-600 transition-colors">
|
||||
Privacy Policy
|
||||
</Link>
|
||||
<Link href="/terms" className="hover:text-gray-600 transition-colors">
|
||||
Terms
|
||||
</Link>
|
||||
<Link href="/impressum" className="hover:text-gray-600 transition-colors">
|
||||
Impressum
|
||||
</Link>
|
||||
|
||||
@@ -269,9 +269,23 @@ export default function Home() {
|
||||
{/* Footer */}
|
||||
<footer className="mt-20 border-t border-gray-200 bg-white">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<p className="text-center text-gray-600 text-sm">
|
||||
<p className="text-center text-gray-600 text-sm mb-3">
|
||||
© {new Date().getFullYear()} InboxConverge — made for people, not enterprises.
|
||||
</p>
|
||||
<div className="flex justify-center gap-4 text-xs text-gray-400">
|
||||
<Link href="/privacy" className="hover:text-gray-600 transition-colors">
|
||||
Privacy Policy
|
||||
</Link>
|
||||
<Link href="/terms" className="hover:text-gray-600 transition-colors">
|
||||
Terms of Service
|
||||
</Link>
|
||||
<Link href="/impressum" className="hover:text-gray-600 transition-colors">
|
||||
Impressum
|
||||
</Link>
|
||||
<Link href="/datenschutz" className="hover:text-gray-600 transition-colors">
|
||||
Datenschutz
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,542 @@
|
||||
import Link from 'next/link';
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
const APP_NAME = process.env.APP_NAME ?? 'InboxConverge';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `Privacy Policy – ${APP_NAME}`,
|
||||
};
|
||||
|
||||
const LAST_UPDATED = 'April 18, 2026';
|
||||
const CONTACT_EMAIL = process.env.CONTACT_EMAIL ?? 'christian@inboxconverge.com';
|
||||
|
||||
export default function PrivacyPage() {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div className="max-w-3xl mx-auto bg-white rounded-lg shadow p-8">
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">Privacy Policy</h1>
|
||||
<p className="text-sm text-gray-500 mb-8">Last updated: {LAST_UPDATED}</p>
|
||||
|
||||
{/* TOC */}
|
||||
<nav className="mb-8 p-4 bg-gray-50 rounded-md text-sm text-blue-700 space-y-1">
|
||||
<p className="font-semibold text-gray-700 mb-2">Contents</p>
|
||||
{[
|
||||
'Who We Are',
|
||||
'Scope of This Policy',
|
||||
'What Data We Collect and Why',
|
||||
'Google API Services — Limited Use Disclosure',
|
||||
'Data Minimisation and Purpose Limitation',
|
||||
'Cookies and Similar Technologies',
|
||||
'Third-Party Services',
|
||||
'International Data Transfers',
|
||||
'Data Retention',
|
||||
'Data Security',
|
||||
'Your Rights (EU / EEA / UK / Switzerland)',
|
||||
'Additional Rights — United States (CCPA / CPRA)',
|
||||
'Additional Rights — Canada (PIPEDA / Law 25)',
|
||||
'Additional Rights — Other Jurisdictions',
|
||||
'Changes to This Policy',
|
||||
'Contact Us',
|
||||
].map((title, i) => (
|
||||
<div key={i}>
|
||||
<a href={`#section-${i + 1}`} className="hover:underline">
|
||||
{i + 1}. {title}
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
{/* 1 */}
|
||||
<section id="section-1" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">1. Who We Are</h2>
|
||||
<p className="text-gray-700 mb-3">
|
||||
The data controller responsible for processing your personal data in
|
||||
accordance with the EU General Data Protection Regulation (GDPR) and
|
||||
equivalent data-protection laws worldwide is:
|
||||
</p>
|
||||
<p className="text-gray-700 mb-3">
|
||||
Christian Louis IT Beratung<br />
|
||||
Alter Steinweg 3, 20459 Hamburg, Germany
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
Contact:{' '}
|
||||
<a
|
||||
href={`mailto:${CONTACT_EMAIL}`}
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
{CONTACT_EMAIL}
|
||||
</a>
|
||||
</p>
|
||||
<p className="text-gray-700 mt-2">
|
||||
For all data-protection enquiries (access, erasure, correction,
|
||||
objection or complaints) please use the email address above. We
|
||||
respond within 30 days (or the period required by applicable law).
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 2 */}
|
||||
<section id="section-2" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
2. Scope of This Policy
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
This policy applies to the {APP_NAME} web application and all
|
||||
associated services. It covers all users worldwide, including those
|
||||
in the European Union (EU), European Economic Area (EEA), United
|
||||
Kingdom, Switzerland, and the United States.
|
||||
</p>
|
||||
<p className="text-gray-700 mt-3">
|
||||
A German-language version of this policy is available at{' '}
|
||||
<Link href="/datenschutz" className="text-blue-600 hover:text-blue-500">
|
||||
/datenschutz
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 3 */}
|
||||
<section id="section-3" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
3. What Data We Collect and Why
|
||||
</h2>
|
||||
|
||||
<h3 className="text-base font-semibold text-gray-700 mt-4 mb-2">
|
||||
3.1 Account and Authentication Data
|
||||
</h3>
|
||||
<p className="text-gray-700 mb-2">
|
||||
When you create an account or sign in with Google we may receive
|
||||
your name, email address, and profile picture from Google OAuth 2.0.
|
||||
We use this data solely to authenticate you and identify your
|
||||
account within {APP_NAME}.
|
||||
</p>
|
||||
<p className="text-gray-700 mb-3">
|
||||
Legal basis (GDPR Art. 6): (b) contract performance.
|
||||
</p>
|
||||
|
||||
<h3 className="text-base font-semibold text-gray-700 mt-4 mb-2">
|
||||
3.2 Source Mailbox Credentials
|
||||
</h3>
|
||||
<p className="text-gray-700 mb-2">
|
||||
To fetch email from your legacy POP3 / IMAP accounts you provide
|
||||
server details and credentials. These are stored encrypted at rest
|
||||
using AES-256 and are never transmitted to any third party.
|
||||
</p>
|
||||
<p className="text-gray-700 mb-3">
|
||||
Legal basis (GDPR Art. 6): (b) contract performance.
|
||||
</p>
|
||||
|
||||
<h3 className="text-base font-semibold text-gray-700 mt-4 mb-2">
|
||||
3.3 Gmail API OAuth Tokens
|
||||
</h3>
|
||||
<p className="text-gray-700 mb-2">
|
||||
To inject email into your Gmail account, {APP_NAME} requests the
|
||||
following Google OAuth 2.0 scopes:
|
||||
</p>
|
||||
<ul className="list-disc list-inside text-gray-700 space-y-2 mb-3">
|
||||
<li>
|
||||
<code className="text-xs bg-gray-100 px-1 rounded">
|
||||
https://www.googleapis.com/auth/gmail.insert
|
||||
</code>{' '}
|
||||
— inserts messages directly into your Gmail mailbox without
|
||||
sending them through SMTP.
|
||||
</li>
|
||||
<li>
|
||||
<code className="text-xs bg-gray-100 px-1 rounded">
|
||||
https://www.googleapis.com/auth/gmail.labels
|
||||
</code>{' '}
|
||||
— creates and manages Gmail labels so imported messages can be
|
||||
tagged (e.g. “imported”).
|
||||
</li>
|
||||
<li>
|
||||
<code className="text-xs bg-gray-100 px-1 rounded">
|
||||
https://www.googleapis.com/auth/gmail.readonly
|
||||
</code>{' '}
|
||||
— reads your Gmail profile (email address) to confirm the
|
||||
connection is working.
|
||||
</li>
|
||||
</ul>
|
||||
<p className="text-gray-700 mb-2">
|
||||
The resulting access and refresh tokens are stored encrypted at
|
||||
rest. Tokens are refreshed automatically by the service when they
|
||||
expire and the refreshed token is persisted back to the database.
|
||||
You can revoke access at any time from your{' '}
|
||||
<a
|
||||
href="https://myaccount.google.com/permissions"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
Google Account permissions
|
||||
</a>{' '}
|
||||
page.
|
||||
</p>
|
||||
<p className="text-gray-700 mb-3">
|
||||
Legal basis (GDPR Art. 6): (b) contract performance.
|
||||
</p>
|
||||
|
||||
<h3 className="text-base font-semibold text-gray-700 mt-4 mb-2">
|
||||
3.4 Email Content
|
||||
</h3>
|
||||
<p className="text-gray-700 mb-2">
|
||||
Email bodies and attachments are read from your source accounts and
|
||||
written to your Gmail account. They are processed in memory only;
|
||||
no email content is written to persistent storage other than within
|
||||
your own Gmail account.
|
||||
</p>
|
||||
<p className="text-gray-700 mb-3">
|
||||
Legal basis (GDPR Art. 6): (b) contract performance.
|
||||
</p>
|
||||
|
||||
<h3 className="text-base font-semibold text-gray-700 mt-4 mb-2">
|
||||
3.5 Processing Logs
|
||||
</h3>
|
||||
<p className="text-gray-700 mb-2">
|
||||
We retain limited operational logs (message subject line, sender
|
||||
address, timestamp, success/failure flag) for up to 90 days. These
|
||||
are used to diagnose delivery problems and are accessible only to
|
||||
you and our operations team.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
Legal basis (GDPR Art. 6): (f) legitimate interests.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 4 — the critical Google Limited Use Disclosure */}
|
||||
<section id="section-4" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
4. Google API Services — Limited Use Disclosure
|
||||
</h2>
|
||||
<div className="border-l-4 border-blue-400 bg-blue-50 p-4 rounded-r-md mb-4">
|
||||
<p className="text-gray-800 font-medium mb-1">
|
||||
Limited Use Policy Compliance
|
||||
</p>
|
||||
<p className="text-gray-700 text-sm">
|
||||
{APP_NAME}’s use of information received from Google APIs
|
||||
adheres to the{' '}
|
||||
<a
|
||||
href="https://developers.google.com/terms/api-services-user-data-policy"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
Google API Services User Data Policy
|
||||
</a>
|
||||
, including the Limited Use requirements.
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-gray-700 mb-3">
|
||||
Specifically, {APP_NAME} commits to the following with respect to
|
||||
data obtained via Google APIs:
|
||||
</p>
|
||||
<ul className="list-disc list-inside text-gray-700 space-y-2">
|
||||
<li>
|
||||
<strong>Single purpose:</strong> Google user data is used only to
|
||||
deliver the core service — importing email from legacy mailboxes
|
||||
into your Gmail account.
|
||||
</li>
|
||||
<li>
|
||||
<strong>No transfer to third parties:</strong> We do not sell,
|
||||
rent, transfer, or disclose Google user data to third parties,
|
||||
except as necessary to provide the service (e.g. the Gmail API
|
||||
call itself) or as required by law.
|
||||
</li>
|
||||
<li>
|
||||
<strong>No advertising:</strong> We do not use Google user data
|
||||
to serve advertisements or for advertising-related purposes.
|
||||
</li>
|
||||
<li>
|
||||
<strong>No human reading:</strong> We do not allow humans to read
|
||||
your Gmail data unless you have given us explicit permission to do
|
||||
so (e.g. for diagnosing a reported technical problem), or it is
|
||||
required by law.
|
||||
</li>
|
||||
<li>
|
||||
<strong>No profiling:</strong> We do not use Google user data to
|
||||
build profiles, perform analytics, or engage in behavioural
|
||||
tracking beyond what is strictly necessary to operate the service.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Security:</strong> All data obtained from Google APIs is
|
||||
stored with AES-256 encryption at rest and transmitted only over
|
||||
TLS-encrypted connections.
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{/* 5 */}
|
||||
<section id="section-5" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
5. Data Minimisation and Purpose Limitation
|
||||
</h2>
|
||||
<ul className="list-disc list-inside text-gray-700 space-y-1">
|
||||
<li>
|
||||
We collect only the minimum personal data needed to operate the
|
||||
service.
|
||||
</li>
|
||||
<li>
|
||||
Email content is processed solely for the forwarding purpose you
|
||||
initiate.
|
||||
</li>
|
||||
<li>
|
||||
No advertising, behavioural tracking, or profiling is performed.
|
||||
</li>
|
||||
<li>No tracking cookies or analytics scripts are loaded.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{/* 6 */}
|
||||
<section id="section-6" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
6. Cookies and Similar Technologies
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
The service uses only strictly necessary session cookies to
|
||||
maintain your authenticated session. These cookies are essential
|
||||
for the service to function and are exempt from prior-consent
|
||||
requirements under the EU ePrivacy Directive (Art. 5(3)). We do
|
||||
not use analytics cookies, advertising cookies, or tracking pixels.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 7 */}
|
||||
<section id="section-7" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
7. Third-Party Services
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-2">
|
||||
<strong>Google OAuth / Gmail API:</strong> Authentication and Gmail
|
||||
delivery are handled via Google’s APIs. Google processes your
|
||||
credentials according to its own{' '}
|
||||
<a
|
||||
href="https://policies.google.com/privacy"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
Privacy Policy
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
<strong>No sale or sharing for advertising:</strong> We do not
|
||||
sell, rent, or share your personal data with third parties for
|
||||
advertising or marketing purposes.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 8 */}
|
||||
<section id="section-8" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
8. International Data Transfers
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
Where personal data is transferred outside the EEA we rely on
|
||||
appropriate safeguards, including Standard Contractual Clauses
|
||||
(SCCs) pursuant to EU Decision 2021/914/EU and European Commission
|
||||
adequacy decisions.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 9 */}
|
||||
<section id="section-9" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
9. Data Retention
|
||||
</h2>
|
||||
<ul className="list-disc list-inside text-gray-700 space-y-1">
|
||||
<li>
|
||||
<strong>Session data:</strong> deleted on logout or session
|
||||
expiry.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Account configuration and metadata:</strong> retained for
|
||||
the duration of your use of the service.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Processing logs:</strong> retained for up to 90 days.
|
||||
</li>
|
||||
<li>
|
||||
<strong>OAuth tokens:</strong> stored encrypted and revocable at
|
||||
any time via your Google Account.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Account deletion:</strong> all data associated with your
|
||||
account is permanently deleted within 30 days of account closure.
|
||||
You can request deletion by emailing{' '}
|
||||
<a
|
||||
href={`mailto:${CONTACT_EMAIL}`}
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
{CONTACT_EMAIL}
|
||||
</a>
|
||||
.
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{/* 10 */}
|
||||
<section id="section-10" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
10. Data Security
|
||||
</h2>
|
||||
<ul className="list-disc list-inside text-gray-700 space-y-1">
|
||||
<li>AES-256 encryption of credentials at rest.</li>
|
||||
<li>TLS / HTTPS for all communications.</li>
|
||||
<li>Role-based access controls to protect personal data.</li>
|
||||
<li>CSRF protection for all state-changing requests.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{/* 11 */}
|
||||
<section id="section-11" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
11. Your Rights (EU / EEA / UK / Switzerland)
|
||||
</h2>
|
||||
<ul className="list-disc list-inside text-gray-700 space-y-1">
|
||||
<li>
|
||||
<strong>Right of access (Art. 15):</strong> a copy of the data
|
||||
held about you.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to rectification (Art. 16):</strong> correction of
|
||||
inaccurate data.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to erasure (Art. 17):</strong> deletion of your
|
||||
personal data.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to restriction (Art. 18):</strong> temporary
|
||||
suspension of processing.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to portability (Art. 20):</strong> data in a
|
||||
machine-readable format.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to object (Art. 21):</strong> objection to
|
||||
processing based on legitimate interests.
|
||||
</li>
|
||||
</ul>
|
||||
<p className="text-gray-700 mt-3">
|
||||
To exercise any of these rights, contact us at{' '}
|
||||
<a
|
||||
href={`mailto:${CONTACT_EMAIL}`}
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
{CONTACT_EMAIL}
|
||||
</a>
|
||||
. Complaints may be directed to the relevant supervisory authority
|
||||
(in Germany: BfDI).
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 12 */}
|
||||
<section id="section-12" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
12. Additional Rights — United States (CCPA / CPRA)
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
If you are a California resident or resident of another US state
|
||||
with applicable privacy legislation, you have the right to know,
|
||||
delete, correct, and opt out of the sale of personal information.
|
||||
We do not sell or share personal information. Contact:{' '}
|
||||
<a
|
||||
href={`mailto:${CONTACT_EMAIL}`}
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
{CONTACT_EMAIL}
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 13 */}
|
||||
<section id="section-13" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
13. Additional Rights — Canada (PIPEDA / Law 25)
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
If you are in Canada, you have the right to access, correct, and
|
||||
withdraw consent under PIPEDA and provincial privacy laws. Contact:{' '}
|
||||
<a
|
||||
href={`mailto:${CONTACT_EMAIL}`}
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
{CONTACT_EMAIL}
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 14 */}
|
||||
<section id="section-14" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
14. Additional Rights — Other Jurisdictions
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
Users in Brazil (LGPD), Japan (APPI), Australia (Privacy Act 1988),
|
||||
South Korea (PIPA), Singapore (PDPA), and other markets may exercise
|
||||
equivalent data-protection rights under applicable national law.
|
||||
Contact:{' '}
|
||||
<a
|
||||
href={`mailto:${CONTACT_EMAIL}`}
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
{CONTACT_EMAIL}
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 15 */}
|
||||
<section id="section-15" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
15. Changes to This Policy
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
We may update this policy from time to time. The “Last
|
||||
updated” date at the top of this page indicates when it was
|
||||
last revised. For material changes we will notify users via an
|
||||
in-app notice or email.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 16 */}
|
||||
<section id="section-16" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
16. Contact Us
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
For questions or concerns about this policy or your data, please
|
||||
contact:{' '}
|
||||
<a
|
||||
href={`mailto:${CONTACT_EMAIL}`}
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
{CONTACT_EMAIL}
|
||||
</a>
|
||||
</p>
|
||||
<p className="text-gray-700 mt-2">
|
||||
Christian Louis IT Beratung<br />
|
||||
Alter Steinweg 3, 20459 Hamburg, Germany
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div className="border-t border-gray-200 pt-4 flex flex-wrap gap-4 text-sm text-gray-500">
|
||||
<Link href="/terms" className="hover:text-blue-600">
|
||||
Terms of Service
|
||||
</Link>
|
||||
<Link href="/datenschutz" className="hover:text-blue-600">
|
||||
Datenschutz (DE)
|
||||
</Link>
|
||||
<Link href="/impressum" className="hover:text-blue-600">
|
||||
Impressum
|
||||
</Link>
|
||||
<Link href="/login" className="hover:text-blue-600">
|
||||
Back to Login
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -156,7 +156,34 @@ export default function RegisterPage() {
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-xs text-center text-gray-400">
|
||||
By creating an account you agree to our{' '}
|
||||
<Link href="/terms" className="underline hover:text-gray-600">
|
||||
Terms of Service
|
||||
</Link>{' '}
|
||||
and{' '}
|
||||
<Link href="/privacy" className="underline hover:text-gray-600">
|
||||
Privacy Policy
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<div className="mt-4 flex justify-center gap-4 text-xs text-gray-400">
|
||||
<Link href="/privacy" className="hover:text-gray-600 transition-colors">
|
||||
Privacy Policy
|
||||
</Link>
|
||||
<Link href="/terms" className="hover:text-gray-600 transition-colors">
|
||||
Terms
|
||||
</Link>
|
||||
<Link href="/impressum" className="hover:text-gray-600 transition-colors">
|
||||
Impressum
|
||||
</Link>
|
||||
<Link href="/datenschutz" className="hover:text-gray-600 transition-colors">
|
||||
Datenschutz
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,412 @@
|
||||
import Link from 'next/link';
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
const APP_NAME = process.env.APP_NAME ?? 'InboxConverge';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `Terms of Service – ${APP_NAME}`,
|
||||
};
|
||||
|
||||
const LAST_UPDATED = 'April 18, 2026';
|
||||
const CONTACT_EMAIL = process.env.CONTACT_EMAIL ?? 'christian@inboxconverge.com';
|
||||
|
||||
export default function TermsPage() {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div className="max-w-3xl mx-auto bg-white rounded-lg shadow p-8">
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">Terms of Service</h1>
|
||||
<p className="text-sm text-gray-500 mb-8">Last updated: {LAST_UPDATED}</p>
|
||||
|
||||
{/* TOC */}
|
||||
<nav className="mb-8 p-4 bg-gray-50 rounded-md text-sm text-blue-700 space-y-1">
|
||||
<p className="font-semibold text-gray-700 mb-2">Contents</p>
|
||||
{[
|
||||
'Acceptance of Terms',
|
||||
'Service Description',
|
||||
'Account Registration',
|
||||
'Acceptable Use',
|
||||
'Google API Services',
|
||||
'Intellectual Property',
|
||||
'Data and Privacy',
|
||||
'Availability and Modifications',
|
||||
'Disclaimers',
|
||||
'Limitation of Liability',
|
||||
'Indemnification',
|
||||
'Termination',
|
||||
'Governing Law and Dispute Resolution',
|
||||
'Changes to These Terms',
|
||||
'Contact',
|
||||
].map((title, i) => (
|
||||
<div key={i}>
|
||||
<a href={`#section-${i + 1}`} className="hover:underline">
|
||||
{i + 1}. {title}
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
{/* 1 */}
|
||||
<section id="section-1" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
1. Acceptance of Terms
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-3">
|
||||
By accessing or using {APP_NAME} (“the Service”), you agree
|
||||
to be bound by these Terms of Service (“Terms”). If you do
|
||||
not agree, do not use the Service.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
The Service is provided by Christian Louis IT Beratung, Alter
|
||||
Steinweg 3, 20459 Hamburg, Germany (“we”, “us”,
|
||||
“our”).
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 2 */}
|
||||
<section id="section-2" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
2. Service Description
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-3">
|
||||
{APP_NAME} is an email consolidation service that polls legacy
|
||||
POP3 and IMAP mailboxes on your behalf and delivers the retrieved
|
||||
messages directly into your Gmail inbox via the Gmail API. The
|
||||
Service is designed for personal and small-business use.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
The Service is not affiliated with, endorsed by, or sponsored by
|
||||
Google LLC. Gmail and Google are trademarks of Google LLC.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 3 */}
|
||||
<section id="section-3" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
3. Account Registration
|
||||
</h2>
|
||||
<ul className="list-disc list-inside text-gray-700 space-y-2">
|
||||
<li>
|
||||
You must be at least 16 years old (or the minimum age of digital
|
||||
consent in your jurisdiction) to create an account.
|
||||
</li>
|
||||
<li>
|
||||
You are responsible for maintaining the security of your account
|
||||
credentials and for all activity that occurs under your account.
|
||||
</li>
|
||||
<li>
|
||||
You must provide accurate, current, and complete information
|
||||
during registration and keep it up to date.
|
||||
</li>
|
||||
<li>
|
||||
You may not share your account with others or create accounts for
|
||||
the purpose of circumventing usage limits.
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{/* 4 */}
|
||||
<section id="section-4" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
4. Acceptable Use
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-3">You agree not to use the Service to:</p>
|
||||
<ul className="list-disc list-inside text-gray-700 space-y-2">
|
||||
<li>
|
||||
Violate any applicable law, regulation, or third-party rights.
|
||||
</li>
|
||||
<li>
|
||||
Transmit unsolicited commercial messages (spam) or malicious
|
||||
content.
|
||||
</li>
|
||||
<li>
|
||||
Attempt to gain unauthorised access to any systems or networks.
|
||||
</li>
|
||||
<li>
|
||||
Interfere with or disrupt the integrity or performance of the
|
||||
Service.
|
||||
</li>
|
||||
<li>
|
||||
Circumvent or reverse-engineer any technical protection measures.
|
||||
</li>
|
||||
<li>
|
||||
Use the Service in a way that could impose an unreasonable load on
|
||||
our infrastructure.
|
||||
</li>
|
||||
</ul>
|
||||
<p className="text-gray-700 mt-3">
|
||||
We reserve the right to suspend or terminate accounts that violate
|
||||
this policy.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 5 */}
|
||||
<section id="section-5" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
5. Google API Services
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-3">
|
||||
The Service uses the Google Gmail API to insert messages into your
|
||||
Gmail account. By connecting your Google account you also agree to
|
||||
Google’s{' '}
|
||||
<a
|
||||
href="https://policies.google.com/terms"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
Terms of Service
|
||||
</a>{' '}
|
||||
and{' '}
|
||||
<a
|
||||
href="https://policies.google.com/privacy"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
Privacy Policy
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<p className="text-gray-700 mb-3">
|
||||
Our use of data obtained via Google APIs complies with the{' '}
|
||||
<a
|
||||
href="https://developers.google.com/terms/api-services-user-data-policy"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
Google API Services User Data Policy
|
||||
</a>
|
||||
, including the Limited Use requirements. In particular, we use
|
||||
Google user data only to provide the email-import service described
|
||||
in these Terms and never for advertising or unrelated purposes.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
You can revoke {APP_NAME}’s access to your Google account at
|
||||
any time from your{' '}
|
||||
<a
|
||||
href="https://myaccount.google.com/permissions"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
Google Account permissions
|
||||
</a>{' '}
|
||||
page.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 6 */}
|
||||
<section id="section-6" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
6. Intellectual Property
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-3">
|
||||
The {APP_NAME} software is open-source and licensed under the
|
||||
terms of the project’s{' '}
|
||||
<a
|
||||
href="https://github.com/christianlouis/InboxConverge/blob/main/LICENSE"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
LICENSE
|
||||
</a>{' '}
|
||||
file. Nothing in these Terms grants you a licence to use the
|
||||
{' '}{APP_NAME} name or logo for purposes outside of the permitted
|
||||
open-source licence.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
You retain all rights to your own email content. We claim no
|
||||
ownership over any messages processed by the Service.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 7 */}
|
||||
<section id="section-7" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
7. Data and Privacy
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
Our collection and use of personal data is described in our{' '}
|
||||
<Link href="/privacy" className="text-blue-600 hover:text-blue-500">
|
||||
Privacy Policy
|
||||
</Link>
|
||||
, which forms part of these Terms. By using the Service you
|
||||
acknowledge and agree to the Privacy Policy.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 8 */}
|
||||
<section id="section-8" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
8. Availability and Modifications
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-3">
|
||||
We aim to provide a reliable service but do not guarantee
|
||||
uninterrupted availability. We may modify, suspend, or discontinue
|
||||
the Service (or any part of it) at any time with reasonable notice
|
||||
where practicable.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
We may update these Terms from time to time. Material changes will
|
||||
be communicated via in-app notice or email. Continued use of the
|
||||
Service after changes take effect constitutes acceptance of the
|
||||
revised Terms.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 9 */}
|
||||
<section id="section-9" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
9. Disclaimers
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-3">
|
||||
The Service is provided “as is” and “as
|
||||
available” without warranties of any kind, express or implied,
|
||||
including but not limited to warranties of merchantability, fitness
|
||||
for a particular purpose, or non-infringement.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
We do not warrant that the Service will be error-free, that defects
|
||||
will be corrected, or that the Service or its infrastructure are
|
||||
free of viruses or other harmful components.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 10 */}
|
||||
<section id="section-10" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
10. Limitation of Liability
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-3">
|
||||
To the maximum extent permitted by applicable law, Christian Louis
|
||||
IT Beratung and its representatives shall not be liable for any
|
||||
indirect, incidental, special, consequential, or punitive damages,
|
||||
or any loss of profits, data, goodwill, or business opportunities
|
||||
arising out of or in connection with your use of the Service.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
Our aggregate liability for any claim relating to the Service is
|
||||
limited to the greater of (a) the amount you paid us in the 12
|
||||
months preceding the claim, or (b) €50.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 11 */}
|
||||
<section id="section-11" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
11. Indemnification
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
You agree to indemnify and hold harmless Christian Louis IT Beratung
|
||||
and its representatives from and against any claims, damages,
|
||||
losses, and expenses (including reasonable legal fees) arising out
|
||||
of your use of the Service, your violation of these Terms, or your
|
||||
violation of any third-party rights.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 12 */}
|
||||
<section id="section-12" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
12. Termination
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-3">
|
||||
You may close your account at any time by contacting us at{' '}
|
||||
<a
|
||||
href={`mailto:${CONTACT_EMAIL}`}
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
{CONTACT_EMAIL}
|
||||
</a>
|
||||
. Upon closure, all your data will be permanently deleted within
|
||||
30 days.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
We may suspend or terminate your account immediately if you breach
|
||||
these Terms or if we are required to do so by law.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 13 */}
|
||||
<section id="section-13" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
13. Governing Law and Dispute Resolution
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-3">
|
||||
These Terms are governed by the laws of the Federal Republic of
|
||||
Germany, excluding its conflict-of-law provisions. The courts of
|
||||
Hamburg, Germany shall have exclusive jurisdiction over any dispute
|
||||
arising out of or in connection with these Terms, except where
|
||||
mandatory consumer-protection laws in your jurisdiction provide
|
||||
otherwise.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
EU consumers may also use the European Commission’s Online
|
||||
Dispute Resolution platform:{' '}
|
||||
<a
|
||||
href="https://ec.europa.eu/consumers/odr"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
https://ec.europa.eu/consumers/odr
|
||||
</a>
|
||||
. We are not obliged to participate in alternative dispute
|
||||
resolution procedures but will consider reasonable requests.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 14 */}
|
||||
<section id="section-14" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
14. Changes to These Terms
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
We reserve the right to modify these Terms at any time. We will
|
||||
provide at least 14 days’ notice of material changes via
|
||||
in-app notification or email. Your continued use of the Service
|
||||
after the effective date of revised Terms constitutes your
|
||||
acceptance of those Terms.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* 15 */}
|
||||
<section id="section-15" className="mb-8">
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-3">
|
||||
15. Contact
|
||||
</h2>
|
||||
<p className="text-gray-700">
|
||||
For questions about these Terms, please contact:
|
||||
</p>
|
||||
<p className="text-gray-700 mt-2">
|
||||
Christian Louis IT Beratung<br />
|
||||
Alter Steinweg 3, 20459 Hamburg, Germany<br />
|
||||
<a
|
||||
href={`mailto:${CONTACT_EMAIL}`}
|
||||
className="text-blue-600 hover:text-blue-500"
|
||||
>
|
||||
{CONTACT_EMAIL}
|
||||
</a>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div className="border-t border-gray-200 pt-4 flex flex-wrap gap-4 text-sm text-gray-500">
|
||||
<Link href="/privacy" className="hover:text-blue-600">
|
||||
Privacy Policy
|
||||
</Link>
|
||||
<Link href="/datenschutz" className="hover:text-blue-600">
|
||||
Datenschutz (DE)
|
||||
</Link>
|
||||
<Link href="/impressum" className="hover:text-blue-600">
|
||||
Impressum
|
||||
</Link>
|
||||
<Link href="/login" className="hover:text-blue-600">
|
||||
Back to Login
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user