Yoti
Mar 2025
yoti-working-mar2025.zip
Index
<?php
ob_start(); // Start output buffering to prevent "headers already sent" errors
if (session_status() === PHP_SESSION_NONE) {
session_start(); // Start session only if it's not already active
}
// ✅ Enable error reporting for debugging
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// ✅ Include necessary files
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/yoti-config.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/add-debug-messages.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/generate_tubes_join_link_nats_API.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/nats-sticky-tracking.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/db.php';
/*
// Check for AVS-ME before including signup form
if (isset($_REQUEST['avs-me'])) {
if (!isset($_SESSION['ref_id'])) {
$_SESSION['ref_id'] = uniqid('AVS_', true);
}
$checkSession = $pdo->prepare("SELECT ref_id FROM yoti_sessions WHERE ref_id = :ref_id");
$checkSession->execute(['ref_id' => $_SESSION['ref_id']]);
if (!$checkSession->fetch()) {
$insertSession = $pdo->prepare("INSERT INTO yoti_sessions (ref_id) VALUES (:ref_id)");
$insertSession->execute(['ref_id' => $_SESSION['ref_id']]);
}
$_SESSION['userHasPassedAVS'] = false;
$_SESSION['skipRestOfVerification'] = false;
unset($_SESSION['checked_yoti_session']);
header('Location: /yoti-token/step4_launch-yoti.php');
exit;
}
*/
//require_once '/home/httpd/html/tubes.nakedsword.com/public_html/yoti-token/signup-form.php';
//require_once '/home/httpd/html/tubes.nakedsword.com/public_html/yoti-token/modal_for_yoti.php';
addDebugMessage("updateAssetFolderAndOverlayInitital starts");
function updateAssetFolderAndOverlay() {
if (!isset($_SESSION['userHasPassedAVS']) || $_SESSION['userHasPassedAVS'] === false) {
if (!isset($_SESSION['assets_folder'])) {
$_SESSION['assets_folder'] = "assets_g";
}
if (!isset($_SESSION['display_signup_overlay'])) {
$_SESSION['display_signup_overlay'] = true;
}
}
if (isset($_SESSION['userHasPassedAVS']) && $_SESSION['userHasPassedAVS'] === true) {
if (!isset($_SESSION['assets_folder'])) {
$_SESSION['assets_folder'] = "assets";
}
if (!isset($_SESSION['display_signup_overlay'])) {
$_SESSION['display_signup_overlay'] = false;
}
}
addDebugMessage("
Assets folder set to {$_SESSION['assets_folder']}.
Signup overlay flag: {$_SESSION['display_signup_overlay']}.
");
} // end initial folder overllay set up
// Add this function to check if Yoti session is active
function hasActiveYotiSession() {
return isset($_SESSION['yoti_session_id']) && !empty($_SESSION['yoti_session_id']);
}
function freshlyAVSUpdateAll() {
if (isset($_SESSION['userHasPassedAVS']) && $_SESSION['userHasPassedAVS'] === true) {
// Just set all states at once
$_SESSION['userHasPassedAVS'] = true;
$_SESSION['assets_folder'] = "assets";
$_SESSION['display_signup_overlay'] = false;
$_SESSION['page_content'] = 'tubes_content_full.php';
unset($_POST['avs-me']); // Clear button state
}
}
/*888 LOGGED IN USER REDIRECDT ********/
if (isset($_SESSION['userHasPassedAVS']) && $_SESSION['userHasPassedAVS'] === true && !isset($_GET['refreshed'])) {
$_SESSION['assets_folder'] = "assets";
$_SESSION['display_signup_overlay'] = false;
// One-time refresh with flag
$nats_code = $_GET['nats'] ?? $_COOKIE['nats'] ?? '';
$refresh_url = '/yoti-token/?refreshed=1';
if ($nats_code) {
$refresh_url .= '&nats=' . urlencode($nats_code);
}
header("Location: {$refresh_url}", true, 302);
exit;
}
addDebugMessage("********************** NATS LINKS ***************************");
addDebugMessage("Get nats code and make links");
// ✅ **Get NATS Code (DO NOT SET THE COOKIE)**
$nats_code = $_COOKIE['nats'] ?? $_GET['nats'] ?? 'MTA1NDY3LjguMS4xLjAuMC4wLjAuMA'; // default is ns default
if (empty($nats_code)) {
$nats_code = 'MTA2MDgzLjYzLjEuMTY1LjAuMC.0.0.0'; // Fallback if needed
}
addDebugMessage("📝 Using NATS Code: {$nats_code}");
// ✅ Initialize the TUBES object safely
try {
$nats_join_link = new \JoinLinkGenerator\TUBES($nats_code);
addDebugMessage("✅ TUBES object initialized.");
} catch (Exception $e) {
addDebugMessage("❌ ERROR: Failed to initialize TUBES class: " . $e->getMessage());
addDebugMessage("Error initializing join link.");
}
// ✅ Generate the join link safely
$plain_join_link = $nats_join_link->generate_join_link(0);
if (!$plain_join_link) {
addDebugMessage("❌ ERROR: Failed to generate join link.");
addDebugMessage("Error generating join link.");
}
addDebugMessage("🔗 Generated Join Link: {$plain_join_link}");
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AVS Verification</title>
<style>
.floating-yoti-overlay {
position: absolute;
top: 10%;
left: 50%;
transform: translateX(-50%);
background: rgba(255, 255, 255, 0.95);
padding: 20px;
border-radius: 10px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.2);
z-index: 9999;
max-width: 400px;
text-align: center;
border: 2px solid #142d59;
}
</style>
</head>
<body>
<form id="pickYotiForm" method="post">
<input type="hidden" name="avs-me" value="1">
<button id="invisible-avs-trigger" type="submit"
style="background-color:transparent;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
cursor: pointer;
padding: 0;
display: block;
position: absolute;
z-index: 9999;">
<img src="https://tubes.nakedsword.com/yoti-token/img/avs-button-transp.gif" style="width: 100%; height: 100%; object-fit: cover;">
</button>
</form><script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('pickYotiForm');
if (form) {
form.addEventListener('submit', function(e) {
e.preventDefault();
// Just do a regular form POST right here
form.submit();
});
}
});
</script>
</body>
</html>
<?php
addDebugMessage("********************** Part 1 - check for old users *******************************");
// Function to get the root domain (prevent redeclaration)
if (!function_exists('getRootDomain')) {
function getRootDomain($host) {
$parts = explode('.', $host);
return (count($parts) >= 3) ? implode('.', array_slice($parts, -2)) : $host;
}
}
$root_domain = getRootDomain($_SERVER['HTTP_HOST']);
// Default trigger variable for checking if a user is already verified
$previousUserAVSChecker = null;
// Retrieve ref_id from GET, session, or cookie
$ref_id = $_GET['ref_id'] ?? $_SESSION['ref_id'] ?? $_COOKIE['ref_id_cookie'] ?? null;
addDebugMessage("Cookie ref_id: " . var_export($_COOKIE['ref_id_cookie'] ?? null, true));
addDebugMessage("✅ checking for ref_idin request/session/cookie");
if ($ref_id) {
addDebugMessage("✅ Found ref_id from request/session/cookie: {$ref_id}");
// Check if this ref_id exists in the database
$query = $pdo->prepare("SELECT assets_folder, userHasPassedAVS, yoti_session_id FROM yoti_sessions WHERE ref_id = :ref_id LIMIT 1");
$query->execute(['ref_id' => $ref_id]);
$result = $query->fetch(PDO::FETCH_ASSOC);
if ($result) {
$_SESSION['ref_id'] = $ref_id; // Store in session for consistency
$assets_folder = $result['assets_folder']; // Use stored assets_folder (even if blank)
// Check DB field for AVS verification status (stored as boolean or 1/0)
if (isset($result['userHasPassedAVS']) && $result['userHasPassedAVS']) {
// Mark as verified
if (!empty($ref_id)) {
$previousUserAVSChecker = $ref_id;
addDebugMessage("✅ Verified user: " . var_export($previousUserAVSChecker, true));
}
$_SESSION['userHasPassedAVS'] = true;
addDebugMessage("✅ Returning User: ref_id = {$ref_id}, assets_folder = '{$assets_folder}', and userHasPassedAVS in DB is true - user is verified.");
} else {
unset($_SESSION['userHasPassedAVS']);
addDebugMessage("✅ Returning User: ref_id = {$ref_id}, assets_folder = '{$assets_folder}', but AVS not passed per DB");
}
addDebugMessage("********************** Part 2 - returning users (imback) *******************************");
// Now check for a returning user via the callback (imback)
// --- Returning User Check ---
$isReturningUser = isset($_GET['imback']) ? true : false;
if ($isReturningUser) {
addDebugMessage("Returning User found (imback=1) on URL: ref_id: {$ref_id} who we are now calling url_ref_id.");
addDebugMessage("Look for ref_id and sessionId on URL.");
// Retrieve the identifiers from the callback URL (or cookies)
$url_ref_id = $_GET['ref_id'] ?? $_COOKIE['ref_id_cookie'] ?? null;
$url_sessionId = $_GET['sessionId'] ?? null;
addDebugMessage("URL ref_id: " . var_export($url_ref_id, true));
addDebugMessage("URL sessionId: " . var_export($url_sessionId, true));
// Step 1: Try to get a record using the URL sessionId, if provided.
if ($url_sessionId) {
$query = $pdo->prepare("SELECT * FROM yoti_sessions WHERE yoti_session_id = :sessionId LIMIT 1");
$query->execute(['sessionId' => $url_sessionId]);
$record_by_session = $query->fetch(PDO::FETCH_ASSOC);
} else {
$record_by_session = null;
}
// Step 2: Try to get a record using the URL ref_id if available.
if ($url_ref_id) {
$query = $pdo->prepare("SELECT * FROM yoti_sessions WHERE ref_id = :ref_id LIMIT 1");
$query->execute(['ref_id' => $url_ref_id]);
$record_by_ref = $query->fetch(PDO::FETCH_ASSOC);
} else {
$record_by_ref = null;
}
// Decide which record to use for the GET call.
if ($record_by_session) {
addDebugMessage("Using record found by URL sessionId.");
$candidate_sessionId = $record_by_session['yoti_session_id'];
$used_ref_id = $record_by_session['ref_id'];
} elseif ($record_by_ref && isset($record_by_ref['yoti_session_id'])) {
addDebugMessage("No record found by URL sessionId; using record from URL ref_id.");
$candidate_sessionId = $record_by_ref['yoti_session_id'];
$used_ref_id = $record_by_ref['ref_id'];
} else {
addDebugMessage("Error: No valid record found using URL sessionId or ref_id.");
exit("Error: No valid user record found.");
}
addDebugMessage("Proceeding with ref_id: {$used_ref_id} and candidate sessionId: {$candidate_sessionId} for Yoti API call.");
// Step 3: Perform the GET call to Yoti's API using the candidate sessionId.
$yotiApiUrl = "https://age.yoti.com/api/v1/sessions/{$candidate_sessionId}/result";
$apiKey = YOTI_API_KEY;
$sdkId = YOTI_SDK_ID;
$headers = [
"Authorization: Bearer {$apiKey}",
"Content-Type: application/json",
"Yoti-Sdk-Id: {$sdkId}",
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $yotiApiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
if (curl_errno($ch)) {
addDebugMessage("❌ cURL Error: " . curl_error($ch));
exit;
}
curl_close($ch);
$responseData = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE || !isset($responseData['status'])) {
addDebugMessage("❌ Invalid response from Yoti API.");
exit;
}
addDebugMessage("📜 Decoded Yoti API Response: " . json_encode($responseData, JSON_PRETTY_PRINT));
$yoti_session_id = strtolower($responseData['id']);
// Check the status from the API response (e.g., 'complete')
$status = strtolower($responseData['status']);
if ($status === 'complete') {
addDebugMessage("✅ Yoti session complete. Granting full access for ref_id: {$used_ref_id}.");
// ✅ **Set flags for Step 6 & stop further verification**
$_SESSION['userHasPassedAVS'] = true;
$_SESSION['onToStep6'] = true; // ✅ NEW FLAG → Moves to YAV Cookie Step
$_SESSION['assets_folder'] = "assets";
// ✅ **Update DB: Mark session as completed**
$update = $pdo->prepare("UPDATE yoti_sessions
SET status = 'complete',
assets_folder = 'assets',
userHasPassedAVS = true,
yoti_session_id = :yoti_session_id
WHERE ref_id = :ref_id");
$update->execute([
'ref_id' => $used_ref_id,
'yoti_session_id' => $yoti_session_id
]);
addDebugMessage("✅ Returning User: ref_id = {$used_ref_id}, status: $status, assets_folder = '{$assets_folder}', and userHasPassedAVS in DB is true, yoti_session_id: $yoti_session_id - user is verified.");
} else {
addDebugMessage("Yoti session status is: {$status}. Further handling may be required.");
}
addDebugMessage("END Returning User check");
}
} else {
addDebugMessage("❌ ref_id not found in DB. Ignoring it.");
$ref_id = null; // Reset ref_id since it’s invalid
}
}
addDebugMessage("previousUserAVSChecker: " . var_export($previousUserAVSChecker, true));
updateAssetFolderAndOverlay();
addDebugMessage("*** set assets and overlay for user with no record or passed is false GOES TO WHRE CONTENT IS CREATED ******");
if (!isset($_SESSION['userHasPassedAVS']) || $_SESSION['userHasPassedAVS'] === false) {
addDebugMessage("******* Code waiting for avs-me signal ***********");
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['avs-me']) && $_POST['avs-me'] == 1) {
addDebugMessage("✅ User clicked AVS ME — Starting full verification sequence");
addDebugMessage(" ** TUBES MAIN SCRIPT - STEP 1: Capture URL & Tracking Data** ");
// ✅ ** TUBES MAIN SCRIPT - STEP 1: Capture URL & Tracking Data**
/* Handles ref_id, nats_code,sets up db - deals with page layout URL parsing, cookies.*/
addDebugMessage("all users hit step 1");
require_once '/home/httpd/html/tubes.nakedsword.com/public_html/yoti-token/step1_capture-url-links-setup-data.php';
addDebugMessage(" check for ref id ");
// ✅ **Ensure ref_id exists before continuing**
if (empty($_SESSION['ref_id'])) {
addDebugMessage("❌ No ref_id found after Step 1. Assigning PG assets and skipping verification.");
require_once '/home/httpd/html/tubes.nakedsword.com/public_html/yoti-token/stepError_norefid.php';
return; // ✅ Allow page to continue with limited access
}
updateAssetFolderAndOverlay();
// only if they have have not passed including when no flag do this step
if (!isset($_SESSION['userHasPassedAVS']) || $_SESSION['userHasPassedAVS'] === false) {
addDebugMessage(" ** TUBES MAIN SCRIPT - STEP 2: Check for YAV Cookie ** ");
// ✅ ** TUBES MAIN SCRIPT - STEP 2: Check for YAV Cookie **
require_once '/home/httpd/html/tubes.nakedsword.com/public_html/yoti-token/step2_check-for-yav.php';
}
updateAssetFolderAndOverlay();
addDebugMessage(" ** TUBES MAIN SCRIPT - STEP 3: NO Yav? Check User's State ** ");
// only if they have have not passed including when no flag do this step
if (!isset($_SESSION['userHasPassedAVS']) || $_SESSION['userHasPassedAVS'] === false) {
require_once '/home/httpd/html/tubes.nakedsword.com/public_html/yoti-token/step3_check-state.php';
}
updateAssetFolderAndOverlay();
// ✅ ** TUBES MAIN SCRIPT - STEP 4: Launch Yoti Verification if Required **
addDebugMessage("** Step 4 - Launch Yoti Verification if Required **");
// only if they have not passed including when no flag do this step
if (!isset($_SESSION['userHasPassedAVS']) || $_SESSION['userHasPassedAVS'] === false) {
require_once '/home/httpd/html/tubes.nakedsword.com/public_html/yoti-token/step4_launch-yoti.php';
}
updateAssetFolderAndOverlay();
addDebugMessage(" ** Step 6b User returned from Yoti - Processing Webhook ** ");
if (!isset($_SESSION['userHasPassedAVS']) || $_SESSION['userHasPassedAVS'] === false) {
require_once '/home/httpd/html/tubes.nakedsword.com/public_html/yoti-token/step6b_yoti-results-webhook.php';
}
addDebugMessage("********** YAV EM *********");
// only if they have have not passed including when no flag do this step
addDebugMessage("*** Step 7 Yav Cookie Creation **");
addDebugMessage("** Rules for this step changed - so that users must have userHaspassedAVS set to true");
if (isset($_SESSION['userHasPassedAVS']) && $_SESSION['userHasPassedAVS'] === true) {
require_once '/home/httpd/html/tubes.nakedsword.com/public_html/yoti-token/step7_make-yav-cookie.php';
}// end make yav
addDebugMessage("********** END OF AVS-ME VERIFICATION FLOW *********");
} // end of avs-me button check
addDebugMessage("********** END FALSE OR NON AVS USERS *********");
} // end all false or non avs users
addDebugMessage("********************** BUILD PAGE WITH ASSETS ***************************");
// FINAL STEP: Show Appropriate Content
if (!isset($_SESSION['userHasPassedAVS']) || $_SESSION['userHasPassedAVS'] !== true) {
// Not verified - Show limited content
$_SESSION['assets_folder'] = "assets_g";
$_SESSION['display_signup_overlay'] = true;
$_SESSION['page_content'] = 'tubes_content.php';
} else {
// Verified - Show full content
$_SESSION['assets_folder'] = "assets";
$_SESSION['display_signup_overlay'] = false;
$_SESSION['page_content'] = 'tubes_content_full.php';
}
// Display the page
include $_SESSION['page_content'];
?>
<?php ob_end_flush(); // Send buffered content at the end ?>
Verification
Step 1 – Set up New User Record
<?php
ob_start(); // Start output buffering to prevent "headers already sent" errors
if (session_status() === PHP_SESSION_NONE) {
session_start(); // Start session only if it's not already active
}
// ✅ Enable error reporting for debugging
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// ✅ Include necessary files
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/yoti-config.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/add-debug-messages.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/generate_tubes_join_link_nats_API.php';
addDebugMessage("📌 Step 1 - index.php STARTED - Checking YAV Cookie & AVS Requirements");
addDebugMessage("Check for old ref_id: " . ($ref_id ?: 'NONE'));
addDebugMessage("********************** Set up new users (skipped if user has old ref_id) *******************************");
// 🚀 **New User Handling (Old user check was in top of script)**
if (!$ref_id) {
addDebugMessage("🆕 New User Detected - Creating ref_id...");
$ref_id = bin2hex(random_bytes(16)); // ✅ Generate a new ref_id
$_SESSION['ref_id'] = $ref_id;
$assets_folder = 'assets_g'; // ✅ Default to PG assets for new users
// ✅ **Insert into DB (assets_folder left as 'assets_g' for now)**
$insert = $pdo->prepare("INSERT INTO yoti_sessions (ref_id) VALUES (:ref_id)");
$insert->execute(['ref_id' => $ref_id]);
// ✅ **Set a cookie for persistence**
setcookie("ref_id_cookie", $ref_id, time() + 2592000, "/", "{$root_domain}", true, false);
addDebugMessage("✅ New User: Created & saved ref_id = {$ref_id}");
}
// ✅ **Step 3: Get NATS Code (DO NOT SET THE COOKIE)**
$nats_code = $_COOKIE['nats'] ?? $_GET['nats'] ?? 'MTA1NDY3LjguMS4xLjAuMC4wLjAuMA';
addDebugMessage("📝 Using NATS Code: {$nats_code}");
// ✅ Initialize the TUBES object
$nats_join_link = new \JoinLinkGenerator\TUBES($nats_code);
if (!$nats_join_link) {
die("❌ ERROR: Failed to initialize TUBES class.");
}
addDebugMessage("✅ TUBES object initialized.");
// ✅ Generate the join link
$plain_join_link = $nats_join_link->generate_join_link(0);
if (!$plain_join_link) {
die("❌ ERROR: Failed to generate join link.");
}
addDebugMessage("🔗 Generated Join Link: {$plain_join_link}");
?>
<?php
$site_version = explode('.', $_SERVER['HTTP_HOST'])[0];
// ✅ ** Get Current Path (Where User Landed)**
$current_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
addDebugMessage("🌍 Current Path Detected: {$current_path}");
// ✅ **Extract Extra Segment**
if (!function_exists('getExtraSegmentFromUrl')) {
function getExtraSegmentFromUrl() {
$pathSegments = explode('/', trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/'));
// Ensure it's not a file (e.g., .php, .html, etc.)
if (!empty($pathSegments[0]) && strpos($pathSegments[0], '.') === false) {
return '/' . $pathSegments[0] . '/';
}
return ''; // No valid extra segment
}
}
$extra_segment = getExtraSegmentFromUrl(); // No need to pass $_SERVER['HTTP_HOST']
addDebugMessage("🔄 Detected Extra Segment: " . ($extra_segment ?: 'NONE'));
// ✅ **Step 6: Construct Base URL**
$base_url = ($site_version !== $root_domain)
? "https://{$site_version}.{$root_domain}"
: "https://{$root_domain}";
// we need to make return_url and yoti the same url
// ✅ **Construct Return URL**
$return_url = !empty($extra_segment)
? "{$base_url}{$extra_segment}?nats={$nats_code}&ref_id={$ref_id}&imback=1"
: "{$base_url}{$current_path}?nats={$nats_code}&ref_id={$ref_id}&imback=1";
addDebugMessage("Initial Return URL: {$return_url}");
// ✅ **Construct NATS TRACK URL (For Special Cases)**
$track_url = "{$base_url}/track/{$nats_code}{$extra_segment}";
addDebugMessage("Initial TRACK URL: {$track_url}");
$callback_url = "{$base_url}{$extra_segment}?ref_id={$ref_id}&imback=1";
$cancel_url = "{$base_url}{$extra_segment}?ref_id={$ref_id}";
$notification_url = "{$base_url}{$extra_segment}yoti_results_webhook.php?ref_id={$ref_id}&webhook=1";
addDebugMessage("Initial Return URL: {$return_url}");
addDebugMessage("Initial Callback URL: {$callback_url}");
addDebugMessage("Initial Cancel URL: {$cancel_url}");
addDebugMessage("Initial Notification URL: {$notification_url}");
// ✅ **Insert Session Data into Database**
addDebugMessage("✅ DB Updates Starting");
try {
$insert = $pdo->prepare("
INSERT INTO yoti_sessions (
base_url, site_version, root_domain, ref_id, current_path, extra_segment,
nats_code, return_url, callback_url, cancel_url, notification_url, track_url,
yoti_session_id, assets_folder, status, userHasPassedAVS, rule_id, method,
age, evidence_id, biometric_consent_required, biometric_consent_given_at,
retry_enabled, resume_enabled, yav_cookie_value, plain_join_link, avs_states, detected_user_state
) VALUES (
:base_url, :site_version, :root_domain, :ref_id, :current_path, :extra_segment,
:nats_code, :return_url, :callback_url, :cancel_url, :notification_url, :track_url,
:yoti_session_id, :assets_folder, :status, :userHasPassedAVS, :rule_id, :method,
:age, :evidence_id, :biometric_consent_required, :biometric_consent_given_at,
:retry_enabled, :resume_enabled, :yav_cookie_value, :plain_join_link, :avs_states, :detected_user_state
)
ON DUPLICATE KEY UPDATE
base_url = VALUES(base_url),
site_version = VALUES(site_version),
root_domain = VALUES(root_domain),
current_path = VALUES(current_path),
extra_segment = VALUES(extra_segment),
nats_code = VALUES(nats_code),
return_url = VALUES(return_url),
callback_url = VALUES(callback_url),
cancel_url = VALUES(cancel_url),
notification_url = VALUES(notification_url),
track_url = VALUES(track_url),
yoti_session_id = VALUES(yoti_session_id),
assets_folder = VALUES(assets_folder),
status = VALUES(status),
userHasPassedAVS = VALUES(userHasPassedAVS),
rule_id = VALUES(rule_id),
method = VALUES(method),
age = VALUES(age),
evidence_id = VALUES(evidence_id),
biometric_consent_required = VALUES(biometric_consent_required),
biometric_consent_given_at = VALUES(biometric_consent_given_at),
retry_enabled = VALUES(retry_enabled),
resume_enabled = VALUES(resume_enabled),
yav_cookie_value = VALUES(yav_cookie_value),
plain_join_link = VALUES(plain_join_link),
avs_states = VALUES(avs_states),
detected_user_state = VALUES(detected_user_state)
");
$insert->execute([
'base_url' => $base_url,
'site_version' => $site_version,
'root_domain' => $root_domain,
'ref_id' => $ref_id,
'current_path' => $current_path,
'extra_segment' => $extra_segment,
'nats_code' => $nats_code,
'return_url' => $return_url,
'callback_url' => $callback_url,
'cancel_url' => $cancel_url,
'notification_url' => $notification_url,
'track_url' => $track_url,
'yoti_session_id' => null, // Default NULL, will be updated later
'assets_folder' => 'assets_g', // Default to PG content until verified
'status' => 'PENDING', // Default session status
'userHasPassedAVS' => 0, // Default to 0
'rule_id' => null,
'method' => null,
'age' => null,
'evidence_id' => null,
'biometric_consent_required' => 0,
'biometric_consent_given_at' => null,
'retry_enabled' => 1,
'resume_enabled' => 1,
'yav_cookie_value' => null,
'plain_join_link' => null,
'avs_states' => null,
'detected_user_state' => null
]);
addDebugMessage("✅ Database update completed successfully");
} catch (PDOException $e) {
addDebugMessage("❌ Database Error: " . $e->getMessage());
error_log("❌ Database Error: " . $e->getMessage());
}
addDebugMessage("✅ DB Entry done ");
addDebugMessage("✅ Starting bottom of script ");
addDebugMessage("previousUserAVSChecker: {$previousUserAVSChecker}");
// If previous user was verified, confirm the session variable is set
if (isset($previousUserAVSChecker) && !empty($previousUserAVSChecker)) {
addDebugMessage("User {$ref_id} has userHasPassedAVS raw value: " . var_export($_SESSION['userHasPassedAVS'], true));
addDebugMessage("✅ Found previous ref_id DB has them verified - userHasPassedAVS value is set to true.");
}
// Return to main script
addDebugMessage("Leave Step 1 To Step 1b - check for other yoti sessions in returning users ");
return;
?>
<?php ob_end_flush(); // Send buffered content at the end ?>
Step 2 – Check for / Verify Yav
<?php
ob_start(); // Start output buffering to prevent "headers already sent" errors
if (session_status() === PHP_SESSION_NONE) {
session_start(); // Start session only if it's not already active
}
// ✅ Enable error reporting for debugging
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// ✅ Include necessary services
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/add-debug-messages.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/db.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/YavCrypterService.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/CrypterConstants.php';
addDebugMessage("********************** STEP TWO - yav check and validation *******************************");
// ✅ Step 1: Get the encrypted YAV cookie
$encryptedValue = $_COOKIE['yav'] ?? null;
if (!$encryptedValue) {
// No YAV cookie found - session not verified
$_SESSION['userHasPassedAVS'] = false;
return;
}
addDebugMessage("decrypt yav");
// ✅ Step 2: Decrypt the YAV cookie
$decryptedValue = YavCrypterService::decrypt($encryptedValue);
addDebugMessage("validate decrypted yav");
// ✅ Step 3: Validate decrypted value
if (!$decryptedValue || !is_numeric($decryptedValue)) {
// Decryption failed or invalid data
$_SESSION['userHasPassedAVS'] = false;
return;
}
addDebugMessage("still valid? (30 days) decrypted yav");
// ✅ Step 4: Check if YAV is expired (30 days limit)
$yavTimestamp = (int) $decryptedValue;
$currentTimestamp = time();
$yavAge = $currentTimestamp - $yavTimestamp;
$maxAge = 30 * 24 * 60 * 60; // 30 days in seconds
if ($yavAge > $maxAge) {
// Expired cookie - verification fails
$_SESSION['userHasPassedAVS'] = false;
addDebugMessage("yav not valid returning to main script");
return;
}
addDebugMessage("session valid - set assets, userHasPassedAVS and signup overlay");
// ✅ Step 5: Mark session as verified
$_SESSION['assets_folder'] = "assets";
$_SESSION['userHasPassedAVS'] = true;
$_SESSION['display_signup_overlay'] = false;
freshlyAVSUpdateAll(); // content, images, overlay, hasBeenAVS
// ✅ Step 6: Store the result in the database
try {
$updateQuery = $pdo->prepare("
UPDATE yoti_sessions
SET assets_folder = :assets_folder, yav_cookie_value = :yav_cookie_value
WHERE ref_id = :ref_id
");
$updateQuery->execute([
'assets_folder' => 'assets',
'yav_cookie_value' => $decryptedValue,
'ref_id' => $_SESSION['ref_id'] ?? null
]);
} catch (Exception $e) {
error_log("Database update failed: " . $e->getMessage());
}
// ✅ Done - no output, just validation
return;
?>
<?php ob_end_flush(); // Send buffered content at the end ?>
Step 3 – Check State
<?php
ob_start(); // Start output buffering to prevent "headers already sent" errors
if (session_status() === PHP_SESSION_NONE) {
session_start(); // Start session only if it's not already active
}
// ✅ Enable error reporting for debugging
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// ✅ Include necessary files
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/add-debug-messages.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/db.php';
addDebugMessage("📌 checkstate.php STARTED");
addDebugMessage("********************** STEP THREE TUBES: Check US State *******************************");
// ✅ **Retrieve ref_id from request, session, or cookie**
// ✅ **Ensure ref_id is available (from GET, session, or cookie)**
$ref_id = $_GET['ref_id'] ?? $_SESSION['ref_id'] ?? $_COOKIE['ref_id_cookie'] ?? null;
if (!$ref_id) {
addDebugMessage("❌ No ref_id found. Cannot proceed.");
exit("Error: No ref_id provided.");
}
// ✅ **Step 2: Pull session details from DB**
if ($ref_id) {
$query = $pdo->prepare("SELECT site_version, root_domain, ref_id FROM yoti_sessions WHERE ref_id = :ref_id LIMIT 1");
$query->execute(['ref_id' => $ref_id]);
$session_data = $query->fetch(PDO::FETCH_ASSOC);
if ($session_data) {
$site_version = $session_data['site_version'] ?? 'www';
$root_domain = $session_data['root_domain'] ?? 'sitename.com';
addDebugMessage("🌍 Site Version: {$site_version} | Root Domain: {$root_domain}");
} else {
addDebugMessage("❌ No session data found for ref_id: {$ref_id}");
}
} else {
addDebugMessage("❌ No ref_id found.");
}
addDebugMessage(" set url for state checker");
// ✅ **Fix for Tubes/Tubes2 (Use `join` for state check)**
$site_version_for_state_check = ($site_version === 'tubes' || $site_version === 'tubes2') ? 'join' : $site_version;
addDebugMessage("🌍 Adjusted Site Version for State Check: {$site_version_for_state_check}");
function getUserIP() {
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
return $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
return explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
} else {
return $_SERVER['REMOTE_ADDR'];
}
}
addDebugMessage(" user ip");
// ✅ Step 1: Get User's IP
$ip = getUserIP();
addDebugMessage("🛠 Detected User IP: {$ip}");
// ✅ Step 2: Query ipinfo.io API
$url = "https://ipinfo.io/{$ip}/json";
addDebugMessage("🌍 Fetching User's State from: {$url}");
$response = @file_get_contents($url);
if (!$response) {
addDebugMessage("❌ API Request Failed: No response from {$url}");
die(json_encode(['error' => 'API request failed']));
}
$data = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE || empty($data['region'])) {
addDebugMessage("❌ Invalid API Response: " . json_encode($data));
die(json_encode(['error' => 'Invalid API response']));
}
addDebugMessage("convert state to abbrevation");
// ✅ Step 3: Extract and Convert State
$stateMap = [
"Alabama" => "AL", "Alaska" => "AK", "Arizona" => "AZ", "Arkansas" => "AR", "California" => "CA",
"Colorado" => "CO", "Connecticut" => "CT", "Delaware" => "DE", "Florida" => "FL", "Georgia" => "GA",
"Hawaii" => "HI", "Idaho" => "ID", "Illinois" => "IL", "Indiana" => "IN", "Iowa" => "IA",
"Kansas" => "KS", "Kentucky" => "KY", "Louisiana" => "LA", "Maine" => "ME", "Maryland" => "MD",
"Massachusetts" => "MA", "Michigan" => "MI", "Minnesota" => "MN", "Mississippi" => "MS", "Missouri" => "MO",
"Montana" => "MT", "Nebraska" => "NE", "Nevada" => "NV", "New Hampshire" => "NH", "New Jersey" => "NJ",
"New Mexico" => "NM", "New York" => "NY", "North Carolina" => "NC", "North Dakota" => "ND",
"Ohio" => "OH", "Oklahoma" => "OK", "Oregon" => "OR", "Pennsylvania" => "PA", "Rhode Island" => "RI",
"South Carolina" => "SC", "South Dakota" => "SD", "Tennessee" => "TN", "Texas" => "TX", "Utah" => "UT",
"Vermont" => "VT", "Virginia" => "VA", "Washington" => "WA", "West Virginia" => "WV", "Wisconsin" => "WI",
"Wyoming" => "WY"
];
$fullState = $data['region'];
$user_state = strtoupper($stateMap[$fullState] ?? 'UNKNOWN');
addDebugMessage("📌 Detected User State: {$fullState} ({$user_state})");
addDebugMessage("fetch avs states");
function fetchAvsRequiredStatesList($root_domain) {
global $DEFAULT_AVS_STATES;
$avsRequiredStatesList = [];
$urls = [
"https://www.{$root_domain}/avs_regions.json",
"https://{$root_domain}/avs_regions.json"
];
foreach ($urls as $url) {
$response = @file_get_contents($url);
addDebugMessage("🔍 Checking AVS data from: {$url}");
$data = json_decode($response, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($data)) {
$avsRequiredStatesList = array_merge(...array_values($data));
addDebugMessage("✅ Loaded AVS states from {$url}");
break;
}
}
if (empty($avsRequiredStatesList)) {
addDebugMessage("⚠️ No valid AVS data – using default list.");
$avsRequiredStatesList = $DEFAULT_AVS_STATES ?? [];
}
addDebugMessage("📜 AVS States List: " . json_encode($avsRequiredStatesList));
return $avsRequiredStatesList;
}
$avsRequiredStatesList = fetchAvsRequiredStatesList($root_domain);
$avs_states_string = implode(',', $avsRequiredStatesList);
addDebugMessage("user if from avs state");
// ✅ Check if user is in an AVS-restricted state
if (in_array($user_state, $avsRequiredStatesList)) {
addDebugMessage("🚨 User is in an AVS State ({$user_state}) – Redirecting to Yoti.");
$_SESSION['userHasPassedAVS'] = false;
// ✅ Update Yoti session
$updateQuery = $pdo->prepare("
UPDATE yoti_sessions
SET detected_user_state = :detected_user_state, avs_states = :avs_states
WHERE ref_id = :ref_id
");
$updateQuery->execute([
'detected_user_state' => $user_state,
'avs_states' => $avs_states_string,
'ref_id' => $ref_id
]);
return;
}
addDebugMessage("User NOT from avs state");
freshlyAVSUpdateAll(); // content, images, overlay, hasBeenAVS
// ✅ User is NOT in an AVS-restricted state
addDebugMessage("✅ User NOT in AVS state – assets_folder set to 'assets'");
$_SESSION['assets_folder'] = "assets";
//Set a flag to suppress the signup overlay (or, alternatively, to show it)
$_SESSION['display_signup_overlay'] = false;
$_SESSION['userHasPassedAVS'] = true;
// ✅ Update session in database
$updateQuery = $pdo->prepare("
UPDATE yoti_sessions
SET assets_folder = :assets_folder, detected_user_state = :detected_user_state, avs_states = :avs_states
WHERE ref_id = :ref_id
");
$updateQuery->execute([
'assets_folder' => 'assets',
'detected_user_state' => $user_state,
'avs_states' => $avs_states_string,
'ref_id' => $ref_id
]);
addDebugMessage("DB Updated with user data");
addDebugMessage("✅ Database updated: assets_folder = 'assets', user US state, avs states stored for ref_id: {$ref_id}");
addDebugMessage("Return to mainscript - should be foraded to end ");
return; // ✅ Returns to main index without running further steps
?>
<?php ob_end_flush(); // Send buffered content at the end ?>
Step 4 – Launch Yoti
<?php
ob_start();
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// ✅ Enable error reporting
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// ✅ Include necessary files
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/add-debug-messages.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/db.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/yoti-config.php';
addDebugMessage("📌 launch-yoti.php STARTED - Checking user record");
// Initialize ref_id if not exists
if (!isset($_SESSION['ref_id'])) {
$_SESSION['ref_id'] = uniqid('AVS_', true);
}
// Ensure yoti session record exists
$checkSession = $pdo->prepare("SELECT ref_id FROM yoti_sessions WHERE ref_id = :ref_id");
$checkSession->execute(['ref_id' => $_SESSION['ref_id']]);
if (!$checkSession->fetch()) {
$insertSession = $pdo->prepare("INSERT INTO yoti_sessions (ref_id) VALUES (:ref_id)");
$insertSession->execute(['ref_id' => $_SESSION['ref_id']]);
}
// ✅ **Ensure ref_id is available (from GET, session, or cookie)**
$ref_id = $_GET['ref_id'] ?? $_SESSION['ref_id'] ?? $_COOKIE['ref_id_cookie'] ?? null;
if (!$ref_id) {
addDebugMessage("❌ No ref_id found. Cannot proceed.");
exit("Error: No ref_id provided.");
}
// ✅ Store ref_id in session for tracking
$_SESSION['ref_id'] = $ref_id;
// ✅ **Fetch User Record (Check for Existing Yoti Session)**
$query = $pdo->prepare("
SELECT callback_url, notification_url, cancel_url, yoti_session_id
FROM yoti_sessions
WHERE ref_id = :ref_id
LIMIT 1
");
$query->execute(['ref_id' => $ref_id]);
$result = $query->fetch(PDO::FETCH_ASSOC);
// ✅ **If user already has a `yoti_session_id`, send them to check status**
if (!empty($result['yoti_session_id'])) {
$storedYotiSessionId = $result['yoti_session_id'];
// ✅ Prevent looping: Only proceed if this session hasn’t been checked before
if (!isset($_SESSION['checked_yoti_session'])) {
$_SESSION['checked_yoti_session'] = true; // ✅ Mark as checked
addDebugMessage("✅ Existing Yoti session found for ref_id: {$ref_id}. Passing to main script for verification. Session ID: {$storedYotiSessionId}");
// ✅ Store session_id in $_SESSION to ensure it is accessible in the main script
$_SESSION['yoti_session_id'] = $storedYotiSessionId;
return; // ✅ Allows the main script to continue normally
}
addDebugMessage("🔄 Loop detected! Already checked Yoti session for ref_id: {$ref_id}. Skipping redundant processing.");
//need a flag to get only some users to step4b_old-user-check.php
// ********* OLD USER REMOVED ************** //
return;
}
// ********* NEW USER NO PREVIOUS SESSION DATA callback / notificaiton all have ref_id paramaters on them ************** //
// ✅ **Use database values or fallback to defaults**
$callback_url = $result['callback_url'] ?? '{$base_url}{$extra_segment}?ref_id={$ref_id}&imback=1/';
$notification_url = $result['notification_url'] ?? '{$base_url}{$extra_segment}yoti_results_webhook.php?ref_id={$ref_id}';
$cancel_url = $result['cancel_url'] ?? '{$base_url}{$extra_segment}?ref_id={$ref_id}'; // Default cancel URL
$rule_id = YOTI_RULE_ID;
addDebugMessage("✅ Launching new Yoti session for ref_id: {$ref_id}");
// ✅ **Create Yoti Session Payload**
$queryData = [
'age_estimation' => ['allowed' => true, 'threshold' => 25, 'level' => 'PASSIVE', 'retry_limit' => 1],
'digital_id' => ['allowed' => true, 'threshold' => 18, 'retry_limit' => 1],
'type' => 'OVER',
'ttl' => 600,
'callback_url' => $callback_url,
'notification_url' => $notification_url,
'cancel_url' => $cancel_url,
'block_biometric_consent' => false,
'rule_id' => $rule_id,
'reference_id' => $ref_id,
];
$query = json_encode($queryData);
$url = 'https://age.yoti.com/api/v1/sessions';
$headers = [
"Authorization: Bearer " . trim(YOTI_API_KEY),
"Content-Type: application/json",
"Yoti-Sdk-Id: " . trim(YOTI_SDK_ID),
"Cache-Control: no-cache"
];
// ✅ **Send Request to Yoti API**
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
addDebugMessage("❌ Yoti API Error: {$error}");
exit("Error: Yoti session could not be created.");
}
// ✅ **Parse Yoti Response**
$responseData = json_decode($response, true);
if (empty($responseData['id'])) {
addDebugMessage("❌ Yoti Session Creation Failed: " . json_encode($responseData));
exit("Error: Yoti session creation failed.");
}
// ✅ **Store Yoti session ID in session and database**
$_SESSION['yoti_session_id'] = $responseData['id'];
$updateQuery = $pdo->prepare("
UPDATE yoti_sessions
SET yoti_session_id = :yoti_session_id
WHERE ref_id = :ref_id
");
$updateQuery->execute([
'yoti_session_id' => $_SESSION['yoti_session_id'],
'ref_id' => $ref_id
]);
addDebugMessage("✅ Pre Launch New Yoti Session Created: " . $_SESSION['yoti_session_id'] . "under ref_id:" . $ref_id);
// ✅ **Redirect User to Yoti Verification**
header("Location: https://age.yoti.com?sessionId={$_SESSION['yoti_session_id']}&sdkId=" . YOTI_SDK_ID);
// ✅ **Set session flags for next steps**
$_SESSION['skipRestOfVerification'] = false; // ✅ Ensure further verification happens
$_SESSION['processThisUsersSessionIDInCallback'] = true; // ✅ Marks user for step 5
// ✅ **Verify what was actually stored in DB**
$checkQuery = $pdo->prepare("SELECT yoti_session_id FROM yoti_sessions WHERE ref_id = :ref_id LIMIT 1");
$checkQuery->execute(['ref_id' => $ref_id]);
$storedSession = $checkQuery->fetch(PDO::FETCH_ASSOC);
$storedYotiSessionId = $storedSession['yoti_session_id'] ?? 'NOT STORED';
addDebugMessage("✅ POST Launch: Yoti Session: " . $_SESSION['yoti_session_id'] . " | Stored in DB: " . $storedYotiSessionId . " | Under ref_id: " . $ref_id);
ob_end_flush();
return;
?>
Step 5 –
Step 6 – callback url
<?php
ob_start(); // Start output buffering to prevent "headers already sent" errors
if (session_status() === PHP_SESSION_NONE) {
session_start(); // Start session only if it's not already active
}
// ✅ Enable error reporting for debugging
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// ✅ Include necessary files
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/add-debug-messages.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/db.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/yoti-config.php';
addDebugMessage("📌 Step 6 Callback - Processing Yoti Return");
addDebugMessage("********************** STEP 6 : Process callback data *******************************");
addDebugMessage("🔍 Full URL on Callback: " . $_SERVER['REQUEST_URI']);
addDebugMessage("🔍 Raw GET Params: " . json_encode($_GET, JSON_PRETTY_PRINT));
//file_put_contents('/home/httpd/html/tubes.nakedsword.com/debug_step5.log', "Step 5 accessed at: " . date('Y-m-d H:i:s') . "\n", FILE_APPEND);
//addDebugMessage("✅ Step 6 Reached!");
// ***** RETURN EXAMPLE
// https://tubes2.nakedsword.com/yoti-token/?ref_id=48908a9ea3a7a077c0b2f08a3d4ddca5&imback=1&sessionId=55dc7439-62a7-4f90-a1b4-bced4ca2fab3
addDebugMessage("🔍 Full URL: " . $_SERVER['REQUEST_URI']);
addDebugMessage("🔍 Raw GET data: " . json_encode($_GET));
// ✅ **1. Retrieve `ref_id` first**
$ref_id = $_GET['ref_id'] ?? $_SESSION['ref_id'] ?? $_COOKIE['ref_id_cookie'] ?? null;
$url_ref_id = $_GET['ref_id'];
addDebugMessage("❌ url_ref_id: {$url_ref_id}");
if (!$ref_id) {
addDebugMessage("❌ No `ref_id` found. Cannot proceed.");
exit("Error: Missing `ref_id`");
}
$_SESSION['ref_id'] = $ref_id; // ✅ Ensure `ref_id` is stored in session
addDebugMessage("Check for yoti_session_id for the {$ref_id}");
// ✅ **2. Retrieve `yoti_session_id` for this `ref_id` from the database**
$query = $pdo->prepare("SELECT ref_id, yoti_session_id FROM yoti_sessions WHERE ref_id = :ref_id LIMIT 1");
$query->execute(['ref_id' => $ref_id]);
$result = $query->fetch(PDO::FETCH_ASSOC);
if (!$result) {
addDebugMessage("❌ No database entry found for `ref_id`: {$ref_id}");
exit("Error: No matching `ref_id` in database.");
}
addDebugMessage("found a session_id for `ref_id`: {$ref_id}");
$stored_yoti_session_id = $result['yoti_session_id'];
addDebugMessage("✅ Retrieved `yoti_session_id`: {$stored_yoti_session_id} for `ref_id`: {$ref_id}");
// ✅ **3. Get `sessionId` from URL**
$sessionId = $_GET['sessionId'] ?? null;
addDebugMessage("sessionId found on url: {$sessionId}");
if (!$sessionId) {
addDebugMessage("❌ No `sessionId` found in URL.");
addDebugMessage("Error: Missing `sessionId` from Yoti response.");
addDebugMessage("Removed exit from here");
}
addDebugMessage("compare url sessionID: {$sessionId} to retrieved sessionId for {$stored_yoti_session_id} for ref_id: {$ref_id}");
// ✅ **4. Compare `sessionId` from URL with stored `yoti_session_id`**
if ($sessionId === $stored_yoti_session_id) {
addDebugMessage("✅ Matched `sessionId` from URL to stored `yoti_session_id`.");
} else {
addDebugMessage("⚠️ Mismatch: `sessionId` from URL ({$sessionId}) does NOT match stored `yoti_session_id` ({$stored_yoti_session_id}).");
addDebugMessage("if they don't match search for correct one");
// ✅ **5. Try to find correct `ref_id` based on `sessionId`**
$query = $pdo->prepare("SELECT ref_id FROM yoti_sessions WHERE yoti_session_id = :yoti_session_id LIMIT 1");
$query->execute(['yoti_session_id' => $sessionId]);
$new_ref = $query->fetch(PDO::FETCH_ASSOC);
if ($new_ref) {
$ref_id = $new_ref['ref_id'];
addDebugMessage("✅ Found correct `ref_id`: {$ref_id} for `sessionId`: {$sessionId}");
} else {
addDebugMessage("❌ No matching `ref_id` found for `sessionId`: {$sessionId}");
addDebugMessage("Error: No matching `ref_id` in database");
addDebugMessage("Removed exit from here");
return;
}
}
addDebugMessage("Have a sessionId:{$sessionId} that matches ref_id: {$ref_id} check results");
addDebugMessage("open session to yoti");
// ✅ **6. Check Yoti API for Session Result**
$apiKey = YOTI_API_KEY;
$sdkId = YOTI_SDK_ID;
$headers = [
"Authorization: Bearer {$apiKey}",
"Content-Type: application/json",
"Yoti-Sdk-Id: {$sdkId}",
];
$yotiApiUrl = "https://age.yoti.com/api/v1/sessions/{$sessionId}/result";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $yotiApiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
if (curl_errno($ch)) {
addDebugMessage("❌ cURL Error: " . curl_error($ch));
exit;
}
curl_close($ch);
addDebugMessage("get / decode response");
// ✅ **7. Decode the JSON response**
$responseData = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE || !isset($responseData['status'])) {
addDebugMessage("❌ Invalid response from Yoti API.");
exit;
}
addDebugMessage("📜 Decoded Yoti API Response: " . json_encode($responseData, JSON_PRETTY_PRINT));
// ✅ **8. FINAL CHECK: Ensure `sessionId` from Yoti API matches our stored one**
$api_response_session_id = $responseData['session_id'] ?? null;
addDebugMessage("check api response sessionId: {$api_response_session_id} to the {$sessionId} we pulled");
if ($api_response_session_id !== $sessionId) {
addDebugMessage("❌ Yoti API returned a different `sessionId` ({$api_response_session_id}) than expected ({$sessionId})!");
addDebugMessage("do not match returning - was exit");
return("Error: Session ID mismatch!");
}
addDebugMessage("✅ Yoti API confirmed sessionId matches!");
// ✅ **9. Process Yoti API Response**
$status = strtolower($responseData['status']);
if ($status === 'complete') {
addDebugMessage("✅ Yoti session complete. Granting full access.");
// ✅ **Set flags for Step 6 & stop further verification**
$_SESSION['userHasPassedAVS'] = true;
$_SESSION['onToStep6'] = true; // ✅ NEW FLAG → Moves to YAV Cookie Step
$_SESSION['assets_folder'] = "assets";
// ✅ **Update DB: Mark session as completed**
$update = $pdo->prepare("UPDATE yoti_sessions SET status = 'complete', assets_folder = 'assets' WHERE ref_id = :ref_id");
$update->execute(['ref_id' => $ref_id]);
addDebugMessage("✅ Yoti session marked as 'complete' for ref_id: {$ref_id}");
// ✅ Return → User will now move to Step 6
return;
}
// ❌ **10. Handle Failed Yoti Session**
addDebugMessage("❌ Yoti session failed. Assigning PG assets - but letting user go to end");
$_SESSION['userHasPassedAVS'] = false; // ✅
$_SESSION['display_signup_overlay'] = true;
$_SESSION['onToStep6'] = false;
$_SESSION['assets_folder'] = "assets_g";
$update = $pdo->prepare("UPDATE yoti_sessions SET status = 'FAILED', assets_folder = 'assets_g' WHERE ref_id = :ref_id");
$update->execute(['ref_id' => $ref_id]);
addDebugMessage("✅ Yoti session failed. User assigned PG assets for ref_id: {$ref_id}");
// ✅ Return → User will see page with PG assets
return;
?>
<?php ob_end_flush(); // Send buffered content at the end ?>
Step 6b – Web hook
<?php
ob_start(); // Start output buffering to prevent "headers already sent" errors
if (session_status() === PHP_SESSION_NONE) {
session_start(); // Start session only if it's not already active
}
// ✅ Enable error reporting for debugging
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// ✅ Include necessary files
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/add-debug-messages.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/db.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/yoti-config.php'; // ✅ Yoti API config
addDebugMessage("📌 Yoti Return Page Loaded - Checking User Status");
addDebugMessage("********************** 6b Yoti Webhook *******************************");
addDebugMessage("✅ User status verified / COMPLETE sent to content");
// ✅ Respond with a success message to Yoti
http_response_code(200);
return;
}
// 🚨 If verification failed, redirect user to retry
if ($status !== 'complete') {
addDebugMessage("🚨 User verification failed. Redirecting to retry.");
freshlyAVSUpdateAll(); // content, images, overlay, hasBeenAVS
return;
}
// 🚨 If status is unknown or still pending, log it and retry
addDebugMessage("⚠️ Unexpected status '{$status}' detected for ref_id={$ref_id}");
addDebugMessage("❌ Invalid or empty webhook data received.");
http_response_code(400); // Bad request
echo json_encode(["status" => "error", "message" => "Invalid data"]);
return;
?>
<?php ob_end_flush(); // Send buffered content at the end ?>
Step 7 – Make Yav
<?php
ob_start();
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/add-debug-messages.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/db.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/YavCrypterService.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/CrypterConstants.php';
addDebugMessage("📌********* makeyavcookie.php STARTED - Setting YAV Cookie *********** ");
// Get ref_id
$ref_id = $_GET['ref_id'] ?? $_SESSION['ref_id'] ?? $_COOKIE['ref_id_cookie'] ?? null;
if (!$ref_id) {
addDebugMessage("❌ No ref_id found. Cannot proceed.");
return;
}
// Generate and encrypt YAV data
$verificationTime = time();
$encryptedValue = YavCrypterService::encrypt($verificationTime);
if (!$encryptedValue) {
addDebugMessage("❌ Encryption failed - YAV not set");
return;
}
// Set the YAV cookie (Valid for 30 days)
setcookie('yav', $encryptedValue, time() + (30 * 24 * 60 * 60), '/', '.' . "{$root_domain}", true, false);
// Update session variables
$_SESSION['assets_folder'] = "assets";
$_SESSION['userHasPassedAVS'] = true;
$_SESSION['display_signup_overlay'] = false;
// Update database
$updateQuery = $pdo->prepare("
UPDATE yoti_sessions
SET assets_folder = :assets_folder, yav_cookie_value = :yav_cookie_value
WHERE ref_id = :ref_id
");
$updateQuery->execute([
'assets_folder' => 'assets',
'yav_cookie_value' => $encryptedValue,
'ref_id' => $ref_id
]);
addDebugMessage("✅ YAV cookie set");
ob_end_flush();
return;
?>
Sign Up Form
<?php
ob_start(); // Start output buffering to prevent "headers already sent" errors
if (session_status() === PHP_SESSION_NONE) {
session_start(); // Start session only if it's not already active
}
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Include necessary files
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/yoti-config.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/add-debug-messages.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/db.php';
$_SESSION['userHasPassedAVS'] = false;
$_SESSION['assets_folder'] = "assets_g";
$_SESSION['display_signup_overlay'] = true;
$assets_folder = $_SESSION['assets_folder'] ?? 'assets_g'; // fallback just in case
?>
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<title>Get Verified</title>
<meta name="keywords" content="NakedSword.com" />
<meta name="description" content="avs stopper" />
<link rel="icon" href="/<?= htmlspecialchars($assets_folder) ?>/favicon.ico" type="image/x-icon">
<link rel=stylesheet href="<?= htmlspecialchars($assets_folder) ?>/css/main.css">
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<style>
.floating-yoti-overlay {
position: fixed;
top: 10%;
left: 50%;
transform: translateX(-50%);
background: rgba(255, 255, 255, 0.95);
padding: 20px;
border-radius: 10px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.2);
z-index: 9998;
max-width: 400px;
text-align: center;
border: 2px solid #142d59;
}
body.locked {
overflow: hidden; /* Prevent scrolling */
}
#contentWrapper {
filter: blur(5px); /* Slightly blur the content until user interacts */
pointer-events: none; /* Prevent clicks on content */
}
.engaged #contentWrapper {
filter: none;
pointer-events: auto;
}
#root { display: block; width: 100%; min-height: 30px; }
.join-button {
background: #142d59;
max-width: 255px;
color: #fff;
font-size: 1.5em;
font-weight: 400;
border-radius: 20px;
padding: 15px 30px 20px;
white-space: nowrap;
overflow: visible;
text-transform: capitalize;
font-family: Oswald, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
border-bottom: 0;
cursor: pointer;
}
#signupformpagecover { width: 100vw; height: 100vh; display: block; background: rgba(0,0,0,0); position: absolute; z-index: 700;}
#signupformpagecover.hidden { display: none; visibility: hidden; }
.plainjoinlink { color: inherit; text-decoration: none; }
.keyinfo { display: none; visibility: hidden; }
body {margin:0; padding: 0;}
</style>
</head>
<body>
<!--- SIGNUP FORM CODE -->
<div id="signupformpagecover" class="<?= $_SESSION['display_signup_overlay'] === false ? 'hidden' : '' ?>">
<!-- Floating Sign-Up + Yoti Verification Form (Must Interact) -->
<div id="floatingSignupForm" class="floating-yoti-overlay">
<h2>Join as easy as 1, 2, 3</h2>
<h3>1. Get Age Verified</h3>
<p><em>(Easy, quick, & leaves no trace)</em></p>
<img src="https://tubes.nakedsword.com/yoti-token/img/avs-icon.svg" style="width: 50%; max-width: 250px;">
<!--
<form id="pickYotiForm" method="post" action="/">
<input type="hidden" name="avs-me" value="1">
<button id="invisible-avs-trigger" type="submit"
style="
background: url('https://tubes.nakedsword.com/yoti-token/img/avs_button.png') no-repeat center center;
background-size: cover;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: 9999;
border: none;
cursor: pointer;
display:block;">
</button>
</form>
--->
<h3>2. Pick from our best plans ...</h3>
<img src="https://tubes.nakedsword.com/yoti-token/img/prices.png" style="width: 100%; max-width: 300px;"">
<!--<input type="text" id="username" placeholder="Username" required />
<input type="password" id="password" placeholder="Password" required />
-->
<h3>3. Start Watching! </h3>
<input class="join-button" type="submit" value="start Watching!!">
</div>
</div>
<!--- END SIGNUP FORM CODE -->
</body>
</html>
<?php ob_end_flush(); // Send buffered content at the end ?>
Content
<?php
ob_start(); // Start output buffering to prevent "headers already sent" errors
if (session_status() === PHP_SESSION_NONE) {
session_start(); // Start session only if it's not already active
}
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Include necessary files
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/yoti-config.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/add-debug-messages.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/db.php';
/*
$_SESSION['userHasPassedAVS'] = false;
$_SESSION['assets_folder'] = "assets_g";
$_SESSION['display_signup_overlay'] = true;
$assets_folder = $_SESSION['assets_folder'] ?? 'assets_g'; // fallback just in cas
$plain_join_link = "https://join.nakedsword.com";
*/
// Get NATS code from URL or cookie
$nats_code = $_GET['nats'] ?? $_COOKIE['nats'] ?? '';
/*
if (isset($_SESSION['userHasPassedAVS']) && $_SESSION['userHasPassedAVS'] === true) {
$_SESSION['assets_folder'] = "assets";
$_SESSION['display_signup_overlay'] = false;
// NATS tracking link when verified
$_SESSION['join_link'] = $nats_join_link->generate_join_link(25000025) . ($nats_code ? '&nats=' . urlencode($nats_code) : '');
} else {
$_SESSION['userHasPassedAVS'] = false;
$_SESSION['assets_folder'] = "assets_g";
$_SESSION['display_signup_overlay'] = true;
// Plain link with NATS tracking when not verified
$_SESSION['join_link'] = '/yoti-token/' . ($nats_code ? '?nats=' . urlencode($nats_code) : '');
}
$assets_folder = $_SESSION['assets_folder'] ?? 'assets_g';
$join_link = $_SESSION['join_link'] ?? '/yoti-token/';
if (isset($_GET['content']) && $_GET['content'] === 'tubes_content_full') {
include 'tubes_content_full.php';
} else {
include 'tubes_content.php';
}
*/
$_SESSION['userHasPassedAVS'] = true;
$_SESSION['assets_folder'] = "assets";
$_SESSION['display_signup_overlay'] = false;
$assets_folder = 'assets';
?>
<!DOCTYPE html>
<head>
<!-- The hidden input field for storing the userId (reference ID) -->
<!--input type="hidden" id="userIdCustom10Input" name="signup[custom10]" value=""-->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<title>Welcome</title>
<meta name="keywords" content="NakedSword.com" />
<meta name="description" content="Avs Teaser" />
<link rel="icon" href="/<?= htmlspecialchars($assets_folder) ?>/favicon.ico" type="image/x-icon">
<link rel=stylesheet href="<?= htmlspecialchars($assets_folder) ?>/css/main.css">
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script>
/*
document.addEventListener("DOMContentLoaded", function () {
fetch('https://tubes.nakedsword.com/yoti-token/check-session.php')
.then(response => response.json())
.then(data => {
if (data.userHasPassedAVS) {
// console.log("✅ User already verified, hiding AVS modal.");
// document.getElementById("avsModal").style.display = "none";
}
// ✅ Update asset folder usage (if needed)
let assetPath = data.assets_folder;
document.querySelectorAll("[data-asset]").forEach(el => {
el.src = assetPath + el.dataset.asset;
});
// ✅ Hide signup overlay if not needed
if (!data.display_signup_overlay) {
console.log("✅ Hiding signup overlay.");
document.getElementById("signupformpagecover").style.display = "none";
}
})
.catch(error => console.error("Error checking session:", error));
});
*/
</script>
</head>
<body>
<div id="pageContainer">
<!--- SIGNUP FORM -->
<?php include 'signup-form.php'; ?>
<!--- END SIGNUP FORM -->
<!--
<div id="userStateDisplay"></div>
<script>
async function fetchUserState() {
try {
const response = await fetch(`https://${window.hostname}/get_user_us_state.php`);
const data = await response.json();
if (data.state) {
return data.state;
} else {
throw new Error(data.error || 'Failed to retrieve state');
}
} catch (error) {
console.error('Error fetching state, assuming user is from an AVS state:', error);
return 'AVS_STATE_UNKNOWN';
}
}
document.addEventListener('DOMContentLoaded', async function () {
const userState = await fetchUserState();
document.getElementById('userStateDisplay').textContent = `State: ${userState}`;
});
</script>
-->
<!--
<div class="header" onclick="window.location.href='<?=$plain_join_link?>' class="plainjoinlink1";">
<a href="<?=$plain_join_link?>"><img class="trck" src="<?= htmlspecialchars($assets_folder) ?>/logo-426x120.png" /><div class="keyinfo">tubes 1</div></a>
</div>
<div class="menu" onclick="window.location.href='<?=$plain_join_link?>''classname="plainjoinlink2";">
<div class="menu-wrap">
<ul class="desk one">
<li class="active">HOME</li>
<li>SCENES</li>
<li>MODELS</li>
</ul>
<ul class="desk two">
<OFF<li>Members Login</li> --
<li class="red1">JOIN NOW</li>
</ul>
<ul class="mobile">
<li>Home</li>
<li>Videos</li>
<li>Login</li>
<li class="red1"><span class="rotate">Join Now</span></li>
</ul>
</div>
</div>
-->
<!-- Example banners with PHP generated links
<a href="<?=$nats_join_link->generate_join_link(25000025);?>"><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos25" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/25.jpg" /><div class="keyinfo">pos25 - 25.jpg<br>25000025</div></a>
<a href="<?=$plain_join_link?>"><img class="trck" src="<?= htmlspecialchars($assets_folder) ?>/logo-426x120.png" /><div class="keyinfo">tubes 1</div></a>
-->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-M7XV3FB" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<!--div class="header" onclick="window.location.href='<?=$plain_join_link?>';"-->
<div class="header">
<a href="<?=$plain_join_link?>" target="_self" class="plainjoinlink" id="plainjoinlink1"><img class="trck" src="<?= htmlspecialchars($assets_folder) ?>/logo-426x120.png" /><div class="keyinfo">tubes 1</div></a>
</div>
<div class="menu" onclick="window.location.href='<?=$plain_join_link?>';">
<div class="menu-wrap">
<ul class="desk one">
<li class="active"><a href="<?=$plain_join_link?>" id="plainjoinlink2" class="plainjoinlink">HOME</a></li>
<li><a href="<?=$plain_join_link?>" id="plainjoinlink3" class="plainjoinlink">SCENES</a></li>
<li><a href="<?=$plain_join_link?>" id="plainjoinlink4" class="plainjoinlink">MODELS</a></li>
</ul>
<ul class="desk two">
<!--<li>Members Login</li> -->
<li class="red1"><a href="<?=$plain_join_link?>" id="plainjoinlink5" class="plainjoinlink">JOIN NOW</a></li>
</ul>
<ul class="mobile">
<li><a href="<?=$plain_join_link?>" id="plainjoinlink6" class="plainjoinlink">Home</a></li>
<li><a href="<?=$plain_join_link?>" id="plainjoinlink7" class="plainjoinlink">Videos</a></li>
<li><a href="<?=$plain_join_link?>" id="plainjoinlink8" class="plainjoinlink">Login</a></li>
<li class="red1"><span class="rotate"><a href="<?=$plain_join_link?>" id="plainjoinlink9" class="plainjoinlink">Join Now</a></span></li>
</ul>
</div>
</div>
<!-- Photo Grid -->
<div class="row">
<?php
/*
Aug 30, 2024 -- hagan changed to line below
<!-- Shows under 480px--> <a href="<?=$nats_join_link->generate_join_link(100000);?>" data-url="https://join.nakedsword.com/" id="natsjoinlink0" style="width:100%"><video id="pos480" data-src="" class="trck lazy hide-on-desktop" playsinline loop muted autoplay src="<?= htmlspecialchars($assets_folder) ?>-new/video/video-mobile.mp4" style="width: 100%;"></video></a>
*/
?>
<!-- Shows under 480px--> <a href="<?=$nats_join_link->generate_join_link(100000);?>" data-url="https://join.nakedsword.com/" id="natsjoinlink0" style="width:100%"><video id="pos480" data-src="" class="trck lazy hide-on-desktop" playsinline loop muted autoplay src="<?= htmlspecialchars($assets_folder) ?>/video/video-mobile.mp4" style="width: 100%;"></video></a>
<div class="column"><!-- column1 -->
<a href="<?=$nats_join_link->generate_join_link(1000001);?>" id="natsjoinlink1" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos1" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/1.jpg" /><div class="keyinfo">pos1 - 1.jpg<br>1000001</div></a>
<a href="<?=$nats_join_link->generate_join_link(2000002);?>" id="natsjoinlink2" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com"id="pos2" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/2.jpg" /><div class="keyinfo">pos2 - 2.jpg<br><span class="imgnumb">2</span><span class="imgsep">000</span><span class="imgposit">002</span></div></a>
<a href="<?=$nats_join_link->generate_join_link(3000003);?>" id="natsjoinlink3" data-url="https://join.nakedsword.com/" ><div class="keyinfo video">pos3 - video4.mp4<br><span class="imgnumb">4</span><span class="imgsep">000</span><span class="imgposit">003</span></div><video data-src="" class="trck lazy" data-url="https://join.nakedsword.com" id="pos3" playsinline loop muted autoplay src="<?= htmlspecialchars($assets_folder) ?>/video/video4.mp4" type="video/mp4">
<source src="" type="video/mp4">
</video></a>
<a href="<?=$nats_join_link->generate_join_link(4000004);?>" id="natsjoinlink4" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos4" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/4.jpg" /><div class="keyinfo">pos4 - 4.jpg<br>4000004</div></a>
<a href="<?=$nats_join_link->generate_join_link(5000005);?>" id="natsjoinlink5" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos5" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/5.jpg" /><div class="keyinfo">pos5 - 5.jpg<br>5000005</div></a>
<a href="<?=$nats_join_link->generate_join_link(6000006);?>" id="natsjoinlink6" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos6" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/6.jpg" /><div class="keyinfo">pos6 - 6.jpg<br>6000006</div></a>
<a href="<?=$nats_join_link->generate_join_link(7000007);?>" id="natsjoinlink7" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos7" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/7.jpg" /><div class="keyinfo">pos7- 7.jpg<br>7000007</div></a>
<a href="<?=$nats_join_link->generate_join_link(8000008);?>" id="natsjoinlink8" data-url="https://join.nakedsword.com/" ><div class="keyinfo video">pos8 - video2.mp4<br>8000008</div><video data-src="" class="trck lazy" data-url="https://join.nakedsword.com" id="pos8" playsinline loop muted autoplay src="<?= htmlspecialchars($assets_folder) ?>/video/video2.mp4" type="video/mp4">
<source src="" type="video/mp4"></video></a>
</div>
<div class="column"> <!-- column2 -->
<a href="<?=$nats_join_link->generate_join_link(9000009);?>" id="natsjoinlink9" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos9" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/9.jpg" /><div class="keyinfo">pos9 - 9.jpg<br>9000009</div></a>
<a href="<?=$nats_join_link->generate_join_link(10000010);?>" id="natsjoinlink10" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos10" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/big-1.jpg" /><div class="keyinfo">pos10- big-1.jpg<br>10000010</div></a>
<a href="<?=$nats_join_link->generate_join_link(11000011);?>" id="natsjoinlink11" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos11" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/11.jpg" /><div class="keyinfo">pos11 - 11.jpg<br>11000011</div></a>
<a href="<?=$nats_join_link->generate_join_link(12000012);?>" id="natsjoinlink12" data-url="https://join.nakedsword.com/" ><div class="keyinfo video">pos12 - video3.mp4<br>12000012</div><video data-src="" class="trck lazy" data-url="https://join.nakedsword.com" id="pos12" playsinline loop muted autoplay src="<?= htmlspecialchars($assets_folder) ?>/video/video3.mp4" type="video/mp4">
<source src="" type="video/mp4">
</video></a>
<a href="<?=$nats_join_link->generate_join_link(13000013);?>" id="natsjoinlink13" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos13" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/13.jpg" /><div class="keyinfo">pos13 - 13.jpg<br>13000013</div></a>
<a href="<?=$nats_join_link->generate_join_link(14000014);?>" id="natsjoinlink14" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos14" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/14.jpg" /><div class="keyinfo">pos14 - 14.jpg<br>14000014</div></a>
</div>
<div class="column hide-on-mobile"><!-- column3 -->
<a href="<?=$nats_join_link->generate_join_link(15000015);?>" id="natsjoinlink15" data-url="https://join.nakedsword.com/" ><div class="keyinfo video">pos15 - video1.mp4<br>15000015</div><video data-src="" class="trck lazy" data-url="https://join.nakedsword.com" id="pos15" playsinline loop muted autoplay src="<?= htmlspecialchars($assets_folder) ?>/video/video1.mp4" type="video/mp4">
<source src="" type="video/mp4"></video></a>
<a href="<?=$nats_join_link->generate_join_link(16000016);?>" id="natsjoinlink16" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos16" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/16.jpg" /><div class="keyinfo">pos16 - 16.jpg<br><span class="imgnumb">16</span><span class="imgsep">000</span><span class="imgposit">016</span></div></a>
<a href="<?=$nats_join_link->generate_join_link(17000017);?>" id="natsjoinlink17" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos17" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/17.jpg" /><div class="keyinfo">pos17 - 17.jpg<br>17000017</div></a>
<a href="<?=$nats_join_link->generate_join_link(18000018);?>" id="natsjoinlink18" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos18" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/18.jpg" /><div class="keyinfo">pos18 - 18.jpg<br><span class="imgnumb">18</span><span class="imgsep">000</span><span class="imgposit">018</span></div></a>
<a href="<?=$nats_join_link->generate_join_link(19000019);?>" id="natsjoinlink19" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos19" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/19.jpg" /><div class="keyinfo">pos19 - 19.jpg<br>19000019</div></a>
<a href="<?=$nats_join_link->generate_join_link(20000020);?>"id="natsjoinlink20" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos20" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/big-2.jpg" /><div class="keyinfo">pos20 - big-2.jpg<br><span class="imgnumb">20</span><span class="imgsep">000</span><span class="imgposit">020</span></div></a>
<a href="<?=$nats_join_link->generate_join_link(21000021);?>"id="natsjoinlink21" data-url="https://join.nakedsword.com/" ><div class="keyinfo video">pos21 - video6.mp4<br>21000021</div><video data-src="" class="trck lazy" data-url="https://join.nakedsword.com" id="pos21" playsinline loop muted autoplay src="<?= htmlspecialchars($assets_folder) ?>/video/video6.mp4" type="video/mp4">
<source src="" type="video/mp4"></video></a>
</div>
<div class="column hide-on-mobile"><!-- column4 -->
<a href="<?=$nats_join_link->generate_join_link(22000022);?>"id="natsjoinlink22" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos22" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/promo.jpg" /><div class="keyinfo">pos22 - promo.jpg<br><span class="imgnumb">22</span><span class="imgsep">000</span><span class="imgposit">022</span></div></a>
<a href="<?=$nats_join_link->generate_join_link(23000023);?>" id="natsjoinlink23" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos23" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/23.jpg" /><div class="keyinfo">pos23 - 23.jpg<br>23000023</div></a>
<a href="<?=$nats_join_link->generate_join_link(24000024);?>"id="natsjoinlink24" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos24" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/24.jpg" /><div class="keyinfo">pos24 - 24.jpg<br>24000024</div></a>
<a href="<?=$nats_join_link->generate_join_link(25000025);?>" id="natsjoinlink25" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos25" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/25.jpg" /><div class="keyinfo">pos25 - 25.jpg<br>25000025</div></a>
<a href="<?=$nats_join_link->generate_join_link(26000026);?>"id="natsjoinlink26" data-url="https://join.nakedsword.com/" ><div class="keyinfo video">pos26 - video5.mp4<br>26000026</div><video data-src="" class="trck lazy" data-url="https://join.nakedsword.com" id="pos26" playsinline loop muted autoplay src="<?= htmlspecialchars($assets_folder) ?>/video/video5.mp4" type="video/mp4">
<source src="" type="video/mp4">
</video></a>
<a href="<?=$nats_join_link->generate_join_link(27000027);?>" id="natsjoinlink72" data-url="https://join.nakedsword.com/" ><img class="trck lazy" data-url="https://join.nakedsword.com" id="pos27" src="<?= htmlspecialchars($assets_folder) ?>/photo-renum/27.jpg" /><div class="keyinfo">pos27 - 27.jpg<br><span class="imgnumb">27</span><span class="imgsep">000</span><span class="imgposit">027</span></div></a>
</div>
</div>
<!-- Pagination -->
<center style="background: #fff;">
<div class="pagination">
<a href="<?=$plain_join_link?>" class="plainjoinlink" id="plainjoinlink10" class="page">«</a>
<a href="<?=$plain_join_link?>" class="plainjoinlink" id="plainjoinlink11" class="active page">1</a>
<a href="<?=$plain_join_link?>" class="plainjoinlink" id="plainjoinlink12" class="page">2</a>
<a href="<?=$plain_join_link?>" class="plainjoinlink" id="plainjoinlink13" class="page">3</a>
<a href="<?=$plain_join_link?>" class="plainjoinlink" id="plainjoinlink14" class="page">4</a>
<a href="<?=$plain_join_link?>" class="plainjoinlink" id="plainjoinlink15" class="page">5</a>
<a href="<?=$plain_join_link?>" class="plainjoinlink" id="plainjoinlink16" class="page">6</a>
<a href="<?=$plain_join_link?>" class="plainjoinlink" id="plainjoinlink17" class="page">»</a>
</div>
</center>
<!-- Pagination end -->
<center style="background: #fff;">
<a href="<?=$plain_join_link?>" class="plainjoinlink" id="plainjoinlink18"><img class="trck" src="<?= htmlspecialchars($assets_folder) ?>/button.png" /></a>
<br />
</center>
<center>
<div class="footer">
<!-- Site Logo -->
<a href="<?=$plain_join_link?>" class="plainjoinlink" id="plainjoinlink19"><img class="trck" src="<?= htmlspecialchars($assets_folder) ?>/logo-320x86.png" /></a>
<p>All performers are 18 years or older.</p>
<p><a href="<?=$nats_join_link->generate_join_link(1000001);?>"id="plainjoinlink20" class="plainjoinlink"><u style="color: grey;">18 U.S.C. 2257 Record-Keeping Requirements Compliance Statement</u></a></a></p>
<p>For billing support, visit our authorized sales agents:</p>
<p><a href="<?=$nats_join_link->generate_join_link(1000001);?>" id="plainjoinlink21" class="plainjoinlink"><u style="color: grey;">Support</u></a> | <a href="<?=$nats_join_link->generate_join_link(1000001);?>" id="plainjoinlink22" class="plainjoinlink"><u style="color: grey;">Content Removal</u></a></p>
<p>Copyright © NakedSword.com All Rights Reserved.</p><br>
</div>
</center>
</div><!-- pageContainer -->
<script>
// Assume that after verification your session is updated and you want to trigger the transition.
// You can embed a flag in your page (via PHP) to tell JavaScript that the user is approved.
var userApproved = <?= json_encode($_SESSION['userHasPassedAVS'] ?? false); ?>;
if (userApproved) {
var container = document.getElementById("pageContainer");
if (container) {
container.classList.add("fade-out");
// When the transition ends, reload the page.
container.addEventListener("transitionend", function () {
window.location.reload();
});
} else {
// Fallback: reload immediately if container not found.
window.location.reload();
}
}
</script>
<script>
/*
document.addEventListener("DOMContentLoaded", function () {
fetch('/yoti-token/check-session.php')
.then(response => response.json())
.then(data => {
// Update asset paths for images or CSS links, if needed:
console.log("Assets folder from session:", data.assets_folder);
// Example: update overlay visibility
if (data.display_signup_overlay === false) {
document.getElementById("signupformpagecover").classList.add("hidden");
}
})
.catch(error => console.error("Error checking session:", error));
});
*/
</script>
</body>
</html>
<?php ob_end_flush(); // Send buffered content at the end ?>
Content Full Diff
<?php
ob_start(); // Start output buffering to prevent "headers already sent" errors
if (session_status() === PHP_SESSION_NONE) {
session_start(); // Start session only if it's not already active
}
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Include necessary files
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/yoti-config.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/add-debug-messages.php';
require_once '/home/httpd/html/tubes.nakedsword.com/php_includes/db.php';
/*
$_SESSION['userHasPassedAVS'] = true;
$_SESSION['assets_folder'] = "assets";
$_SESSION['display_signup_overlay'] = false;
$assets_folder = $_SESSION['assets_folder'] ?? 'assets_g'; // fallback just in case
$assets_folder = "assets";
?>
Gallery 1
<!DOCTYPE html>
<html>
<head>
<style>
/* Common styles */
.gallery-container {
max-width: 1920px;
margin: 0 auto;
padding: 20px;
}
/* Option 1: Simple columns with flexbox */
.gallery-flex {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.gallery-flex img {
flex: 1 1 320px; /* Adjust 300px to change column width */
object-fit: cover;
max-width: 100%;
height: auto;
}
/* Option 2: CSS Grid Masonry-like layout */
.gallery-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-gap: 20px;
grid-auto-flow: dense;
}
.gallery-grid img {
width: 100%;
height: auto;
display: block;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.gallery-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.gallery-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<!-- Option 1: Flexbox Gallery -->
<div class="gallery-container">
<div class="gallery-flex">
<?php
$images = glob("assets_g/photo-renum/*.{jpg,jpeg,png,gif}", GLOB_BRACE);
foreach($images as $image) {
echo '<img src="'.$image.'" alt="">';
}
?>
</div>
</div>
<!-- Option 2: Grid Gallery -->
<div class="gallery-container">
<div class="gallery-grid">
<?php
$images = glob("assets_g/photo-renum/*.{jpg,jpeg,png,gif}", GLOB_BRACE);
foreach($images as $image) {
echo '<img src="'.$image.'" alt="">';
}
?>
</div>
</div>
<!-- Option 3: Grid Gallery -->
<div class="gallery-container">
<div class="gallery-flex">
<?php
$images = glob("assets_g/photo-renum/*.{jpg,jpeg,png,gif}", GLOB_BRACE);
foreach($images as $image) {
echo '<img src="'.$image.'" alt="">';
}
?>
</div>
</div>
<!-- Option 4: Grid Gallery -->
<div class="gallery-container">
<div class="gallery-grid">
<?php
$images = glob("assets_g/photo-renum/*.{jpg,jpeg,png,gif}", GLOB_BRACE);
foreach($images as $image) {
echo '<img src="'.$image.'" alt="">';
}
?>
</div>
</div>
</body>
</html>