System update (brave new world)

This commit is contained in:
markseu 2016-04-12 15:58:56 +02:00
parent 608f411a4c
commit 35573ecd90
12 changed files with 889 additions and 259 deletions

View file

@ -1,7 +1,6 @@
---
Title: Home
---
Your website works!
You can now [edit this page] or use your text editor.
For more information see [Yellow help](http://developers.datenstrom.se/help/).
---
Title: Home
---
Your website works!
You can now [edit this page] or use your text editor.

View file

@ -1,6 +1,4 @@
---
Title: About
Title: About
---
A new website.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna pizza. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

View file

@ -2,6 +2,7 @@
Sitename: Yellow
Author: Yellow
Email: postmaster
Language: en
Theme: flatsite
@ -42,7 +43,9 @@ Siteicon: icon
Parser: markdown
ParserSafeMode: 0
MultiLanguageMode: 0
InstallationMode: 1
WebinterfaceLocation: /edit/
WebinterfaceUserPasswordMinLength: 4
WebinterfaceUserHashAlgorithm: bcrypt
WebinterfaceUserHashCost: 10
WebinterfaceUserHome: /

View file

@ -5,7 +5,7 @@
// Command line plugin
class YellowCommandline
{
const Version = "0.6.8";
const Version = "0.6.9";
var $yellow; //access to API
var $files; //number of files
var $errors; //number of errors
@ -94,8 +94,13 @@ class YellowCommandline
} else {
$statusCode = 500;
$this->files = 0; $this->errors = 1;
$fileName = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
echo "ERROR building files: Please configure ServerScheme, ServerName, ServerBase, ServerTime in file '$fileName'!\n";
if($this->yellow->config->get("installationMode"))
{
echo "ERROR building files: Please open your website in a web browser to detect server settings!\n";
} else {
$fileName = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
echo "ERROR building files: Please configure ServerScheme, ServerName, ServerBase, ServerTime in file '$fileName'!\n";
}
}
echo "Yellow $command: $this->files file".($this->files!=1 ? 's' : '');
echo ", $this->errors error".($this->errors!=1 ? 's' : '');
@ -332,10 +337,11 @@ class YellowCommandline
// Check static configuration
function checkStaticConfig()
{
$installationMode = $this->yellow->config->get("installationMode");
$serverScheme = $this->yellow->config->get("serverScheme");
$serverName = $this->yellow->config->get("serverName");
$serverBase = $this->yellow->config->get("serverBase");
return !empty($serverScheme) && !empty($serverName) &&
return !$installationMode && !empty($serverScheme) && !empty($serverName) &&
$this->yellow->lookup->isValidLocation($serverBase) && $serverBase!="/";
}

View file

@ -5,7 +5,7 @@
// Yellow core
class YellowCore
{
const Version = "0.6.3";
const Version = "0.6.4";
var $page; //current page
var $pages; //pages from file system
var $files; //files from file system
@ -154,7 +154,7 @@ class YellowCore
if($this->isRequestContentDirectory($location))
{
$statusCode = 301;
$location = $this->lookup->isFileLocation($location) ? "$location/" : "/".$this->getRequestLanguage()."/";
$location = $this->lookup->isFileLocation($location) ? "$location/" : "/".$this->getRequestLanguage(true)."/";
$location = $this->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
$this->sendStatus($statusCode, $location);
}
@ -300,9 +300,10 @@ class YellowCore
}
// Return request language
function getRequestLanguage()
function getRequestLanguage($multiLanguage = false)
{
return $this->toolbox->detectBrowserLanguage($this->pages->getLanguages(), $this->config->get("language"));
$languages = $multiLanguage ? $this->pages->getLanguages() : $this->text->getLanguages();
return $this->toolbox->detectBrowserLanguage($languages, $this->config->get("language"));
}
// Return request handler

View file

@ -1,9 +1,9 @@
# Yellow text strings
# Yellow language file
Language: de
LanguageDescription: Deutsch
LanguageAuthor: David Fehrmann
LanguageVersion: 0.6.2
LanguageVersion: 0.6.4
BlogBy: von
BlogFilter: Blog:
@ -29,23 +29,67 @@ SearchQuery: Suche:
SearchResultsNone: Bitte einen Suchbegriff eingeben.
SearchResultsEmpty: Keine Treffer für diese Suchanfrage.
SearchButton: Suchen
WebinterfaceLoginText: Yellow-Anmeldung
WebinterfaceInstallationTitle: Willkommen
WebinterfaceInstallationSitename: Webseite:
WebinterfaceInstallationAuthor: Name:
WebinterfaceInstallationHomePage: ---\nTitle: Home\n---\nDeine Webseite funktioniert!\n\nDu kannst [edit - diese Seite bearbeiten] oder einen Texteditor benutzen.
WebinterfaceLoginTitle: Yellow
WebinterfaceLoginEmail: E-Mail:
WebinterfaceLoginPassword: Kennwort:
WebinterfaceLoginRecover: Kennwort vergessen?
WebinterfaceLoginSignup: Benutzerkonto erstellen?
WebinterfaceLoginButton: Anmelden
WebinterfaceSignupTitle: Benutzerkonto erstellen
WebinterfaceSignupName: Name:
WebinterfaceSignupEmail: E-Mail:
WebinterfaceSignupPassword: Kennwort:
WebinterfaceSignupButton: Erstellen
WebinterfaceSignupStatusNone: Hier kannst du ein neues Benutzerkonto erstellen.
WebinterfaceSignupStatusIncomplete: Bitte alle Felder ausfüllen.
WebinterfaceSignupStatusInvalid: Bitte eine gültige E-Mail angeben.
WebinterfaceSignupStatusWeak: Bitte eine anderes Kennwort angeben.
WebinterfaceSignupStatusNext: Benutzerkonto wird erstellt, bitte überprüfe deine E-Mails.
WebinterfaceRecoverTitle: Kennwort vergessen
WebinterfaceRecoverEmail: E-Mail:
WebinterfaceRecoverPassword: Kennwort:
WebinterfaceRecoverButton: Absenden
WebinterfaceRecoverStatusNone: Kein Problem, du kannst ein neues Kennwort erstellen.
WebinterfaceRecoverStatusInvalid: Bitte eine gültige E-Mail angeben.
WebinterfaceRecoverStatusPassword: Bitte ein neues Kennwort angeben.
WebinterfaceRecoverStatusWeak: Bitte eine anderes Kennwort angeben.
WebinterfaceRecoverStatusNext: Benutzerkonto wird wiederhergestellt, bitte überprüfe deine E-Mails.
WebinterfaceConfirmSubject: Benutzerkonto bestätigen
WebinterfaceConfirmMessage: Hallo @usershort, bitte bestätige dein Benutzerkonto. Klicke auf den folgenden Link.
WebinterfaceConfirmStatusDone: Benutzerkonto wurde bestätigt. Vielen Dank!
WebinterfaceConfirmStatusExpire: Benutzerkonto kann nicht bestätigt werden. Link ist abgelaufen!
WebinterfaceApproveSubject: Benutzerkonto genehmigen
WebinterfaceApproveMessage: Hallo @usershort, bitte genehmige ein neues Benutzerkonto für @useraccount. Klicke auf den folgenden Link.
WebinterfaceApproveStatusDone: Benutzerkonto wurde genehmigt. Vielen Dank!
WebinterfaceApproveStatusExpire: Benutzerkonto kann nicht genehmigt werden. Link ist abgelaufen!
WebinterfaceRecoverSubject: Benutzerkonto wiederherstellen
WebinterfaceRecoverMessage: Hallo @usershort, bitte bestätige dass du dein Kennwort vergessen hast. Klicke auf den folgenden Link.
WebinterfaceRecoverStatusDone: Benutzerkonto wurde wiederhergestellt. Vielen Dank!
WebinterfaceRecoverStatusExpire: Benutzerkonto kann nicht wiederhergestellt werden. Link ist abgelaufen!
WebinterfaceWelcomeSubject: Willkommen
WebinterfaceWelcomeMessage: Hallo @usershort, dein Benutzerkonto wurde erstellt. Viel Spass beim Bearbeiten der Webseite.
WebinterfaceInformationSubject: Willkommen zurück
WebinterfaceInformationMessage: Hallo @usershort, dein Benutzerkonto wurde wiederhergestellt. Viel Spass beim Bearbeiten der Webseite.
WebinterfaceOkButton: Ok
WebinterfaceCancelButton: Abbruch
WebinterfaceCreateButton: Erzeugen
WebinterfaceEditButton: Ändern
WebinterfaceDeleteButton: Löschen
WebinterfaceCancelButton: Abbruch
WebinterfaceEdit: Seite ändern
WebinterfaceCreate: +
WebinterfaceDelete: -
WebinterfaceCreateTitle: Neue Seite
WebinterfaceDeleteTitle: Seite löschen
WebinterfaceMarkdownHelp: Markdown
WebinterfaceUserHelp: Hilfe
WebinterfaceUserHelpUrl: http://developers.datenstrom.se/help/help-de
WebinterfaceUserAccountUrl: http://developers.datenstrom.se/help/how-to-add-a-user-account-de
WebinterfaceUserLogout: Abmelden
WikiFilter: Wiki:
WikiTag: Tags:
WikiSpecialChanges: Letzte Änderungen
YellowUrl: http://datenstrom.se/yellow/yellow-deutsch
YellowUserHelpUrl: http://developers.datenstrom.se/help/help-de
YellowMarkdownHelpUrl: http://developers.datenstrom.se/help/markdown-cheat-sheet-de

View file

@ -1,9 +1,9 @@
# Yellow text strings
# Yellow language file
Language: en
LanguageDescription: English
LanguageAuthor: Mark Seuffert
LanguageVersion: 0.6.2
LanguageVersion: 0.6.4
BlogBy: by
BlogFilter: Blog:
@ -16,7 +16,7 @@ ContactButton: Send message
ContactStatusNone: Say hello. Your feedback is very welcome.
ContactStatusIncomplete: Please fill out all fields.
ContactStatusInvalid: Please enter a valid email.
ContactStatusDone: You have sucessfully sent an email. Thank you!
ContactStatusDone: You have sent an email. Thank you!
ContactStatusError: Email could not be sent, please try again later!
DateMonths: January, February, March, April, May, June, July, August, September, October, November, December
DateWeekdays: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
@ -29,23 +29,67 @@ SearchQuery: Search:
SearchResultsNone: Enter a search term.
SearchResultsEmpty: No results found.
SearchButton: Search
WebinterfaceLoginText: Yellow login
WebinterfaceInstallationTitle: Welcome
WebinterfaceInstallationSitename: Website:
WebinterfaceInstallationAuthor: Name:
WebinterfaceInstallationHomePage: ---\nTitle: Home\n---\nYour website works!\n\nYou can now [edit this page] or use your text editor.
WebinterfaceLoginTitle: Yellow
WebinterfaceLoginEmail: Email:
WebinterfaceLoginPassword: Password:
WebinterfaceLoginRecover: Forgot your password?
WebinterfaceLoginSignup: Create user account?
WebinterfaceLoginButton: Log in
WebinterfaceSignupTitle: Create user account
WebinterfaceSignupName: Name:
WebinterfaceSignupEmail: Email:
WebinterfaceSignupPassword: Password:
WebinterfaceSignupButton: Create
WebinterfaceSignupStatusNone: Here you can create a new user account.
WebinterfaceSignupStatusIncomplete: Please fill out all fields.
WebinterfaceSignupStatusInvalid: Please enter a valid email.
WebinterfaceSignupStatusWeak: Please enter a different password.
WebinterfaceSignupStatusNext: User account will be created, please check your emails.
WebinterfaceRecoverTitle: Forgot your password
WebinterfaceRecoverEmail: Email:
WebinterfaceRecoverPassword: Password:
WebinterfaceRecoverButton: Send
WebinterfaceRecoverStatusNone: No problem, you can create a new password.
WebinterfaceRecoverStatusInvalid: Please enter a valid email.
WebinterfaceRecoverStatusPassword: Please enter a new password.
WebinterfaceRecoverStatusWeak: Please enter a different password.
WebinterfaceRecoverStatusNext: User account will be recovered, please check your emails.
WebinterfaceConfirmSubject: Confirm user account
WebinterfaceConfirmMessage: Hi @usershort, please confirm your user account. Click the following link.
WebinterfaceConfirmStatusDone: User account confirmed. Thank you!
WebinterfaceConfirmStatusExpire: User account can not be confirmed. Link has expired!
WebinterfaceApproveSubject: Approve user account
WebinterfaceApproveMessage: Hi @usershort, please approve a new user account for @useraccount. Click the following link.
WebinterfaceApproveStatusDone: User account approved. Thank you!
WebinterfaceApproveStatusExpire: User account can not be approved. Link has expired!
WebinterfaceRecoverSubject: Recover user account
WebinterfaceRecoverMessage: Hi @usershort, please confirm that you forgot your password. Click the following link.
WebinterfaceRecoverStatusDone: User account recovered. Thank you!
WebinterfaceRecoverStatusExpire: User account can not be recovered. Link has expired!
WebinterfaceWelcomeSubject: Welcome
WebinterfaceWelcomeMessage: Hi @usershort, your user account has been created. Have fun editing the website.
WebinterfaceInformationSubject: Welcome back
WebinterfaceInformationMessage: Hi @usershort, your user account has been recovered. Have fun editing the website.
WebinterfaceOkButton: Ok
WebinterfaceCancelButton: Cancel
WebinterfaceCreateButton: Create
WebinterfaceEditButton: Save
WebinterfaceDeleteButton: Delete
WebinterfaceCancelButton: Cancel
WebinterfaceEdit: Edit page
WebinterfaceCreate: +
WebinterfaceDelete: -
WebinterfaceCreateTitle: New page
WebinterfaceDeleteTitle: Delete page
WebinterfaceMarkdownHelp: Markdown
WebinterfaceUserHelp: Help
WebinterfaceUserHelpUrl: http://developers.datenstrom.se/help/
WebinterfaceUserAccountUrl: http://developers.datenstrom.se/help/how-to-add-a-user-account
WebinterfaceUserLogout: Logout
WikiFilter: Wiki:
WikiTag: Tags:
WikiSpecialChanges: Recent changes
YellowUrl: http://datenstrom.se/yellow
YellowUserHelpUrl: http://developers.datenstrom.se/help/
YellowMarkdownHelpUrl: http://developers.datenstrom.se/help/markdown-cheat-sheet

View file

@ -1,9 +1,9 @@
# Yellow text strings
# Yellow language file
Language: fr
LanguageDescription: Français
LanguageAuthor: Juh Nibreh
LanguageVersion: 0.6.2
LanguageVersion: 0.6.4
BlogBy: par
BlogFilter: Blog:
@ -29,23 +29,67 @@ SearchQuery: Rechercher:
SearchResultsNone: Entrez un mot dans le champ de recherche.
SearchResultsEmpty: Pas de résultats.
SearchButton: Rechercher
WebinterfaceLoginText: Yellow connexion
WebinterfaceInstallationTitle: Bienvenue
WebinterfaceInstallationSitename: Site web:
WebinterfaceInstallationAuthor: Nom:
WebinterfaceInstallationHomePage: ---\nTitle: Home\n---\nVotre site web fonctionne!\n\nVous pouvez [edit - modifier cette page] ou utilisez un éditeur de texte.
WebinterfaceLoginTitle: Yellow
WebinterfaceLoginEmail: Email:
WebinterfaceLoginPassword: Mot de passe:
WebinterfaceLoginRecover: Mot de passe oublié?
WebinterfaceLoginSignup: Créer un compte utilisateur?
WebinterfaceLoginButton: Se connecter
WebinterfaceSignupTitle: Créer un compte utilisateur
WebinterfaceSignupName: Name:
WebinterfaceSignupEmail: Email:
WebinterfaceSignupPassword: Password:
WebinterfaceSignupButton: Create
WebinterfaceSignupStatusNone: Here you can create a new user account.
WebinterfaceSignupStatusIncomplete: Please fill out all fields.
WebinterfaceSignupStatusInvalid: Please enter a valid email.
WebinterfaceSignupStatusWeak: Please enter a different password.
WebinterfaceSignupStatusNext: User account will be created, please check your emails.
WebinterfaceRecoverTitle: Forgot your password
WebinterfaceRecoverEmail: Email:
WebinterfaceRecoverPassword: Password:
WebinterfaceRecoverButton: Send
WebinterfaceRecoverStatusNone: No problem, you can create a new password.
WebinterfaceRecoverStatusInvalid: Please enter a valid email.
WebinterfaceRecoverStatusPassword: Please enter a new password.
WebinterfaceRecoverStatusWeak: Please enter a different password.
WebinterfaceRecoverStatusNext: User account will be recovered, please check your emails.
WebinterfaceConfirmSubject: Confirm user account
WebinterfaceConfirmMessage: Bonjour @usershort, please confirm your user account. Click the following link.
WebinterfaceConfirmStatusDone: User account confirmed. Thank you!
WebinterfaceConfirmStatusExpire: User account can not be confirmed. Link has expired!
WebinterfaceApproveSubject: Approve user account
WebinterfaceApproveMessage: Bonjour @usershort, please approve a new user account for @useraccount. Click the following link.
WebinterfaceApproveStatusDone: User account approved. Thank you!
WebinterfaceApproveStatusExpire: User account can not be approved. Link has expired!
WebinterfaceRecoverSubject: Recover user account
WebinterfaceRecoverMessage: Bonjour @usershort, please confirm that you forgot your password. Click the following link.
WebinterfaceRecoverStatusDone: User account recovered. Thank you!
WebinterfaceRecoverStatusExpire: User account can not be recovered. Link has expired!
WebinterfaceWelcomeSubject: Welcome
WebinterfaceWelcomeMessage: Bonjour @usershort, your user account has been created. Have fun editing the website.
WebinterfaceInformationSubject: Welcome back
WebinterfaceInformationMessage: Bonjour @usershort, your user account has been recovered. Have fun editing the website.
WebinterfaceOkButton: Ok
WebinterfaceCancelButton: Annuler
WebinterfaceCreateButton: Créer
WebinterfaceEditButton: Sauvegarder
WebinterfaceDeleteButton: Supprimer
WebinterfaceCancelButton: Annuler
WebinterfaceEdit: Éditer page
WebinterfaceCreate: +
WebinterfaceDelete: -
WebinterfaceCreateTitle: Nouvelle page
WebinterfaceDeleteTitle: Supprimer page
WebinterfaceMarkdownHelp: Markdown
WebinterfaceUserHelp: Aide
WebinterfaceUserHelpUrl: http://developers.datenstrom.se/help/help-fr
WebinterfaceUserAccountUrl: http://developers.datenstrom.se/help/how-to-add-a-user-account-fr
WebinterfaceUserLogout: Déconnexion
WikiFilter: Wiki:
WikiTag: Tags:
WikiSpecialChanges: Changements récents
YellowUrl: http://datenstrom.se/yellow/yellow-français
YellowUserHelpUrl: http://developers.datenstrom.se/help/help-fr
YellowMarkdownHelpUrl: http://developers.datenstrom.se/help/markdown-cheat-sheet-fr

View file

@ -1,4 +1,4 @@
/* Yellow web interface 0.6.1 */
/* Yellow web interface 0.6.6 */
.yellow-bar { position:relative; overflow:hidden; height:2em; margin-bottom:10px; }
.yellow-bar-left { display:block; float:left; }
@ -54,7 +54,7 @@
}
.yellow-btn {
margin:0; padding:4px 22px;
display:inline-block; min-width:7em;
display:inline-block; min-width:8em;
background-color:#eaeaea; color:#333333;
background-image:linear-gradient(to bottom, #f8f8f8, #e1e1e1);
border:1px solid #bbb;
@ -91,15 +91,34 @@
#yellow-pane-login { text-align:center; white-space:nowrap; }
#yellow-pane-login h1 { margin:0 1em; font-size:2em; }
#yellow-pane-login-status { display:inline-block; }
#yellow-pane-login-fields { width:15em; text-align:left; margin:0 auto; }
#yellow-pane-login input { width:15em; box-sizing:border-box; }
#yellow-pane-login .yellow-btn { width:15em; margin:1em 1em 0.5em 0; }
#yellow-pane-login-fields { width:15em; text-align:left; margin:0 auto; }
#yellow-pane-login-buttons { margin:0.5em 0; }
#yellow-pane-login-buttons p { margin:0; }
#yellow-pane-signup { text-align:center; white-space:nowrap; }
#yellow-pane-signup h1 { margin:0 1em; font-size:2em; }
#yellow-pane-signup input { width:15em; box-sizing:border-box; }
#yellow-pane-signup .yellow-btn { width:15em; margin:1em 1em 0.5em 0; }
#yellow-pane-signup-status { margin:0.5em 0; display:inline-block; }
#yellow-pane-signup-fields { width:15em; text-align:left; margin:0 auto; }
#yellow-pane-signup-buttons { margin-top:-0.5em; }
#yellow-pane-recover { text-align:center; white-space:nowrap; }
#yellow-pane-recover h1 { margin:0 1em; font-size:2em; }
#yellow-pane-recover input { width:15em; box-sizing:border-box; }
#yellow-pane-recover .yellow-btn { width:15em; margin:1em 1em 0.5em 0; }
#yellow-pane-recover-status { margin:0.5em 0; display:inline-block; }
#yellow-pane-recover-fields-first, #yellow-pane-recover-fields-second { width:15em; text-align:left; margin:0 auto; }
#yellow-pane-recover-buttons { margin-top:-0.5em; }
#yellow-pane-edit { }
#yellow-pane-edit h1 { margin:0 0 10px 0; font-size:1.5em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#yellow-pane-edit-page { padding:5px; outline:none; resize:none; }
#yellow-pane-edit-buttons { margin-top:5px; }
#yellow-pane-edit-buttons input { margin-right:10px; }
#yellow-pane-edit-help { float:right; }
#yellow-pane-user { cursor:pointer; }
#yellow-pane-user a { text-decoration:none; }
#yellow-pane-user a:hover { text-decoration:underline; }

View file

@ -1,14 +1,14 @@
// Copyright (c) 2013-2015 Datenstrom, http://datenstrom.se
// Copyright (c) 2013-2016 Datenstrom, http://datenstrom.se
// This file may be used and distributed under the terms of the public license.
// Yellow API
var yellow =
{
version: "0.6.1",
version: "0.6.6",
action: function(text) { yellow.webinterface.action(text); },
onClick: function(e) { yellow.webinterface.hidePanesOnClick(yellow.toolbox.getEventElement(e)); },
onKeydown: function(e) { yellow.webinterface.hidePanesOnKeydown(yellow.toolbox.getEventKeycode(e)); },
onResize: function() { yellow.webinterface.resizePanes(); },
onResize: function() { yellow.webinterface.resizePane(yellow.webinterface.paneId); },
onUpdate: function() { yellow.webinterface.updatePane(yellow.webinterface.paneId, yellow.webinterface.paneType); },
webinterface:{}, toolbox:{}, page:{}, config:{}, text:{}
}
@ -50,7 +50,9 @@ yellow.webinterface =
} else {
this.createBar("yellow-bar", false, body.firstChild);
this.createPane("yellow-pane-login", false, body.firstChild);
if(yellow.config.login) this.showPane("yellow-pane-login");
this.createPane("yellow-pane-signup", false, body.firstChild);
this.createPane("yellow-pane-recover", false, body.firstChild);
yellow.action(yellow.page.loginAction);
}
}
clearInterval(this.intervalId);
@ -62,14 +64,18 @@ yellow.webinterface =
{
switch(text)
{
case "create": this.togglePane("yellow-pane-edit", "create", true); break;
case "edit": this.togglePane("yellow-pane-edit", "edit", true); break;
case "delete": this.togglePane("yellow-pane-edit", "delete", true); break;
case "user": this.togglePane("yellow-pane-user"); break;
case "send": this.sendPane(this.paneId, this.paneType); break;
case "cancel": this.hidePane(this.paneId); break;
case "login": this.togglePane("yellow-pane-login"); break;
case "logout": yellow.toolbox.submitForm({"action":"logout"}); break;
case "login": this.togglePane("yellow-pane-login"); break;
case "logout": yellow.toolbox.submitForm({"action":"logout"}); break;
case "signup": this.togglePane("yellow-pane-signup", "signup"); break;
case "confirm": this.togglePane("yellow-pane-signup", "confirm"); break;
case "approve": this.togglePane("yellow-pane-signup", "approve"); break;
case "recover": this.togglePane("yellow-pane-recover", "recover"); break;
case "create": this.togglePane("yellow-pane-edit", "create", true); break;
case "edit": this.togglePane("yellow-pane-edit", "edit", true); break;
case "delete": this.togglePane("yellow-pane-edit", "delete", true); break;
case "user": this.togglePane("yellow-pane-user"); break;
case "send": this.sendPane(this.paneId, this.paneType); break;
case "close": this.hidePane(this.paneId); break;
}
},
@ -116,14 +122,54 @@ yellow.webinterface =
{
elementDiv.innerHTML =
"<form method=\"post\">"+
"<a href=\"#\" onclick=\"yellow.action('cancel'); return false;\" class=\"yellow-cancel\">x</a>"+
"<h1>"+this.getText("LoginText")+"</h1>"+
"<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-cancel\">x</a>"+
"<h1>"+this.getText("LoginTitle")+"</h1>"+
"<div id=\"yellow-pane-login-fields\">"+
"<input type=\"hidden\" name=\"action\" value=\"login\" />"+
"<p><label for=\"email\">"+this.getText("LoginEmail")+"</label><br /><input class=\"yellow-form-control\" name=\"email\" id=\"email\" maxlength=\"64\" value=\""+yellow.config.loginEmail+"\" /></p>"+
"<p><label for=\"password\">"+this.getText("LoginPassword")+"</label><br /><input class=\"yellow-form-control\" type=\"password\" name=\"password\" id=\"password\" maxlength=\"64\" value=\""+yellow.config.loginPassword+"\" /></p>"+
"<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("LoginButton")+"\" /></p>"+
"</div>"+
"<div id=\"yellow-pane-login-buttons\">"+
"<p><a href=\"#\" onclick=\"yellow.action('recover'); return false;\">"+this.getText("LoginRecover")+"</a><p>"+
"<p><a href=\"#\" onclick=\"yellow.action('signup'); return false;\">"+this.getText("LoginSignup")+"</a><p>"+
"</div>"+
"</form>";
} else if(paneId == "yellow-pane-signup") {
elementDiv.innerHTML =
"<form method=\"post\">"+
"<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-cancel\">x</a>"+
"<h1>"+this.getText("SignupTitle")+"</h1>"+
"<div id=\"yellow-pane-signup-status\" class=\""+yellow.page.loginStatus+"\">"+this.getText("SignupStatus", "", yellow.page.loginStatus)+"</div>"+
"<div id=\"yellow-pane-signup-fields\">"+
"<input type=\"hidden\" name=\"action\" value=\"signup\" />"+
"<p><label for=\"name\">"+this.getText("SignupName")+"</label><br /><input class=\"yellow-form-control\" name=\"name\" id=\"name\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("Name"))+"\" /></p>"+
"<p><label for=\"email\">"+this.getText("SignupEmail")+"</label><br /><input class=\"yellow-form-control\" name=\"email\" id=\"email\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("Email"))+"\" /></p>"+
"<p><label for=\"password\">"+this.getText("SignupPassword")+"</label><br /><input class=\"yellow-form-control\" type=\"password\" name=\"password\" id=\"password\" maxlength=\"64\" value=\"\" /></p>"+
"<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("SignupButton")+"\" /></p>"+
"</div>"+
"<div id=\"yellow-pane-signup-buttons\">"+
"<p><input class=\"yellow-btn\" type=\"button\" onclick=\"yellow.action('close'); return false;\" value=\""+this.getText("OkButton")+"\" /></p>"+
"</div>"+
"</form>";
} else if(paneId == "yellow-pane-recover") {
elementDiv.innerHTML =
"<form method=\"post\">"+
"<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-cancel\">x</a>"+
"<h1>"+this.getText("RecoverTitle")+"</h1>"+
"<div id=\"yellow-pane-recover-status\" class=\""+yellow.page.loginStatus+"\">"+this.getText("RecoverStatus", "", yellow.page.loginStatus)+"</div>"+
"<div id=\"yellow-pane-recover-fields-first\">"+
"<input type=\"hidden\" name=\"action\" value=\"recover\" />"+
"<p><label for=\"email\">"+this.getText("RecoverEmail")+"</label><br /><input class=\"yellow-form-control\" name=\"email\" id=\"email\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("Email"))+"\" /></p>"+
"<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("RecoverButton")+"\" /></p>"+
"</div>"+
"<div id=\"yellow-pane-recover-fields-second\">"+
"<p><label for=\"password\">"+this.getText("RecoverPassword")+"</label><br /><input class=\"yellow-form-control\" type=\"password\" name=\"password\" id=\"password\" maxlength=\"64\" value=\"\" /></p>"+
"<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("RecoverButton")+"\" /></p>"+
"</div>"+
"<div id=\"yellow-pane-recover-buttons\">"+
"<p><input class=\"yellow-btn\" type=\"button\" onclick=\"yellow.action('close'); return false;\" value=\""+this.getText("OkButton")+"\" /></p>"+
"</div>"+
"</form>";
} else if(paneId == "yellow-pane-edit") {
elementDiv.innerHTML =
@ -132,13 +178,14 @@ yellow.webinterface =
"<textarea id=\"yellow-pane-edit-page\" class=\"yellow-form-control\" name=\"rawdataedit\"></textarea>"+
"<div id=\"yellow-pane-edit-buttons\">"+
"<input id=\"yellow-pane-edit-send\" class=\"yellow-btn\" type=\"button\" onclick=\"yellow.action('send'); return false;\" value=\""+this.getText("EditButton")+"\" />"+
"<input id=\"yellow-pane-edit-cancel\" class=\"yellow-btn\" type=\"button\" onclick=\"yellow.action('cancel'); return false;\" value=\""+this.getText("CancelButton")+"\" />"+
"<input id=\"yellow-pane-edit-close\" class=\"yellow-btn\" type=\"button\" onclick=\"yellow.action('close'); return false;\" value=\""+this.getText("CancelButton")+"\" />"+
"<a href=\""+this.getText("MarkdownHelpUrl", "yellow")+"\" target=\"_blank\" id=\"yellow-pane-edit-help\">"+this.getText("MarkdownHelp")+"</a>" +
"</div>"+
"</form>";
} else if(paneId == "yellow-pane-user") {
elementDiv.innerHTML =
"<p>"+yellow.config.userEmail+"</p>"+
"<p><a href=\""+this.getText("UserHelpUrl")+"\" onclick=\"yellow.action('user'); return true;\">"+this.getText("UserHelp")+"</a></p>" +
"<p><a href=\""+this.getText("UserHelpUrl", "yellow")+"\" onclick=\"yellow.action('user'); return true;\">"+this.getText("UserHelp")+"</a></p>" +
"<p><a href=\"#\" onclick=\"yellow.action('logout'); return false;\">"+this.getText("UserLogout")+"</a></p>";
}
elementPane.appendChild(elementDiv);
@ -149,8 +196,41 @@ yellow.webinterface =
updatePane: function(paneId, paneType, init)
{
if(yellow.debug) console.log("yellow.webinterface.updatePane id:"+paneId);
if(paneId == "yellow-pane-edit")
if(paneId == "yellow-pane-login")
{
if(!yellow.config.loginExtra)
{
document.getElementById("yellow-pane-login-buttons").style.display = "none";
}
} else if(paneId == "yellow-pane-signup") {
switch(paneType)
{
case "signup": text = this.getText("SignupStatus", "", yellow.page.loginStatus); break;
case "confirm": text = this.getText("ConfirmStatus", "", yellow.page.loginStatus); break;
case "approve": text = this.getText("ApproveStatus", "", yellow.page.loginStatus); break;
}
document.getElementById("yellow-pane-signup-status").innerHTML = yellow.toolbox.encodeHtml(text);
if(yellow.page.loginStatus=="next" || yellow.page.loginStatus=="done" || yellow.page.loginStatus=="expire")
{
document.getElementById("yellow-pane-signup-fields").style.display = "none";
} else {
document.getElementById("yellow-pane-signup-buttons").style.display = "none";
}
} else if(paneId == "yellow-pane-recover") {
if(yellow.page.loginStatus=="next" || yellow.page.loginStatus=="done" || yellow.page.loginStatus=="expire")
{
document.getElementById("yellow-pane-recover-fields-first").style.display = "none";
document.getElementById("yellow-pane-recover-fields-second").style.display = "none";
} else {
document.getElementById("yellow-pane-recover-buttons").style.display = "none";
if(this.getRequest("Id"))
{
document.getElementById("yellow-pane-recover-fields-first").style.display = "none";
} else {
document.getElementById("yellow-pane-recover-fields-second").style.display = "none";
}
}
} else if(paneId == "yellow-pane-edit") {
if(init)
{
var title = yellow.page.title;
@ -229,7 +309,7 @@ yellow.webinterface =
}
this.paneId = paneId;
this.paneType = paneType;
this.resizePanes();
this.resizePane(paneId);
this.updatePane(paneId, paneType, true);
}
},
@ -280,8 +360,8 @@ yellow.webinterface =
if(keycode == 27) this.hidePanes();
},
// Resize panes, recalculate width and height where needed
resizePanes: function()
// Resize panes where needed
resizePane: function(paneId)
{
if(document.getElementById("yellow-bar"))
{
@ -289,37 +369,39 @@ yellow.webinterface =
var paneTop = yellow.toolbox.getOuterTop(elementBar) + yellow.toolbox.getOuterHeight(elementBar);
var paneWidth = yellow.toolbox.getOuterWidth(elementBar, true);
var paneHeight = yellow.toolbox.getWindowHeight() - paneTop - yellow.toolbox.getOuterHeight(elementBar);
if(yellow.toolbox.isVisible(document.getElementById("yellow-pane-login")))
switch(paneId)
{
yellow.toolbox.setOuterTop(document.getElementById("yellow-pane-login"), paneTop);
yellow.toolbox.setOuterWidth(document.getElementById("yellow-pane-login"), paneWidth);
case "yellow-pane-login":
case "yellow-pane-signup":
case "yellow-pane-recover":
yellow.toolbox.setOuterTop(document.getElementById(paneId), paneTop);
yellow.toolbox.setOuterWidth(document.getElementById(paneId), paneWidth);
break;
case "yellow-pane-edit":
yellow.toolbox.setOuterTop(document.getElementById("yellow-pane-edit"), paneTop);
yellow.toolbox.setOuterHeight(document.getElementById("yellow-pane-edit"), paneHeight);
yellow.toolbox.setOuterWidth(document.getElementById("yellow-pane-edit"), paneWidth);
yellow.toolbox.setOuterWidth(document.getElementById("yellow-pane-edit-page"), yellow.toolbox.getWidth(document.getElementById("yellow-pane-edit")));
var height1 = yellow.toolbox.getHeight(document.getElementById("yellow-pane-edit"));
var height2 = yellow.toolbox.getOuterHeight(document.getElementById("yellow-pane-edit-content"));
var height3 = yellow.toolbox.getOuterHeight(document.getElementById("yellow-pane-edit-page"));
yellow.toolbox.setOuterHeight(document.getElementById("yellow-pane-edit-page"), height1 - height2 + height3);
var elementLink = document.getElementById("yellow-pane-"+this.paneType+"-link");
var position = yellow.toolbox.getOuterLeft(elementLink) + yellow.toolbox.getOuterWidth(elementLink)/2;
position -= yellow.toolbox.getOuterLeft(document.getElementById("yellow-pane-edit")) + 1;
yellow.toolbox.setOuterLeft(document.getElementById("yellow-pane-edit-arrow"), position);
break;
case "yellow-pane-user":
yellow.toolbox.setOuterTop(document.getElementById("yellow-pane-user"), paneTop);
yellow.toolbox.setOuterHeight(document.getElementById("yellow-pane-user"), paneHeight, true);
yellow.toolbox.setOuterLeft(document.getElementById("yellow-pane-user"), paneWidth - yellow.toolbox.getOuterWidth(document.getElementById("yellow-pane-user")), true);
var elementLink = document.getElementById("yellow-pane-user-link");
var position = yellow.toolbox.getOuterLeft(elementLink) + yellow.toolbox.getOuterWidth(elementLink)/2;
position -= yellow.toolbox.getOuterLeft(document.getElementById("yellow-pane-user"));
yellow.toolbox.setOuterLeft(document.getElementById("yellow-pane-user-arrow"), position);
break;
}
if(yellow.toolbox.isVisible(document.getElementById("yellow-pane-edit")))
{
yellow.toolbox.setOuterTop(document.getElementById("yellow-pane-edit"), paneTop);
yellow.toolbox.setOuterHeight(document.getElementById("yellow-pane-edit"), paneHeight);
yellow.toolbox.setOuterWidth(document.getElementById("yellow-pane-edit"), paneWidth);
yellow.toolbox.setOuterWidth(document.getElementById("yellow-pane-edit-page"), yellow.toolbox.getWidth(document.getElementById("yellow-pane-edit")));
var height1 = yellow.toolbox.getHeight(document.getElementById("yellow-pane-edit"));
var height2 = yellow.toolbox.getOuterHeight(document.getElementById("yellow-pane-edit-content"));
var height3 = yellow.toolbox.getOuterHeight(document.getElementById("yellow-pane-edit-page"));
yellow.toolbox.setOuterHeight(document.getElementById("yellow-pane-edit-page"), height1 - height2 + height3);
var elementLink = document.getElementById("yellow-pane-"+this.paneType+"-link");
var position = yellow.toolbox.getOuterLeft(elementLink) + yellow.toolbox.getOuterWidth(elementLink)/2;
position -= yellow.toolbox.getOuterLeft(document.getElementById("yellow-pane-edit")) + 1;
yellow.toolbox.setOuterLeft(document.getElementById("yellow-pane-edit-arrow"), position);
}
if(yellow.toolbox.isVisible(document.getElementById("yellow-pane-user")))
{
yellow.toolbox.setOuterTop(document.getElementById("yellow-pane-user"), paneTop);
yellow.toolbox.setOuterHeight(document.getElementById("yellow-pane-user"), paneHeight, true);
yellow.toolbox.setOuterLeft(document.getElementById("yellow-pane-user"), paneWidth - yellow.toolbox.getOuterWidth(document.getElementById("yellow-pane-user")), true);
var elementLink = document.getElementById("yellow-pane-user-link");
var position = yellow.toolbox.getOuterLeft(elementLink) + yellow.toolbox.getOuterWidth(elementLink)/2;
position -= yellow.toolbox.getOuterLeft(document.getElementById("yellow-pane-user"));
yellow.toolbox.setOuterLeft(document.getElementById("yellow-pane-user-arrow"), position);
}
if(yellow.debug) console.log("yellow.webinterface.resizePanes bar:"+elementBar.offsetWidth+"/"+elementBar.offsetHeight);
if(yellow.debug) console.log("yellow.webinterface.resizePane bar:"+elementBar.offsetWidth+"/"+elementBar.offsetHeight);
}
},
@ -329,7 +411,7 @@ yellow.webinterface =
var action = "";
if(paneId == "yellow-pane-edit")
{
if(yellow.page.userPermission)
if(!yellow.page.userRestrictions)
{
var string = document.getElementById("yellow-pane-edit-page").value;
switch(paneType)
@ -343,11 +425,22 @@ yellow.webinterface =
}
return action;
},
// Return text string
getText: function(key)
// Return request string
getRequest: function(key, prefix)
{
return ("webinterface"+key in yellow.text) ? yellow.text["webinterface"+key] : "[webinterface"+key+"]";
if(!prefix) prefix = "request";
key = prefix + key;
return (key in yellow.page) ? yellow.page[key] : "";
},
// Return text string
getText: function(key, prefix, postfix)
{
if(!prefix) prefix = "webinterface";
if(!postfix) postfix = ""
key = prefix + key + postfix.charAt(0).toUpperCase() + postfix.slice(1);
return (key in yellow.text) ? yellow.text[key] : "["+key+"]";
}
}

