|
|
@@ -0,0 +1,768 @@
|
|
|
+<?php
|
|
|
+session_start();
|
|
|
+ini_set('session.cookie_lifetime', 0); // till browser closes
|
|
|
+ini_set('session.gc_maxlifetime', 600); // 10 minutes
|
|
|
+ini_set('display_errors', 1);
|
|
|
+ini_set('display_startup_errors', 1);
|
|
|
+error_reporting(E_ALL);
|
|
|
+
|
|
|
+if (!isset($_SESSION['form_token'])) {
|
|
|
+ $_SESSION['form_token'] = bin2hex(random_bytes(32));
|
|
|
+}
|
|
|
+
|
|
|
+if (isset($_SESSION['form_success']) && $_SESSION['form_success']) {
|
|
|
+ $_SESSION['form_success'] = false;
|
|
|
+}
|
|
|
+
|
|
|
+// dont ask why i have this here
|
|
|
+if (isset($_SESSION['success_message'])) {
|
|
|
+ $success = $_SESSION['success_message'];
|
|
|
+ unset($_SESSION['success_message']);
|
|
|
+}
|
|
|
+
|
|
|
+// load the config (edit this to your needs)
|
|
|
+$config = parse_ini_file('/home/crt/helper-emailproxy/config/config.env');
|
|
|
+
|
|
|
+$configPath = $config['EMAILPROXY_CONFIG_FILE'];
|
|
|
+$authBaseConfigPath = $config['EMAILPROXY_AUTH_CONFIG'] ?? '/home/crt/helper-emailproxy/config/emailproxy-auth.config'; // base config path plus fallback to my default service user
|
|
|
+$logPath = $config['EMAILPROXY_LOG_FILE'];
|
|
|
+$allowedDomains = array_map('trim', explode(',', $config['ALLOWED_DOMAINS']));
|
|
|
+$debugWeb = isset($config['DEBUG_WEB']) && in_array(strtolower($config['DEBUG_WEB']), ['1', 'true', 'yes'], true);
|
|
|
+$debugLogFile = $config['DEBUG_WEB_LOG_FILE'] ?? '/tmp/web-debug.log';
|
|
|
+$authTimeout = 600; // if le auth session is not done in le 10 minutes welp too bad
|
|
|
+$publicMode = isset($config['PUBLIC']) && in_array(strtolower($config['PUBLIC']), ['1', 'true', 'yes'], true);
|
|
|
+$emailproxyExec = $config['EMAILPROXY_EXECUTABLE'];
|
|
|
+$commandPort = 8765; // little port to talk back to the auth-injector, should probably secure this more
|
|
|
+
|
|
|
+$mailServerName = $config['MAIL_SERVER_NAME'] ?? 'localhost';
|
|
|
+$mailImapPort = $config['MAIL_IMAP_PORT'] ?? '993';
|
|
|
+$mailSmtpPort = $config['MAIL_SMTP_PORT'] ?? '587';
|
|
|
+$mailImapSsl = isset($config['MAIL_IMAP_SSL']) && in_array(strtolower($config['MAIL_IMAP_SSL']), ['1', 'true', 'yes'], true); // is this a shit way to handle this ? yes very much so, does it make it more foolproof ? also yes
|
|
|
+$mailSmtpSsl = isset($config['MAIL_SMTP_SSL']) && in_array(strtolower($config['MAIL_SMTP_SSL']), ['1', 'true', 'yes'], true);
|
|
|
+$mailImapProtocol = $config['MAIL_IMAP_PROTOCOL'] ?? 'IMAP';
|
|
|
+$mailSmtpProtocol = $config['MAIL_SMTP_PROTOCOL'] ?? 'SMTP';
|
|
|
+
|
|
|
+// our super duper shit captcha that can be bypassed in seconds
|
|
|
+if (!isset($_SESSION['captcha']) || empty($_SESSION['captcha'])) {
|
|
|
+ $_SESSION['captcha'] = rand(1000, 9999);
|
|
|
+}
|
|
|
+
|
|
|
+// i dont know if my code breaks without debuging enabled yet :harold:.exe
|
|
|
+function debugLog($text, $debug, $file) {
|
|
|
+ if (!$debug) return;
|
|
|
+ $entry = "[" . date("Y-m-d H:i:s") . "] " . $text . "\n";
|
|
|
+ file_put_contents($file, $entry, FILE_APPEND);
|
|
|
+}
|
|
|
+
|
|
|
+function isEmailAllowed($email, $allowedDomains) {
|
|
|
+ $parts = explode('@', $email);
|
|
|
+ if (count($parts) !== 2) return false;
|
|
|
+ return in_array($parts[1], $allowedDomains);
|
|
|
+}
|
|
|
+
|
|
|
+function sendCommandToAuthInjector($command, $debug, $file) {
|
|
|
+ global $commandPort;
|
|
|
+
|
|
|
+ debugLog("Sending command to auth-injector: " . json_encode($command), $debug, $file);
|
|
|
+
|
|
|
+ $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
|
|
+ if ($socket === false) {
|
|
|
+ debugLog("socket_create() failed: " . socket_strerror(socket_last_error()), $debug, $file);
|
|
|
+ return ['success' => false, 'error' => "Failed to create socket"];
|
|
|
+ }
|
|
|
+
|
|
|
+ $result = socket_connect($socket, 'localhost', $commandPort);
|
|
|
+ if ($result === false) {
|
|
|
+ debugLog("socket_connect() failed: " . socket_strerror(socket_last_error($socket)), $debug, $file);
|
|
|
+ socket_close($socket);
|
|
|
+ return ['success' => false, 'error' => "Failed to connect to auth-injector"];
|
|
|
+ }
|
|
|
+
|
|
|
+ $data = json_encode($command);
|
|
|
+ socket_write($socket, $data, strlen($data));
|
|
|
+
|
|
|
+ $response = socket_read($socket, 4096);
|
|
|
+ socket_close($socket);
|
|
|
+
|
|
|
+ $response = json_decode($response, true);
|
|
|
+ debugLog("Received response from auth-injector: " . json_encode($response), $debug, $file);
|
|
|
+
|
|
|
+ return $response;
|
|
|
+}
|
|
|
+
|
|
|
+function getAuthURL($logFile, $email) {
|
|
|
+ global $debugWeb, $debugLogFile;
|
|
|
+
|
|
|
+ if (!file_exists($logFile)) {
|
|
|
+ debugLog("Log file not found: $logFile", $debugWeb, $debugLogFile);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ debugLog("Searching for auth URL in $logFile for email $email", $debugWeb, $debugLogFile);
|
|
|
+ $lines = array_reverse(file($logFile));
|
|
|
+
|
|
|
+ foreach ($lines as $line) {
|
|
|
+ if (strpos($line, "Please visit the following URL") !== false) {
|
|
|
+ debugLog("Found 'Please visit' line: $line", $debugWeb, $debugLogFile);
|
|
|
+
|
|
|
+ if (strpos($line, $email) !== false) {
|
|
|
+ preg_match('/https:\/\/login\\.microsoftonline\\.com\\/[^ ]+/', $line, $matches);
|
|
|
+ $url = $matches[0] ?? null;
|
|
|
+ debugLog("Extracted URL: $url", $debugWeb, $debugLogFile);
|
|
|
+ return $url;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ debugLog("No auth URL found for $email after checking " . count($lines) . " lines", $debugWeb, $debugLogFile);
|
|
|
+ return null;
|
|
|
+}
|
|
|
+
|
|
|
+// add "temporary" debug function for session ...
|
|
|
+function debugSession($message) {
|
|
|
+ file_put_contents('/tmp/session_debug.log',
|
|
|
+ date('Y-m-d H:i:s') . " - " . $message . ": " .
|
|
|
+ json_encode($_SESSION) . "\n",
|
|
|
+ FILE_APPEND);
|
|
|
+}
|
|
|
+
|
|
|
+// more debug functions for IMAP
|
|
|
+function debugImap($message, $debug = true, $debugFile = null) {
|
|
|
+ if (!$debug) return;
|
|
|
+ $timestamp = date('Y-m-d H:i:s');
|
|
|
+ $logMessage = "[$timestamp] [IMAP] $message\n";
|
|
|
+ file_put_contents($debugFile ?? '/tmp/imap-debug.log', $logMessage, FILE_APPEND);
|
|
|
+ error_log($logMessage); // Also log to PHP error log
|
|
|
+}
|
|
|
+
|
|
|
+// part of the user checking yk
|
|
|
+function userExistsInConfig($configPath, $email) {
|
|
|
+ if (!file_exists($configPath)) return false;
|
|
|
+ $content = file_get_contents($configPath);
|
|
|
+ return strpos($content, "[$email]") !== false;
|
|
|
+}
|
|
|
+
|
|
|
+function verifyUserPassword($email, $password) {
|
|
|
+ global $debugWeb, $debugLogFile;
|
|
|
+
|
|
|
+ // imagine using the correct port
|
|
|
+ $imapPort = getMainImapPort();
|
|
|
+ if (!$imapPort) {
|
|
|
+ debugLog("Could not determine IMAP port", $debugWeb, $debugLogFile);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ debugLog("Attempting to verify password for $email using IMAP port $imapPort", $debugWeb, $debugLogFile);
|
|
|
+
|
|
|
+ // try and connect, if it fails, it fails lol
|
|
|
+ $fp = @fsockopen('127.0.0.1', $imapPort, $errno, $errstr, 5);
|
|
|
+ if (!$fp) {
|
|
|
+ debugLog("Could not connect to IMAP server: $errstr ($errno)", $debugWeb, $debugLogFile);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // we need timeout, python isnt that fast
|
|
|
+ stream_set_timeout($fp, 10);
|
|
|
+
|
|
|
+ // get le hello from das server
|
|
|
+ $greeting = fgets($fp, 1024);
|
|
|
+ debugLog("IMAP greeting: $greeting", $debugWeb, $debugLogFile);
|
|
|
+
|
|
|
+ // check if its a valid greeting and not an insulting one lol
|
|
|
+ if (!$greeting || strpos($greeting, '* OK') === false) {
|
|
|
+ debugLog("Invalid IMAP greeting, closing connection", $debugWeb, $debugLogFile);
|
|
|
+ fclose($fp);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // totally untested function to escape the email and password custom characters
|
|
|
+ $safeEmail = str_replace(array('\\', '"'), array('\\\\', '\\"'), $email);
|
|
|
+ $safePassword = str_replace(array('\\', '"'), array('\\\\', '\\"'), $password);
|
|
|
+
|
|
|
+ // send the login command obviously
|
|
|
+ $loginCommand = "a001 LOGIN \"$safeEmail\" \"$safePassword\"\r\n";
|
|
|
+ debugLog("Sending login command...", $debugWeb, $debugLogFile);
|
|
|
+ fwrite($fp, $loginCommand);
|
|
|
+
|
|
|
+ // wait for python to piss its pants and respond
|
|
|
+ $response = '';
|
|
|
+ $timeout = time() + 10; // 10 seconds for pissing time
|
|
|
+
|
|
|
+ while (!feof($fp) && time() < $timeout) {
|
|
|
+ $line = fgets($fp, 1024);
|
|
|
+ if (!$line) break;
|
|
|
+
|
|
|
+ $response .= $line;
|
|
|
+ debugLog("IMAP response line: " . trim($line), $debugWeb, $debugLogFile);
|
|
|
+
|
|
|
+ // is ok? then good
|
|
|
+ if (strpos($line, 'a001 OK') === 0) {
|
|
|
+ fwrite($fp, "a002 LOGOUT\r\n");
|
|
|
+ fclose($fp);
|
|
|
+ debugLog("Authentication succeeded", $debugWeb, $debugLogFile);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ // is no? then bad
|
|
|
+ if (strpos($line, 'a001 NO') === 0 || strpos($line, 'a001 BAD') === 0) {
|
|
|
+ fclose($fp);
|
|
|
+ debugLog("Authentication failed: " . trim($line), $debugWeb, $debugLogFile);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // if we here then we failed and we should go and cry
|
|
|
+ fclose($fp);
|
|
|
+ debugLog("Authentication timed out or had other issue", $debugWeb, $debugLogFile);
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+function getMainImapPort() {
|
|
|
+ global $configPath;
|
|
|
+
|
|
|
+ if (!file_exists($configPath)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ $content = file_get_contents($configPath);
|
|
|
+ if (preg_match('/\[IMAP-(\d+)\]/', $content, $matches)) {
|
|
|
+ return (int)$matches[1];
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+}
|
|
|
+
|
|
|
+function removeUserFromConfig($configPath, $email) {
|
|
|
+ if (!file_exists($configPath)) return false;
|
|
|
+
|
|
|
+ $content = file_get_contents($configPath);
|
|
|
+
|
|
|
+ // danger zone ahead we are using regex to remove the user from the config in a terrible way
|
|
|
+ $pattern = '/\[' . preg_quote($email, '/') . '\].*?(?=\n\[|\Z)/s';
|
|
|
+ $contentAfterRemoval = preg_replace($pattern, '', $content);
|
|
|
+
|
|
|
+ // i have ocd
|
|
|
+ $contentAfterRemoval = preg_replace("/\n\n\n+/", "\n\n", $contentAfterRemoval);
|
|
|
+
|
|
|
+ // update prem file
|
|
|
+ return file_put_contents($configPath, $contentAfterRemoval) !== false;
|
|
|
+}
|
|
|
+
|
|
|
+// state ? AMERICA !!! RAHHHHHH
|
|
|
+$step = $_SESSION['step'] ?? 1;
|
|
|
+$authUrl = '';
|
|
|
+$email = $_SESSION['email'] ?? '';
|
|
|
+$success = '';
|
|
|
+$error = '';
|
|
|
+
|
|
|
+// mmmm posting
|
|
|
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
|
+ // check if the token is valid if is not it has no rights
|
|
|
+ $valid_token = false;
|
|
|
+
|
|
|
+ if (isset($_POST['form_token']) && isset($_SESSION['form_token']) &&
|
|
|
+ $_POST['form_token'] === $_SESSION['form_token']) {
|
|
|
+ $valid_token = true;
|
|
|
+ }
|
|
|
+ // i wont even pretend i know what this does
|
|
|
+ elseif (isset($_POST['form_token']) && isset($_SESSION['previous_form_token']) &&
|
|
|
+ $_POST['form_token'] === $_SESSION['previous_form_token']) {
|
|
|
+ $valid_token = true;
|
|
|
+ // stolen code yay !!!
|
|
|
+ unset($_SESSION['previous_form_token']);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$valid_token) {
|
|
|
+ // le user has pressed refresh and submiteed the form again most likely so uhm nuh uh
|
|
|
+ $error = "Form submission error. Please try again.";
|
|
|
+ } else {
|
|
|
+ // MORE STOLEN CODE !!! YIPPIE
|
|
|
+ $_SESSION['form_token'] = bin2hex(random_bytes(32));
|
|
|
+
|
|
|
+ if ($step === 1 && isset($_POST['captcha'])) {
|
|
|
+ debugSession("Before CAPTCHA validation");
|
|
|
+ // Step nummero eins: nutzloses gschiss catptcha
|
|
|
+ $captcha = trim($_POST['captcha']);
|
|
|
+ if ($captcha !== (string)$_SESSION['captcha']) {
|
|
|
+ $error = "Invalid CAPTCHA. Please try again.";
|
|
|
+ // kei ahnig wiso mer ned üsih function benützed aber okay hets problem gfixxed
|
|
|
+ $_SESSION['captcha'] = rand(1000, 9999);
|
|
|
+ } else {
|
|
|
+ // isch guet denn bye bye kaptcha damit "sicherheit und so"
|
|
|
+ unset($_SESSION['captcha']);
|
|
|
+
|
|
|
+ // ich verlühre mini hoffnig das das jemals sicher wird sih aber mer chans ja probiere (ich han depressioneh)
|
|
|
+ $imapPort = 2993 + rand(1, 100);
|
|
|
+ $smtpPort = 2465 + rand(1, 100);
|
|
|
+
|
|
|
+ // session ID, isch so fürs authentifizierig dingens
|
|
|
+ $sessionId = time() . '_' . rand(1000, 9999);
|
|
|
+
|
|
|
+ // merken sonst wiso haben wir es gemacht ???
|
|
|
+ $_SESSION['imapPort'] = $imapPort;
|
|
|
+ $_SESSION['smtpPort'] = $smtpPort;
|
|
|
+ $_SESSION['sessionId'] = $sessionId;
|
|
|
+
|
|
|
+ // yk vlt bruchid mer zersch emol d'email adresse deswege mal zu steppo 2 gah
|
|
|
+ $_SESSION['step'] = 2;
|
|
|
+ $_SESSION['form_success'] = true;
|
|
|
+
|
|
|
+ // save session and redirect to the same page ... to update the content kinda terribly
|
|
|
+ session_write_close();
|
|
|
+ header('Location: ' . $_SERVER['PHP_SELF']);
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+ debugSession("After CAPTCHA validation");
|
|
|
+ } elseif ($step === 2 && isset($_POST['email']) && isset($_POST['password'])) {
|
|
|
+ debugSession("Before email/password processing");
|
|
|
+ // Schritt numbero due ... email und passwort ihtöggele
|
|
|
+ $email = trim($_POST['email']);
|
|
|
+ $password = trim($_POST['password']);
|
|
|
+
|
|
|
+ if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
|
+ $error = "Invalid email address.";
|
|
|
+ } elseif (!isEmailAllowed($email, $allowedDomains)) {
|
|
|
+ $error = "Email domain not allowed.";
|
|
|
+ } else {
|
|
|
+ // mmm mal güxle ob de user scho existiert im config
|
|
|
+ if (userExistsInConfig($configPath, $email)) {
|
|
|
+ // sehr guet denn chömer mal gugge ob das passwort au stimmt
|
|
|
+ if (verifyUserPassword($email, $password)) {
|
|
|
+ // das isch save ned sicher aber yoa lets fucking go oder so
|
|
|
+ $_SESSION['added_email'] = $email;
|
|
|
+ $_SESSION['verified_password'] = $password; // mmm yes very secure password storage right here so you can steal it from the session :harold:
|
|
|
+ $_SESSION['step'] = 4; // go to SEX panel ... to show the user config page
|
|
|
+
|
|
|
+ // redirect to the same page to update the content
|
|
|
+ session_write_close();
|
|
|
+ header('Location: ' . $_SERVER['PHP_SELF']);
|
|
|
+ exit;
|
|
|
+ } else {
|
|
|
+ // GOOD BYE MY NI... back to the lobby !!!
|
|
|
+ $error = "Incorrect password for existing account. If you're having trouble, contact " .
|
|
|
+ htmlspecialchars($config['SYSADMIN_EMAIL'] ?? 'your system administrator');
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // user existiert ned also lets go und mache das authentifizierig dingens zum ms nerve
|
|
|
+ $_SESSION['email'] = $email;
|
|
|
+ $imapPort = $_SESSION['imapPort'];
|
|
|
+ $smtpPort = $_SESSION['smtpPort'];
|
|
|
+ $sessionId = $_SESSION['sessionId'];
|
|
|
+
|
|
|
+ // now launch emailproxy temp session (look at me so sekurity)
|
|
|
+ $command = [
|
|
|
+ 'type' => 'new_user',
|
|
|
+ 'email' => $email,
|
|
|
+ 'imap_port' => $imapPort,
|
|
|
+ 'smtp_port' => $smtpPort,
|
|
|
+ 'session_id' => $sessionId
|
|
|
+ ];
|
|
|
+
|
|
|
+ // note to self : following line has been fixed by an LLM (because i was lazy and i have no oversight of my code at this point its late and i want to sleep)
|
|
|
+ $response = sendCommandToAuthInjector($command, $debugWeb, $debugLogFile);
|
|
|
+
|
|
|
+ if (!$response['success']) {
|
|
|
+ $error = "Failed to start authentication process. Please try again.";
|
|
|
+ } else {
|
|
|
+ sleep(3); // more spaghetti timeouts to ensure my slow server can handle it
|
|
|
+
|
|
|
+ // connect to the IMAP server and send creds (this fails sometimes but we ignore it)
|
|
|
+ $fp = fsockopen("127.0.0.1", $imapPort, $errno, $errstr, 5);
|
|
|
+ if (!$fp) {
|
|
|
+ $error = "Failed to connect to the temporary emailproxy (IMAP port $imapPort).";
|
|
|
+ } else {
|
|
|
+ // Send login command to IMAP
|
|
|
+ fwrite($fp, "a001 LOGIN $email $password\r\n");
|
|
|
+ sleep(5); // demonstration of ignoring it
|
|
|
+ fclose($fp);
|
|
|
+
|
|
|
+ $maxAttempts = 10; // how many times we try to get the url before deciding le server is le fucked
|
|
|
+ $authUrl = null;
|
|
|
+
|
|
|
+ for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
|
|
|
+ $authUrl = getAuthURL($logPath, $email);
|
|
|
+ if ($authUrl) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ sleep(3); // more demonstration of ignoring the problem
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($authUrl) {
|
|
|
+ $_SESSION['authUrl'] = $authUrl;
|
|
|
+ $_SESSION['step'] = 3; // move to step numbero tres ... tres bien oder so wenn mer das url hend
|
|
|
+ $_SESSION['form_success'] = true;
|
|
|
+
|
|
|
+ // Save session and redirect
|
|
|
+ session_write_close();
|
|
|
+ header('Location: ' . $_SERVER['PHP_SELF']);
|
|
|
+ exit;
|
|
|
+ } else {
|
|
|
+ $error = "Failed to retrieve the authentication URL. Please try again.";
|
|
|
+ debugLog("Authentication URL not found after $maxAttempts attempts", $debugWeb, $debugLogFile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } elseif ($step === 3 && isset($_POST['auth_redirect'])) {
|
|
|
+ debugSession("Processing redirect URL");
|
|
|
+ // number tres ... redirect url processing
|
|
|
+ $authRedirect = trim($_POST['auth_redirect']);
|
|
|
+ $email = $_SESSION['email'];
|
|
|
+ $sessionId = $_SESSION['sessionId'];
|
|
|
+
|
|
|
+ // send the redirect URL to the auth-injector (or by this point known as emailproxy-ui.py backend)
|
|
|
+ $command = [
|
|
|
+ 'type' => 'redirect_url',
|
|
|
+ 'session_id' => $sessionId,
|
|
|
+ 'email' => $email,
|
|
|
+ 'redirect_url' => $authRedirect
|
|
|
+ ];
|
|
|
+
|
|
|
+ $response = sendCommandToAuthInjector($command, $debugWeb, $debugLogFile);
|
|
|
+
|
|
|
+ if ($response['success']) {
|
|
|
+ $command = [
|
|
|
+ 'type' => 'merge_config',
|
|
|
+ 'session_id' => $sessionId
|
|
|
+ ];
|
|
|
+ $mergeResponse = sendCommandToAuthInjector($command, $debugWeb, $debugLogFile);
|
|
|
+ if ($mergeResponse['success']) {
|
|
|
+ // checking if the user exists in the config ... again ... because stupid
|
|
|
+ $is_existing = userExistsInConfig($configPath, $email);
|
|
|
+
|
|
|
+ $_SESSION['added_email'] = $email;
|
|
|
+ $_SESSION['auth_success'] = true;
|
|
|
+ $_SESSION['form_success'] = true;
|
|
|
+ $_SESSION['is_existing_account'] = $is_existing; // attempt at trying to make it display a different message upon creating or editing an account but didnt work lol
|
|
|
+ $_SESSION['step'] = 4; // numbero quatro oder so
|
|
|
+
|
|
|
+ // save sessino and redirect to the same page ... yk updates yap yap
|
|
|
+ session_write_close();
|
|
|
+ header('Location: ' . $_SERVER['PHP_SELF']);
|
|
|
+ exit;
|
|
|
+ } else {
|
|
|
+ $error = "Failed to merge configuration. Please try again.";
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $error = "Authentication failed. The URL you provided may be invalid or the authentication timed out.";
|
|
|
+ $command = [
|
|
|
+ 'type' => 'cleanup',
|
|
|
+ 'session_id' => $sessionId
|
|
|
+ ];
|
|
|
+ sendCommandToAuthInjector($command, $debugWeb, $debugLogFile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // Idk what the following mystery is but its AI's spin on fixing and securing my user delete process
|
|
|
+ // Add this after your existing POST handlers, before the closing } of the if ($_SERVER['REQUEST_METHOD'] === 'POST') block
|
|
|
+ elseif (isset($_POST['remove_email']) && isset($_POST['confirm_password'])) {
|
|
|
+ $email = trim($_POST['remove_email']);
|
|
|
+
|
|
|
+ // uhm we uhm please actually want to delete an email and not accidentally match all config entries
|
|
|
+ if (empty($email) && isset($_SESSION['email_for_removal'])) {
|
|
|
+ $email = $_SESSION['email_for_removal'];
|
|
|
+ unset($_SESSION['email_for_removal']);
|
|
|
+ }
|
|
|
+
|
|
|
+ $password = trim($_POST['confirm_password']);
|
|
|
+
|
|
|
+ if (empty($email)) {
|
|
|
+ $_SESSION['success_message'] = "Error: No email address specified for removal.";
|
|
|
+ } else {
|
|
|
+ // you very very sure the password is le correcto amigo ?
|
|
|
+ if (verifyUserPassword($email, $password)) {
|
|
|
+ // tell the auth-injector to brutally cut out the user from running config
|
|
|
+ $command = [
|
|
|
+ 'type' => 'remove_user',
|
|
|
+ 'email' => $email
|
|
|
+ ];
|
|
|
+
|
|
|
+ $response = sendCommandToAuthInjector($command, $debugWeb, $debugLogFile);
|
|
|
+
|
|
|
+ if ($response['success']) {
|
|
|
+ $_SESSION['success_message'] = "Account $email has been successfully removed from the email proxy.";
|
|
|
+ } else {
|
|
|
+ $_SESSION['success_message'] = "Failed to remove account. Error: " . ($response['error'] ?? 'Unknown error');
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $_SESSION['success_message'] = "Password verification failed. If you need assistance, please contact " .
|
|
|
+ ($config['SYSADMIN_EMAIL'] ?? 'your system administrator');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // redir to first page (maybe clear session ? idk yet)
|
|
|
+ header('Location: ' . $_SERVER['PHP_SELF']);
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+?>
|
|
|
+
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="en">
|
|
|
+<head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <title>Emailproxy Auth Panel</title>
|
|
|
+ <style>
|
|
|
+ body {
|
|
|
+ font-family: Arial, sans-serif;
|
|
|
+ max-width: 800px;
|
|
|
+ margin: 0 auto;
|
|
|
+ padding: 20px;
|
|
|
+ }
|
|
|
+ .error {
|
|
|
+ color: red;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ .success {
|
|
|
+ color: green;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ .form-group {
|
|
|
+ margin-bottom: 15px;
|
|
|
+ }
|
|
|
+ label {
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 5px;
|
|
|
+ }
|
|
|
+ input[type="text"],
|
|
|
+ input[type="email"],
|
|
|
+ input[type="password"] {
|
|
|
+ width: 100%;
|
|
|
+ padding: 8px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+ button {
|
|
|
+ padding: 10px 15px;
|
|
|
+ background-color: #4CAF50;
|
|
|
+ color: white;
|
|
|
+ border: none;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ button:hover {
|
|
|
+ background-color: #45a049;
|
|
|
+ }
|
|
|
+ .auth-url {
|
|
|
+ word-break: break-all;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ padding: 10px;
|
|
|
+ border: 1px solid #ddd;
|
|
|
+ }
|
|
|
+ .success-container {
|
|
|
+ max-width: 700px;
|
|
|
+ margin: 0 auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .mail-settings {
|
|
|
+ background-color: #f9f9f9;
|
|
|
+ border: 1px solid #ddd;
|
|
|
+ border-radius: 5px;
|
|
|
+ padding: 20px;
|
|
|
+ margin: 20px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-container {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-box {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 250px;
|
|
|
+ padding: 10px;
|
|
|
+ margin: 5px;
|
|
|
+ background: white;
|
|
|
+ border: 1px solid #eee;
|
|
|
+ border-radius: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-box h5 {
|
|
|
+ margin-top: 0;
|
|
|
+ color: #333;
|
|
|
+ border-bottom: 1px solid #eee;
|
|
|
+ padding-bottom: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-box ul {
|
|
|
+ list-style: none;
|
|
|
+ padding-left: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-box li {
|
|
|
+ margin-bottom: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .note {
|
|
|
+ font-style: italic;
|
|
|
+ color: #666;
|
|
|
+ margin-top: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .button {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 10px 15px;
|
|
|
+ background-color: #4CAF50;
|
|
|
+ color: white;
|
|
|
+ text-decoration: none;
|
|
|
+ border-radius: 4px;
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .button:hover {
|
|
|
+ background-color: #45a049;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add this to your existing <style> section
|
|
|
+ .actions-container {
|
|
|
+ margin-top: 30px;
|
|
|
+ border-top: 1px solid #eee;
|
|
|
+ padding-top: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .remove-account {
|
|
|
+ margin-top: 30px;
|
|
|
+ padding: 15px;
|
|
|
+ background-color: #fff4f4;
|
|
|
+ border: 1px solid #ffdddd;
|
|
|
+ border-radius: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .remove-account h4 {
|
|
|
+ color: #cc0000;
|
|
|
+ margin-top: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .button.danger {
|
|
|
+ background-color: #d9534f;
|
|
|
+ }
|
|
|
+
|
|
|
+ .button.danger:hover {
|
|
|
+ background-color: #c9302c;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+ <h2>OAutsch Sucks Authorization Panel</h2>
|
|
|
+ <p>for people who hate 2FA, Microsoft and overcomplicated E-Mail.</p>
|
|
|
+ <p>Made with love for PHP <br> and PURE RAGE AND HATRED FOR AZURE, TEAMS, EXCHANGE AND MICRO$SOFT <br> by UMTS at <a href="https://teleco.ch">teleco</a></p>
|
|
|
+ <hr>
|
|
|
+
|
|
|
+ <?php if ($error): ?>
|
|
|
+ <p class="error"><?= htmlspecialchars($error) ?></p>
|
|
|
+ <?php endif; ?>
|
|
|
+
|
|
|
+ <?php if ($success): ?>
|
|
|
+ <p class="success"><?= htmlspecialchars($success) ?></p>
|
|
|
+ <?php endif; ?>
|
|
|
+
|
|
|
+ <?php if ($step === 1): ?>
|
|
|
+ <form method="POST">
|
|
|
+ <div class="form-group">
|
|
|
+ <label>CAPTCHA: <?= isset($_SESSION['captcha']) ? $_SESSION['captcha'] : rand(1000, 9999) ?></label>
|
|
|
+ <input type="text" name="captcha" required placeholder="Enter the CAPTCHA code">
|
|
|
+ </div>
|
|
|
+ <input type="hidden" name="form_token" value="<?= $_SESSION['form_token'] ?>">
|
|
|
+ <button type="submit">Start Authentication</button>
|
|
|
+ </form>
|
|
|
+ <?php elseif ($step === 2): ?>
|
|
|
+ <form method="POST">
|
|
|
+ <div class="form-group">
|
|
|
+ <label>Email Address:</label>
|
|
|
+ <input type="email" name="email" required placeholder="Enter your email address">
|
|
|
+ </div>
|
|
|
+ <div class="form-group">
|
|
|
+ <label>Password:</label>
|
|
|
+ <input type="password" name="password" required placeholder="Enter your password">
|
|
|
+ </div>
|
|
|
+ <input type="hidden" name="form_token" value="<?= $_SESSION['form_token'] ?>">
|
|
|
+ <button type="submit">Submit</button>
|
|
|
+ </form>
|
|
|
+ <?php elseif ($step === 3): ?>
|
|
|
+ <p><strong>Please visit the following URL to complete authentication:</strong></p>
|
|
|
+ <div class="auth-url">
|
|
|
+ <a href="<?= htmlspecialchars($_SESSION['authUrl']) ?>" target="_blank"><?= htmlspecialchars($_SESSION['authUrl']) ?></a>
|
|
|
+ </div>
|
|
|
+ <p>After completing the authentication process, you will be redirected to a page with a final URL. Copy that URL and paste it below:</p>
|
|
|
+
|
|
|
+ <form method="POST">
|
|
|
+ <div class="form-group">
|
|
|
+ <label>Paste the redirected URL here:</label>
|
|
|
+ <input type="text" name="auth_redirect" required placeholder="Paste the final URL here">
|
|
|
+ </div>
|
|
|
+ <input type="hidden" name="form_token" value="<?= $_SESSION['form_token'] ?>">
|
|
|
+ <button type="submit">Complete Authentication</button>
|
|
|
+ </form>
|
|
|
+ <?php elseif ($step === 4): ?>
|
|
|
+ <div class="success-container">
|
|
|
+ <h3>Success!</h3>
|
|
|
+ <p class="success">Your account <strong><?= htmlspecialchars($_SESSION['added_email'] ?? '') ?></strong> exists on the email proxy.</p>
|
|
|
+
|
|
|
+ <div class="mail-settings">
|
|
|
+ <h4>Mail Client Configuration</h4>
|
|
|
+
|
|
|
+ <div class="settings-container">
|
|
|
+ <div class="settings-box">
|
|
|
+ <h5>Incoming Mail Server (<?= htmlspecialchars($mailImapProtocol) ?>)</h5>
|
|
|
+ <ul>
|
|
|
+ <li><strong>Server:</strong> <?= htmlspecialchars($mailServerName) ?></li>
|
|
|
+ <li><strong>Port:</strong> <?= htmlspecialchars($mailImapPort) ?></li>
|
|
|
+ <li><strong>Security:</strong> <?= $mailImapSsl ? 'SSL/TLS' : 'None' ?></li>
|
|
|
+ <li><strong>Username:</strong> <?= htmlspecialchars($_SESSION['added_email'] ?? 'Your full email address') ?></li>
|
|
|
+ <li><strong>Authentication:</strong> Normal Password</li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="settings-box">
|
|
|
+ <h5>Outgoing Mail Server (<?= htmlspecialchars($mailSmtpProtocol) ?>)</h5>
|
|
|
+ <ul>
|
|
|
+ <li><strong>Server:</strong> <?= htmlspecialchars($mailServerName) ?></li>
|
|
|
+ <li><strong>Port:</strong> <?= htmlspecialchars($mailSmtpPort) ?></li>
|
|
|
+ <li><strong>Security:</strong> <?= $mailSmtpSsl ? 'SSL/TLS' : 'None' ?></li>
|
|
|
+ <li><strong>Username:</strong> <?= htmlspecialchars($_SESSION['added_email'] ?? 'Your full email address') ?></li>
|
|
|
+ <li><strong>Authentication:</strong> Normal Password</li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <p class="note">Use your defined password to sign into the proxy server (can differ from OAuth Providers account password).</p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="actions-container">
|
|
|
+ <p><a href="<?= $_SERVER['PHP_SELF'] ?>" class="button">Add Another Account</a></p>
|
|
|
+
|
|
|
+ <div class="remove-account">
|
|
|
+ <h4>Remove Account</h4>
|
|
|
+ <p>If you wish to remove this account from the email proxy, please confirm your password below.</p>
|
|
|
+
|
|
|
+ <form method="POST" onsubmit="return confirm('Are you sure?')">
|
|
|
+ <div class="form-group">
|
|
|
+ <label>Confirm Password:</label>
|
|
|
+ <input type="password" name="confirm_password" required placeholder="Enter your password">
|
|
|
+ </div>
|
|
|
+ <input type="hidden" name="remove_email" value="<?= htmlspecialchars($_SESSION['added_email'] ?? '') ?>">
|
|
|
+ <?php $form_token = $_SESSION['form_token']; ?>
|
|
|
+ <input type="hidden" name="form_token" value="<?= $form_token ?>">
|
|
|
+ <button type="submit" class="button danger">Remove Account from Proxy</button>
|
|
|
+ </form>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <?php
|
|
|
+ $email_for_removal = $_SESSION['added_email'] ?? '';
|
|
|
+
|
|
|
+ // Make new token before bye bye old one
|
|
|
+ $new_token = bin2hex(random_bytes(32));
|
|
|
+
|
|
|
+ // clean up le session after super premio success in hating ms
|
|
|
+ $_SESSION = [];
|
|
|
+ $_SESSION['captcha'] = rand(1000, 9999);
|
|
|
+ $_SESSION['form_token'] = $new_token;
|
|
|
+ // keep token for the next form just in case doe
|
|
|
+ $_SESSION['previous_form_token'] = $form_token;
|
|
|
+ $_SESSION['email_for_removal'] = $email_for_removal;
|
|
|
+ $step = 1;
|
|
|
+ ?>
|
|
|
+<?php endif; ?>
|
|
|
+</body>
|
|
|
+</html>
|