Diff -- /var/www/vhosts/3dshawn.com/affiliate.3dshawn.com/portal.cgi

O Operator
Diff

/var/www/vhosts/3dshawn.com/affiliate.3dshawn.com/portal.cgi

added on local at 2026-07-01 13:47:38

Added
+189
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 62d014ab601d
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# AffSoft -- branded affiliate portal landing.
4#
5# Hit two ways:
6# * Direct: /portal.cgi?program_id=N -- preview from the merchant's
7# dashboard while DNS is still propagating
8# * Via custom hostname: when an affiliate visits the merchant's
9# branded hostname (DNS CNAME'd to affiliate.3dshawn.com), the
10# incoming HTTP_HOST is looked up in affiliate_programs.portal_host
11# and that program's portal renders. Renders a fully white-label
12# landing -- no AffSoft branding -- with "Apply to join" CTA.
13#======================================================================
14use strict; use warnings;
15
16use lib '/var/www/vhosts/3dshawn.com/affiliate.3dshawn.com';
17use CGI;
18use MODS::DBConnect;
19use MODS::AffSoft::Config;
20
21my $q = CGI->new;
22my $db = MODS::DBConnect->new;
23my $cfg = MODS::AffSoft::Config->new;
24my $DB = $cfg->settings('database_name');
25
26my $pid = ($q->param('program_id') || 0) + 0;
27my $host = lc($ENV{HTTP_HOST} || '');
28$host =~ s/:\d+$//;
29
30my $dbh = $db->db_connect or _bail();
31
32my $prog;
33if ($pid > 0) {
34 $prog = $db->db_readwrite($dbh, qq~
35 SELECT id, name, description, slug, status,
36 portal_brand_name, portal_logo_url, portal_intro_html,
37 portal_primary_color, portal_secondary_color,
38 portal_enabled, portal_host
39 FROM ${DB}.affiliate_programs WHERE id = $pid LIMIT 1
40 ~, $0, __LINE__);
41}
42elsif (length $host) {
43 my $h_q = $host; $h_q =~ s/'/\\'/g;
44 $prog = $db->db_readwrite($dbh, qq~
45 SELECT id, name, description, slug, status,
46 portal_brand_name, portal_logo_url, portal_intro_html,
47 portal_primary_color, portal_secondary_color,
48 portal_enabled, portal_host
49 FROM ${DB}.affiliate_programs
50 WHERE portal_host = '$h_q' AND portal_enabled = 1
51 LIMIT 1
52 ~, $0, __LINE__);
53}
54
55$db->db_disconnect($dbh);
56
57unless ($prog && $prog->{id} && $prog->{status} eq 'active') {
58 _bail();
59}
60
61my $brand = $prog->{portal_brand_name} || $prog->{name};
62my $logo = $prog->{portal_logo_url} || '';
63my $primary = $prog->{portal_primary_color} || '#5b21b6';
64my $secondary = $prog->{portal_secondary_color} || '#7c3aed';
65my $intro = $prog->{portal_intro_html} || '<p>Welcome to our affiliate program.</p>';
66my $desc = $prog->{description} || '';
67
68my $brand_h = _h($brand);
69my $logo_block = $logo ? qq~<img src="${\ _h($logo) }" alt="$brand_h" style="max-height:48px;max-width:200px">~ : qq~<div style="font-size:22px;font-weight:800;color:#fff">$brand_h</div>~;
70my $apply_link = "/marketplace.cgi?act=apply&program_id=$prog->{id}";
71
72print "Content-Type: text/html; charset=utf-8\r\nCache-Control: no-cache\r\n\r\n";
73print <<HTML;
74<!doctype html>
75<html lang="en">
76<head>
77<meta charset="utf-8">
78<meta name="viewport" content="width=device-width,initial-scale=1">
79<title>$brand_h \xe2\x80\x94 Affiliate Program</title>
80<style>
81 :root {
82 --primary: $primary;
83 --secondary: $secondary;
84 }
85 * { box-sizing: border-box; }
86 body {
87 margin: 0;
88 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
89 background: #0a0a0d;
90 color: #e5e7eb;
91 min-height: 100vh;
92 }
93 header {
94 padding: 22px 32px;
95 border-bottom: 1px solid rgba(255,255,255,.06);
96 display: flex;
97 align-items: center;
98 justify-content: space-between;
99 }
100 .cta {
101 display: inline-block;
102 padding: 11px 22px;
103 background: var(--primary);
104 color: #fff;
105 text-decoration: none;
106 font-weight: 600;
107 border-radius: 8px;
108 font-size: 14px;
109 transition: filter .2s;
110 }
111 .cta:hover { filter: brightness(1.15); }
112 main { max-width: 820px; margin: 0 auto; padding: 64px 24px; }
113 .hero-pill {
114 display: inline-block;
115 padding: 6px 14px;
116 background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 25%, transparent), color-mix(in srgb, var(--secondary) 12%, transparent));
117 border: 1px solid color-mix(in srgb, var(--primary) 50%, transparent);
118 color: color-mix(in srgb, var(--secondary) 100%, #fff 60%);
119 font-size: 11px;
120 text-transform: uppercase;
121 letter-spacing: 1.5px;
122 font-weight: 700;
123 border-radius: 99px;
124 margin-bottom: 22px;
125 }
126 h1 {
127 font-size: clamp(32px, 5vw, 52px);
128 line-height: 1.08;
129 letter-spacing: -1px;
130 margin: 0 0 16px;
131 color: #fff;
132 }
133 h1 .grad {
134 background: linear-gradient(135deg, var(--primary), var(--secondary));
135 -webkit-background-clip: text;
136 background-clip: text;
137 -webkit-text-fill-color: transparent;
138 }
139 .intro { font-size: 17px; line-height: 1.7; color: #cbd5e1; margin-bottom: 32px; }
140 .intro p { margin: 0 0 16px; }
141 .desc { color: #94a3b8; font-size: 15px; line-height: 1.7; margin-bottom: 40px; }
142 .cta-row { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
143 .cta-ghost {
144 color: #cbd5e1;
145 text-decoration: none;
146 font-size: 14px;
147 padding: 11px 18px;
148 border: 1px solid rgba(255,255,255,.15);
149 border-radius: 8px;
150 }
151 footer { padding: 32px; text-align: center; font-size: 11px; color: #475569; border-top: 1px solid rgba(255,255,255,.04); }
152 footer a { color: #64748b; text-decoration: none; }
153</style>
154</head>
155<body>
156<header>
157 <div>$logo_block</div>
158 <a class="cta-ghost" href="/login.cgi">Affiliate sign in</a>
159</header>
160
161<main>
162 <span class="hero-pill">Partner program</span>
163 <h1>Earn with <span class="grad">$brand_h</span></h1>
164 <div class="intro">$intro</div>
165 ${\ ($desc ? qq~<div class="desc">$desc</div>~ : '') }
166 <div class="cta-row">
167 <a class="cta" href="$apply_link">Apply to join</a>
168 <a class="cta-ghost" href="/login.cgi">Already an affiliate? Sign in</a>
169 </div>
170</main>
171
172<footer>
173 Powered by <a href="https://affiliate.3dshawn.com">AffSoft</a>
174</footer>
175</body>
176</html>
177HTML
178exit;
179
180sub _bail {
181 print "Status: 404 Not Found\r\nContent-Type: text/plain\r\n\r\nNo portal configured for this domain.\n";
182 exit;
183}
184
185sub _h {
186 my $s = shift // '';
187 $s =~ s/&/&amp;/g; $s =~ s/</&lt;/g; $s =~ s/>/&gt;/g; $s =~ s/"/&quot;/g; $s =~ s/'/&#39;/g;
188 return $s;
189}