View file

@ -5,11 +5,12 @@
// Web interface plugin
class YellowWebinterface
{
const Version = "0.6.5";
const Version = "0.6.6";
var $yellow; //access to API
var $active; //web interface is active? (boolean)
var $userLoginFailed; //web interface login failed? (boolean)
var $userPermission; //web interface can change page? (boolean)
var $loginAction; //web interface login action
var $loginStatus; //web interface login status
var $userRestrictions; //web interface user can change page? (boolean)
var $users; //web interface users
var $merge; //web interface merge
var $rawDataSource; //raw data of page for comparison
@ -24,8 +25,10 @@ class YellowWebinterface
$this->yellow->config->setDefault("webinterfaceServerScheme", $this->yellow->config->get("serverScheme"));
$this->yellow->config->setDefault("webinterfaceServerName", $this->yellow->config->get("serverName"));
$this->yellow->config->setDefault("webinterfaceLocation", "/edit/");
$this->yellow->config->setDefault("webinterfaceUserPasswordMinLength", "4");
$this->yellow->config->setDefault("webinterfaceUserHashAlgorithm", "bcrypt");
$this->yellow->config->setDefault("webinterfaceUserHashCost", "10");
$this->yellow->config->setDefault("webinterfaceUserStatus", "active");
$this->yellow->config->setDefault("webinterfaceUserHome", "/");
$this->yellow->config->setDefault("webinterfaceUserFile", "user.ini");
$this->yellow->config->setDefault("webinterfaceNewFile", "page-new-(.*).txt");
@ -58,9 +61,9 @@ class YellowWebinterface
// Handle page meta data parsing
function onParseMeta($page)
{
if($this->isActive() && $this->isUser())
if($this->isActive() && $page==$this->yellow->page)
{
if($page == $this->yellow->page)
if($this->isUser())
{
if(empty($this->rawDataSource)) $this->rawDataSource = $page->rawData;
if(empty($this->rawDataEdit)) $this->rawDataEdit = $page->rawData;
@ -69,6 +72,10 @@ class YellowWebinterface
$title = $this->yellow->toolbox->createTextTitle($page->location);
$this->rawDataEdit = $this->getRawDataNew($title);
}
} else {
if(empty($this->loginAction)) $this->loginAction = "login";
if(empty($this->loginStatus)) $this->loginStatus = "none";
if($this->loginStatus == "error") $this->loginAction = "error";
}
}
}
@ -92,20 +99,17 @@ class YellowWebinterface
$output = NULL;
if($this->isActive() && $name=="header")
{
if($this->users->getNumber())
{
$location = $this->yellow->config->get("serverBase").$this->yellow->config->get("pluginLocation")."webinterface";
$output = "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"".htmlspecialchars($location).".css\" />\n";
$output .= "<script type=\"text/javascript\" src=\"".htmlspecialchars($location).".js\"></script>\n";
$output .= "<script type=\"text/javascript\">\n";
$output .= "// <![CDATA[\n";
$output .= "yellow.page = ".json_encode($this->getPageData()).";\n";
$output .= "yellow.config = ".json_encode($this->getConfigData()).";\n";
$output .= "yellow.text = ".json_encode($this->getTextData()).";\n";
if(defined("DEBUG") && DEBUG>=1) $output .= "yellow.debug = ".json_encode(DEBUG).";\n";
$output .= "// ]]>\n";
$output .= "</script>\n";
}
$location = $this->yellow->config->get("serverBase").$this->yellow->config->get("pluginLocation")."webinterface";
$output = "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"".htmlspecialchars($location).".css\" />\n";
$output .= "<script type=\"text/javascript\" src=\"".htmlspecialchars($location).".js\"></script>\n";
$output .= "<script type=\"text/javascript\">\n";
$output .= "// <![CDATA[\n";
$output .= "yellow.page = ".json_encode($this->getPageData()).";\n";
$output .= "yellow.config = ".json_encode($this->getConfigData()).";\n";
$output .= "yellow.text = ".json_encode($this->getTextData()).";\n";
if(defined("DEBUG") && DEBUG>=1) $output .= "yellow.debug = ".json_encode(DEBUG).";\n";
$output .= "// ]]>\n";
$output .= "</script>\n";
}
return $output;
}
@ -135,20 +139,28 @@ class YellowWebinterface
list($dummy, $command, $email, $password, $name, $language, $status, $home) = $args;
if(!empty($email) && !empty($password))
{
$fileName = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile");
$algorithm = $this->yellow->config->get("webinterfaceUserHashAlgorithm");
$cost = $this->yellow->config->get("webinterfaceUserHashCost");
$hash = $this->yellow->toolbox->createHash($password, $algorithm, $cost);
if(empty($hash))
$userExisting = $this->users->isExisting($email);
$status = $this->getUserAccount($email, $password, $command);
switch($status)
{
$statusCode = 500;
echo "ERROR creating hash: Algorithm '$algorithm' not supported!\n";
} else {
$statusCode = $this->users->createUser($fileName, $email, $hash, $name, $language, $status, $home) ? 200 : 500;
if($statusCode != 200) echo "ERROR updating configuration: Can't write file '$fileName'!\n";
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("webinterfaceUserFile");
$status = $this->users->update($fileNameUser, $email, $password, $name, $language, $status, $home) ? "ok" : "error";
if($status == "error") echo "ERROR updating configuration: Can't write file '$fileNameUser'!\n";
}
if($status == "ok")
{
$algorithm = $this->yellow->config->get("webinterfaceUserHashAlgorithm");
$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 ($this->users->isExisting($email) ? "updated" : "created")."\n";
echo ($userExisting ? "updated" : "created")."\n";
} else {
$statusCode = 200;
foreach($this->getUserData() as $line) echo "$line\n";
@ -161,28 +173,36 @@ class YellowWebinterface
function processRequest($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if($this->checkUser($location, $fileName))
if($this->isActive() && $this->checkUser($location, $fileName))
{
switch($_POST["action"])
switch($_REQUEST["action"])
{
case "": $statusCode = $this->processRequestShow($serverScheme, $serverName, $base, $location, $fileName); break;
case "create": $statusCode = $this->processRequestCreate($serverScheme, $serverName, $base, $location, $fileName); break;
case "edit": $statusCode = $this->processRequestEdit($serverScheme, $serverName, $base, $location, $fileName); break;
case "delete": $statusCode = $this->processRequestDelete($serverScheme, $serverName, $base, $location, $fileName); break;
case "login": $statusCode = $this->processRequestLogin($serverScheme, $serverName, $base, $location, $fileName); break;
case "logout": $statusCode = $this->processRequestLogout($serverScheme, $serverName, $base, $location, $fileName); break;
case "": $statusCode = $this->processRequestShow($serverScheme, $serverName, $base, $location, $fileName); break;
case "login": $statusCode = $this->processRequestLogin($serverScheme, $serverName, $base, $location, $fileName); break;
case "logout": $statusCode = $this->processRequestLogout($serverScheme, $serverName, $base, $location, $fileName); break;
case "signup": $statusCode = $this->processRequestSignup($serverScheme, $serverName, $base, $location, $fileName); break;
case "confirm": $statusCode = $this->processRequestConfirm($serverScheme, $serverName, $base, $location, $fileName); break;
case "approve": $statusCode = $this->processRequestApprove($serverScheme, $serverName, $base, $location, $fileName); break;
case "recover": $statusCode = $this->processRequestRecover($serverScheme, $serverName, $base, $location, $fileName); break;
case "create": $statusCode = $this->processRequestCreate($serverScheme, $serverName, $base, $location, $fileName); break;
case "edit": $statusCode = $this->processRequestEdit($serverScheme, $serverName, $base, $location, $fileName); break;
case "delete": $statusCode = $this->processRequestDelete($serverScheme, $serverName, $base, $location, $fileName); break;
case "install": $statusCode = $this->processRequestInstall($serverScheme, $serverName, $base, $location, $fileName); break;
}
} else {
switch($_REQUEST["action"])
{
case "signup": $statusCode = $this->processRequestSignup($serverScheme, $serverName, $base, $location, $fileName); break;
case "confirm": $statusCode = $this->processRequestConfirm($serverScheme, $serverName, $base, $location, $fileName); break;
case "approve": $statusCode = $this->processRequestApprove($serverScheme, $serverName, $base, $location, $fileName); break;
case "recover": $statusCode = $this->processRequestRecover($serverScheme, $serverName, $base, $location, $fileName); break;
case "install": $statusCode = $this->processRequestInstall($serverScheme, $serverName, $base, $location, $fileName); break;
}
}
if($statusCode == 0)
{
$statusCode = $this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
if($this->users->getNumber())
{
if($this->userLoginFailed) $this->yellow->page->error(500, "Login failed, [please log in](javascript:yellow.action('login');)!");
} else {
$url = $this->yellow->text->get("webinterfaceUserAccountUrl");
$this->yellow->page->error(500, "You are not authorised on this server, [please add a user account]($url)!");
}
if($this->loginAction == "fail") $this->yellow->page->error(500, "Login failed, [please log in](javascript:yellow.action('login');)!");
}
return $statusCode;
}
@ -202,7 +222,7 @@ class YellowWebinterface
$location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = $this->userPermission ? 424 : 404;
$statusCode = $this->userRestrictions ? 404 : 424;
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
$this->yellow->page->error($statusCode);
}
@ -210,14 +230,158 @@ class YellowWebinterface
return $statusCode;
}
// Process request for user login
function processRequestLogin($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
$home = $this->users->getHome();
if(substru($location, 0, strlenu($home)) == $home)
{
$statusCode = 303;
$location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = 302;
$location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $home);
$this->yellow->sendStatus($statusCode, $location);
}
return $statusCode;
}
// Process request for user logout
function processRequestLogout($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 302;
$this->users->destroyCookie("login");
$this->users->email = "";
$location = $this->yellow->lookup->normaliseUrl(
$this->yellow->config->get("serverScheme"),
$this->yellow->config->get("serverName"),
$this->yellow->config->get("serverBase"), $location);
$this->yellow->sendStatus($statusCode, $location);
return $statusCode;
}
// Process request for user signup
function processRequestSignup($serverScheme, $serverName, $base, $location, $fileName)
{
$this->loginAction = "signup";
$this->loginStatus = "ok";
$name = trim(preg_replace("/[^\pL\d\-\. ]/u", "-", $_REQUEST["name"]));
$email = trim($_REQUEST["email"]);
$password = trim($_REQUEST["password"]);
if(empty($name) || empty($email) || empty($password)) $this->loginStatus = "incomplete";
if($this->loginStatus == "ok") $this->loginStatus = $this->getUserAccount($email, $password, $this->loginAction);
if($this->loginStatus == "ok" && !$this->isExtra()) $this->loginStatus = "next";
if($this->loginStatus == "ok" && $this->users->isExisting($email)) $this->loginStatus = "next";
if($this->loginStatus == "ok")
{
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile");
$this->loginStatus = $this->users->update($fileNameUser, $email, $password, $name, "", "unconfirmed") ? "ok" : "error";
if($this->loginStatus == "error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
if($this->loginStatus == "ok")
{
$this->loginStatus = $this->sendMail($serverScheme, $serverName, $base, $email, "confirm") ? "next" : "error";
if($this->loginStatus == "error") $this->yellow->page->error(500, "Can't send email on this server!");
}
$statusCode = $this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
return $statusCode;
}
// Process request to confirm user signup
function processRequestConfirm($serverScheme, $serverName, $base, $location, $fileName)
{
$this->loginAction = "confirm";
$this->loginStatus = "ok";
$email = $_REQUEST["email"];
$this->loginStatus = $this->getUserRequest($email, $_REQUEST["action"], $_REQUEST["expire"], $_REQUEST["id"]);
if($this->loginStatus == "ok")
{
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile");
$this->loginStatus = $this->users->update($fileNameUser, $email, "", "", "", "unapproved") ? "ok" : "error";
if($this->loginStatus == "error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
if($this->loginStatus == "ok")
{
$this->loginStatus = $this->sendMail($serverScheme, $serverName, $base, $email, "approve") ? "done" : "error";
if($this->loginStatus == "error") $this->yellow->page->error(500, "Can't send email on this server!");
}
$statusCode = $this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
return $statusCode;
}
// Process request to approve user signup
function processRequestApprove($serverScheme, $serverName, $base, $location, $fileName)
{
$this->loginAction = "approve";
$this->loginStatus = "ok";
$email = $_REQUEST["email"];
$this->loginStatus = $this->getUserRequest($email, $_REQUEST["action"], $_REQUEST["expire"], $_REQUEST["id"]);
if($this->loginStatus == "ok")
{
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile");
$this->loginStatus = $this->users->update($fileNameUser, $email, "", "", "", "active") ? "ok" : "error";
if($this->loginStatus == "error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
if($this->loginStatus == "ok")
{
$this->loginStatus = $this->sendMail($serverScheme, $serverName, $base, $email, "welcome") ? "done" : "error";
if($this->loginStatus == "error") $this->yellow->page->error(500, "Can't send email on this server!");
}
$statusCode = $this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
return $statusCode;
}
// Process request to recover password
function processRequestRecover($serverScheme, $serverName, $base, $location, $fileName)
{
$this->loginAction = "recover";
$this->loginStatus = "ok";
$email = trim($_REQUEST["email"]);
$password = trim($_REQUEST["password"]);
if(empty($_REQUEST["id"]))
{
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) $this->loginStatus = "invalid";
if($this->loginStatus == "ok" && !$this->isExtra()) $this->loginStatus = "next";
if($this->loginStatus == "ok" && !$this->users->isExisting($email)) $this->loginStatus = "next";
if($this->loginStatus == "ok")
{
$this->loginStatus = $this->sendMail($serverScheme, $serverName, $base, $email, "recover") ? "next" : "error";
if($this->loginStatus == "error") $this->yellow->page->error(500, "Can't send email on this server!");
}
} else {
$this->loginStatus = $this->getUserRequest($email, $_REQUEST["action"], $_REQUEST["expire"], $_REQUEST["id"]);
if($this->loginStatus == "ok")
{
if(empty($password)) $this->loginStatus = "password";
if($this->loginStatus == "ok") $this->loginStatus = $this->getUserAccount($email, $password, $this->loginAction);
if($this->loginStatus == "ok")
{
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile");
$this->loginStatus = $this->users->update($fileNameUser, $email, $password) ? "ok" : "error";
if($this->loginStatus == "error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
if($this->loginStatus == "ok")
{
$this->loginStatus = $this->sendMail($serverScheme, $serverName, $base, $email, "information") ? "done" : "error";
if($this->loginStatus == "error") $this->yellow->page->error(500, "Can't send email on this server!");
}
}
}
$statusCode = $this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
return $statusCode;
}
// Process request to create page
function processRequestCreate($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if($this->userPermission && !empty($_POST["rawdataedit"]))
if(!$this->userRestrictions && !empty($_POST["rawdataedit"]))
{
$this->rawDataSource = $this->rawDataEdit = rawurldecode($_POST["rawdatasource"]);
$page = $this->getPageNew($serverScheme, $serverName, $base, $location, $fileName, rawurldecode($_POST["rawdataedit"]));
$rawData = $this->normaliseText(rawurldecode($_POST["rawdataedit"]));
$page = $this->getPageNew($serverScheme, $serverName, $base, $location, $fileName, $rawData);
if(!$page->isError())
{
if($this->yellow->toolbox->createFile($page->fileName, $page->rawData))
@ -232,7 +396,7 @@ class YellowWebinterface
}
} else {
$statusCode = 500;
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, $false);
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
$this->yellow->page->error($statusCode, $page->get("pageError"));
}
}
@ -243,10 +407,10 @@ class YellowWebinterface
function processRequestEdit($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if($this->userPermission && !empty($_POST["rawdataedit"]))
if(!$this->userRestrictions && !empty($_POST["rawdataedit"]))
{
$this->rawDataSource = rawurldecode($_POST["rawdatasource"]);
$this->rawDataEdit = rawurldecode($_POST["rawdataedit"]);
$this->rawDataEdit = $this->normaliseText(rawurldecode($_POST["rawdataedit"]));
$page = $this->getPageUpdate($serverScheme, $serverName, $base, $location, $fileName,
$this->rawDataSource, $this->rawDataEdit, $this->yellow->toolbox->readFile($fileName));
if(!$page->isError())
@ -275,7 +439,7 @@ class YellowWebinterface
function processRequestDelete($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if($this->userPermission)
if(!$this->userRestrictions)
{
$this->rawDataSource = $this->rawDataEdit = rawurldecode($_POST["rawdatasource"]);
if(!is_file($fileName) || $this->yellow->toolbox->deleteFile($fileName))
@ -292,48 +456,118 @@ class YellowWebinterface
return $statusCode;
}
// Process request for user login
function processRequestLogin($serverScheme, $serverName, $base, $location, $fileName)
// Process request to install
function processRequestInstall($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
$home = $this->users->getHome();
if(substru($location, 0, strlenu($home)) == $home)
if($this->yellow->config->get("installationMode") && !$this->yellow->isStaticFile($location, $fileName, false))
{
$statusCode = 303;
$location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = 302;
$location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $home);
$this->yellow->sendStatus($statusCode, $location);
$fileName = $this->yellow->config->get("configDir")."page-installation.txt";
$this->yellow->pages->pages["root/"] = array();
$this->yellow->page = new YellowPage($this->yellow);
$this->yellow->page->setRequestInformation($serverScheme, $serverName, $base, $location, $fileName);
$this->yellow->page->parseData($this->getRawDataInstallation($fileName, $this->yellow->getRequestLanguage()), false, 404);
$this->yellow->page->parserSafeMode = false;
$this->yellow->page->parseContent();
$author = trim($_REQUEST["author"]);
$email = trim($_REQUEST["email"]);
$password = trim($_REQUEST["password"]);
$language = trim($_REQUEST["language"]);
$status = trim($_REQUEST["status"]);
if($status == "install")
{
$status = "ok";
$fileNamePage = $this->yellow->lookup->findFileFromLocation("/");
$rawData = strreplaceu("\\n", "\n", $this->yellow->text->getText("webinterfaceInstallationHomePage", "en"));
if($this->yellow->toolbox->readFile($fileNamePage)==$rawData && $language!="en")
{
$rawData = strreplaceu("\\n", "\n", $this->yellow->text->getText("webinterfaceInstallationHomePage", $language));
$status = $this->yellow->toolbox->createFile($fileNamePage, $rawData) ? "ok" : "error";
if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNamePage'!");
}
}
if($status == "ok")
{
if($this->getUserAccount($email, $password, "install") == "ok")
{
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile");
$status = $this->users->update($fileNameUser, $email, $password, $author, $language, "active", "/") ? "ok" : "error";
if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
}
if($status == "ok")
{
$fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
$status = $this->yellow->config->update($fileNameConfig, $this->getInstallationData()) ? "done" : "error";
if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameConfig'!");
}
if($status == "done")
{
$statusCode = 303;
$location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = $this->yellow->sendPage();
}
}
return $statusCode;
}
// Process request for user logout
function processRequestLogout($serverScheme, $serverName, $base, $location, $fileName)
// Send mail to web interface user
function sendMail($serverScheme, $serverName, $base, $email, $action)
{
$statusCode = 302;
$this->users->destroyCookie("login");
$this->users->email = "";
$location = $this->yellow->lookup->normaliseUrl(
$this->yellow->config->get("serverScheme"),
$this->yellow->config->get("serverName"),
$this->yellow->config->get("serverBase"), $location);
$this->yellow->sendStatus($statusCode, $location);
return $statusCode;
if($action=="welcome" || $action == "information")
{
$url = "$serverScheme://$serverName$base/";
} else {
$expire = time()+60*60*24*30;
$id = $this->users->createRequestId($email, $action, $expire);
$url = "$serverScheme://$serverName$base"."/action:$action/email:$email/expire:$expire/id:$id";
}
if($action == "approve")
{
$account = $email;
$name = $this->yellow->config->get("author");
$email = $this->yellow->config->get("email");
} else {
$account = $email;
$name = $this->users->getName($email);
}
$language = $this->users->getLanguage($email);
if(!$this->yellow->text->isLanguage($language)) $language = $this->yellow->config->get("language");
$sitename = $this->yellow->config->get("sitename");
$prefix = "webinterface".ucfirst($action);
$message = $this->yellow->text->getText("{$prefix}Message", $language);
$message = preg_replace("/@useraccount/i", $account, $message);
$message = preg_replace("/@usershort/i", strtok($name, " "), $message);
$message = preg_replace("/@username/i", $name, $message);
$message = preg_replace("/@userlanguage/i", $language, $message);
$mailTo = mb_encode_mimeheader("$name <$email>");
$mailSubject = mb_encode_mimeheader($this->yellow->text->getText("{$prefix}Subject", $language));
$mailHeaders = mb_encode_mimeheader("From: $sitename <noreply>")."\r\n";
$mailHeaders .= mb_encode_mimeheader("X-Request-Url: $serverScheme://$serverName$base")."\r\n";
$mailHeaders .= mb_encode_mimeheader("X-Remote-Addr: $_SERVER[REMOTE_ADDR]")."\r\n";
$mailHeaders .= "Mime-Version: 1.0\r\n";
$mailHeaders .= "Content-Type: text/plain; charset=utf-8\r\n";
$mailMessage = "$message\r\n\r\n$url\r\n-- \r\n$sitename";
return mail($mailTo, $mailSubject, $mailMessage, $mailHeaders);
}
// Check web interface request
function checkRequest($location)
{
if($this->yellow->toolbox->getServerScheme()==$this->yellow->config->get("webinterfaceServerScheme") &&
$this->yellow->toolbox->getServerName()==$this->yellow->config->get("webinterfaceServerName"))
if($this->yellow->config->get("installationMode"))
{
$locationLength = strlenu($this->yellow->config->get("webinterfaceLocation"));
$this->active = substru($location, 0, $locationLength) == $this->yellow->config->get("webinterfaceLocation");
$_REQUEST["action"] = "install";
} else {
if($this->yellow->toolbox->getServerScheme()==$this->yellow->config->get("webinterfaceServerScheme") &&
$this->yellow->toolbox->getServerName()==$this->yellow->config->get("webinterfaceServerName"))
{
$locationLength = strlenu($this->yellow->config->get("webinterfaceLocation"));
$this->active = substru($location, 0, $locationLength) == $this->yellow->config->get("webinterfaceLocation");
}
}
return $this->isActive();
return $this->yellow->config->get("installationMode") || $this->isActive();
}
// Check web interface user
@ -347,62 +581,82 @@ class YellowWebinterface
{
$this->users->createCookie("login", $email);
$this->users->email = $email;
$this->userPermission = $this->getUserPermission($location, $fileName);
$this->userRestrictions = $this->getUserRestrictions($email, $location, $fileName);
} else {
$this->userLoginFailed = true;
$this->loginAction = "fail";
}
} else if(isset($_COOKIE["login"])) {
list($email, $session) = $this->users->getCookieInformation($_COOKIE["login"]);
list($email, $session) = explode(',', $_COOKIE["login"], 2);
if($this->users->checkCookie($email, $session))
{
$this->users->email = $email;
$this->userPermission = $this->getUserPermission($location, $fileName);
$this->userRestrictions = $this->getUserRestrictions($email, $location, $fileName);
} else {
$this->userLoginFailed = true;
$this->loginAction = "fail";
}
}
return $this->isUser();
}
// Return permission to change page
function getUserPermission($location, $fileName)
// Return user account request
function getUserRequest($email, $action, $expire, $id)
{
$userPermission = NULL;
foreach($this->yellow->plugins->plugins as $key=>$value)
{
if(method_exists($value["obj"], "onUserPermission"))
{
$userPermission = $value["obj"]->onUserPermission($location, $fileName, $this->users);
if(!is_null($userPermission)) break;
}
}
if(is_null($userPermission))
{
$userPermission = is_dir(dirname($fileName)) && strlenu(basename($fileName))<128;
$userPermission &= substru($location, 0, strlenu($this->users->getHome())) == $this->users->getHome();
}
return $userPermission;
$loginStatus = $this->users->checkRequest($email, $action, $expire, $id) ? "ok" : "done";
if($loginStatus=="done" && $expire<=time()) $loginStatus = "expire";
return $loginStatus;
}
// Return user data
function getUserData()
// Return user account changes
function getUserAccount($email, $password, $action)
{
$data = array();
foreach($this->users->users as $key=>$value)
$loginStatus = NULL;
foreach($this->yellow->plugins->plugins as $key=>$value)
{
$data[$key] = "$value[email] - $value[name] $value[language] $value[status] $value[home]";
if(method_exists($value["obj"], "onUserAccount"))
{
$loginStatus = $value["obj"]->onUserAccount($email, $password, $action, $status, $this->users);
if(!is_null($loginStatus)) break;
}
}
usort($data, strnatcasecmp);
return $data;
if(is_null($loginStatus))
{
$loginStatus = "ok";
if(strlenu($password)<$this->yellow->config->get("webinterfaceUserPasswordMinLength")) $loginStatus = "weak";
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) $loginStatus = "invalid";
}
return $loginStatus;
}
// Return user restrictions to change page
function getUserRestrictions($email, $location, $fileName)
{
$userRestrictions = NULL;
foreach($this->yellow->plugins->plugins as $key=>$value)
{
if(method_exists($value["obj"], "onUserRestrictions"))
{
$userRestrictions = $value["obj"]->onUserRestrictions($email, $location, $fileName, $this->users);
if(!is_null($userRestrictions)) break;
}
}
if(is_null($userRestrictions))
{
$userRestrictions = !is_dir(dirname($fileName)) || strlenu(basename($fileName))>128;
$userRestrictions |= substru($location, 0, strlenu($this->users->getHome())) != $this->users->getHome();
}
return $userRestrictions;
}
// Update request information
function updateRequestInformation()
{
$serverScheme = $this->yellow->config->get("webinterfaceServerScheme");
$serverName = $this->yellow->config->get("webinterfaceServerName");
$base = rtrim($this->yellow->config->get("serverBase").$this->yellow->config->get("webinterfaceLocation"), '/');
$this->yellow->page->base = $base;
if($this->isActive())
{
$serverScheme = $this->yellow->config->get("webinterfaceServerScheme");
$serverName = $this->yellow->config->get("webinterfaceServerName");
$base = rtrim($this->yellow->config->get("serverBase").$this->yellow->config->get("webinterfaceLocation"), '/');
$this->yellow->page->base = $base;
}
return $this->yellow->getRequestInformation($serverScheme, $serverName, $base);
}
@ -461,7 +715,10 @@ class YellowWebinterface
if(!$ok) $page->error(500, "Page '".$page->get("title")."' can not be created!");
}
}
if(!$this->getUserPermission($page->location, $page->fileName)) $page->error(500, "Page '".$page->get("title")."' is not allowed!");
if($this->getUserRestrictions($this->users->email, $page->location, $page->fileName))
{
$page->error(500, "Page '".$page->get("title")."' is not allowed!");
}
return $page;
}
@ -495,10 +752,43 @@ class YellowWebinterface
}
}
}
if(!$this->getUserPermission($page->location, $page->fileName)) $page->error(500, "Page '".$page->get("title")."' is not allowed!");
if($this->getUserRestrictions($this->users->email, $page->location, $page->fileName))
{
$page->error(500, "Page '".$page->get("title")."' is not allowed!");
}
return $page;
}
// Return raw data for installation page
function getRawDataInstallation($fileName, $language)
{
$fileData = $this->yellow->toolbox->readFile($fileName);
if(empty($fileData))
{
$this->yellow->text->setLanguage($language);
$fileData = "---\nTitle:".$this->yellow->text->get("webinterfaceInstallationTitle")."\nLanguage:$language\nNavigation:navigation\n---\n";
$fileData .= "<form class=\"installation-form\" action=\"".$this->yellow->page->getLocation()."\" method=\"post\">\n";
$fileData .= "<p><label for=\"sitename\">".$this->yellow->text->get("webinterfaceInstallationSitename")."</label><br /><input class=\"form-control\" type=\"text\" name=\"sitename\" id=\"sitename\" value=\"".$this->yellow->config->getHtml("sitename")."\"></p>\n";
$fileData .= "<p><label for=\"author\">".$this->yellow->text->get("webinterfaceInstallationAuthor")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"author\" id=\"author\" value=\"\"></p>\n";
$fileData .= "<p><label for=\"email\">".$this->yellow->text->get("webinterfaceLoginEmail")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"email\" id=\"email\" value=\"\"></p>\n";
$fileData .= "<p><label for=\"password\">".$this->yellow->text->get("webinterfaceLoginPassword")."</label><br /><input class=\"form-control\" type=\"password\" maxlength=\"64\" name=\"password\" id=\"password\" value=\"\"></p>\n";
if(count($this->yellow->text->getLanguages()) > 1)
{
$fileData .= "<p>";
foreach($this->yellow->text->getLanguages() as $language)
{
$checked = $language==$this->yellow->text->language ? " checked=\"checked\"" : "";
$fileData .= "<label for=\"$language\"><input type=\"radio\" name=\"language\" id=\"$language\" value=\"$language\"$checked> ".$this->yellow->text->getTextHtml("languageDescription", $language)."</label><br />";
}
$fileData .= "</p>\n";
}
$fileData .= "<input class=\"btn\" type=\"submit\" value=\"".$this->yellow->text->get("webinterfaceOkButton")."\" />\n";
$fileData .= "<input type=\"hidden\" name=\"status\" value=\"install\" />\n";
$fileData .= "</form>\n";
}
return $fileData;
}
// Return raw data for new page
function getRawDataNew($title = "")
{
@ -509,13 +799,14 @@ class YellowWebinterface
$fileData = $this->yellow->toolbox->readFile($fileName);
$fileData = preg_replace("/@datetime/i", date("Y-m-d H:i:s"), $fileData);
$fileData = preg_replace("/@date/i", date("Y-m-d"), $fileData);
$fileData = preg_replace("/@usershort/i", strtok($this->users->getName(), " "), $fileData);
$fileData = preg_replace("/@username/i", $this->users->getName(), $fileData);
$fileData = preg_replace("/@userlanguage/i", $this->users->getLanguage(), $fileData);
if(!empty($title)) $fileData = $this->updateDataTitle($fileData, $title);
return $fileData;
}
// Return page data including webinterface information
// Return page data including login information
function getPageData()
{
$data = array();
@ -525,10 +816,14 @@ class YellowWebinterface
$data["rawDataSource"] = $this->rawDataSource;
$data["rawDataEdit"] = $this->rawDataEdit;
$data["rawDataNew"] = $this->getRawDataNew();
$data["userPermission"] = $this->userPermission;
$data["userRestrictions"] = $this->userRestrictions;
$data["pageFile"] = $this->yellow->page->get("pageFile");
$data["parserSafeMode"] = $this->yellow->page->parserSafeMode;
$data["statusCode"] = $this->yellow->page->statusCode;
} else {
$data["loginAction"] = $this->loginAction;
$data["loginStatus"] = $this->loginStatus;
if($this->loginAction != "none") $data = array_merge($data, $this->getRequestData());
}
return $data;
}
@ -550,13 +845,54 @@ class YellowWebinterface
$data["serverTime"] = $this->yellow->config->get("serverTime");
$data["serverLanguages"] = $this->yellow->text->getLanguages();
} else {
$data["login"] = $this->yellow->page->statusCode==200;
$data["loginEmail"] = $this->yellow->config->get("loginEmail");
$data["loginPassword"] = $this->yellow->config->get("loginPassword");
$data["loginExtra"] = intval($this->isExtra());
}
return $data;
}
// Return installation data
function getInstallationData()
{
$data = array();
foreach($_REQUEST as $key=>$value)
{
if(!$this->yellow->config->isExisting($key)) continue;
$data[$key] = trim($value);
}
$data["# serverScheme"] = $this->yellow->toolbox->getServerScheme();
$data["# serverName"] = $this->yellow->toolbox->getServerName();
$data["# serverBase"] = $this->yellow->toolbox->getServerBase();
$data["# serverTime"] = $this->yellow->toolbox->getServerTime();
$data["installationMode"] = "0";
return $data;
}
// Return request strings
function getRequestData()
{
$data = array();
foreach($_REQUEST as $key=>$value)
{
if($key == "password") continue;
$data["request".ucfirst($key)] = trim($value);
}
return $data;
}
// Return user data
function getUserData()
{
$data = array();
foreach($this->users->users as $key=>$value)
{
$data[$key] = "$value[email] - $value[name] $value[language] $value[status] $value[home]";
}
usort($data, strnatcasecmp);
return $data;
}
// Return text strings
function getTextData()
{
@ -568,11 +904,27 @@ class YellowWebinterface
return array_merge($textLanguage, $textWebinterface, $textYellow);
}
// Normlise text with special characters
function normaliseText($text)
{
if($this->yellow->plugins->isExisting("emojiawesome"))
{
$text = $this->yellow->plugins->get("emojiawesome")->normaliseText($text, true, false);
}
return $text;
}
// Check if web interface request
function isActive()
{
return $this->active;
}
// Check if extra login features
function isExtra()
{
return strposu($this->yellow->config->get("email"), '@') !== false;
}
// Check if user is logged in
function isUser()
@ -612,6 +964,49 @@ class YellowUsers
}
}
// Update users in file
function update($fileName, $email, $password = "", $name = "", $language = "", $status = "", $home = "")
{
if(!empty($password))
{
$algorithm = $this->yellow->config->get("webinterfaceUserHashAlgorithm");
$cost = $this->yellow->config->get("webinterfaceUserHashCost");
$hash = $this->yellow->toolbox->createHash($password, $algorithm, $cost);
if(empty($hash)) $hash = "error-hash-algorithm-$algorithm";
}
if($this->isExisting($email))
{
$email = strreplaceu(',', '-', $email);
$hash = strreplaceu(',', '-', empty($hash) ? $this->users[$email]["hash"] : $hash);
$name = strreplaceu(',', '-', empty($name) ? $this->users[$email]["name"] : $name);
$language = strreplaceu(',', '-', empty($language) ? $this->users[$email]["language"] : $language);
$status = strreplaceu(',', '-', empty($status) ? $this->users[$email]["status"] : $status);
$home = strreplaceu(',', '-', empty($home) ? $this->users[$email]["home"] : $home);
} else {
$email = strreplaceu(',', '-', empty($email) ? "none" : $email);
$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("webinterfaceUserStatus") : $status);
$home = strreplaceu(',', '-', empty($home) ? $this->yellow->config->get("webinterfaceUserHome") : $home);
}
$this->set($email, $hash, $name, $language, $status, $home);
$fileData = $this->yellow->toolbox->readFile($fileName);
foreach($this->yellow->toolbox->getTextLines($fileData) as $line)
{
preg_match("/^(.*?)\s*:\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?)\s*$/", $line, $matches);
if(!empty($matches[1]) && $matches[1]==$email)
{
$fileDataNew .= "$email: $hash,$name,$language,$status,$home\n";
$found = true;
} else {
$fileDataNew .= $line;
}
}
if(!$found) $fileDataNew .= "$email: $hash,$name,$language,$status,$home\n";
return $this->yellow->toolbox->createFile($fileName, $fileDataNew);
}
// Set user data
function set($email, $hash, $name, $language, $status, $home)
{
@ -624,42 +1019,6 @@ class YellowUsers
$this->users[$email]["home"] = $home;
}
// Create or update user in file
function createUser($fileName, $email, $hash, $name, $language, $status, $home)
{
$email = strreplaceu(',', '-', $email);
$hash = strreplaceu(',', '-', $hash);
$fileData = $this->yellow->toolbox->readFile($fileName);
foreach($this->yellow->toolbox->getTextLines($fileData) as $line)
{
preg_match("/^(.*?)\s*:\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?)\s*$/", $line, $matches);
if(!empty($matches[1]) && !empty($matches[2]) && !empty($matches[3]) && !empty($matches[4]) &&
!empty($matches[5]) && !empty($matches[6]))
{
if($matches[1] == $email)
{
$name = strreplaceu(',', '-', empty($name) ? $matches[3] : $name);
$language = strreplaceu(',', '-', empty($language) ? $matches[4] : $language);
$status = strreplaceu(',', '-', empty($status) ? $matches[5] : $status);
$home = strreplaceu(',', '-', empty($home) ? $matches[6] : $home);
$fileDataNew .= "$email: $hash,$name,$language,$status,$home\n";
$found = true;
continue;
}
}
$fileDataNew .= $line;
}
if(!$found)
{
$name = strreplaceu(',', '-', empty($name) ? $this->yellow->config->get("sitename") : $name);
$language = strreplaceu(',', '-', empty($language) ? $this->yellow->config->get("language") : $language);
$status = strreplaceu(',', '-', empty($status) ? "active" : $status);
$home = strreplaceu(',', '-', empty($home) ? $this->yellow->config->get("webinterfaceUserHome") : $home);
$fileDataNew .= "$email: $hash,$name,$language,$status,$home\n";
}
return $this->yellow->toolbox->createFile($fileName, $fileDataNew);
}
// Check user login
function checkUser($email, $password)
{
@ -668,6 +1027,13 @@ class YellowUsers
$this->yellow->toolbox->verifyHash($password, $algorithm, $this->users[$email]["hash"]);
}
// Check user login from browser cookie
function checkCookie($email, $session)
{
return $this->isExisting($email) && $this->users[$email]["status"]=="active" &&
$this->yellow->toolbox->verifyHash($this->users[$email]["hash"], "sha256", $session);
}
// Create browser cookie
function createCookie($cookieName, $email)
{
@ -689,20 +1055,26 @@ class YellowUsers
setcookie($cookieName, "", time()-3600, $location, "", $serverScheme=="https");
}
// Return information from browser cookie
function getCookieInformation($cookie)
// Check user request
function checkRequest($email, $action, $expire, $id)
{
return explode(',', $cookie, 2);
switch($action)
{
case "confirm": $status = "unconfirmed"; break;
case "approve": $status = "unapproved"; break;
case "recover": $status = "active"; break;
}
return $this->isExisting($email) && $this->users[$email]["status"]==$status && $expire>time() &&
$this->yellow->toolbox->verifyHash($this->users[$email]["hash"].$action.$expire, "sha256", $id);
}
// Check user login from browser cookie
function checkCookie($email, $session)
// Create user request ID
function createRequestId($email, $action, $expire)
{
return $this->isExisting($email) && $this->users[$email]["status"]=="active" &&
$this->yellow->toolbox->verifyHash($this->users[$email]["hash"], "sha256", $session);
return $this->yellow->toolbox->createHash($this->users[$email]["hash"].$action.$expire, "sha256");
}
// Retun user login information
// Retun user login information, TODO: this is an obsolete function and will be removed soon
function getUserInfo($email, $password, $name, $language, $home)
{
$algorithm = $this->yellow->config->get("webinterfaceUserHashAlgorithm");
@ -714,13 +1086,20 @@ class YellowUsers
$hash = strreplaceu(',', '-', $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) ? "active" : $status);
$status = strreplaceu(',', '-', empty($status) ? $this->yellow->config->get("webinterfaceUserStatus") : $status);
$home = strreplaceu(',', '-', empty($home) ? $this->yellow->config->get("webinterfaceUserHome") : $home);
$user = "$email: $hash,$name,$language,$status,$home\n";
}
return $user;
}
// Return user hash
function getHash($email = "")
{
if(empty($email)) $email = $this->email;
return $this->isExisting($email) ? $this->users[$email]["hash"] : "";
}
// Return user name
function getName($email = "")
{

View file

@ -1,7 +1,7 @@
<div class="footer">
<a href="<?php echo $yellow->page->base."/" ?>">&copy; 2016 <?php echo $yellow->page->getHtml("sitename") ?></a>.
<a href="<?php echo $yellow->page->get("pageEdit") ?>">Edit</a>.
<a href="http://datenstrom.se/yellow">Made with Yellow</a>.
<a href="<?php echo $yellow->text->get("yellowUrl") ?>">Made with Yellow</a>.
</div>
</div>
<?php echo $yellow->page->getExtra("footer") ?>