diff --git a/app/privacy/page.tsx b/app/privacy/page.tsx new file mode 100644 index 0000000..c269f85 --- /dev/null +++ b/app/privacy/page.tsx @@ -0,0 +1,190 @@ +import type { Metadata } from "next"; +import { LegalPageLayout } from "@/components/LegalPageLayout"; +import { LEGAL_OPERATOR } from "@/lib/legal/constants"; + +export const metadata: Metadata = { + title: "Privacy Policy | Songs2VID", + description: "How Songs2VID collects, uses, and protects your personal data.", +}; + +export default function PrivacyPage() { + return ( + +

1. Overview

+

+ This Privacy Policy explains how {LEGAL_OPERATOR.name} ("we", "us") + processes personal data when you use our website, hosted cloud service, and related features + that convert audio and images into videos for upload to YouTube. +

+

+ We process personal data in accordance with applicable data protection laws, including the + General Data Protection Regulation (GDPR) where it applies. +

+ +

2. Data controller

+

+ {LEGAL_OPERATOR.legalName} +
+ {LEGAL_OPERATOR.address} +
+ {LEGAL_OPERATOR.city} +
+ Email: {LEGAL_OPERATOR.email} +

+ +

3. What data we collect

+

3.1 Account and authentication data

+

When you sign in with Google, we receive and store:

+ + +

3.2 Uploaded content

+

When you use the service, we temporarily process:

+ + +

3.3 Usage and technical data

+ + +

3.4 Payment data

+

+ If you purchase a paid plan, payment processing is handled by our payment provider. We do + not store full payment card details on our servers. We may receive billing status, + subscription identifiers, and transaction references. +

+ +

4. Why we process your data

+ + +

5. Third-party services

+

We use trusted third parties to operate Songs2VID, including:

+ +

+ These providers process data only as necessary to deliver their services and under + appropriate contractual safeguards where required. +

+ +

Google User Data Sharing and Disclosure

+

+ We do not sell, share, transfer, or disclose any Google user data to any third parties. +

+

+ All user data retrieved via Google OAuth APIs is used solely and strictly for the core + functionality of the application (uploading user-generated media) and is never distributed, + transferred, or disclosed to external services, partners, or third parties. +

+ +

6. Data retention

+ +

You may request deletion of your account data subject to legal retention obligations.

+ +

7. Self-hosted deployments

+

+ If you deploy Songs2VID on your own infrastructure, you are the data controller for data + processed on your instance. This Privacy Policy applies to the hosted cloud service + operated by us, not to independent self-hosted installations unless we provide managed + hosting for you under contract. +

+ +

8. Your rights

+

Depending on your location, you may have the right to:

+ +

+ To exercise these rights, contact{" "} + {LEGAL_OPERATOR.email}. +

+ +

9. Cookies and local storage

+

+ We use essential cookies and similar technologies for authentication, session management, + and security. We do not use non-essential tracking cookies unless disclosed separately and + enabled with your consent where required. +

+ +

10. Security

+

+ We implement appropriate technical and organizational measures to protect your data, + including encryption in transit, access controls, and isolated processing environments. + No method of transmission or storage is 100% secure. +

+ +

11. International transfers

+

+ If data is transferred outside your country, we ensure appropriate safeguards such as + standard contractual clauses or equivalent mechanisms where required by law. +

+ +

12. Children

+

+ Songs2VID is not directed at children under 16. We do not knowingly collect personal data + from children. If you believe a child has provided us data, please contact us. +

+ +

13. Changes to this policy

+

+ We may update this Privacy Policy from time to time. Material changes will be posted on + this page with an updated effective date. +

+ +

14. Contact

+

+ Questions about this Privacy Policy:{" "} + {LEGAL_OPERATOR.email} +

+
+ ); +} diff --git a/lib/auth.ts b/lib/auth.ts index ef54dad..7e9c9a9 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -1,5 +1,6 @@ import { NextAuthOptions } from "next-auth"; import GoogleProvider from "next-auth/providers/google"; +import { encryptSecret } from "./crypto/secrets"; import { prisma } from "./db"; import { getInitialQuotaResetAt } from "./quota"; import { fetchYouTubeChannel } from "./youtube/upload"; @@ -18,8 +19,8 @@ export const authOptions: NextAuthOptions = { "openid", "email", "profile", - "https://www.googleapis.com/auth/youtube.upload", - "https://www.googleapis.com/auth/youtube.readonly", + // Single YouTube Data API scope (covers upload, channel, and playlist APIs) + "https://www.googleapis.com/auth/youtube.force-ssl", ].join(" "), }, }, @@ -49,12 +50,15 @@ export const authOptions: NextAuthOptions = { account.refresh_token, ); + const accessToken = encryptSecret(account.access_token); + const refreshToken = encryptSecret(account.refresh_token); + await prisma.youTubeConnection.upsert({ where: { userId: dbUser.id }, create: { userId: dbUser.id, - accessToken: account.access_token, - refreshToken: account.refresh_token, + accessToken, + refreshToken, expiresAt: account.expires_at ? new Date(account.expires_at * 1000) : new Date(Date.now() + 3600 * 1000), @@ -62,8 +66,8 @@ export const authOptions: NextAuthOptions = { channelTitle: channel.channelTitle, }, update: { - accessToken: account.access_token, - refreshToken: account.refresh_token, + accessToken, + refreshToken, expiresAt: account.expires_at ? new Date(account.expires_at * 1000) : new Date(Date.now() + 3600 * 1000),