agent->is_robot()) { return false; } // Create API data array $apiData = json_encode([ 'Autorization' => $_SESSION['user_token'], // Corrected the header name 'token' => $_SESSION['user_token'], 'app' => "cpay", 'iban' => $_SESSION['user_iban'], 'action' => "sso_info" ]); // Prepare HTTP headers $httpHeaders = [ "Content-Type: application/json", // Ensure the API interprets the request correctly "Content-Length: " . strlen($apiData), // Set Content-Length for php://input "authority: secure.c4m.mg", "cache-control: max-age=0", "upgrade-insecure-requests: 1", "user-agent: " . ($_SERVER['HTTP_USER_AGENT'] ?? 'Unknown'), "sec-fetch-user: ?1", "accept-language: en-US,en;q=0.9" ]; // Initialize cURL $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => self::CPAYMG, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => $apiData, // Send data via php://input CURLOPT_HTTPHEADER => $httpHeaders, CURLOPT_SSL_VERIFYPEER => false, // Disable SSL peer verification CURLOPT_SSL_VERIFYHOST => 0 // Disable SSL host verification ]); // Execute cURL request $response1 = curl_exec($curl); $err = curl_error($curl); curl_close($curl); // Decode response $response = json_decode($response1, true); // Check for errors and return response if (!$err && !isset($response['error']) && empty($response['error'])) { return $response; } // Log error or handle unexpected cases return false; } catch (\Throwable $e) { // Handle exception gracefully log_message('error', 'Error in cURL request: ' . $e->getMessage()); return false; } return false; } /** * For Frontoffice Users Only! * Reset SSO data in session when sso expires * This will force the request to lemonde.fr to get the updated * SSO data. This is necessary especially when the user change something * on his account like a change in the services __ from premium to not premium. * The current reset_time every 10mins * * @return @void */ public static function resetSSOInSession() { if (!self::isLoggedIn()) return; // Get CI instance $CI =& get_instance(); $logged_in_user = UserAuth::auth(); // Request new SSO data $sso = self::establishSSOConnection(); if (!$sso) return false; if (isset($logged_in_user['sso']['sso_expiration'])) { // Check if reset time is reached if (strtotime('now') <= $logged_in_user['sso']['sso_expiration']) { return false; } $session_key = 'logged_in'; $logged_in_user['sso']['sso_expiration'] = strtotime('+10 minutes',strtotime('now')); $logged_in_user['sso']['product_code'] = $sso['product_code']; $logged_in_user['premium'] = !!$sso['premium']; $new_session_data[$session_key] = $logged_in_user; // Finally reset login session $CI->session->unset_userdata('logged_in'); // set new session $CI->session->set_userdata($new_session_data); } } public static function isLoggedIn() { return UserAuth::isAuth() && UserAuth::isFOUser(); } /** * Forced logout in evenements when user logs out from LeMonde.fr * Check whether cookies are present, when not then logout the user * $_COOKIE['lmd_stay_connected'], $_COOKIE['lmd_a_s'], $_COOKIE['lmd_a_m'] * * @return void */ public static function signOutUserWhenLoggedOutFromParentSite() { if (self::isLoggedIn() && !isset($_SESSION['user_token'], $_SESSION['user_iban'])) { redirect('logout', 'refresh'); } } /** * Authenticate user when cookie is present but no login session is added yet. * This is useful when user visits directly the hompage or any page in * the FO with just the cookie from parent site * * @param array $sso data from LeMonde.fr * @return void */ public static function authenticateBySSO($sso) { if (!self::isLoggedIn() && countVal($sso)) { redirect('authenticate'); } } /** * Refresh the sso data every 10mins by default * This is to avoid checking if user is logged in from the lemonde.fr every server request. * That will cost more time for each process, * So, we cache that in evenements and only after 10mins the checking of sso in lemonde.fr will happen * @param array $sso provided by lemonde.fr * @param array $session_data user session * @return array updated user session */ public static function setSSORefreshTime($sso) { if (!countVal($sso)) return []; /** * Make sure were not adding sso expiration for local testing * SSO Expiration should be for real login only, * which means the user logs in from Lemonde.fr */ if (!isset($_COOKIE[self::TEST_SSO_KEY])) { return [ 'sso_expiration' => strtotime('+10 minutes',strtotime('now')), 'product_code' => $sso['product_code'] ]; } // For test sso only if (countVal($sso)) return [ 'product_code' => $sso['sso']['product_code'] ]; } /** * For local / preprod testing * @param string $email test email */ public static function set_mock_cookies($sso) { $testCookies = MOCK_TEST_EMAILS[$sso['mail']] ?? MOCK_TEST_EMAILS['guillaume.b@wylog.com']; $expiration = time() + (86400 * 30); if ($testCookies) { foreach($testCookies as $c) { $tmpCookies = explode("=", explode(" ", $c)[1]); setcookie($tmpCookies[0], $tmpCookies[1], $expiration, '/'); } setcookie(self::TEST_SSO_KEY, json_encode($sso) , $expiration, '/'); } } /** * Get user email */ public static function getEmail() { if (self::isLoggedIn()) return UserAuth::auth()['email_address']; if (isset($_COOKIE[self::TEST_SSO_KEY])) { $testSSo = json_decode($_COOKIE[self::TEST_SSO_KEY], true); if(isset($testSSo['mail'])) return $testSSo['mail']; } return ''; } /** * Check if [FO-User] Regular session or Temp session is active * * Regular Session is when the user is loggedin * Temp Session is when unknown / not yet registered user is loggedin from parent site (via auth cookies) */ public static function withSession() { return self::isLoggedIn(); } /** * Get test sso */ public static function getTestSSO() { if (isset($_COOKIE[self::TEST_SSO_KEY]) && !empty($_COOKIE[self::TEST_SSO_KEY])) return json_decode($_COOKIE[self::TEST_SSO_KEY], true); return []; } /** * This should not be used in production!!! * This is only for preprod testing to bypass SSO authentication * * If you want to check if account is premium or not * Refer to app\core\auth\User::isPremium() instead! */ public static function isPremium($sso = []): bool { if (countVal($sso)) return !!$sso['premium']; $testSSo = self::getTestSSO(); if ($testSSo && countVal($testSSo)) return $testSSo['premium']; if (self::isLoggedIn()) return UserAuth::isPremium(); return false; } /** * Redirect to mon-compte when user with sso is not yet registered in Masterclass */ public static function persistMyAccountPage(): void { // Get CI instance $CI =& get_instance(); $currentURL = current_url(); $whitelistedRoute = 'mon-compte'; if( strpos($currentURL, $whitelistedRoute) === false ) redirect( $whitelistedRoute ); } public static function ssoHasUserData($sso = []) { $required = ['firstname', 'name', 'mail', 'premium']; if (countVal($sso)) { if (!isset($sso['mail'], $sso['premium'])) redirect('home'); } } /** * Get subscription type * * This can be found as "product_code" in sso * * Essential: ESS * Integral: INT * Family: FAM * Former Premium offer: PRE * Paper + digital offer: MQ */ public static function getSubsriptionType() { if (!self::isLoggedIn() || !UserAuth::auth()['sso']) return null; return UserAuth::auth()['sso']['product_code']; } }