( ′∀`)σ≡σ☆))Д′)レ(゚∀゚;)ヘ=З=З=Зε≡(ノ´_ゝ`)ノ HEX
HEX
Server: Apache/2.4.58 (Ubuntu)
System: Linux mail.thebrand.ai 6.8.0-107-generic #107-Ubuntu SMP PREEMPT_DYNAMIC Fri Mar 13 19:51:50 UTC 2026 x86_64
User: www-data (33)
PHP: 8.3.6
Disabled: NONE
Upload Files
File: /var/www/html/tmpr/../tmpr/..//tmpr/..//tmpr/../tmpr/../tmpr/..//connect/register.php
<?php
// Connect registration using BrandCreator's join styling and functionality,
// then auto-sign in across Insights, Sites, and I.

require_once __DIR__ . '/auth.php';

// Read optional redirect destination
$redirect = isset($_GET['redirect']) ? trim($_GET['redirect']) : '/connect/index.php';
?>
<!DOCTYPE html>
<html lang="en" class="light-style layout-wide  customizer-hide" dir="ltr" data-theme="theme-default" data-assets-path="/brandcreator/dashboard/assets/" data-template="vertical-menu-template" data-style="light">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum=1.0" />
  <title>Join | BrandCreator – Build Your Brand Effortlessly</title>

  <meta name="description" content="Join BrandCreator to quickly and effortlessly build a stunning, professional brand that stands out." />
  <meta name="keywords" content="BrandCreator registration, sign up, brand building, professional branding">
  <link rel="canonical" href="https://thebrand.ai/insights">

  <!-- Favicon -->
  <link rel="icon" type="image/x-icon" href="https://thebrand.ai/favicon/favicon.ico" />

  <!-- Fonts -->
  <link rel="preconnect" href="https://fonts.googleapis.com/">
  <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">

  <!-- Icons -->
  <link rel="stylesheet" href="/brandcreator/dashboard/assets/vendor/fonts/boxicons.css" />

  <!-- Core CSS -->
  <link rel="stylesheet" href="/brandcreator/dashboard/assets/vendor/css/rtl/core.css" class="template-customizer-core-css" />
  <link rel="stylesheet" href="/brandcreator/dashboard/assets/vendor/css/rtl/theme-default.css" class="template-customizer-theme-css" />
  <link rel="stylesheet" href="/brandcreator/dashboard/assets/css/demo.css" />

  <!-- Page CSS -->
  <link rel="stylesheet" href="/brandcreator/dashboard/assets/vendor/css/pages/page-auth.css">

  <!-- SweetAlert / animations (for parity) -->
  <link rel="stylesheet" href="/brandcreator/dashboard/assets/vendor/libs/animate-css/animate.css" />
  <link rel="stylesheet" href="/brandcreator/dashboard/assets/vendor/libs/sweetaler/sweetalert2.css" />

  <!-- Helpers & Config -->
  <script src="/brandcreator/dashboard/assets/vendor/js/helpers.js"></script>
  <script src="/brandcreator/dashboard/assets/vendor/js/template-customizer.js"></script>
  <script src="/brandcreator/dashboard/assets/js/config.js"></script>

  <style>
    .hero-button { box-shadow:none; color:#fff; letter-spacing:-0.02em; background-color:#eb008b; border:0; padding:10px 40px; font-size:20px; border-radius:15px; cursor:pointer; transition:background-color .3s,color .3s,transform .2s ease-out; }
    .status{font-size:13px}.ok{color:#0a7f28}.err{color:#b00020}
    .hidden{display:none}
    #bgX{background-image:url('https://www.thebrand.ai/brandcreator/dashboard/assets/img/illustrations/business-meeting-over-coffee.png?yy');background-size:cover;background-repeat:no-repeat;background-attachment:fixed;background-color:#9fccde;height:100vh;margin:0;background-position:bottom}
    swal2-deny{display:none!important;visibility:hidden!important}.swal2-cancel{display:none!important;visibility:hidden!important}
    /* Google button styles (match Connect login) */
    .gsi-material-button{background-color:#fff;border:1px solid #747775;border-radius:20px;box-sizing:border-box;color:#1f1f1f;cursor:pointer;font-family:'Roboto',arial,sans-serif;font-size:14px;height:40px;letter-spacing:.25px;outline:none;overflow:hidden;padding:0 12px;text-align:center;transition:background-color .218s,border-color .218s,box-shadow .218s;vertical-align:middle;white-space:nowrap;width:auto;max-width:400px}
    .gsi-material-button-content{display:flex;align-items:center;justify-content:flex-start;height:100%}
    .gsi-material-button-icon{height:20px;width:20px}
    .gsi-material-button-contents{flex-grow:1;text-align:center}
  </style>
</head>
<body>
<div class="authentication-wrapper authentication-cover">
  <a href="/connect/index.php" class="app-brand auth-cover-brand gap-2">
    <span class="app-brand-logo demo"><img src="/brandcreator/files/assets/logo-white3.png" style="max-height:60px"></span>
  </a>
  <div class="authentication-inner row m-0">
    <div class="d-none d-lg-flex col-lg-7 col-xl-8 align-items-center p-5" id="bgX"></div>
    <div class="d-flex col-12 col-lg-5 col-xl-4 align-items-center authentication-bg p-sm-12 p-6">
      <div class="w-px-400 mx-auto mt-12 pt-5">
        <h4 class="mb-1">Join Brand AI 👋</h4>
        <p class="mb-6">Create your account to access your brand identity, AI-powered insights, design tools, and more — all in one place.</p>

        <form id="formAuthentication" class="mb-6" method="POST">
          <div class="mb-6">
            <label for="username" class="form-label">Username</label>
            <input type="text" class="form-control" id="username" name="username" placeholder="Enter your username" autofocus>
          </div>
          <div class="mb-6">
            <label for="first_name" class="form-label">First name</label>
            <input type="text" class="form-control" id="first_name" name="first_name" placeholder="Enter your first name">
          </div>
          <div class="mb-6">
            <label for="last_name" class="form-label">Last name</label>
            <input type="text" class="form-control" id="last_name" name="last_name" placeholder="Enter your last name">
          </div>
          <div class="mb-6">
            <label for="email" class="form-label">Email</label>
            <input type="text" class="form-control" id="email" name="email" placeholder="Enter your email">
          </div>
          <div class="mb-6 form-password-toggle">
            <label class="form-label" for="password">Password</label>
            <div class="input-group input-group-merge">
              <input type="password" id="password" class="form-control" name="password" placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;" aria-describedby="password" />
              <span class="input-group-text cursor-pointer"><i class="bx bx-hide"></i></span>
            </div>
          </div>
          <div class="mb-6 form-password-toggle">
            <label class="form-label" for="confirm_password">Confirm password</label>
            <div class="input-group input-group-merge">
              <input type="password" id="confirm_password" class="form-control" name="confirm_password" placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;" aria-describedby="confirm_password" />
              <span class="input-group-text cursor-pointer"><i class="bx bx-hide"></i></span>
            </div>
          </div>

          <div class="mb-6 mt-8">
            <div class="form-check mb-8 ms-2">
              <input class="form-check-input" type="checkbox" id="terms-conditions" name="terms">
              <label class="form-check-label" for="terms-conditions">
                I agree to
                <a href="https://www.thebrand.ai/policy/privacy.html">privacy policy & terms</a>
              </label>
            </div>
          </div>
          <button class="btn btn-primary d-grid w-100 hero-button" type="submit">
            Sign up
          </button>
        </form>

        <p class="text-center">
          <span>Already have an account?</span>
          <a href="/connect/index.php">
            <span>Sign in instead</span>
          </a>
        </p>
        <div class="divider my-6">
          <div class="divider-text">or</div>
        </div>

        <p class="text-center">
          <button type="button" class="gsi-material-button w-100" onclick="googleSignIn()">
            <div class="gsi-material-button-content">
              <img class="gsi-material-button-icon" src="https://www.gstatic.com/images/branding/googleg/1x/googleg_standard_color_128dp.png" alt="Google" />
              <span class="gsi-material-button-contents">Continue with Google</span>
            </div>
          </button>
        </p>

        <div id="progressPanel" class="hidden">
          <h4 class="mb-1">Signing you in across apps…</h4>
          <div class="list-group mb-4">
            <div class="d-flex justify-content-between py-2"><span class="fw-bold">Insights</span><span id="st-insights" class="status">Initializing…</span></div>
            <div class="d-flex justify-content-between py-2"><span class="fw-bold">Sites</span><span id="st-sites" class="status">Initializing…</span></div>
            <div class="d-flex justify-content-between py-2"><span class="fw-bold">Design Templates</span><span id="st-i" class="status">Initializing…</span></div>
          </div>
          <button id="continueBtn" class="btn btn-primary w-100" disabled>Continue</button>
        </div>

      </div>
    </div>
  </div>
</div>
<script>
(function(){
  const redirect = <?php echo json_encode($redirect); ?>;
  const progressPanel = document.getElementById('progressPanel');
  const joinForm = document.getElementById('formAuthentication');
  const statuses = {
    insights: document.getElementById('st-insights'),
    sites: document.getElementById('st-sites'),
    i: document.getElementById('st-i')
  };
  const results = { insights: false, sites: false, i: false };
  function setStatus(id, text, cls){ statuses[id].textContent = text; statuses[id].className = 'status ' + (cls || ''); }
  function mark(id, ok, msg){
    results[id] = !!ok;
    setStatus(id, ok ? 'Signed in' : ('Failed: ' + (msg || 'Error')), ok ? 'ok' : 'err');
    const allDone = Object.values(results).every(Boolean);
    document.getElementById('continueBtn').disabled = !allDone;
  }

  function googleSignIn(){
    // Match I’s flow: go directly to I’s Google connect endpoint
    window.location.href = '/i/connect-with-google';
  }

  async function issueCookie(email, name){
    // Issue Connect SSO cookie for unified session
    const resp = await fetch('/connect/issue_sso.php', {
      method: 'POST', credentials: 'include',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({ email, name })
    });
    return resp.ok;
  }

  async function loginInsights(email, password){
    try {
      setStatus('insights', 'Signing in…');
      const resp = await fetch('/insights/data/files/login.php', {
        method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, credentials: 'include',
        body: new URLSearchParams({ email, password })
      });
      const ct = resp.headers.get('content-type') || '';
      if (ct.includes('application/json')) {
        const data = await resp.json();
        if (data && data.success) return mark('insights', true);
        const msg = (data && data.message) || '';
        if (/verify your email/i.test(msg)) {
          return mark('insights', false, 'Requires email verification');
        }
        return mark('insights', false, msg);
      }
      return mark('insights', resp.ok);
    } catch(e){ return mark('insights', false, e.message); }
  }

  async function loginSites(email, password){
    try {
      setStatus('sites', 'Signing in…');
      const token = getCookie('csrf_cookie_brandsites') || await ensureSitesCsrf();
      const resp = await fetch('/sites/index.php/authenticate/verifyLogin', {
        method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' }, credentials: 'include',
        body: new URLSearchParams({ ppl_email: email, ppl_pass: password, csrf_brandsites: token })
      });
      const ct = resp.headers.get('content-type') || '';
      if (ct.includes('application/json')) {
        const data = await resp.json();
        if (data.status === 'success') {
          try { await fetch('/sites/index.php/accounts/splashPage', { credentials: 'include' }); } catch(e) {}
          return mark('sites', true);
        }
      }
      // Provision/update Sites user with the same password, then retry
      setStatus('sites', 'Provisioning user…');
      const prov = await fetch('/connect/provision_sites.php', {
        method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: new URLSearchParams({ email: email, password: password })
      });
      const pjson = await prov.json().catch(() => ({ success:false }));
      if (pjson && pjson.success) {
        setStatus('sites', 'Retrying sign in…');
        const token2 = getCookie('csrf_cookie_brandsites') || await ensureSitesCsrf();
        const resp2 = await fetch('/sites/index.php/authenticate/verifyLogin', {
          method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' }, credentials: 'include',
          body: new URLSearchParams({ ppl_email: email, ppl_pass: password, csrf_brandsites: token2 })
        });
        const ct2 = resp2.headers.get('content-type') || '';
        if (ct2.includes('application/json')) {
          const data2 = await resp2.json();
          const ok = data2.status === 'success';
          if (ok) { try { await fetch('/sites/index.php/accounts/splashPage', { credentials: 'include' }); } catch(e) {} }
          return mark('sites', ok, data2.message);
        }
        return mark('sites', resp2.ok);
      }
      return mark('sites', false, (pjson && pjson.message) || 'Provisioning failed');
    } catch(e){ return mark('sites', false, e.message); }
  }

  async function signUpSites(name, email, password){
    try {
      setStatus('sites', 'Creating account…');
      const token = getCookie('csrf_cookie_brandsites') || await ensureSitesCsrf();
      const resp = await fetch('/sites/index.php/authenticate/verifySignUp', {
        method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' }, credentials: 'include',
        body: new URLSearchParams({ pps_name: name || (email.split('@')[0]), pps_email: email, pps_password: password, csrf_brandsites: token })
      });
      const ct = resp.headers.get('content-type') || '';
      if (ct.includes('application/json')) {
        const data = await resp.json();
        if (data && data.status === 'success') return true;
        // If the email already exists, treat as non-fatal and proceed to login
        const msg = (data && data.message) || '';
        if (/already exists/i.test(msg)) return true;
        setStatus('sites', 'Signup failed');
        return false;
      }
      // Non-JSON response: treat based on HTTP ok
      return resp.ok;
    } catch(e){ setStatus('sites', 'Signup error'); return false; }
  }

  function getCookie(name){
    const v = (`; ${document.cookie}`).split(`; ${name}=`);
    if (v.length === 2) return v.pop().split(';').shift();
    return '';
  }
  async function ensureSitesCsrf(){
    try {
      // Hit a Sites page to ensure CSRF cookie is seeded
      await fetch('/sites/index.php/accounts/login', { method: 'GET', credentials: 'include' });
      return getCookie('csrf_cookie_brandsites');
    } catch(e){ return ''; }
  }

  async function signUpI(name, email, password, firstName, lastName, confirmPassword){
    try {
      setStatus('i', 'Creating account…');
      const resp = await fetch('/i/auth_controller/register_post', {
        method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' }, credentials: 'include',
        body: new URLSearchParams({
          username: name || (email.split('@')[0]),
          first_name: firstName || '',
          last_name: lastName || '',
          email: email,
          password: password,
          confirm_password: confirmPassword || password,
          sys_lang_id: '1'
        })
      });
      const ct = resp.headers.get('content-type') || '';
      if (ct.includes('application/json')) {
        const data = await resp.json();
        if (data && (data.result === 1 || data.success)) return true;
        setStatus('i', 'Signup failed');
        return false;
      }
      return resp.ok;
    } catch(e){ setStatus('i', 'Signup error'); return false; }
  }

  async function loginBrandCreator(email, password, username){
    try {
      const resp = await fetch('/brandcreator/dashboard/data/files/login.php', {
        method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, credentials: 'include',
        body: new URLSearchParams({ email, password })
      });
      const ct = resp.headers.get('content-type') || '';
      if (ct.includes('application/json')) {
        const data = await resp.json();
        if (data && data.success) return true;
      }
      // If login failed, provision account then login
      const r = await fetch('/brandcreator/dashboard/data/files/register.php', {
        method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: new URLSearchParams({ username: (username || (email.split('@')[0])), email, password })
      });
      const txt = await r.text();
      if (txt === '2' || txt === '1' || txt === '0') {
        await fetch('/brandcreator/dashboard/data/files/login.php', {
          method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, credentials: 'include',
          body: new URLSearchParams({ email, password })
        });
      }
      return true;
    } catch(e){ return false; }
  }

  async function loginI(email, password){
    try {
      setStatus('i', 'Signing in…');
      const resp = await fetch('/i/auth_controller/login_post', {
        method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' }, credentials: 'include',
        body: new URLSearchParams({ email: email, password: password, sys_lang_id: '1' })
      });
      const ct = resp.headers.get('content-type') || '';
      if (ct.includes('application/json')) {
        const data = await resp.json();
        if (data && (data.result === 1 || data.success)) return mark('i', true);
        return mark('i', false, (data && (data.error || data.message)));
      }
      return mark('i', resp.ok);
    } catch(e){ return mark('i', false, e.message); }
  }

  function showProgress(){ joinForm.classList.add('hidden'); progressPanel.classList.remove('hidden'); }

  document.getElementById('continueBtn').addEventListener('click', function(){ window.location.href = redirect; });

  // Submit handler: align with I/register fields and post to I

  joinForm.addEventListener('submit', async function(ev){
    ev.preventDefault();
    const username = document.getElementById('username').value.trim();
    const firstName = document.getElementById('first_name').value.trim();
    const lastName = document.getElementById('last_name').value.trim();
    const email = document.getElementById('email').value.trim();
    const password = document.getElementById('password').value;
    const confirmPassword = document.getElementById('confirm_password').value;
    const agreed = document.getElementById('terms-conditions').checked;
    if (!agreed) { alert('Please agree to privacy policy & terms'); return; }
    if (!firstName || !lastName) { alert('Please enter your first and last name'); return; }
    if (!password || password.length < 4) { alert('Password must be at least 4 characters'); return; }
    if (confirmPassword !== password) { alert('Passwords do not match'); return; }
    // Register via I and then cascade sign-ins
    try {
      const okI = await signUpI(username, email, password, firstName, lastName, confirmPassword);
      if (!okI) { alert('Registration failed'); return; }
      // Ensure BrandCreator session (attempt login, or provision then login)
      await loginBrandCreator(email, password, username);
      // Issue Connect SSO cookie
      await issueCookie(email, username || (email.split('@')[0]));
      // Copy details to Sites table (sign up), then start cross-app sign-in
      await signUpSites(username, email, password);
      showProgress();
      await loginInsights(email, password);
      await loginI(email, password);
      await loginSites(email, password);
      // Auto-redirect only if all app sign-ins succeeded
      try {
        var allOk = Object.values(results).every(Boolean);
        if (allOk) {
          setTimeout(function(){ window.location.href = redirect; }, 5000);
        }
      } catch(e) { /* swallow */ }
    } catch(e){ alert('Error: ' + e.message); }
  });
})();
</script>
</body>
</html>