feat(saas): full SquareMCP SaaS platform v1

- JWT auth with bcrypt password hashing, cookie sessions, forgot/reset password
- Per-user encrypted credential storage (Redis + AES-256-GCM) for all 9 platforms
- Usage tracking with monthly limits per plan (free/starter/growth/enterprise)
- Invoice generation and retrieval (admin + user views)
- Admin panel with customer listing (role-based access)
- Web app UI at app.squaremcp.com — login, dashboard, connections, usage, invoices
- Unified auth middleware: API key, OAuth Bearer, and JWT cookie support
- Facebook Graph API fixes: published_posts endpoint, photo/video post support
- TikTok sandbox compliance: SELF_ONLY privacy for unaudited apps
- URL verification files for TikTok app review
This commit is contained in:
Garfield
2026-05-13 08:42:33 -04:00
parent 7796de12bf
commit a5e4c55885
46 changed files with 4054 additions and 171 deletions

230
product/app/index.html Normal file
View File

@@ -0,0 +1,230 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SquareMCP — AI Social Gateway</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="app">
<!-- Password Reset Request View -->
<div id="reset-request-view" class="view hidden">
<div class="auth-card">
<div class="logo">
<div class="logo-mark">S</div>
<h1>Reset Password</h1>
<p>Enter your email to receive a reset link</p>
</div>
<form id="reset-request-form" class="auth-form">
<input type="email" name="email" placeholder="Email" required>
<button type="submit" class="btn btn-primary">Send Reset Link</button>
<p class="error-msg" id="reset-request-error"></p>
<p class="success-msg" id="reset-request-success"></p>
<a href="#" id="back-to-login" style="color:#888;font-size:13px;text-align:center;display:block;margin-top:12px;">Back to login</a>
</form>
</div>
</div>
<!-- Password Reset Confirm View -->
<div id="reset-confirm-view" class="view hidden">
<div class="auth-card">
<div class="logo">
<div class="logo-mark">S</div>
<h1>New Password</h1>
<p>Enter your new password below</p>
</div>
<form id="reset-confirm-form" class="auth-form">
<input type="password" name="password" placeholder="New password (min 8 chars)" required minlength="8">
<button type="submit" class="btn btn-primary">Update Password</button>
<p class="error-msg" id="reset-confirm-error"></p>
<p class="success-msg" id="reset-confirm-success"></p>
</form>
</div>
</div>
<!-- Login View -->
<div id="login-view" class="view">
<div class="auth-card">
<div class="logo">
<div class="logo-mark">S</div>
<h1>SquareMCP</h1>
<p>AI Social Media Gateway</p>
</div>
<div class="tabs">
<button class="tab-btn active" data-tab="login">Sign In</button>
<button class="tab-btn" data-tab="signup">Create Account</button>
</div>
<form id="login-form" class="auth-form">
<input type="email" name="email" placeholder="Email" required>
<input type="password" name="password" placeholder="Password" required minlength="8">
<button type="submit" class="btn btn-primary">Sign In</button>
<p class="error-msg" id="login-error"></p>
</form>
<form id="signup-form" class="auth-form hidden">
<input type="email" name="email" placeholder="Email" required>
<input type="password" name="password" placeholder="Password (min 8 chars)" required minlength="8">
<button type="submit" class="btn btn-primary">Create Account</button>
<p class="error-msg" id="signup-error"></p>
</form>
</div>
</div>
<!-- Dashboard View -->
<div id="dashboard-view" class="view hidden">
<header class="app-header">
<div class="header-left">
<div class="logo-mark small">S</div>
<span class="app-title">SquareMCP</span>
</div>
<div class="header-right">
<nav class="header-nav">
<button class="nav-link active" data-view="platforms">Platforms</button>
<button class="nav-link" data-view="invoices">Invoices</button>
<button class="nav-link hidden" data-view="admin" id="admin-nav">Admin</button>
</nav>
<span id="user-email" class="user-email"></span>
<button id="logout-btn" class="btn btn-ghost">Logout</button>
</div>
</header>
<main class="dashboard">
<section class="welcome">
<h2>Connect your platforms</h2>
<p>Link your social accounts to publish, analyze, and manage content from one place.</p>
</section>
<section class="usage-bar" id="usage-bar">
<div class="usage-info">
<span class="plan-badge" id="plan-badge">Free</span>
<span class="usage-text" id="usage-text">0 / 100 calls this month</span>
</div>
<div class="usage-bar-track"><div class="usage-bar-fill" id="usage-bar-fill" style="width:0%"></div></div>
</section>
<section class="platform-grid">
<!-- TikTok -->
<div class="platform-card" data-platform="tiktok">
<div class="platform-icon" style="background:#000;">🎵</div>
<div class="platform-info">
<h3>TikTok</h3>
<p class="platform-desc">Publish videos and view analytics</p>
<span class="status-badge disconnected">Not connected</span>
</div>
<button class="btn btn-connect" data-platform="tiktok">Connect</button>
</div>
<!-- Facebook -->
<div class="platform-card" data-platform="facebook">
<div class="platform-icon" style="background:#1877f2;">f</div>
<div class="platform-info">
<h3>Facebook</h3>
<p class="platform-desc">Post to pages and manage content</p>
<span class="status-badge disconnected">Not connected</span>
</div>
<button class="btn btn-connect" data-platform="facebook">Connect</button>
</div>
<!-- Instagram -->
<div class="platform-card" data-platform="instagram">
<div class="platform-icon" style="background:linear-gradient(45deg,#f09433,#e6683c,#dc2743,#cc2366,#bc1888);">📷</div>
<div class="platform-info">
<h3>Instagram</h3>
<p class="platform-desc">Publish reels and images</p>
<span class="status-badge disconnected">Not connected</span>
</div>
<button class="btn btn-connect" data-platform="instagram">Connect</button>
</div>
<!-- LinkedIn -->
<div class="platform-card" data-platform="linkedin">
<div class="platform-icon" style="background:#0a66c2;">in</div>
<div class="platform-info">
<h3>LinkedIn</h3>
<p class="platform-desc">Share posts, images, and videos</p>
<span class="status-badge disconnected">Not connected</span>
</div>
<button class="btn btn-connect" data-platform="linkedin">Connect</button>
</div>
<!-- Twitter/X -->
<div class="platform-card" data-platform="twitter">
<div class="platform-icon" style="background:#000;">𝕏</div>
<div class="platform-info">
<h3>Twitter / X</h3>
<p class="platform-desc">Tweet with media support</p>
<span class="status-badge disconnected">Not connected</span>
</div>
<button class="btn btn-connect" data-platform="twitter">Connect</button>
</div>
<!-- Telegram -->
<div class="platform-card" data-platform="telegram">
<div class="platform-icon" style="background:#0088cc;">✈️</div>
<div class="platform-info">
<h3>Telegram</h3>
<p class="platform-desc">Send messages via bot</p>
<span class="status-badge disconnected">Not connected</span>
</div>
<button class="btn btn-connect" data-platform="telegram">Connect</button>
</div>
<!-- Discord -->
<div class="platform-card" data-platform="discord">
<div class="platform-icon" style="background:#5865f2;">🎮</div>
<div class="platform-info">
<h3>Discord</h3>
<p class="platform-desc">Send messages to channels</p>
<span class="status-badge disconnected">Not connected</span>
</div>
<button class="btn btn-connect" data-platform="discord">Connect</button>
</div>
<!-- WhatsApp -->
<div class="platform-card" data-platform="whatsapp">
<div class="platform-icon" style="background:#25d366;">💬</div>
<div class="platform-info">
<h3>WhatsApp</h3>
<p class="platform-desc">Business messaging</p>
<span class="status-badge disconnected">Not connected</span>
</div>
<button class="btn btn-connect" data-platform="whatsapp">Connect</button>
</div>
<!-- Email -->
<div class="platform-card" data-platform="email">
<div class="platform-icon" style="background:#ea4335;">✉️</div>
<div class="platform-info">
<h3>Email</h3>
<p class="platform-desc">IMAP/SMTP accounts</p>
<span class="status-badge disconnected">Not connected</span>
</div>
<button class="btn btn-connect" data-platform="email">Connect</button>
</div>
</section>
<section class="invoices-section hidden" id="invoices-section">
<h3>Invoices</h3>
<div id="invoices-list" class="invoices-list"></div>
</section>
<section class="admin-section hidden" id="admin-section">
<h3>Admin Panel</h3>
<div id="admin-customers" class="admin-customers"></div>
</section>
</main>
</div>
<!-- Connection Modal -->
<div id="connect-modal" class="modal hidden">
<div class="modal-backdrop"></div>
<div class="modal-content">
<button class="modal-close">&times;</button>
<div id="modal-body"></div>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>