diff --git a/system/config/config.ini b/system/config/config.ini index 649e54b..568956e 100644 --- a/system/config/config.ini +++ b/system/config/config.ini @@ -63,10 +63,7 @@ EditUserFile: user.ini EditUserPasswordMinLength: 8 EditUserHashAlgorithm: bcrypt EditUserHashCost: 10 -EditUserStatus: active EditUserHome: / -EditLoginEmail: -EditLoginPassword: EditLoginRestrictions: 0 EditLoginSessionTimeout: 2592000 EditBruteForceProtection: 25 diff --git a/system/plugins/edit.css b/system/plugins/edit.css index e005d93..98c4ef7 100644 --- a/system/plugins/edit.css +++ b/system/plugins/edit.css @@ -198,6 +198,13 @@ #yellow-pane-version-fields { text-align:center; margin:0.5em 0; } #yellow-pane-version-buttons { margin-top:-0.5em; } +#yellow-pane-quit { text-align:center; } +#yellow-pane-quit .yellow-form-control { width:15em; box-sizing:border-box; } +#yellow-pane-quit .yellow-btn { width:15em; margin:1em 1em 0.5em 0; } +#yellow-pane-quit-status { margin:0.5em 0; display:inline-block; } +#yellow-pane-quit-fields { width:15em; text-align:left; margin:0 auto; } +#yellow-pane-quit-buttons { margin-top:-0.5em; } + #yellow-pane-edit-toolbar-title { margin:-5px 0 0 0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } #yellow-pane-edit-text { padding:0 2px; outline:none; resize:none; border:none; } #yellow-pane-edit-preview { padding:0; overflow:auto; } diff --git a/system/plugins/edit.js b/system/plugins/edit.js index 3c70532..0ed14e3 100644 --- a/system/plugins/edit.js +++ b/system/plugins/edit.js @@ -57,6 +57,8 @@ yellow.edit = case "change": this.showPane("yellow-pane-settings", action, status); break; case "version": this.showPane("yellow-pane-version", action, status); break; case "update": this.sendPane("yellow-pane-update", action, status, args); break; + case "quit": this.showPane("yellow-pane-quit", action, status); break; + case "remove": this.showPane("yellow-pane-quit", action, status); break; case "create": this.showPane("yellow-pane-edit", action, status, true); break; case "edit": this.showPane("yellow-pane-edit", action, status, true); break; case "delete": this.showPane("yellow-pane-edit", action, status, true); break; @@ -261,6 +263,7 @@ yellow.edit = "


"+ "


"+ "


"+rawDataLanguages+ + "

"+this.getText("SettingsQuit")+" "+this.getText("SettingsMore")+"

"+ "

"+ ""+ "
"+ @@ -280,6 +283,23 @@ yellow.edit = "
"+ ""; break; + case "yellow-pane-quit": + elementDiv.innerHTML = + "
"+ + ""+ + "

"+this.getText("QuitTitle")+"

"+ + "
"+this.getText(paneAction+"Status", "", paneStatus)+"
"+ + "
"+ + ""+ + ""+ + "


"+ + "

"+ + "
"+ + "
"+ + "

"+this.getText("OkButton")+"

