diff --git a/Dockerfile b/Dockerfile index badba47c8b391d17955709618fe3a60955946075..e5a9297ec81952b334e4f5c792d07eded8cdf56e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,7 +35,10 @@ RUN apt-get update && apt-get install -y libyaml-dev nano libpng-dev libfreetype RUN docker-php-ext-configure gd --with-freetype --with-jpeg RUN docker-php-ext-install -j$(nproc) gd RUN docker-php-ext-install mysqli -RUN COMPOSER_ALLOW_SUPERUSER=1 composer require --no-plugins --no-scripts pear/mail pear/net_smtp pear/auth_sasl pear/mail_mime phpseclib/phpseclib:~3.0 curl/curl sendgrid/sendgrid +RUN apt-get install libldap2-dev -y && \ + docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ && \ + docker-php-ext-install ldap +RUN COMPOSER_ALLOW_SUPERUSER=1 composer require --no-plugins --no-scripts directorytree/ldaprecord pear/mail pear/net_smtp pear/auth_sasl pear/mail_mime phpseclib/phpseclib:~3.0 curl/curl sendgrid/sendgrid RUN apt-get remove -y git unzip RUN rm -rf /var/lib/apt/lists/* && rm /usr/bin/composer RUN chown -R www-data:www-data /var/www/html/vendor/ /var/www/html/composer.lock /var/www/html/composer.json diff --git a/README.md b/README.md index 1b6647da1ab5254c71b22d510106af611fb82cf2..c7b6a47f0200503aaec13f5943f2eadf4c354194 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,10 @@ flowchart TD B --> |4. Create entry for user's email, code and ecloud username| E[(auth.file.done)] B --> |5. Send user welcome email| A ``` +# To use with LDAP backend + +- Add the following environment variables to use welcome with LDAP backend + - `LDAP_HOSTS`, `LDAP_PORT`, `LDAP_ADMIN_DN`, `LDAP_ADMIN_PASSWORD`, `LDAP_USERS_BASE_DN`, `LDAP_BACKEND_ENABLED` # SendGrid integration To be able to use [SendGrid](https://sendgrid.com/) as the email sender, you need to set the following ENV variables: diff --git a/htdocs/account_creator.php b/htdocs/accounts/account_creator.php similarity index 100% rename from htdocs/account_creator.php rename to htdocs/accounts/account_creator.php diff --git a/htdocs/ecloud_account_creator.php b/htdocs/accounts/base_ecloud_account_creator.php similarity index 60% rename from htdocs/ecloud_account_creator.php rename to htdocs/accounts/base_ecloud_account_creator.php index 47af0acc86d76b9771ad3a7dfa412393e89f7fb2..fe1d38984cf7ddfed5cc13e7f94aaa4874ebe26a 100644 --- a/htdocs/ecloud_account_creator.php +++ b/htdocs/accounts/base_ecloud_account_creator.php @@ -1,16 +1,14 @@ ecloudAccountsApiUrl = $this->ecloudUrl . 'apps/ecloud-accounts/api/'; $quota = getenv('CLOUD_QUOTA_IN_MB'); if ($quota !== false) { - $this->quotaInMB = intval($quota); + $this->quota = intval($quota); + } + } + + public function tryToCreate(object $userData) + { + global $strings; + $pw = $userData->password; + $answer = $this->createAccount($userData->email, $userData->username, $pw, $pw, $userData->name, $this->quota, $userData->authmail, $userData->referrerCode); + if ($answer->success === false) { + sendAPIResponse(400, createAPIResponse("general", $strings[$answer->type])); } } @@ -26,8 +34,8 @@ class ECloudAccountCreator implements AccountCreator { $id = "e_cloud_account_data"; try { - // We use $userData->email as uid as it is set to username@domain - if ($this->isUsernameTaken($userData->email)) { + // We check if account with uid set to email or username exists + if ($this->isUsernameTaken($userData->email) || $this->isUsernameTaken($userData->username)) { return new \ValidatedData($id, "error_account_taken"); } } catch (\Error $_) { @@ -36,41 +44,34 @@ class ECloudAccountCreator implements AccountCreator return new \ValidatedData($id, null); } - private function isUsernameTaken(string $uid): bool + protected function postCreationActions(string $email, string $username, string $authmail, string $quota, string $commonApiVersion = '') { - $token = getenv('ECLOUD_ACCOUNTS_SECRET'); - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - - $data = array( - "uid" => $uid, - "token" => $token, - ); - curl_setopt($ch, CURLOPT_URL, $this->ecloudAccountsApiUrl . 'user_exists'); - curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); - - $output = curl_exec($ch); - $output = json_decode($output); - $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - - if ($statusCode !== 200) { - $err = curl_error($ch); - throw new Error($err); + try { + $hmeAlias = ''; + $commonApiUrl = getenv('COMMON_SERVICES_URL'); + $commonApiUrl = endsWith($commonApiUrl, '/') ? $commonApiUrl : $commonApiUrl . '/'; + + $aliasDomain = getenv('ALIAS_DOMAIN'); + // Create HME Alias + $hmeAlias = $this->createHMEAlias($email, $commonApiUrl, $commonApiVersion, $aliasDomain); + // Create Alias to new domain + $this->createNewDomainAlias($username, $email, $commonApiUrl, $commonApiVersion, $aliasDomain); + + // Create alias with same name as email pointing to email to block this alias + $domain = getMailDomain(); + $this->createNewDomainAlias($username, $email, $commonApiUrl, $commonApiVersion, $domain); + } catch (Error $e) { + error_log('Error during alias creation for user: ' . $username . ' with email: ' . $email . ' : ' . $e->getMessage()); } - - return $output; + $answer = $this->setAccountDataAtNextcloud($username, $email, $quota . ' MB', $authmail, $hmeAlias); + return $answer; } - private function createHMEAlias(string $resultmail) : string + private function createHMEAlias(string $resultmail, string $commonApiUrl, string $commonApiVersion, string $domain) : string { $token = getenv('COMMON_SERVICES_TOKEN'); - $url = getenv('COMMON_SERVICES_URL'); - $domain = getenv('ALIAS_DOMAIN'); - - $endpoint = '/aliases/hide-my-email/'; - $url .= $endpoint . $resultmail; + $endpoint = $commonApiVersion . '/aliases/hide-my-email/'; + $url = $commonApiUrl . $endpoint . $resultmail; $data = array( "token" => $token, "domain" => $domain @@ -86,18 +87,16 @@ class ECloudAccountCreator implements AccountCreator return $alias; } - private function createNewDomainAlias(string $username, string $resultmail) + private function createNewDomainAlias(string $alias, string $resultmail, string $commonApiUrl, string $commonApiVersion, string $domain) { $token = getenv('COMMON_SERVICES_TOKEN'); - $url = getenv('COMMON_SERVICES_URL'); - $domain = getenv('ALIAS_DOMAIN'); - $endpoint = '/aliases/'; - $url .= $endpoint . $resultmail; + $endpoint = $commonApiVersion . '/aliases/'; + $url = $commonApiUrl . $endpoint . $resultmail; $data = array( "token" => $token, - "alias" => $username, + "alias" => $alias, "domain" => $domain ); $result = curlPostJSON($url, $data); @@ -108,7 +107,7 @@ class ECloudAccountCreator implements AccountCreator } } - private function setAccountDataAtNextcloud(string $email, string $quota, string $recoveryEmail, string $hmeAlias) + private function setAccountDataAtNextcloud(string $username, string $email, string $quota, string $recoveryEmail, string $hmeAlias) { $token = getenv('ECLOUD_ACCOUNTS_SECRET'); @@ -116,14 +115,15 @@ class ECloudAccountCreator implements AccountCreator curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - $data = array( - "uid" => $email, + $data = [ "token" => $token, "email" => $email, "quota" => $quota, "recoveryEmail" => $recoveryEmail, "hmeAlias" => $hmeAlias - ); + ]; + $data['uid'] = $this->usernameIsEmail ? $email : $username; + curl_setopt($ch, CURLOPT_URL, $this->ecloudAccountsApiUrl . 'set_account_data'); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); $output = curl_exec($ch); @@ -155,50 +155,34 @@ class ECloudAccountCreator implements AccountCreator return $answer; } - private function createMailAccount($resultmail, $username, $pw, $pw2, $name, $quota, $authmail, ?string $referrerCode = null) + private function isUsernameTaken(string $uid): bool { - global $strings; - $PF_HOSTNAME = "postfixadmin"; - $PF_USER = "pfexec"; - $PF_PWD = getenv("POSTFIXADMIN_SSH_PASSWORD"); - - $ssh = new SSH2($PF_HOSTNAME); - if (!$ssh->login($PF_USER, $PF_PWD)) { - $error_string = $strings["error_server_side"]; - sendAPIResponse(500, createAPIResponse("general", $error_string)); - } + $token = getenv('ECLOUD_ACCOUNTS_SECRET'); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - // 1 - create the account - $creationFeedBack = explode("\n", $ssh->exec('/postfixadmin/scripts/postfixadmin-cli mailbox add ' . escapeshellarg($resultmail) . ' --password ' . escapeshellarg($pw) . ' --password2 ' . escapeshellarg($pw2) . ' --name ' . escapeshellarg($name) . ' --email_other ' . escapeshellarg($authmail) . ' --quota ' . $quota . ' --active 1 --welcome-mail 0 2>&1')); - $isCreated = preg_grep('/added/', $creationFeedBack); - $answer = new \stdClass(); - if (empty($isCreated)) { - // There was an error during account creation on PFA side, return it - $answer->success = false; - $answer->type = "error_creating_account"; - return $answer; - } else { - // 2 - the account was created, set some settings - $hmeAlias = ''; - try { - $hmeAlias = $this->createHMEAlias($resultmail); - $this->createNewDomainAlias($username, $resultmail); - } catch (Error $e) { - error_log('Error during alias creation for user: ' . $resultmail . ' : ' . $e->getMessage()); - } - $answer = $this->setAccountDataAtNextcloud($resultmail, $quota . ' MB', $authmail, $hmeAlias); - return $answer; + $data = array( + "uid" => $uid, + "token" => $token, + ); + curl_setopt($ch, CURLOPT_URL, $this->ecloudAccountsApiUrl . 'user_exists'); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); + + $output = curl_exec($ch); + $output = json_decode($output); + $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + if ($statusCode !== 200) { + $err = curl_error($ch); + throw new Error($err); } + + return $output; } - public function tryToCreate(object $userData) + protected function createAccount(string $resultmail, string $username, string $pw, string $pw2, string $name, int $quota, string $authmail, ?string $referrerCode = null) { - global $strings; - $pw = $userData->password; - $answer = $this->createMailAccount($userData->email, $userData->username, $pw, $pw, $userData->name, $this->quotaInMB, $userData->authmail, $userData->referrerCode); - if ($answer->success === false) { - sendAPIResponse(400, createAPIResponse("general", $strings[$answer->type])); - } } } diff --git a/htdocs/accounts/ecloud_account_creator.php b/htdocs/accounts/ecloud_account_creator.php new file mode 100644 index 0000000000000000000000000000000000000000..b5dc4fd6a63cc60fe9ecfdcfa84432871188db63 --- /dev/null +++ b/htdocs/accounts/ecloud_account_creator.php @@ -0,0 +1,47 @@ +login($PF_USER, $PF_PWD)) { + $error_string = $strings["error_server_side"]; + sendAPIResponse(500, createAPIResponse("general", $error_string)); + } + + + // 1 - create the account + $creationFeedBack = explode("\n", $ssh->exec('/postfixadmin/scripts/postfixadmin-cli mailbox add ' . escapeshellarg($resultmail) . ' --password ' . escapeshellarg($pw) . ' --password2 ' . escapeshellarg($pw2) . ' --name ' . escapeshellarg($name) . ' --email_other ' . escapeshellarg($authmail) . ' --quota ' . $quota . ' --active 1 --welcome-mail 0 2>&1')); + $isCreated = preg_grep('/added/', $creationFeedBack); + $answer = new \stdClass(); + if (empty($isCreated)) { + // There was an error during account creation on PFA side, return it + $answer->success = false; + $answer->type = "error_creating_account"; + return $answer; + } else { + $answer = $this->postCreationActions($resultmail, $username, $authmail, $quota); + return $answer; + } + } + +} diff --git a/htdocs/gitlab_account_creator.php b/htdocs/accounts/gitlab_account_creator.php similarity index 98% rename from htdocs/gitlab_account_creator.php rename to htdocs/accounts/gitlab_account_creator.php index e040c4b04b92528fdc0a688180a02bed7fdba375..443d86a3da19bfd066e29c7449c386d8524b9888 100644 --- a/htdocs/gitlab_account_creator.php +++ b/htdocs/accounts/gitlab_account_creator.php @@ -1,5 +1,5 @@ quota = $this->quotaInBytes; + } else { + $this->quota = intval($quota); + } + $this->usernameIsEmail = false; + $this->connectToLDAPServer(); + } + + protected function createAccount(string $email, string $username, string $password, string $pw2, string $name, int $quota, string $authmail, ?string $referrerCode = null) + { + $baseDn = getenv('LDAP_USERS_BASE_DN'); + $userDn = "username=$username," . $baseDn; + $userClusterID = getenv('CLUSTER_ID'); + $answer = new \stdClass(); + try { + $user =[ + 'mailAddress' => $email, + 'username' => $username, + 'usernameWithoutDomain' => $username, + 'userPassword' => $password, + 'displayName' => $name, + 'quota' => $quota, + 'mailAlternate' => $authmail, + 'recoveryMailAddress' => $authmail, + 'active'=> 'TRUE', + 'mailActive' => 'TRUE', + 'userClusterID' => $userClusterID, + 'objectClass' => User::$objectClasses + ]; + $userEntry = new User($user); + $userEntry->setDn($userDn); + $userEntry->save(); + } catch (Exception $e) { + error_log('Error creating user ' . $e->getMessage()); + $answer->success= false; + $answer->type = 'error_creating_account'; + return $answer; + } + $answer = $this->postCreationActions($email, $username, $authmail, $quota, 'v2'); + return $answer; + } + + private function getLDAPConfig() : array + { + $ldapHosts = getenv('LDAP_HOSTS'); + $ldapHosts = explode(",", $ldapHosts); + $ldapPort = getenv('LDAP_PORT'); + $ldapAdminDn = getenv('LDAP_ADMIN_DN'); + $ldapAdminPassword = getenv('LDAP_ADMIN_PASSWORD'); + + $baseDn = getenv('LDAP_USERS_BASE_DN'); + + return [ + 'hosts' => $ldapHosts, + 'port' => $ldapPort, + 'base_dn' => $baseDn, + 'username' => $ldapAdminDn, + 'password' => $ldapAdminPassword + ]; + } + + private function connectToLDAPServer() : void + { + $config = $this->getLDAPConfig(); + + $this->conn = new Connection( + $config + ); + Container::addConnection($this->conn); + } +} diff --git a/htdocs/wp_account_creator.php b/htdocs/accounts/wp_account_creator.php similarity index 99% rename from htdocs/wp_account_creator.php rename to htdocs/accounts/wp_account_creator.php index f3b4c9cc69bef4ed709f8f314a922a4663e59791..11e5fb60b8c50eb7898b80922610a69b9def04eb 100644 --- a/htdocs/wp_account_creator.php +++ b/htdocs/accounts/wp_account_creator.php @@ -1,5 +1,5 @@ 30 || - strlen($name) > 30 || - strlen($pw) > 1024 || - strlen($pw2) > 1024 || - strlen($authmail) > 1024 || + strlen($mbox) > 30 || + strlen($name) > 30 || + strlen($pw) > 1024 || + strlen($pw2) > 1024 || + strlen($authmail) > 1024 || strlen($authsecret) > 1024 || is_string($referrerCode) && strlen($referrerCode) > 1024 ) { @@ -62,7 +63,7 @@ if (in_array($mbox, array('abuse', 'hostmaster', 'postmaster', 'webmaster', 'pos sendAPIResponse(400, createAPIResponse("username", $error_string)); } -if ( hasEmailAlreadyCreatedAnAccount($authmail) ) { +if (hasEmailAlreadyCreatedAnAccount($authmail)) { $error_string = $strings["error_already_registered"]; sendAPIResponse(400, createAPIResponse("general", $error_string)); } @@ -111,6 +112,7 @@ sendAPIResponse(200, createAPIResponse("success", $success_string)); function getAccountsCreators(string $domain): array { + global $strings; $NC_URL = "https://$domain/"; $GITLAB_URL = getenv("GITLAB_URL"); $GITLAB_TOKEN = getenv("GITLAB_TOKEN"); @@ -118,11 +120,22 @@ function getAccountsCreators(string $domain): array $E_SHOP_USERNAME = getenv("E_SHOP_USERNAME"); $E_SHOP_APP_PASS = getenv("E_SHOP_APP_PASS"); - $accountsCreators = array( - 'ecloud' => new \ECloudAccountCreator($NC_URL) - ); + $ldapBackendEnabled = boolval(getenv('LDAP_BACKEND_ENABLED')) || false; + $ecloudAccountCreatorClass = ECloudAccountCreator::class; + if ($ldapBackendEnabled) { + $ecloudAccountCreatorClass = LDAPAccountCreator::class; + } + try { + $accountsCreators = [ + 'ecloud' => new $ecloudAccountCreatorClass($NC_URL) + ]; + } catch (Exception $e) { + error_log('Error while starting LDAP Account Creator '. $e->getMessage()); + $errorResponse = createAPIResponse('error', $strings['error_creating_account']); + sendAPIResponse(500, $errorResponse); + } if (shouldCreateGitlabAccount()) { - $accountsCreators['gitlab'] = new \GitlabAccountCreator($GITLAB_URL, $GITLAB_TOKEN); + $accountsCreators['gitlab'] = new \GitlabAccountCreator($GITLAB_URL, $GITLAB_TOKEN); } if (shouldCreateEShopAccount()) { @@ -165,8 +178,7 @@ function shouldRewardReferrer(object $userData): bool function createAccounts(array $accountsCreators, object $userData) { - foreach($accountsCreators as $accountCreator) - { + foreach ($accountsCreators as $accountCreator) { try { $accountCreator->tryToCreate($userData); } catch (\Exception $err) { @@ -176,8 +188,7 @@ function createAccounts(array $accountsCreators, object $userData) } } - if (shouldRewardReferrer($userData)) - { + if (shouldRewardReferrer($userData)) { $E_SHOP_URL = getenv("E_SHOP_URL"); $E_SHOP_USERNAME = getenv("E_SHOP_USERNAME"); $E_SHOP_APP_PASS = getenv("E_SHOP_APP_PASS"); @@ -188,10 +199,11 @@ function createAccounts(array $accountsCreators, object $userData) function validateAccountOnAllServices(array $accountsCreators, object $userData) { - foreach($accountsCreators as $accountCreator) - { + foreach ($accountsCreators as $accountCreator) { $validatedData = $accountCreator->validateData($userData); - if ($validatedData->isValid()) continue; + if ($validatedData->isValid()) { + continue; + } sendAPIResponseFromValidatedData($userData, $validatedData); } } @@ -199,14 +211,14 @@ function validateAccountOnAllServices(array $accountsCreators, object $userData) function sendAPIResponseFromValidatedData(object $userData, ValidatedData $validatedData) { global $strings; - if ($validatedData->getErrorCode() === "error_account_taken" ) { + if ($validatedData->getErrorCode() === "error_account_taken") { $message = $strings["error_account_taken"]; $message = str_replace("@@@username@@@", $userData->username, $message); $response = createAPIResponse("error", $message); sendAPIResponse(400, $response); } - if ($validatedData->getErrorCode() === "error_already_registered" ) { + if ($validatedData->getErrorCode() === "error_already_registered") { $message = $strings["error_already_registered"]; $response = createAPIResponse("error", $message); sendAPIResponse(400, $response); diff --git a/htdocs/postDeleteLDAP.php b/htdocs/postDeleteLDAP.php new file mode 100644 index 0000000000000000000000000000000000000000..3d6ee533efc62d08510bc909e0b4fc214b3b00f0 --- /dev/null +++ b/htdocs/postDeleteLDAP.php @@ -0,0 +1,150 @@ + $line) { + if (preg_match($regex, $line) == 1) { + // temporarely save the line for later use on the file below + $tmpLine = $line; + + unset($lines[$key]); + } + } + if ($tmpLine) { + //Unique line was found, save $AUTH_FILE_DONE with exclusive lock on the file + $lines[] = ""; + $data = implode(PHP_EOL, $lines); + ftruncate($lockedFileDone, 0); + fwrite($lockedFileDone, $data); + fclose($lockedFileDone); + + /** + * for $AUTH_FILE, line pattern is : + * MAIL_USED_FOR_REGISTRATION:SECRET + * + * remove ALL lines on this file based on MAIL_USED_FOR_REGISTRATION + * + * get MAIL_USED_FOR_REGISTRATION from $tmpLine stored earlier + * create regex pattern to prevent false positives :only lines STARTING with $mail + */ + $mail = strtok($tmpLine, ":"); + $regex = "/^" . preg_quote($mail) . ":/"; + + $lockedFile = fopen($AUTH_FILE, "c", LOCK_EX); + // c mode to open the file in write mode WITH EXCLUSIVE LOCK, but DO NOT truncate it + + // find and delete all the line containing this MAIL_USED_FOR_REGISTRATION + $lines = file($AUTH_FILE, FILE_IGNORE_NEW_LINES); + foreach ($lines as $key => $line) { + if (preg_match($regex, $line) == 1) { + unset($lines[$key]); + } + } + $lines[] = ""; + $data = implode(PHP_EOL, $lines); + //save $AUTH_FILE with exclusive lock on the file + ftruncate($lockedFile, 0); + fwrite($lockedFile, $data); + fclose($lockedFile); + + // return MAIL_USED_FOR_REGISTRATION + return $mail; + } else { + return null; + } //NO line was found for this user +} + +/** + * function to : + * - connect to postfixadmin container to delete user account, using postfixadmin-cli + * - delete account's maildir as mail volume is now bind mounted to PFA container too + * + */ +function deleteMailFolders() +{ + $PF_HOSTNAME = "common_microservices"; + $PF_USER = "pfexec"; + $PF_PWD = getenv("POSTFIXADMIN_SSH_PASSWORD"); + + // Dir where /mnt/repo-base/volumes/mail/ is bind mounted on postfixadmin container + $baseDir = "/var/mail/vhosts/"; + + global $userOnly, $domain; + + if (!empty($domain) && !empty($userOnly)) { + $ssh = new SSH2($PF_HOSTNAME); + if (!$ssh->login($PF_USER, $PF_PWD)) { + exit('Login Failed'); + } + + $ssh->exec('sudo /usr/local/bin/mailbox-postdeletion.sh ' . escapeshellarg($userOnly) . ' ' . escapeshellarg($domain)); + // build path to check deletion + $fullPath = $baseDir . $domain . "/" . $userOnly; + $delDirConfirm = $ssh->exec('[ ! -d ' . escapeshellarg($fullPath) . ' ] && echo "DELETED"'); + + return $delDirConfirm === "DELETED"; + } else { + return null; + } // $domain OR $userOnly empty, do nothing!! +} + + +if (sha1($_POST['sec']) !== getenv("WELCOME_SECRET_SHA")) { + http_response_code(403); + exit(); +} else { + $user2delete = $_POST['uid']; + $exploded = explode("@", $user2delete); + $userOnly = $exploded[0]; + $domain = $exploded[1]; + + // STEP 1 : remove $user2delete from postfix database AND remove its mail folder + $mailDeletionReturn = deleteMailFolders(); + if ($mailDeletionReturn == true) { + /** + * mail DB account AND mailbox dir successfully deleted + * NO user data remaining on the server + * TODO : + * - fire mail for user to confirm deletion of his account is complete + * - handle onlyoffice part + * + */ + } + // STEP 2 : Purge system files AUTH_FILE & AUTH_FILE_DONE + $registrationMail = purgeAccountFiles(); + return ($registrationMail !== null); +}