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: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import CommunityPage from './pages/CommunityPage'
import BlogPage from './pages/BlogPage'
import BlogPostPage from './pages/BlogPostPage'
import FaqPage from './pages/FaqPage'
import ModerationPage from './pages/ModerationPage'
import NotFoundPage from './pages/NotFoundPage'
import AuthModal from './components/AuthModal/AuthModal'
import ProtectedRoute from './components/ProtectedRoute/ProtectedRoute'
Expand Down Expand Up @@ -80,6 +81,7 @@ export default function App() {
<Route path="/terms" element={<Layout><TermsPage /></Layout>} />
<Route path="/cookies" element={<Layout><CookiesPage /></Layout>} />
<Route path="/imprint" element={<Layout><ImprintPage /></Layout>} />
<Route path="/moderation" element={<Layout><ModerationPage /></Layout>} />
<Route path="/blog" element={<Layout><BlogPage /></Layout>} />
<Route path="/blog/:slug" element={<Layout><BlogPostPage /></Layout>} />
<Route path="/faq" element={<Layout><FaqPage /></Layout>} />
Expand Down
4 changes: 2 additions & 2 deletions src/components/BYOKSection/BYOKSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const featureCards: Carousel3DCard[] = [
{
icon: <KeyIcon />,
title: 'Bring your own keys',
description: 'Hook up OpenAI, Anthropic, Gemini whatever you use. OpenThorn never touches your API keys.',
description: 'Hook up OpenAI, Anthropic, Gemini - whatever you use. OpenThorn uses your keys only for requests you make.',
},
{
icon: <DollarIcon />,
Expand All @@ -22,7 +22,7 @@ const featureCards: Carousel3DCard[] = [
{
icon: <SparkIcon />,
title: 'Real code, real time',
description: 'OpenThorn writes production-grade code not a drag-and-drop approximation. Watch every file appear.',
description: 'OpenThorn writes production-grade code - not a drag-and-drop approximation. Watch every file appear.',
},
{
icon: <GlobeIcon />,
Expand Down
1 change: 1 addition & 0 deletions src/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const legalLinks = [
{ label: 'Privacy Policy', to: '/privacy' },
{ label: 'Terms of Service', to: '/terms' },
{ label: 'Cookie Policy', to: '/cookies' },
{ label: 'Moderation & DSA', to: '/moderation' },
{ label: 'Imprint', to: '/imprint' },
]

Expand Down
81 changes: 67 additions & 14 deletions src/pages/CookiesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,90 @@ import { usePageTitle } from '../lib/usePageTitle'
export default function CookiesPage() {
usePageTitle('Cookie Policy')
return (
<LegalPage title="Cookie Policy" lastUpdated="June 6, 2026">
<h2>1. What Are Cookies and Local Storage</h2>
<LegalPage title="Cookie and Storage Policy" lastUpdated="June 8, 2026">
Comment on lines 4 to +7
<h2>1. What Cookies and Local Storage Are</h2>
<p>
Cookies are small text files stored in your browser by a website. Many modern web
applications also use the browser's <strong>localStorage</strong> API — a similar
mechanism that stores data locally without an expiry date. This page explains
exactly what OpenThorn stores and why.
Cookies are small text files stored in your browser by a website. Modern web apps
also use browser storage such as <strong>localStorage</strong> and{' '}
<strong>sessionStorage</strong>. This page explains what OpenThorn stores in your
browser and why.
</p>

<h2>2. Essential Storage</h2>
<h2>2. Essential Authentication Storage</h2>
<p>
The following storage is strictly necessary for the service to function. It cannot
be disabled without breaking the service.
OpenThorn uses Supabase Auth to keep you signed in and protect account-only pages.
Depending on browser and Supabase behavior, session information may be stored in
browser storage and related authentication cookies. This storage is necessary for
login, logout, account security, and session restoration.
</p>

<h2>3. Essential App Storage</h2>
<p>
OpenThorn also uses localStorage for product features that need to survive page
reloads on the same browser:
</p>
<ul>
<li>
<strong>Supabase authentication session</strong> — stores your login session so
you remain signed in across page loads. Set by Supabase when you sign in.
Removed when you sign out or clear your browser data.
<strong>seen_shared_projects_*</strong> - remembers which shared-project
notifications you have already seen, so the dashboard does not repeat the same
notice after every refresh.
</li>
<li>
<strong>github_repo_*</strong> - stores per-project GitHub repository owner,
repository name, and auto-sync preference for the browser you are using.
</li>
<li>
<strong>openthorn.memory.*</strong> - stores local user-memory entries such as
inferred design preferences, recurring fixes, and useful facts across projects.
</li>
<li>
<strong>Preview storage polyfills</strong> - generated project previews may use
in-memory replacements for localStorage or sessionStorage when sandboxed previews
cannot access normal browser storage.
</li>
</ul>

<h2>3. What We Do Not Use</h2>
<h2>4. Consent Banner</h2>
<p>
OpenThorn currently does not use analytics cookies, advertising cookies,
retargeting pixels, or third-party social media tracking pixels. Because the
current browser storage is used for authentication, security, and requested app
functionality, we do not show a cookie consent banner. If we add non-essential
cookies or tracking, we will update this page and request consent where required.
</p>

<h2>5. External Resource Requests</h2>
<p>
OpenThorn may load fonts, generated-preview runtime packages, type definitions,
or WebAssembly resources from third-party CDNs. These requests are not used by
OpenThorn for advertising or behavioural tracking, but the third-party provider
may receive technical request data such as your IP address, browser information,
requested URL, referrer, and request time.
</p>
<p>
We describe these providers and data flows in the Privacy Policy. If we add
analytics, profiling, advertising, or other non-essential tracking, we will update
this notice and request consent where required.
</p>

<h2>6. How to Control Storage</h2>
<p>
You can clear cookies and localStorage through your browser settings. Clearing
storage may sign you out, remove local preferences, reset notification state, and
disconnect browser-local GitHub repository settings. Server-side account,
project, provider-key, integration, collaboration, and community records are
handled as described in the Privacy Policy.
</p>

<h2>7. What We Do Not Use</h2>
<ul>
<li>No analytics or tracking cookies.</li>
<li>No advertising or retargeting cookies.</li>
<li>No third-party social media tracking pixels.</li>
<li>No data shared with or sold to data brokers.</li>
</ul>

<h2>4. Contact</h2>
<h2>8. Contact</h2>
<p>
For questions about our use of cookies or local storage, contact us at{' '}
<strong><a href="mailto:mys.thomas00@gmail.com">mys.thomas00@gmail.com</a></strong>.
Expand Down
4 changes: 2 additions & 2 deletions src/pages/FaqPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ const FAQ_DATA: FaqCategory[] = [
{
question: 'Are my API keys safe?',
answer:
'Yes. API keys are encrypted with AES-256-GCM before being stored in our database. They are never logged, never shared with third parties, and are only decrypted at the moment your request is sent to the provider.',
'Saved API keys are encrypted before database storage, are not used for OpenThorn billing, and are decrypted only when needed to send your request to the AI provider you selected. You should still set provider-side spend limits, rotate keys, and revoke any key you suspect has been exposed.',
},
{
question: 'What data does OpenThorn store?',
answer:
'We store your email address, your encrypted API keys, your project names, and the prompts and generated code within your projects. We do not collect payment information, browsing behaviour, or any data beyond what is needed to provide the service.',
'We store the data needed to provide the service, including account/profile data, encrypted API keys, project names, prompts, generated code, collaboration records, community likes, deployment metadata, and optional GitHub integration data. Browser-local storage may also keep app preferences and local user memory.',
},
{
question: 'Where is my data hosted?',
Expand Down
36 changes: 33 additions & 3 deletions src/pages/ImprintPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,48 @@ import { usePageTitle } from '../lib/usePageTitle'
export default function ImprintPage() {
usePageTitle('Imprint')
return (
<LegalPage title="Imprint" lastUpdated="June 6, 2026">
<h2>Operator</h2>
<LegalPage title="Imprint" lastUpdated="June 8, 2026">
<h2>Service Provider</h2>
<p>
<strong>Thomas Tschinkel</strong><br />
OpenThorn<br />
Rome, Italy
</p>

<h2>Contact</h2>
<h2>Legal Address</h2>
<p>
The full postal address of the operator must be added here before public or
commercial operation of the service. "Rome, Italy" alone may not satisfy provider
information duties for an Italian or EU information society service.
</p>
Comment on lines +15 to +20

<h2>Contact Details</h2>
<p>
Name: Thomas Tschinkel<br />
Email: <a href="mailto:mys.thomas00@gmail.com">mys.thomas00@gmail.com</a>
</p>

<h2>Business and Tax Information</h2>
<p>
If OpenThorn is operated commercially or through a registered business, add the
applicable business name, legal form, registration number, register court or
chamber of commerce entry, VAT or Partita IVA, and PEC address here.
</p>
Comment on lines +28 to +33

<h2>Responsible for Content</h2>
<p>
Thomas Tschinkel is responsible for OpenThorn content unless otherwise stated.
User-generated Community content is handled under the{' '}
<a href="/moderation">Moderation and DSA Notice</a>.
</p>

<h2>Dispute Resolution</h2>
<p>
The European Commission's former Online Dispute Resolution platform stopped
accepting new complaints on March 20, 2025 and was discontinued on July 20, 2025.
OpenThorn is not currently obliged or willing to participate in a voluntary
consumer arbitration procedure unless mandatory law requires otherwise.
</p>
</LegalPage>
)
}
1 change: 1 addition & 0 deletions src/pages/LegalPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const DOC_NAV = [
{ path: '/terms', label: 'Terms of Service' },
{ path: '/privacy', label: 'Privacy Policy' },
{ path: '/cookies', label: 'Cookie Policy' },
{ path: '/moderation', label: 'Moderation & DSA' },
{ path: '/imprint', label: 'Imprint' },
]

Expand Down
87 changes: 87 additions & 0 deletions src/pages/ModerationPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import LegalPage from './LegalPage'
import { usePageTitle } from '../lib/usePageTitle'

export default function ModerationPage() {
usePageTitle('Moderation and DSA')
return (
<LegalPage title="Moderation and DSA Notice" lastUpdated="June 8, 2026">
<h2>1. Scope</h2>
<p>
This notice explains how OpenThorn handles reports about illegal content,
unlawful activity, intellectual-property complaints, and community moderation.
It applies to public or shared areas of the service, including Community
projects, public previews, project metadata, and user-visible profile details.
</p>

<h2>2. Single Point of Contact</h2>
<p>
For Digital Services Act, moderation, law-enforcement, or regulatory enquiries,
contact us at{' '}
<strong><a href="mailto:mys.thomas00@gmail.com">mys.thomas00@gmail.com</a></strong>.
Please write in English, German, or Italian and include enough detail for us to
identify the content or account concerned.
</p>

<h2>3. How to Report Illegal Content</h2>
<p>
If you believe content on OpenThorn is illegal or infringes your rights, email us
with the following information:
</p>
<ul>
<li>The URL, project ID, username, screenshot, or other identifier of the content.</li>
<li>A clear explanation of why you believe the content is illegal or infringing.</li>
<li>Your name and email address, unless you have a legally valid reason to report anonymously.</li>
<li>For intellectual-property reports, proof that you own or represent the affected rights.</li>
<li>A statement that the information in your report is accurate to the best of your knowledge.</li>
</ul>

<h2>4. Review and Action</h2>
<p>
We review reports in good faith and may remove, restrict, disable, or preserve
content where this is necessary to comply with law, protect users, enforce our
Terms, or investigate abuse. We may also reject reports that are incomplete,
abusive, clearly unfounded, or not related to OpenThorn.
</p>
<p>
When we take moderation action against user content, we will provide the affected
user with a brief explanation where appropriate and legally permitted. We may not
provide details if doing so would create security risks, reveal confidential
information, interfere with an investigation, or violate applicable law.
</p>

<h2>5. Appeals</h2>
<p>
If your content or account is restricted and you believe the decision was wrong,
contact us at{' '}
<strong><a href="mailto:mys.thomas00@gmail.com">mys.thomas00@gmail.com</a></strong>
{' '}with the subject line "Moderation Appeal". Include the original decision,
your account email, the affected content, and why you believe the decision should
be changed.
</p>

<h2>6. Repeat Abuse</h2>
<p>
We may suspend or terminate accounts that repeatedly publish illegal content,
submit manifestly unfounded reports, attempt to evade moderation, or abuse the
reporting process.
</p>

<h2>7. Community Standards</h2>
<p>
Public OpenThorn content must not include illegal material, malware, phishing,
stolen credentials, private personal data, impersonation, copyright-infringing
material, hate or harassment, sexual exploitation, or content that endangers
children. Do not publish API keys, passwords, private repository data, or personal
information you do not have permission to share.
</p>

<h2>8. Emergency and Authority Requests</h2>
<p>
Public authorities and law-enforcement bodies may contact us at{' '}
<strong><a href="mailto:mys.thomas00@gmail.com">mys.thomas00@gmail.com</a></strong>.
We will review requests under applicable law and may require proof of authority,
legal basis, and a clear description of the requested action.
</p>
</LegalPage>
)
}
Loading