Diff -- /var/www/vhosts/3dshawn.com/shop.3dshawn.com/unsubscribe.cgi
Diff

/var/www/vhosts/3dshawn.com/shop.3dshawn.com/unsubscribe.cgi

added on local at 2026-07-01 22:10:07

Added
+105
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to ea9213c11793
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1#!/usr/bin/perl
2#======================================================================
3# ShopCart -- /unsubscribe.cgi?t=TOKEN
4#
5# One-click unsubscribe from email footer. Resolves the token to a user,
6# either unsubscribes a single category (?cat=lifecycle) or all
7# non-essential (?unsub_all=1).
8#
9# Always responds with a public-facing confirmation page, even if the
10# token is invalid (don't leak whether the token was real).
11#======================================================================
12use strict;
13use warnings;
14
15use lib '/var/www/vhosts/3dshawn.com/shop.3dshawn.com';
16use CGI;
17use MODS::DBConnect;
18use MODS::ShopCart::Config;
19
20my $q = CGI->new;
21my $form = $q->Vars;
22my $db = MODS::DBConnect->new;
23my $cfg = MODS::ShopCart::Config->new;
24my $DB = $cfg->settings('database_name');
25
26my $tok = $form->{t} || '';
27$tok =~ s/[^a-zA-Z0-9]//g;
28my $cat = $form->{cat} || '';
29$cat =~ s/[^a-z]//g;
30my $all = ($form->{unsub_all} || '') eq '1' ? 1 : 0;
31
32my $dbh = $db->db_connect;
33my $user_id = 0;
34my $email = '';
35if (length($tok) >= 12) {
36 my $r = $db->db_readwrite($dbh, qq~
37 SELECT t.user_id, u.email
38 FROM ${DB}.email_unsubscribe_tokens t
39 JOIN ${DB}.users u ON u.id = t.user_id
40 WHERE t.token='$tok' LIMIT 1
41 ~, $0, __LINE__);
42 if ($r && $r->{user_id}) {
43 $user_id = $r->{user_id} + 0;
44 $email = $r->{email} || '';
45 }
46}
47
48my $changed = 0;
49if ($user_id) {
50 $db->db_readwrite($dbh, qq~
51 UPDATE ${DB}.email_unsubscribe_tokens SET last_used_at=NOW() WHERE token='$tok'
52 ~, $0, __LINE__);
53
54 my @cats_to_off;
55 if ($all) {
56 @cats_to_off = qw(lifecycle product marketing);
57 } elsif ($cat =~ /^(lifecycle|product|marketing)$/) {
58 @cats_to_off = ($cat);
59 }
60 foreach my $c (@cats_to_off) {
61 $db->db_readwrite($dbh, qq~
62 INSERT INTO ${DB}.user_email_preferences (user_id, category, is_subscribed)
63 VALUES ('$user_id', '$c', 0)
64 ON DUPLICATE KEY UPDATE is_subscribed=0
65 ~, $0, __LINE__);
66 $changed++;
67 }
68}
69
70$db->db_disconnect($dbh);
71
72print "Content-Type: text/html; charset=utf-8\r\nCache-Control: no-store\r\n\r\n";
73
74my $email_h = $email; $email_h =~ s/&/&amp;/g; $email_h =~ s/</&lt;/g; $email_h =~ s/>/&gt;/g;
75
76my $msg;
77if (!$user_id) {
78 $msg = qq~<h1 style="font-size:24px;color:#fff;margin:0 0 14px">Unsubscribe link expired</h1>
79<p style="color:#cbd5e1;font-size:15px;line-height:1.6">That link is no longer valid. If you're signed in, you can manage your email preferences directly:</p>
80<p style="margin-top:18px"><a href="/email_preferences.cgi" style="display:inline-block;background:#5aa9ff;color:#fff;padding:10px 18px;border-radius:6px;text-decoration:none;font-weight:600">Manage preferences</a></p>~;
81} elsif ($all) {
82 $msg = qq~<h1 style="font-size:24px;color:#fff;margin:0 0 14px">You're unsubscribed</h1>
83<p style="color:#cbd5e1;font-size:15px;line-height:1.6">We won't send <strong>$email_h</strong> any more lifecycle, product, or marketing emails.</p>
84<p style="color:#94a3b8;font-size:13px;line-height:1.6;margin-top:16px">You'll still get transactional emails (password resets, billing receipts, team invites you accept) because those are essential to using the account.</p>
85<p style="margin-top:18px"><a href="/email_preferences.cgi" style="color:#5aa9ff">Change preferences instead</a></p>~;
86} elsif ($changed) {
87 $msg = qq~<h1 style="font-size:24px;color:#fff;margin:0 0 14px">Unsubscribed from $cat</h1>
88<p style="color:#cbd5e1;font-size:15px;line-height:1.6">We won't send <strong>$email_h</strong> any more <strong>$cat</strong> emails.</p>
89<p style="margin-top:18px"><a href="/email_preferences.cgi" style="color:#5aa9ff">Manage all preferences</a></p>~;
90} else {
91 $msg = qq~<h1 style="font-size:24px;color:#fff;margin:0 0 14px">Manage email preferences</h1>
92<p style="color:#cbd5e1;font-size:15px;line-height:1.6">No category specified. Use the link below to pick which emails you'd like.</p>
93<p style="margin-top:18px"><a href="/email_preferences.cgi" style="display:inline-block;background:#5aa9ff;color:#fff;padding:10px 18px;border-radius:6px;text-decoration:none;font-weight:600">Manage preferences</a></p>~;
94}
95
96print qq~<!doctype html><html><head><meta charset="utf-8"><title>Unsubscribe &middot; ShopCart</title>
97<style>
98body{background:#0b0d10;color:#cbd5e1;font-family:system-ui,-apple-system,sans-serif;margin:0;padding:80px 24px;display:flex;justify-content:center}
99.card{max-width:520px;width:100%;background:rgba(20,20,30,.6);border:1px solid rgba(255,255,255,.08);border-radius:14px;padding:36px 32px}
100.brand{display:flex;align-items:center;gap:10px;margin-bottom:24px}
101.brand-logo{width:32px;height:32px;border-radius:8px;background:#2c0508;color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;border:1.5px solid #fff;font-size:13px}
102</style></head><body><div class="card">
103<div class="brand"><div class="brand-logo">PT</div><div style="font-weight:700;color:#fff">ShopCart</div></div>
104$msg
105</div></body></html>~;
Keyboard: j next diff k previous diff g top G bottom r restore c compile-check ? help