"+ + "
"+ + "
"; + break; case "yellow-pane-edit": var rawDataButtons = ""; if(yellow.config.editToolbarButtons && yellow.config.editToolbarButtons!="none") @@ -375,6 +395,15 @@ yellow.edit = document.getElementById("yellow-pane-version-status").innerHTML = ""+this.getText("VersionUpdateNormal")+""; } break; + case "yellow-pane-quit": + yellow.toolbox.setVisible(document.getElementById("yellow-pane-quit-fields"), showFields); + yellow.toolbox.setVisible(document.getElementById("yellow-pane-quit-buttons"), !showFields); + if(paneStatus=="none") + { + document.getElementById("yellow-pane-quit-status").innerHTML = this.getText("QuitStatusNone"); + document.getElementById("yellow-pane-quit-name").value = ""; + } + break; case "yellow-pane-edit": document.getElementById("yellow-pane-edit-text").focus(); if(init) @@ -434,6 +463,7 @@ yellow.edit = case "yellow-pane-recover": case "yellow-pane-settings": case "yellow-pane-version": + case "yellow-pane-quit": yellow.toolbox.setOuterLeft(document.getElementById(paneId), paneLeft); yellow.toolbox.setOuterTop(document.getElementById(paneId), paneTop); yellow.toolbox.setOuterWidth(document.getElementById(paneId), paneWidth); @@ -795,7 +825,7 @@ yellow.edit = var extensions = yellow.config.editUploadExtensions.split(/\s*,\s*/); if(file.size<=yellow.config.serverFileSizeMax && extensions.indexOf(extension)!=-1) { - var text = this.getText("UploadProgress"); + var text = this.getText("UploadProgress")+"\u200b"; yellow.editor.setMarkdown(elementText, text, "insert"); var thisObject = this; var formData = new FormData(); @@ -815,7 +845,7 @@ yellow.edit = var result = JSON.parse(responseText); if(result) { - var textOld = this.getText("UploadProgress"); + var textOld = this.getText("UploadProgress")+"\u200b"; var textNew; if(result.location.substring(0, yellow.config.imageLocation.length)==yellow.config.imageLocation) { @@ -833,7 +863,7 @@ yellow.edit = var result = JSON.parse(responseText); if(result) { - var textOld = this.getText("UploadProgress"); + var textOld = this.getText("UploadProgress")+"\u200b"; var textNew = "["+result.error+"]"; yellow.editor.replace(elementText, textOld, textNew); } diff --git a/system/plugins/edit.php b/system/plugins/edit.php index a658fa4..5628f2a 100644 --- a/system/plugins/edit.php +++ b/system/plugins/edit.php @@ -5,7 +5,7 @@ class YellowEdit { - const VERSION = "0.7.18"; + const VERSION = "0.7.19"; var $yellow; //access to API var $response; //web response var $users; //user accounts @@ -28,7 +28,6 @@ class YellowEdit $this->yellow->config->setDefault("editUserPasswordMinLength", "8"); $this->yellow->config->setDefault("editUserHashAlgorithm", "bcrypt"); $this->yellow->config->setDefault("editUserHashCost", "10"); - $this->yellow->config->setDefault("editUserStatus", "active"); $this->yellow->config->setDefault("editUserHome", "/"); $this->yellow->config->setDefault("editLoginRestrictions", "0"); $this->yellow->config->setDefault("editLoginSessionTimeout", "2592000"); @@ -39,7 +38,28 @@ class YellowEdit // Handle startup function onStartup($update) { - if($update) $this->cleanCommand(array("clean", "all")); + if($update) + { + $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); + $fileData = $this->yellow->toolbox->readFile($fileNameUser); + foreach($this->yellow->toolbox->getTextLines($fileData) as $line) + { + preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); + if(!empty($matches[1]) && !empty($matches[2]) && $matches[1][0]!='#') + { + list($hash, $name, $language, $status, $stamp, $modified, $errors, $pending, $home) = explode(',', $matches[2]); + if($errors=="none") { $home=$pending; $pending=$errors; $errors=$modified; $modified=$stamp; $stamp=""; } //TODO: remove later + if(strlenb($stamp)!=20) $stamp=$this->createStamp(); //TODO: remove later, converts old file format + if($status!="active" && $status!="inactive") { unset($this->users->users[$matches[1]]); continue; } + $pending = "none"; + $this->users->set($matches[1], $hash, $name, $language, $status, $stamp, $modified, $errors, $pending, $home); + $fileDataNew .= "$matches[1]: $hash,$name,$language,$status,$stamp,$modified,$errors,$pending,$home\n"; + } else { + $fileDataNew .= $line; + } + } + if($fileData!=$fileDataNew) $this->yellow->toolbox->createFile($fileNameUser, $fileDataNew); + } } // Handle request @@ -116,7 +136,6 @@ class YellowEdit list($command) = $args; switch($command) { - case "clean": $statusCode = $this->cleanCommand($args); break; case "user": $statusCode = $this->userCommand($args); break; default: $statusCode = 0; } @@ -126,60 +145,111 @@ class YellowEdit // Handle command help function onCommandHelp() { - return "user [EMAIL PASSWORD NAME LANGUAGE]\n"; + return "user [OPTION EMAIL PASSWORD NAME]\n"; } - // Clean user accounts - function cleanCommand($args) + // Update user account + function userCommand($args) { - $statusCode = 0; - list($command, $path) = $args; - if($path=="all") + list($command, $option) = $args; + switch($option) { - $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - if(!$this->users->clean($fileNameUser)) - { - $statusCode = 500; - echo "ERROR cleaning configuration: Can't write file '$fileNameUser'!\n"; - } + case "": $statusCode = $this->userShow($args); break; + case "add": $statusCode = $this->userAdd($args); break; + case "change": $statusCode = $this->userChange($args); break; + case "remove": $statusCode = $this->userRemove($args); break; + default: $statusCode = 400; echo "Yellow $command: Invalid arguments\n"; } return $statusCode; } - // Update user account - function userCommand($args) + // Show user accounts + function userShow($args) { - $statusCode = 0; - list($command, $email, $password, $name, $language) = $args; - if(!empty($email) && !empty($password)) + list($command) = $args; + foreach($this->users->getData() as $line) echo "$line\n"; + if(!$this->users->getNumber()) echo "Yellow $command: No user accounts\n"; + return 200; + } + + // Add user account + function userAdd($args) + { + $status = "ok"; + list($command, $option, $email, $password, $name) = $args; + if(empty($email) || empty($password)) $status = $this->response->status = "incomplete"; + if($status=="ok") $status = $this->getUserAccount($email, $password, "add"); + if($status=="ok" && $this->users->isTaken($email)) $status = "taken"; + switch($status) { - $userExisting = $this->users->isExisting($email); - $status = $this->getUserAccount($email, $password, $command); - switch($status) - { - case "invalid": echo "ERROR updating configuration: Please enter a valid email!\n"; break; - case "weak": echo "ERROR updating configuration: Please enter a different password!\n"; break; - } - if($status=="ok") - { - $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $status = $this->users->update($fileNameUser, $email, $password, $name, $language, "active") ? "ok" : "error"; - if($status=="error") echo "ERROR updating configuration: Can't write file '$fileNameUser'!\n"; - } - if($status=="ok") - { - $algorithm = $this->yellow->config->get("editUserHashAlgorithm"); - $status = substru($this->users->getHash($email), 0, 5)!="error-hash" ? "ok" : "error"; - if($status=="error") echo "ERROR updating configuration: Hash algorithm '$algorithm' not supported!\n"; - } - $statusCode = $status=="ok" ? 200 : 500; - echo "Yellow $command: User account ".($statusCode!=200 ? "not " : ""); - echo ($userExisting ? "updated" : "created")."\n"; - } else { - $statusCode = 200; - foreach($this->users->getData() as $line) echo "$line\n"; - if(!$this->users->getNumber()) echo "Yellow $command: No user accounts\n"; + case "incomplete": echo "ERROR updating configuration: Please enter email and password!\n"; break; + case "invalid": echo "ERROR updating configuration: Please enter a valid email!\n"; break; + case "taken": echo "ERROR updating configuration: Please enter a different email!\n"; break; + case "weak": echo "ERROR updating configuration: Please enter a different password!\n"; break; } + if($status=="ok") + { + $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); + $status = $this->users->save($fileNameUser, $email, $password, $name, "", "active") ? "ok" : "error"; + if($status=="error") echo "ERROR updating configuration: Can't write file '$fileNameUser'!\n"; + } + if($status=="ok") + { + $algorithm = $this->yellow->config->get("editUserHashAlgorithm"); + $status = substru($this->users->getHash($email), 0, 10)!="error-hash" ? "ok" : "error"; + if($status=="error") echo "ERROR updating configuration: Hash algorithm '$algorithm' not supported!\n"; + } + $statusCode = $status=="ok" ? 200 : 500; + echo "Yellow $command: User account ".($statusCode!=200 ? "not " : "")."added\n"; + return $statusCode; + } + + // Change user account + function userChange($args) + { + $status = "ok"; + list($command, $option, $email, $password, $name) = $args; + if(empty($email)) $status = $this->response->status = "invalid"; + if($status=="ok") $status = $this->getUserAccount($email, $password, "change"); + if($status=="ok" && !$this->users->isExisting($email)) $status = "unknown"; + switch($status) + { + case "invalid": echo "ERROR updating configuration: Please enter a valid email!\n"; break; + case "unknown": echo "ERROR updating configuration: Can't find email '$email'!\n"; break; + case "weak": echo "ERROR updating configuration: Please enter a different password!\n"; break; + } + if($status=="ok") + { + $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); + $status = $this->users->save($fileNameUser, $email, $password, $name) ? "ok" : "error"; + if($status=="error") echo "ERROR updating configuration: Can't write file '$fileNameUser'!\n"; + } + $statusCode = $status=="ok" ? 200 : 500; + echo "Yellow $command: User account ".($statusCode!=200 ? "not " : "")."changed\n"; + return $statusCode; + } + + // Remove user account + function userRemove($args) + { + $status = "ok"; + list($command, $option, $email) = $args; + if(empty($email)) $status = $this->response->status = "invalid"; + if($status=="ok") $status = $this->getUserAccount($email, "", "remove"); + if($status=="ok" && !$this->users->isExisting($email)) $status = "unknown"; + switch($status) + { + case "invalid": echo "ERROR updating configuration: Please enter a valid email!\n"; break; + case "unknown": echo "ERROR updating configuration: Can't find email '$email'!\n"; break; + } + if($status=="ok") + { + $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); + $status = $this->users->remove($fileNameUser, $email) ? "ok" : "error"; + if($status=="error") echo "ERROR updating configuration: Can't write file '$fileNameUser'!\n"; + } + $statusCode = $status=="ok" ? 200 : 500; + echo "Yellow $command: User account ".($statusCode!=200 ? "not " : "")."removed\n"; return $statusCode; } @@ -197,6 +267,7 @@ class YellowEdit case "settings": $statusCode = $this->processRequestSettings($scheme, $address, $base, $location, $fileName); break; case "version": $statusCode = $this->processRequestVersion($scheme, $address, $base, $location, $fileName); break; case "update": $statusCode = $this->processRequestUpdate($scheme, $address, $base, $location, $fileName); break; + case "quit": $statusCode = $this->processRequestQuit($scheme, $address, $base, $location, $fileName); break; case "create": $statusCode = $this->processRequestCreate($scheme, $address, $base, $location, $fileName); break; case "edit": $statusCode = $this->processRequestEdit($scheme, $address, $base, $location, $fileName); break; case "delete": $statusCode = $this->processRequestDelete($scheme, $address, $base, $location, $fileName); break; @@ -216,6 +287,7 @@ class YellowEdit case "reactivate": $statusCode = $this->processRequestReactivate($scheme, $address, $base, $location, $fileName); break; case "verify": $statusCode = $this->processRequestVerify($scheme, $address, $base, $location, $fileName); break; case "change": $statusCode = $this->processRequestChange($scheme, $address, $base, $location, $fileName); break; + case "remove": $statusCode = $this->processRequestRemove($scheme, $address, $base, $location, $fileName); break; } } $this->checkUserFailed($scheme, $address, $base, $location, $fileName); @@ -247,7 +319,7 @@ class YellowEdit function processRequestLogin($scheme, $address, $base, $location, $fileName) { $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - if($this->users->update($fileNameUser, $this->response->userEmail)) + if($this->users->save($fileNameUser, $this->response->userEmail)) { $home = $this->users->getHome($this->response->userEmail); if(substru($location, 0, strlenu($home))==$home) @@ -294,10 +366,16 @@ class YellowEdit if($this->response->status=="ok") { $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $this->response->status = $this->users->update($fileNameUser, $email, $password, $name, "", "unconfirmed") ? "ok" : "error"; + $this->response->status = $this->users->save($fileNameUser, $email, $password, $name, "", "unconfirmed") ? "ok" : "error"; if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } if($this->response->status=="ok") + { + $algorithm = $this->yellow->config->get("editUserHashAlgorithm"); + $this->response->status = substru($this->users->getHash($email), 0, 10)!="error-hash" ? "ok" : "error"; + if($this->response->status=="error") $this->yellow->page->error(500, "Hash algorithm '$algorithm' not supported!"); + } + if($this->response->status=="ok") { $this->response->status = $this->response->sendMail($scheme, $address, $base, $email, "confirm") ? "next" : "error"; if($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!"); @@ -316,7 +394,7 @@ class YellowEdit if($this->response->status=="ok") { $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $this->response->status = $this->users->update($fileNameUser, $email, "", "", "", "unapproved") ? "ok" : "error"; + $this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "unapproved") ? "ok" : "error"; if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } if($this->response->status=="ok") @@ -338,7 +416,7 @@ class YellowEdit if($this->response->status=="ok") { $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $this->response->status = $this->users->update($fileNameUser, $email, "", "", "", "active") ? "ok" : "error"; + $this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "active") ? "ok" : "error"; if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } if($this->response->status=="ok") @@ -382,15 +460,13 @@ class YellowEdit if($this->response->status=="ok") { $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $this->response->status = $this->users->update($fileNameUser, $email, $password) ? "ok" : "error"; + $this->response->status = $this->users->save($fileNameUser, $email, $password) ? "ok" : "error"; if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } if($this->response->status=="ok") { - $this->response->userEmail = ""; $this->response->destroyCookies($scheme, $address, $base); - $this->response->status = $this->response->sendMail($scheme, $address, $base, $email, "information") ? "done" : "error"; - if($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!"); + $this->response->status = "done"; } } $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); @@ -407,7 +483,7 @@ class YellowEdit if($this->response->status=="ok") { $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $this->response->status = $this->users->update($fileNameUser, $email, "", "", "", "active") ? "done" : "error"; + $this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "active") ? "done" : "error"; if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); @@ -434,14 +510,14 @@ class YellowEdit $pending = $emailSource; $home = $this->users->getHome($emailSource); $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $this->response->status = $this->users->update($fileNameUser, $email, "no", $name, $language, "unverified", "", "", "", $pending, $home) ? "ok" : "error"; + $this->response->status = $this->users->save($fileNameUser, $email, "no", $name, $language, "unverified", "", "", "", $pending, $home) ? "ok" : "error"; if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } if($this->response->status=="ok") { $pending = $email.':'.(empty($password) ? $this->users->getHash($emailSource) : $this->users->createHash($password)); $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $this->response->status = $this->users->update($fileNameUser, $emailSource, "", $name, $language, "", "", "", "", $pending) ? "ok" : "error"; + $this->response->status = $this->users->save($fileNameUser, $emailSource, "", $name, $language, "", "", "", "", $pending) ? "ok" : "error"; if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } if($this->response->status=="ok") @@ -454,7 +530,7 @@ class YellowEdit if($this->response->status=="ok") { $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $this->response->status = $this->users->update($fileNameUser, $email, "", $name, $language) ? "done" : "error"; + $this->response->status = $this->users->save($fileNameUser, $email, "", $name, $language) ? "done" : "error"; if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } } @@ -483,7 +559,7 @@ class YellowEdit if($this->response->status=="ok") { $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $this->response->status = $this->users->update($fileNameUser, $email, "", "", "", "unchanged") ? "ok" : "error"; + $this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "unchanged") ? "ok" : "error"; if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } if($this->response->status=="ok") @@ -507,27 +583,24 @@ class YellowEdit list($email, $hash) = explode(':', $this->users->getPending($email), 2); if(!$this->users->isExisting($email) || empty($hash)) $this->response->status = "done"; } - if($this->response->status=="ok" && $email!=$emailSource) - { - $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $this->users->users[$emailSource]["pending"] = "none"; - $this->response->status = $this->users->update($fileNameUser, $emailSource, "", "", "", "removed") ? "ok" : "error"; - if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); - } if($this->response->status=="ok") { $this->users->users[$email]["hash"] = $hash; $this->users->users[$email]["pending"] = "none"; $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $this->response->status = $this->users->update($fileNameUser, $email, "", "", "", "active") ? "ok" : "error"; + $this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "active") ? "ok" : "error"; + if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); + } + if($this->response->status=="ok" && $email!=$emailSource) + { + $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); + $this->response->status = $this->users->remove($fileNameUser, $emailSource) ? "ok" : "error"; if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } if($this->response->status=="ok") { - $this->response->userEmail = ""; $this->response->destroyCookies($scheme, $address, $base); - $this->response->status = $this->response->sendMail($scheme, $address, $base, $email, "information") ? "done" : "error"; - if($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!"); + $this->response->status = "done"; } $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); return $statusCode; @@ -599,6 +672,58 @@ class YellowEdit return $statusCode; } + // Process request to quit account + function processRequestQuit($scheme, $address, $base, $location, $fileName) + { + $this->response->action = "quit"; + $this->response->status = "ok"; + $name = trim($_REQUEST["name"]); + $email = $this->response->userEmail; + if(empty($name)) $this->response->status = "none"; + if($this->response->status=="ok" && $name!=$this->users->getName($email)) $this->response->status = "mismatch"; + if($this->response->status=="ok") $this->response->status = $this->getUserAccount($email, "", $this->response->action); + if($this->response->status=="ok") + { + $this->response->status = $this->response->sendMail($scheme, $address, $base, $email, "remove") ? "next" : "error"; + if($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!"); + } + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); + return $statusCode; + } + + // Process request to remove account + function processRequestRemove($scheme, $address, $base, $location, $fileName) + { + $this->response->action = "remove"; + $this->response->status = "ok"; + $email = $_REQUEST["email"]; + $this->response->status = $this->getUserStatus($email, $_REQUEST["action"]); + if($this->response->status=="ok") + { + $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); + $this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "removed") ? "ok" : "error"; + if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); + } + if($this->response->status=="ok") + { + $this->response->status = $this->response->sendMail($scheme, $address, $base, $email, "goodbye") ? "ok" : "error"; + if($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!"); + } + if($this->response->status=="ok") + { + $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); + $this->response->status = $this->users->remove($fileNameUser, $email) ? "ok" : "error"; + if($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); + } + if($this->response->status=="ok") + { + $this->response->destroyCookies($scheme, $address, $base); + $this->response->status = "done"; + } + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); + return $statusCode; + } + // Process request to create page function processRequestCreate($scheme, $address, $base, $location, $fileName) { @@ -796,6 +921,7 @@ class YellowEdit if($this->users->checkActionToken($_REQUEST["actiontoken"], $_REQUEST["email"], $_REQUEST["action"], $_REQUEST["expire"])) { $ok = true; + $this->response->language = $this->getUserLanguage($_REQUEST["email"]); } else { $this->response->userFailedError = "action"; $this->response->userFailedEmail = $_REQUEST["email"]; @@ -816,15 +942,15 @@ class YellowEdit $modified = $this->users->getModified($email); $errors = $this->users->getErrors($email)+1; $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $status = $this->users->update($fileNameUser, $email, "", "", "", "", "", $modified, $errors) ? "ok" : "error"; + $status = $this->users->save($fileNameUser, $email, "", "", "", "", "", $modified, $errors) ? "ok" : "error"; if($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); if($errors==$this->yellow->config->get("editBruteForceProtection")) { $statusBeforeProtection = $this->users->getStatus($email); - $statusAfterProtection = ($statusBeforeProtection=="active" || $statusBeforeProtection=="inactive") ? "inactive" : "removed"; + $statusAfterProtection = ($statusBeforeProtection=="active" || $statusBeforeProtection=="inactive") ? "inactive" : "failed"; if($status=="ok") { - $status = $this->users->update($fileNameUser, $email, "", "", "", $statusAfterProtection, "", $modified, $errors) ? "ok" : "error"; + $status = $this->users->save($fileNameUser, $email, "", "", "", $statusAfterProtection, "", $modified, $errors) ? "ok" : "error"; if($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } if($status=="ok" && $statusBeforeProtection=="active") @@ -857,6 +983,7 @@ class YellowEdit case "reactivate": $statusExpected = "inactive"; break; case "verify": $statusExpected = "unverified"; break; case "change": $statusExpected = "active"; break; + case "remove": $statusExpected = "active"; break; } return $this->users->getStatus($email)==$statusExpected ? "ok" : "done"; } @@ -1348,7 +1475,7 @@ class YellowResponse // Send mail to user function sendMail($scheme, $address, $base, $email, $action) { - if($action=="welcome" || $action=="information") + if($action=="welcome" || $action=="goodbye") { $url = "$scheme://$address$base/"; } else { @@ -1463,39 +1590,14 @@ class YellowUsers if(!empty($matches[1]) && !empty($matches[2])) { list($hash, $name, $language, $status, $stamp, $modified, $errors, $pending, $home) = explode(',', $matches[2]); - if($errors=="none") { $home=$pending; $pending=$errors; $errors=$modified; $modified=$stamp; $stamp=$matches[1]; } //TODO: remove later $this->set($matches[1], $hash, $name, $language, $status, $stamp, $modified, $errors, $pending, $home); if(defined("DEBUG") && DEBUG>=3) echo "YellowUsers::load email:$matches[1]
\n"; } } } - - // Clean users in file - function clean($fileName) - { - $fileData = $this->yellow->toolbox->readFile($fileName); - foreach($this->yellow->toolbox->getTextLines($fileData) as $line) - { - preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); - if(!empty($matches[1]) && !empty($matches[2])) - { - list($hash, $name, $language, $status, $stamp, $modified, $errors, $pending, $home) = explode(',', $matches[2]); - if($errors=="none") { $home=$pending; $pending=$errors; $errors=$modified; $modified=$stamp; $stamp=$this->createStamp(); } //TODO: remove later - if(strlenb($stamp)!=20) $stamp=$this->createStamp(); //TODO: remove later, converts old file format - if($status=="active" || $status=="inactive") - { - $pending = "none"; - $fileDataNew .= "$matches[1]: $hash,$name,$language,$status,$stamp,$modified,$errors,$pending,$home\n"; - } - } else { - $fileDataNew .= $line; - } - } - return $this->yellow->toolbox->createFile($fileName, $fileDataNew); - } - - // Update users in file - function update($fileName, $email, $password = "", $name = "", $language = "", $status = "", $stamp = "", $modified = "", $errors = "", $pending = "", $home = "") + + // Save user to file + function save($fileName, $email, $password = "", $name = "", $language = "", $status = "", $stamp = "", $modified = "", $errors = "", $pending = "", $home = "") { if(!empty($password)) $hash = $this->createHash($password); if($this->isExisting($email)) @@ -1515,7 +1617,7 @@ class YellowUsers $hash = strreplaceu(',', '-', empty($hash) ? "none" : $hash); $name = strreplaceu(',', '-', empty($name) ? $this->yellow->config->get("sitename") : $name); $language = strreplaceu(',', '-', empty($language) ? $this->yellow->config->get("language") : $language); - $status = strreplaceu(',', '-', empty($status) ? $this->yellow->config->get("editUserStatus") : $status); + $status = strreplaceu(',', '-', empty($status) ? "active" : $status); $stamp = strreplaceu(',', '-', empty($stamp) ? $this->createStamp() : $stamp); $modified = strreplaceu(',', '-', empty($modified) ? time() : $modified); $errors = strreplaceu(',', '-', empty($errors) ? "0" : $errors); @@ -1538,7 +1640,23 @@ class YellowUsers if(!$found) $fileDataNew .= "$email: $hash,$name,$language,$status,$stamp,$modified,$errors,$pending,$home\n"; return $this->yellow->toolbox->createFile($fileName, $fileDataNew); } - + + // Remove user from file + function remove($fileName, $email) + { + unset($this->users[$email]); + $fileData = $this->yellow->toolbox->readFile($fileName); + foreach($this->yellow->toolbox->getTextLines($fileData) as $line) + { + preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); + if(!empty($matches[1]) && !empty($matches[2]) && $matches[1]!=$email) + { + $fileDataNew .= $line; + } + } + return $this->yellow->toolbox->createFile($fileName, $fileDataNew); + } + // Set user data function set($email, $hash, $name, $language, $status, $stamp, $modified, $errors, $pending, $home) { @@ -1706,10 +1824,8 @@ class YellowUsers foreach($this->users as $key=>$value) { $name = $value["name"]; if(preg_match("/\s/", $name)) $name = "\"$name\""; - $language = $value["language"]; if(preg_match("/\s/", $language)) $language = "\"$language\""; $status = $value["status"]; if(preg_match("/\s/", $status)) $status = "\"$status\""; - $data[$key] = "$value[email] - $name $language $status"; - if($value["home"]!="/") $data[$key] .= " restrictions"; + $data[$key] = "$value[email] $name $status"; } uksort($data, "strnatcasecmp"); return $data; diff --git a/system/plugins/language-de.txt b/system/plugins/language-de.txt index 9fd1fe3..e723094 100644 --- a/system/plugins/language-de.txt +++ b/system/plugins/language-de.txt @@ -3,7 +3,7 @@ Language: de LanguageDescription: Deutsch LanguageTranslator: David Fehrmann -LanguageVersion: 0.7.8 +LanguageVersion: 0.7.9 BlogBy: von BlogFilter: Blog: @@ -12,7 +12,7 @@ BlogMore: Lies mehr… ContactName: Name: ContactEmail: E-Mail: ContactMessage: Nachricht: -ContactConsent: Ich stimme zu, dass diese Webseite meine persönlichen Daten speichert und zur Kontaktaufnahme verwendet. +ContactConsent: Ich stimme zu, dass diese Webseite meine persönlichen Daten speichert. ContactButton: Nachricht absenden ContactStatusNone: Sag Hallo! Dein Feedback ist sehr willkommen. ContactStatusIncomplete: Bitte alle Felder ausfüllen. @@ -58,10 +58,16 @@ EditRecoverPassword: Kennwort: EditRecoverStatusPassword: Bitte ein neues Kennwort angeben. EditRecoverStatusWeak: Bitte ein anderes Kennwort angeben. EditSettingsTitle: Einstellungen +EditSettingsQuit: Du kannst dein Benutzerkonto jederzeit löschen. +EditSettingsMore: Mehr… EditSettingsStatusInvalid: Bitte eine gültige E-Mail angeben. EditSettingsStatusTaken: Bitte eine andere E-Mail angeben. EditSettingsStatusWeak: Bitte ein anderes Kennwort angeben. EditSettingsStatusNext: Benutzerkonto wird geändert, bitte überprüfe deine E-Mails. +EditQuitTitle: Benutzerkonto löschen +EditQuitStatusNone: Bitte gib deinen Namen zur Bestätigung ein. +EditQuitStatusMismatch: Bitte gib einen anderen Namen ein. +EditQuitStatusNext: Benutzerkonto wird gelöscht, bitte überprüfe deine E-Mails. EditConfirmSubject: Benutzerkonto bestätigen EditConfirmMessage: Hallo @usershort, bitte bestätige dein Benutzerkonto. Klicke auf den folgenden Link. EditConfirmStatusDone: Benutzerkonto wurde bestätigt und wartet auf Genehmigung. Vielen Dank! @@ -80,10 +86,13 @@ EditVerifyStatusDone: Benutzerkonto wurde bestätigt. Vielen Dank! EditChangeSubject: Benutzerkonto ändern EditChangeMessage: Hallo @usershort, bitte bestätige, dass du dein Benutzerkonto ändern möchtest. Klicke auf den folgenden Link. EditChangeStatusDone: Benutzerkonto wurde geändert. Vielen Dank! +EditRemoveSubject: Benutzerkonto löschen +EditRemoveMessage: Hallo @usershort, bitte bestätige, dass du dein Benutzerkonto löschen möchtest. Klicke auf den folgenden Link. +EditRemoveStatusDone: Benutzerkonto wurde gelöscht. Vielen Dank! EditWelcomeSubject: Willkommen EditWelcomeMessage: Hallo @usershort, dein Benutzerkonto wurde erstellt. Viel Spass beim Bearbeiten der Webseite. -EditInformationSubject: Willkommen zurück -EditInformationMessage: Hallo @usershort, dein Benutzerkonto wurde geändert. Du kannst dich jetzt anmelden. +EditGoodbyeSubject: Auf Wiedersehen +EditGoodbyeMessage: Hallo @usershort, dein Benutzerkonto wurde gelöscht. Mach's gut. EditVersionTitle: Über diese Webseite EditVersionStatusNone: Datenstrom Yellow ist für Menschen die Webseiten machen. EditVersionStatusCheck: Nach Aktualisierung suchen… diff --git a/system/plugins/language-en.txt b/system/plugins/language-en.txt index 88c5a4e..5885185 100644 --- a/system/plugins/language-en.txt +++ b/system/plugins/language-en.txt @@ -3,7 +3,7 @@ Language: en LanguageDescription: English LanguageTranslator: Mark Seuffert -LanguageVersion: 0.7.8 +LanguageVersion: 0.7.9 BlogBy: by BlogFilter: Blog: @@ -12,7 +12,7 @@ BlogMore: Read more… ContactName: Name: ContactEmail: Email: ContactMessage: Message: -ContactConsent: I consent that this website stores my personal data and uses it to contact me. +ContactConsent: I consent that this website stores my personal data. ContactButton: Send message ContactStatusNone: Say hello. Your feedback is very welcome. ContactStatusIncomplete: Please fill out all fields. @@ -58,10 +58,16 @@ EditRecoverPassword: Password: EditRecoverStatusPassword: Please enter a new password. EditRecoverStatusWeak: Please enter a different password. EditSettingsTitle: Settings +EditSettingsQuit: You can delete your user account anytime. +EditSettingsMore: More… EditSettingsStatusInvalid: Please enter a valid email. EditSettingsStatusTaken: Please enter a different email. EditSettingsStatusWeak: Please enter a different password. EditSettingsStatusNext: User account will be changed, please check your emails. +EditQuitTitle: Delete user account +EditQuitStatusNone: Please enter your name to confirm. +EditQuitStatusMismatch: Please enter a different name. +EditQuitStatusNext: User account will be deleted, please check your emails. EditConfirmSubject: Confirm user account EditConfirmMessage: Hi @usershort, please confirm your user account. Click the following link. EditConfirmStatusDone: User account confirmed and waiting for approval. Thank you! @@ -80,10 +86,13 @@ EditVerifyStatusDone: User account confirmed. Thank you! EditChangeSubject: Change user account EditChangeMessage: Hi @usershort, please confirm that you want to change your user account. Click the following link. EditChangeStatusDone: User account changed. Thank you! +EditRemoveSubject: Delete user account +EditRemoveMessage: Hi @usershort, please confirm that you want to delete your user account. Click the following link. +EditRemoveStatusDone: User account deleted. Thank you! EditWelcomeSubject: Welcome EditWelcomeMessage: Hi @usershort, your user account has been created. Have fun editing the website. -EditInformationSubject: Welcome back -EditInformationMessage: Hi @usershort, your user account has been changed. You can now log in. +EditGoodbyeSubject: Goodbye +EditGoodbyeMessage: Hi @usershort, your user account has been deleted. Take care. EditVersionTitle: About this website EditVersionStatusNone: Datenstrom Yellow is for people who make websites. EditVersionStatusCheck: Checking for updates… diff --git a/system/plugins/language-fr.txt b/system/plugins/language-fr.txt index 2db48f5..207ac1d 100644 --- a/system/plugins/language-fr.txt +++ b/system/plugins/language-fr.txt @@ -3,7 +3,7 @@ Language: fr LanguageDescription: Français LanguageTranslator: Juh Nibreh -LanguageVersion: 0.7.8 +LanguageVersion: 0.7.9 BlogBy: par BlogFilter: Blog: @@ -12,7 +12,7 @@ BlogMore: Lire la suite… ContactName: Nom: ContactEmail: Email: ContactMessage: Message: -ContactConsent: Je consens que ce site web stocke mes données personnelles et l'utilise pour me contacter. +ContactConsent: Je consens que ce site web stocke mes données personnelles. ContactButton: Envoyer le message ContactStatusNone: Dites bonjour! Vos commentaires sont les bienvenus. ContactStatusIncomplete: S'il vous plaît, veuillez remplir tous les champs. @@ -58,10 +58,16 @@ EditRecoverPassword: Mot de passe: EditRecoverStatusPassword: S'il vous plaît, choisissez un nouveau mot de passe. EditRecoverStatusWeak: S'il vous plaît, choisissez un mot de passe différent. EditSettingsTitle: Paramètres +EditSettingsQuit: Vous pouvez supprimer votre compte d'utilisateur. +EditSettingsMore: Plus… EditSettingsStatusInvalid: S'il vous plaît, veuillez entrer une adresse email valide. EditSettingsStatusTaken: S'il vous plaît, veuillez entrer une adresse email différent. EditSettingsStatusWeak: S'il vous plaît, choisissez un mot de passe différent. EditSettingsStatusNext: Votre compte a été changé, vérifiez vos emails. +EditQuitTitle: Supprimer le compte d'utilisateur +EditQuitStatusNone: S'il vous plaît entrez votre nom pour confirmer. +EditQuitStatusMismatch: S'il vous plaît entrer un nom différent. +EditQuitStatusNext: Votre compte sera supprimé, vérifier vos emails. EditConfirmSubject: Confirmation d'un compte utilisateur EditConfirmMessage: Bonjour @usershort, veuillez confirmer votre compte utilisateur. Cliquez sur le lien suivant. EditConfirmStatusDone: Votre compte utilisateur est confirmé et en attente d'approbation. Merci! @@ -80,10 +86,13 @@ EditVerifyStatusDone: Votre compte utilisateur est confirmé. Merci! EditChangeSubject: Changement d'un compte utilisateur EditChangeMessage: Bonjour @usershort, veuillez confirmer que vous souhaitez modifier votre compte utilisateur. Cliquez sur le lien suivant. EditChangeStatusDone: Compte utilisateur changé. Merci! +EditRemoveSubject: Supprimer le compte d'utilisateur +EditRemoveMessage: Bonjour @usershort, veuillez confirmer que vous souhaitez supprimer votre compte d'utilisateur. Cliquez sur le lien suivant. +EditRemoveStatusDone: Compte d'utilisateur supprimé. Merci! EditWelcomeSubject: Bienvenue EditWelcomeMessage: Bonjour @usershort, votre compte utilisateur a bien été créé. Amusez-vous bien en éditant le site web. -EditInformationSubject: Bienvenue à nouveau -EditInformationMessage: Bonjour @usershort, votre compte utilisateur a bien été changé. Vous pouvez maintenant vous connecter. +EditGoodbyeSubject: Au revoir +EditGoodbyeMessage: Bonjour @usershort, votre compte utilisateur a bien été supprimé. Prends soin. EditVersionTitle: A propos de ce site EditVersionStatusNone: Datenstrom Yellow est fait pour les gens qui font des sites web. EditVersionStatusCheck: Vérification des mises à jour… diff --git a/system/plugins/language.php b/system/plugins/language.php index cf73e61..11f6d72 100644 --- a/system/plugins/language.php +++ b/system/plugins/language.php @@ -5,7 +5,7 @@ class YellowLanguage { - const VERSION = "0.7.8"; + const VERSION = "0.7.9"; } $yellow->plugins->register("language", "YellowLanguage", YellowLanguage::VERSION); diff --git a/system/plugins/update.php b/system/plugins/update.php index 259f2a8..c2d9b11 100644 --- a/system/plugins/update.php +++ b/system/plugins/update.php @@ -5,7 +5,7 @@ class YellowUpdate { - const VERSION = "0.7.10"; + const VERSION = "0.7.11"; var $yellow; //access to API var $updates; //number of updates @@ -607,7 +607,7 @@ class YellowUpdate if(!empty($email) && !empty($password) && $this->yellow->plugins->isExisting("edit")) { $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $status = $this->yellow->plugins->get("edit")->users->update($fileNameUser, $email, $password, $name, $language) ? "ok" : "error"; + $status = $this->yellow->plugins->get("edit")->users->save($fileNameUser, $email, $password, $name, $language) ? "ok" : "error"; if($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); } }