Merge the monetization feature branch.

Add RYS Premium subscription system

Introduce optional paid tier with sign-in, Stripe billing, and premium
feature gating. Core features remain free. Includes Node.js server for
auth, payments, and license management.

Extension changes:
- Sign-in flow with magic link email
- Premium/upgrade/account modals with branded UI
- Premium feature gating (60+ advanced settings)
- Password lock and scheduling (premium)
- Fix "hide all but first row" for YouTube's new flat homepage DOM
- Hide sidebar ad panels by default
- Enable "Hide all Shorts" by default

Server:
- Magic link auth with rate limiting
- Stripe checkout, webhooks, and billing portal
- JWT-based license tokens
- AWS SES transactional emails (welcome, sign-in, cancellation)
- Grandfathered donor support

Also adds CI workflow, server test suite, and extension unit tests.
This commit is contained in:
Lawrence Hook
2026-02-15 18:45:37 -05:00
parent a76f69804b
commit 8825666512
63 changed files with 10364 additions and 482 deletions
+72
View File
@@ -0,0 +1,72 @@
# RYS Premium Server
Backend server for the premium subscription system.
## Quick Start
```bash
# Install dependencies
npm install
# Copy env and fill in values
cp .env.example .env
# Run tests
npm test
# Start development server
npm run dev
# Start production server
npm start
```
## API Endpoints
| Endpoint | Method | Auth | Description |
|----------|--------|------|-------------|
| `/health` | GET | No | Health check |
| `/auth/send-magic-link` | POST | No | Send magic link email |
| `/auth/verify` | GET | No | Magic link target (HTML) |
| `/auth/poll` | GET | No | Poll for verification status |
| `/license/check` | GET | Yes | Check premium status |
| `/checkout/create` | POST | Yes | Create Stripe checkout session |
| `/checkout/success` | GET | No | Success page (HTML) |
| `/checkout/cancel` | GET | No | Cancel page (HTML) |
| `/billing/portal` | POST | Yes | Create billing portal session |
| `/billing/return` | GET | No | Return page (HTML) |
| `/webhook/stripe` | POST | No* | Stripe webhook |
*Authenticated via Stripe signature
## File Structure
```
server/
├── src/
│ ├── index.js # Entry point
│ ├── config.js # Configuration
│ ├── routes/ # Express routes
│ ├── services/ # Stripe, JWT, email
│ └── storage/ # File-based storage
├── data/
│ ├── grandfathered.json # Donor emails (gitignored)
│ ├── auth-requests/ # Pending auth (auto-created)
│ └── rate-limits/ # Rate limit counters (auto-created)
├── tests/
└── package.json
```
## Grandfathered Users
Past donors get lifetime premium. Store emails in `data/grandfathered.json`:
```json
["donor1@example.com", "donor2@example.com"]
```
This file is gitignored. See `data.example/` for format.
## Full Documentation
See [DEPLOYMENT.md](../DEPLOYMENT.md) for complete setup, deployment, and testing instructions.