pokerface/frontend/src/components/LegalPage.jsx
Jan Willem Mannaerts 3ab584e2ab
All checks were successful
Build & Push Container Image / build (push) Successful in 8s
Update env example with full Jira scopes and add source code link to privacy page
- Added all required Jira OAuth scopes to .env.example
- Added NATS_TOKEN and JIRA_MOCK_FALLBACK to .env.example
- Added open source section to privacy policy linking to the repo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:32:59 +01:00

253 lines
11 KiB
JavaScript

export default function LegalPage({ page, dark, onBack }) {
return (
<div className="min-h-screen flex flex-col" style={{ background: dark ? '#09090b' : '#f0f1f5' }}>
<header className="flex items-center gap-3 px-5 py-3 shrink-0">
<button
onClick={onBack}
className="text-sm font-medium px-3 py-1 border-none cursor-pointer transition-colors"
style={{
color: dark ? '#94a3b8' : '#64748b',
background: dark ? '#1e293b' : '#e2e8f0'
}}
>
&larr; Back
</button>
<span className="font-syne font-bold text-sm tracking-tight" style={{ color: dark ? '#fff' : '#0f172a' }}>
POKERFACE
</span>
</header>
<main className="flex-1 px-5 py-6 max-w-2xl mx-auto w-full">
{page === 'terms' && <TermsOfService dark={dark} />}
{page === 'privacy' && <PrivacyPolicy dark={dark} />}
{page === 'support' && <Support dark={dark} />}
</main>
</div>
);
}
function Heading({ children, dark }) {
return <h1 className="text-2xl font-bold mb-4 mt-0" style={{ color: dark ? '#fff' : '#0f172a' }}>{children}</h1>;
}
function SubHeading({ children, dark }) {
return <h2 className="text-base font-semibold mt-6 mb-2" style={{ color: dark ? '#e2e8f0' : '#1e293b' }}>{children}</h2>;
}
function P({ children, dark }) {
return <p className="text-sm leading-relaxed my-2" style={{ color: dark ? '#94a3b8' : '#475569' }}>{children}</p>;
}
function Li({ children, dark }) {
return <li className="text-sm leading-relaxed my-1" style={{ color: dark ? '#94a3b8' : '#475569' }}>{children}</li>;
}
function TermsOfService({ dark }) {
return (
<>
<Heading dark={dark}>Terms of Service</Heading>
<P dark={dark}><em>Last updated: February 2026</em></P>
<SubHeading dark={dark}>1. Acceptance</SubHeading>
<P dark={dark}>
By accessing or using Pokerface ("the Service"), you agree to these terms.
If you do not agree, do not use the Service.
</P>
<SubHeading dark={dark}>2. Description</SubHeading>
<P dark={dark}>
Pokerface is a free sprint planning poker tool that integrates with Atlassian Jira.
It is provided as a convenience for agile teams to facilitate estimation sessions.
</P>
<SubHeading dark={dark}>3. No Warranty</SubHeading>
<P dark={dark}>
THE SERVICE IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTIES OF ANY KIND,
WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
NON-INFRINGEMENT. NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED FROM
THE SERVICE SHALL CREATE ANY WARRANTY NOT EXPRESSLY STATED HEREIN.
</P>
<SubHeading dark={dark}>4. Limitation of Liability</SubHeading>
<P dark={dark}>
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL THE DEVELOPERS,
OPERATORS, OR CONTRIBUTORS OF POKERFACE BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES, OR ANY LOSS OF PROFITS, DATA, USE, OR
GOODWILL, HOWEVER CAUSED AND UNDER ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY, OR OTHERWISE, ARISING OUT OF OR IN
CONNECTION WITH YOUR ACCESS TO OR USE OF (OR INABILITY TO USE) THE SERVICE.
</P>
<P dark={dark}>
THE TOTAL AGGREGATE LIABILITY OF THE SERVICE OPERATORS FOR ALL CLAIMS RELATING TO
THE SERVICE SHALL NOT EXCEED ZERO EUROS (EUR 0.00).
</P>
<SubHeading dark={dark}>5. No Guarantee of Availability</SubHeading>
<P dark={dark}>
The Service may be modified, suspended, or discontinued at any time without notice.
We are under no obligation to maintain, support, or update the Service.
</P>
<SubHeading dark={dark}>6. User Responsibilities</SubHeading>
<P dark={dark}>
You are responsible for your use of the Service and any data you transmit through it.
You must comply with Atlassian's terms of service when using Jira integration features.
</P>
<SubHeading dark={dark}>7. Third-Party Services</SubHeading>
<P dark={dark}>
Pokerface integrates with Atlassian Jira via OAuth. Your use of Jira is governed by
Atlassian's own terms and privacy policy. We are not responsible for any third-party
service availability or behavior.
</P>
<SubHeading dark={dark}>8. Changes to Terms</SubHeading>
<P dark={dark}>
These terms may be updated at any time. Continued use of the Service after changes
constitutes acceptance of the revised terms.
</P>
</>
);
}
function PrivacyPolicy({ dark }) {
return (
<>
<Heading dark={dark}>Privacy Policy</Heading>
<P dark={dark}><em>Last updated: February 2026</em></P>
<SubHeading dark={dark}>1. What Data We Collect</SubHeading>
<P dark={dark}>
When you sign in with Jira, we receive the following information from Atlassian via OAuth:
</P>
<ul className="pl-5 my-2">
<Li dark={dark}><strong>Jira account ID</strong> your unique Atlassian identifier</Li>
<Li dark={dark}><strong>Display name</strong> your Jira profile name</Li>
<Li dark={dark}><strong>Avatar URL</strong> a link to your Jira profile picture</Li>
<Li dark={dark}><strong>Email address</strong> your Jira account email</Li>
<Li dark={dark}><strong>Cloud ID and site URL</strong> identifies your Jira workspace</Li>
<Li dark={dark}><strong>OAuth tokens</strong> access and refresh tokens for Jira API calls</Li>
</ul>
<P dark={dark}>
During poker sessions, we temporarily store:
</P>
<ul className="pl-5 my-2">
<Li dark={dark}>Room and session metadata (project name, sprint name, issue keys)</Li>
<Li dark={dark}>Participant names and avatar URLs</Li>
<Li dark={dark}>Votes submitted during estimation sessions</Li>
</ul>
<SubHeading dark={dark}>2. How We Use Your Data</SubHeading>
<P dark={dark}>
Your data is used solely to operate the poker planning functionality:
authenticating you with Jira, displaying participants in sessions, recording votes,
and writing agreed estimates back to Jira issues. We do not use your data for
analytics, advertising, profiling, or any other purpose.
</P>
<SubHeading dark={dark}>3. Data Storage and Retention</SubHeading>
<P dark={dark}>
All data is stored in NATS JetStream key-value buckets with automatic time-to-live (TTL) expiration:
</P>
<ul className="pl-5 my-2">
<Li dark={dark}><strong>OAuth connections</strong> automatically deleted after 24 hours</Li>
<Li dark={dark}><strong>Rooms and sessions</strong> automatically deleted after 24 hours</Li>
<Li dark={dark}><strong>OAuth state tokens</strong> automatically deleted after 10 minutes</Li>
</ul>
<P dark={dark}>
There is no long-term database. All session data is ephemeral and automatically purged
by TTL. When a poker session is saved, the session data is deleted immediately.
</P>
<SubHeading dark={dark}>4. Cookies</SubHeading>
<P dark={dark}>
Pokerface uses a single, strictly functional cookie:
</P>
<ul className="pl-5 my-2">
<Li dark={dark}>
<strong>pokerface_session</strong> an HttpOnly, Secure, SameSite=Lax JWT cookie
that contains your Jira account ID, cloud ID, display name, and avatar URL. It
expires after 24 hours. This cookie is required for the application to function.
</Li>
</ul>
<P dark={dark}>
We do not use tracking cookies, analytics cookies, or any third-party cookies.
A dark mode preference is stored in your browser's localStorage (not a cookie)
and never sent to our servers.
</P>
<SubHeading dark={dark}>5. Data Sharing</SubHeading>
<P dark={dark}>
We do not sell, share, or transfer your personal data to any third party.
The only external communication is between our backend and Atlassian's Jira API,
using the OAuth tokens you authorized, to read project/sprint data and write
estimates back to issues.
</P>
<SubHeading dark={dark}>6. Data Security</SubHeading>
<P dark={dark}>
All traffic is encrypted via HTTPS in production. Session cookies are marked HttpOnly
and Secure. Security headers (HSTS, X-Frame-Options DENY, nosniff) are applied to all
responses. OAuth tokens are stored server-side only and never exposed to the browser.
</P>
<SubHeading dark={dark}>7. Your Rights</SubHeading>
<P dark={dark}>
Since all data expires automatically within 24 hours, there is no persistent personal
data to request deletion of. You can sign out at any time to clear your session cookie.
Revoking the Pokerface OAuth connection in your Atlassian account settings will
invalidate all stored tokens.
</P>
<SubHeading dark={dark}>8. Open Source</SubHeading>
<P dark={dark}>
Pokerface is open source. If you want to verify how your data is handled, you can
review the full source code at{' '}
<a
href="https://git.faralmail.com/faral/pokerface"
target="_blank"
rel="noopener noreferrer"
style={{ color: dark ? '#60a5fa' : '#2563eb', textDecoration: 'underline' }}
>
git.faralmail.com/faral/pokerface
</a>.
</P>
</>
);
}
function Support({ dark }) {
return (
<>
<Heading dark={dark}>Support</Heading>
<P dark={dark}><em>Last updated: February 2026</em></P>
<SubHeading dark={dark}>About Pokerface</SubHeading>
<P dark={dark}>
Pokerface is a free, open tool for sprint planning poker with Jira integration.
It is provided as-is, with no guarantees of availability, support, or maintenance.
</P>
<SubHeading dark={dark}>No Formal Support</SubHeading>
<P dark={dark}>
This product does not come with dedicated support, SLAs, or guaranteed response times.
There is no helpdesk, ticketing system, or support team.
</P>
<SubHeading dark={dark}>Best-Effort Assistance</SubHeading>
<P dark={dark}>
If you encounter a bug or issue, you may reach out via the project's repository.
Any assistance is provided on a best-effort basis at the maintainer's discretion.
</P>
<SubHeading dark={dark}>Alternatives</SubHeading>
<P dark={dark}>
If Pokerface does not meet your needs, there are many alternative planning poker tools
available in the Atlassian Marketplace and elsewhere. You are free to stop using
Pokerface at any time simply sign out and revoke the OAuth connection in your
Atlassian account settings.
</P>
</>
);
}