max / makenotwork
43 files changed,
+1489 insertions,
-138 deletions
| @@ -20,9 +20,9 @@ server_code/makenotwork/ # Main Rust application | |||
| 20 | 20 | docs/ # Documentation (public/ and unpublished/) | |
| 21 | 21 | ``` | |
| 22 | 22 | ||
| 23 | - | ## Production Server (5.78.144.244) | |
| 23 | + | ## Production Server (hetzner) | |
| 24 | 24 | ||
| 25 | - | Hetzner VPS, x86_64 Linux. SSH as `root@5.78.144.244`. | |
| 25 | + | Hetzner VPS, x86_64 Linux. Tailscale hostname: `alpha-west-1` (IP: `100.120.174.96`). Public IP: `5.78.144.244`. SSH as `root@100.120.174.96` (via Tailscale). | |
| 26 | 26 | ||
| 27 | 27 | ### Filesystem | |
| 28 | 28 | ||
| @@ -102,7 +102,7 @@ psql -t -c "SELECT datname FROM pg_database WHERE datname LIKE 'mnw_test_%';" po | |||
| 102 | 102 | ||
| 103 | 103 | - **Stripe Connect** — payments (live mode) | |
| 104 | 104 | - **Hetzner Object Storage** — S3-compatible file storage (fsn1 region) | |
| 105 | - | - **Postmark** — transactional email (password reset, verification, purchase receipts, notifications). Currently in trial mode: can only send to @makenot.work addresses until domain approval completes. | |
| 105 | + | - **Postmark** — transactional email (password reset, verification, purchase receipts, notifications). Live mode. | |
| 106 | 106 | - **Cloudflare** — DNS, CDN, DDoS protection | |
| 107 | 107 | - **Sentry** — error tracking | |
| 108 | 108 | - **Fastmail** — business email (support@, legal@, max@) |
| @@ -4,8 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | 5 | Check if your question is answered: | |
| 6 | 6 | - [FAQ](./faq.md) | |
| 7 | - | - [Troubleshooting](./troubleshooting.md) | |
| 8 | - | - [Documentation](./docs.md) | |
| 9 | 7 | ||
| 10 | 8 | ## Email Support | |
| 11 | 9 | ||
| @@ -39,9 +37,7 @@ Email support@makenot.work with detailed reproduction steps, or file an issue on | |||
| 39 | 37 | ||
| 40 | 38 | ## Feature Requests | |
| 41 | 39 | ||
| 42 | - | Have an idea? | |
| 43 | - | - [Feature Requests](./features.md) for suggestions | |
| 44 | - | - Platform forum for community input | |
| 40 | + | Have an idea? Email support@makenot.work with your suggestion. | |
| 45 | 41 | ||
| 46 | 42 | ## What We Can't Help With | |
| 47 | 43 |
| @@ -180,7 +180,7 @@ Not on Makenot.work. We recognize our infrastructure suits adult content well. M | |||
| 180 | 180 | ||
| 181 | 181 | ### What content isn't allowed? | |
| 182 | 182 | ||
| 183 | - | Content that dehumanizes, harasses, or incites violence toward any group. We hold content discussing marginalized groups to a higher standard. See [Acceptable Use](../../public/legal/acceptable-use.md). | |
| 183 | + | Content that dehumanizes, harasses, or incites violence toward any group. We hold content discussing marginalized groups to a higher standard. See [Acceptable Use](../legal/acceptable-use.md). | |
| 184 | 184 | ||
| 185 | 185 | ### What's your stance on AI-generated content? | |
| 186 | 186 |
| @@ -68,4 +68,4 @@ Drafts are private until you publish them. | |||
| 68 | 68 | ||
| 69 | 69 | - [Set up your profile](./profile.md) | |
| 70 | 70 | - [Organize with tags](../creator/tag-hierarchy.md) | |
| 71 | - | - [Set up pricing](./pricing.md) | |
| 71 | + | - [Set up pricing](../../public/guide/07-pricing.md) |
| @@ -98,6 +98,6 @@ If you earn less on the platform than you paid in subscription fees during a 12- | |||
| 98 | 98 | ||
| 99 | 99 | ## See Also | |
| 100 | 100 | ||
| 101 | - | - [Pricing Overview](./pricing.md) | |
| 101 | + | - [Pricing Overview](../../public/guide/07-pricing.md) | |
| 102 | 102 | - [Small Files Tier ($20/month)](./tier-small-files.md) | |
| 103 | 103 | - [Setting Up Subscriptions](../creator/subscriptions.md) |
| @@ -128,6 +128,6 @@ If you earn less on the platform than you paid in subscription fees during a 12- | |||
| 128 | 128 | ||
| 129 | 129 | ## See Also | |
| 130 | 130 | ||
| 131 | - | - [Pricing Overview](./pricing.md) | |
| 131 | + | - [Pricing Overview](../../public/guide/07-pricing.md) | |
| 132 | 132 | - [Streaming Tier ($40/month)](./tier-streaming.md) | |
| 133 | 133 | - [Small Files Tier ($20/month)](./tier-small-files.md) |
| @@ -143,6 +143,6 @@ If you earn less on the platform than you paid in subscription fees during a 12- | |||
| 143 | 143 | ||
| 144 | 144 | ## See Also | |
| 145 | 145 | ||
| 146 | - | - [Pricing Overview](./pricing.md) | |
| 146 | + | - [Pricing Overview](../../public/guide/07-pricing.md) | |
| 147 | 147 | - [Basic Tier ($10/month)](./tier-text.md) | |
| 148 | 148 | - [Big Files Tier ($30/month)](./tier-big-files.md) |
| @@ -159,5 +159,5 @@ If you earn less on the platform than you paid in subscription fees during a 12- | |||
| 159 | 159 | ||
| 160 | 160 | ## See Also | |
| 161 | 161 | ||
| 162 | - | - [Pricing Overview](./pricing.md) | |
| 162 | + | - [Pricing Overview](../../public/guide/07-pricing.md) | |
| 163 | 163 | - [Big Files Tier ($30/month)](./tier-big-files.md) |
| @@ -109,4 +109,4 @@ Beyond that, our decision is final. We're a small team and can't endlessly re-li | |||
| 109 | 109 | ||
| 110 | 110 | - [Content Moderation](./moderation.md) - how we make decisions | |
| 111 | 111 | - [Account Enforcement](./enforcement.md) - enforcement actions | |
| 112 | - | - [Acceptable Use Policy](./acceptable-use.md) - what we enforce | |
| 112 | + | - [Acceptable Use Policy](../../public/legal/acceptable-use.md) - what we enforce |
| @@ -94,4 +94,4 @@ We track abuse patterns. Repeat false filers may be blocked from our DMCA proces | |||
| 94 | 94 | ||
| 95 | 95 | - [Counter-Notification](./dmca-counter.md) - disputing a takedown | |
| 96 | 96 | - [Content Moderation](./moderation.md) - our broader moderation approach | |
| 97 | - | - [Terms of Service](./terms-of-service.md) - content ownership terms | |
| 97 | + | - [Terms of Service](../../public/legal/terms-of-service.md) - content ownership terms |
| @@ -139,6 +139,6 @@ Even terminated accounts can file appeals. We've overturned terminations when we | |||
| 139 | 139 | ||
| 140 | 140 | ## See Also | |
| 141 | 141 | ||
| 142 | - | - [Acceptable Use Policy](./acceptable-use.md) - what we enforce | |
| 142 | + | - [Acceptable Use Policy](../../public/legal/acceptable-use.md) - what we enforce | |
| 143 | 143 | - [Content Moderation](./moderation.md) - how we make decisions | |
| 144 | 144 | - [Appeal Process](./appeals.md) - disputing decisions |
| @@ -91,5 +91,5 @@ If you believe we made an error, contact appeals@makenot.work. | |||
| 91 | 91 | ||
| 92 | 92 | - [Creator Guarantees](../../public/about/guarantees.md) | |
| 93 | 93 | - [Appeal Process](./appeals.md) | |
| 94 | - | - [Acceptable Use Policy](./acceptable-use.md) | |
| 94 | + | - [Acceptable Use Policy](../../public/legal/acceptable-use.md) | |
| 95 | 95 | - [Transparency Reports](./transparency.md) |
| @@ -175,6 +175,6 @@ Conversion rates and timing vary by country. Check Stripe's documentation for sp | |||
| 175 | 175 | ||
| 176 | 176 | ## See Also | |
| 177 | 177 | ||
| 178 | - | - [Economics](../business/economics.md) - our pricing and cost structure | |
| 178 | + | - Economics (`docs/internal/business/economics.md`) - our pricing and cost structure | |
| 179 | 179 | - [Creator Guarantees](../../public/about/guarantees.md) - our commitments on revenue | |
| 180 | 180 | - [Stripe Documentation](https://stripe.com/docs) - for Stripe-specific questions |
| @@ -31,7 +31,7 @@ For software we run ourselves, we prefer open source. Managed services sometimes | |||
| 31 | 31 | ||
| 32 | 32 | We can explain every line item in our infrastructure bill. When creators ask where their subscription money goes, we have clear answers. | |
| 33 | 33 | ||
| 34 | - | See [Economics](../business/economics.md) for the breakdown. | |
| 34 | + | See the economics documentation for the breakdown. | |
| 35 | 35 | ||
| 36 | 36 | --- | |
| 37 | 37 | ||
| @@ -145,5 +145,5 @@ We accept these trade-offs because the alternative — expensive vendor lock-in | |||
| 145 | 145 | ||
| 146 | 146 | - [Architecture](./architecture.md) — system design and components | |
| 147 | 147 | - [Security](./security.md) — how we protect data | |
| 148 | - | - [Economics](../business/economics.md) — where infrastructure costs fit in | |
| 149 | - | - [Partnerships](../business/partnerships.md) — our approach to vendor relationships | |
| 148 | + | - Economics (`docs/internal/business/economics.md`) — where infrastructure costs fit in | |
| 149 | + | - Partnerships (`docs/internal/business/partnerships.md`) — our approach to vendor relationships |
| @@ -3453,7 +3453,7 @@ dependencies = [ | |||
| 3453 | 3453 | ||
| 3454 | 3454 | [[package]] | |
| 3455 | 3455 | name = "makenotwork" | |
| 3456 | - | version = "0.1.6" | |
| 3456 | + | version = "0.1.7" | |
| 3457 | 3457 | dependencies = [ | |
| 3458 | 3458 | "ammonia", | |
| 3459 | 3459 | "anyhow", |
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | [package] | |
| 2 | 2 | name = "makenotwork" | |
| 3 | - | version = "0.1.7" | |
| 3 | + | version = "0.1.8" | |
| 4 | 4 | edition = "2024" | |
| 5 | 5 | license-file = "../../LICENSE" | |
| 6 | 6 |
| @@ -56,7 +56,7 @@ openssl rand -base64 24 | |||
| 56 | 56 | ### 2. Initial Server Setup | |
| 57 | 57 | ```bash | |
| 58 | 58 | # SSH into server | |
| 59 | - | ssh root@5.78.144.244 | |
| 59 | + | ssh root@100.120.174.96 | |
| 60 | 60 | ||
| 61 | 61 | # Update system | |
| 62 | 62 | apt update && apt upgrade -y | |
| @@ -118,19 +118,19 @@ chown -R makenotwork:makenotwork /opt/makenotwork | |||
| 118 | 118 | From your local machine: | |
| 119 | 119 | ```bash | |
| 120 | 120 | # Copy Caddyfile | |
| 121 | - | scp deploy/Caddyfile root@5.78.144.244:/etc/caddy/Caddyfile | |
| 121 | + | scp deploy/Caddyfile root@100.120.174.96:/etc/caddy/Caddyfile | |
| 122 | 122 | ||
| 123 | 123 | # Copy systemd service | |
| 124 | - | scp deploy/makenotwork.service root@5.78.144.244:/etc/systemd/system/ | |
| 124 | + | scp deploy/makenotwork.service root@100.120.174.96:/etc/systemd/system/ | |
| 125 | 125 | ||
| 126 | 126 | # Copy environment template | |
| 127 | - | scp deploy/env.production root@5.78.144.244:/opt/makenotwork/.env | |
| 127 | + | scp deploy/env.production root@100.120.174.96:/opt/makenotwork/.env | |
| 128 | 128 | ``` | |
| 129 | 129 | ||
| 130 | 130 | ### 7. Configure Environment | |
| 131 | 131 | ```bash | |
| 132 | 132 | # SSH into server | |
| 133 | - | ssh root@5.78.144.244 | |
| 133 | + | ssh root@100.120.174.96 | |
| 134 | 134 | ||
| 135 | 135 | # Edit .env with your actual values | |
| 136 | 136 | nano /opt/makenotwork/.env | |
| @@ -172,16 +172,16 @@ From your local machine in `server_code/makenotwork/`: | |||
| 172 | 172 | chmod +x deploy/deploy.sh | |
| 173 | 173 | ||
| 174 | 174 | # Deploy — cross-compiles for x86_64 Linux, uploads binary, restarts service | |
| 175 | - | ./deploy/deploy.sh root@5.78.144.244 | |
| 175 | + | ./deploy/deploy.sh root@100.120.174.96 | |
| 176 | 176 | ``` | |
| 177 | 177 | ||
| 178 | 178 | ### Verify Deployment | |
| 179 | 179 | ```bash | |
| 180 | 180 | # Check service status | |
| 181 | - | ssh root@5.78.144.244 "systemctl status makenotwork" | |
| 181 | + | ssh root@100.120.174.96 "systemctl status makenotwork" | |
| 182 | 182 | ||
| 183 | 183 | # Check logs | |
| 184 | - | ssh root@5.78.144.244 "journalctl -u makenotwork -f" | |
| 184 | + | ssh root@100.120.174.96 "journalctl -u makenotwork -f" | |
| 185 | 185 | ||
| 186 | 186 | # Test endpoints | |
| 187 | 187 | curl https://makenot.work/ | |
| @@ -261,16 +261,16 @@ cat /etc/postgresql/*/main/pg_hba.conf | grep makenotwork | |||
| 261 | 261 | ||
| 262 | 262 | ### Update Application | |
| 263 | 263 | ```bash | |
| 264 | - | ./deploy/deploy.sh root@5.78.144.244 | |
| 264 | + | ./deploy/deploy.sh root@100.120.174.96 | |
| 265 | 265 | ``` | |
| 266 | 266 | ||
| 267 | 267 | ### View Logs | |
| 268 | 268 | ```bash | |
| 269 | 269 | # Application logs | |
| 270 | - | ssh root@5.78.144.244 "journalctl -u makenotwork -f" | |
| 270 | + | ssh root@100.120.174.96 "journalctl -u makenotwork -f" | |
| 271 | 271 | ||
| 272 | 272 | # Caddy logs | |
| 273 | - | ssh root@5.78.144.244 "tail -f /var/log/caddy/makenotwork.log" | |
| 273 | + | ssh root@100.120.174.96 "tail -f /var/log/caddy/makenotwork.log" | |
| 274 | 274 | ``` | |
| 275 | 275 | ||
| 276 | 276 | ### Database Backups | |
| @@ -280,6 +280,6 @@ For recovery procedures, see `RECOVERY.md`. | |||
| 280 | 280 | ||
| 281 | 281 | ### Restart Services | |
| 282 | 282 | ```bash | |
| 283 | - | ssh root@5.78.144.244 "sudo systemctl restart makenotwork" | |
| 284 | - | ssh root@5.78.144.244 "sudo systemctl restart caddy" | |
| 283 | + | ssh root@100.120.174.96 "sudo systemctl restart makenotwork" | |
| 284 | + | ssh root@100.120.174.96 "sudo systemctl restart caddy" | |
| 285 | 285 | ``` |
| @@ -16,7 +16,7 @@ | |||
| 16 | 16 | set -e | |
| 17 | 17 | ||
| 18 | 18 | # Configuration | |
| 19 | - | SERVER="root@5.78.144.244" | |
| 19 | + | SERVER="root@100.120.174.96" | |
| 20 | 20 | REMOTE_DIR="/opt/makenotwork" | |
| 21 | 21 | BINARY_NAME="makenotwork" | |
| 22 | 22 | TARGET="x86_64-unknown-linux-gnu" |
| @@ -307,6 +307,7 @@ mod tests { | |||
| 307 | 307 | scan: None, | |
| 308 | 308 | git_repos_path: None, | |
| 309 | 309 | postmark_webhook_token: None, | |
| 310 | + | postmark_broadcast_webhook_token: None, | |
| 310 | 311 | }; | |
| 311 | 312 | assert!(require_admin(&user, &config).is_ok()); | |
| 312 | 313 | } | |
| @@ -353,6 +354,7 @@ mod tests { | |||
| 353 | 354 | scan: None, | |
| 354 | 355 | git_repos_path: None, | |
| 355 | 356 | postmark_webhook_token: None, | |
| 357 | + | postmark_broadcast_webhook_token: None, | |
| 356 | 358 | }; | |
| 357 | 359 | assert!(require_admin(&user, &config).is_err()); | |
| 358 | 360 | } |
| @@ -35,6 +35,8 @@ pub struct Config { | |||
| 35 | 35 | pub git_repos_path: Option<String>, | |
| 36 | 36 | /// Bearer token for authenticating Postmark webhook requests (optional) | |
| 37 | 37 | pub postmark_webhook_token: Option<String>, | |
| 38 | + | /// Bearer token for authenticating Postmark broadcast stream webhooks (optional) | |
| 39 | + | pub postmark_broadcast_webhook_token: Option<String>, | |
| 38 | 40 | } | |
| 39 | 41 | ||
| 40 | 42 | /// S3-compatible storage configuration (Hetzner Object Storage) | |
| @@ -117,6 +119,9 @@ impl Config { | |||
| 117 | 119 | // Postmark webhook token - optional, webhook endpoint returns 401 if unset | |
| 118 | 120 | let postmark_webhook_token = std::env::var("POSTMARK_WEBHOOK_TOKEN").ok(); | |
| 119 | 121 | ||
| 122 | + | // Postmark broadcast stream webhook token - optional, same endpoint accepts either token | |
| 123 | + | let postmark_broadcast_webhook_token = std::env::var("POSTMARK_BROADCAST_WEBHOOK_TOKEN").ok(); | |
| 124 | + | ||
| 120 | 125 | Ok(Config { | |
| 121 | 126 | host, | |
| 122 | 127 | port, | |
| @@ -132,6 +137,7 @@ impl Config { | |||
| 132 | 137 | scan, | |
| 133 | 138 | git_repos_path, | |
| 134 | 139 | postmark_webhook_token, | |
| 140 | + | postmark_broadcast_webhook_token, | |
| 135 | 141 | }) | |
| 136 | 142 | } | |
| 137 | 143 | ||
| @@ -257,6 +263,7 @@ impl std::fmt::Debug for Config { | |||
| 257 | 263 | .field("scan", &self.scan) | |
| 258 | 264 | .field("git_repos_path", &self.git_repos_path) | |
| 259 | 265 | .field("postmark_webhook_token", &self.postmark_webhook_token.as_ref().map(|_| "[REDACTED]")) | |
| 266 | + | .field("postmark_broadcast_webhook_token", &self.postmark_broadcast_webhook_token.as_ref().map(|_| "[REDACTED]")) | |
| 260 | 267 | .finish() | |
| 261 | 268 | } | |
| 262 | 269 | } | |
| @@ -316,6 +323,7 @@ mod tests { | |||
| 316 | 323 | scan: None, | |
| 317 | 324 | git_repos_path: None, | |
| 318 | 325 | postmark_webhook_token: None, | |
| 326 | + | postmark_broadcast_webhook_token: None, | |
| 319 | 327 | }; | |
| 320 | 328 | let addr = config.socket_addr(); | |
| 321 | 329 | assert_eq!(addr.port(), 8080); |