commit 35573ecd9090ab008e0376ed2aef3bff769f3090
parent 608f411a4ca93f747c5179e9a74bb3daf25b58fa
Author: markseu <mark2011@mayberg.se>
Date: Tue, 12 Apr 2016 15:58:56 +0200
System update (brave new world)
Diffstat:
12 files changed, 882 insertions(+), 252 deletions(-)
diff --git a/content/1-home/page.txt b/content/1-home/page.txt
@@ -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/).
-\ No newline at end of file
+---
+Title: Home
+---
+Your website works!
+
+You can now [edit this page] or use your text editor.
+\ No newline at end of file
diff --git a/content/2-about/page.txt b/content/2-about/page.txt
@@ -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.
\ No newline at end of file
diff --git a/system/config/config.ini b/system/config/config.ini
@@ -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: /
diff --git a/system/plugins/commandline.php b/system/plugins/commandline.php
@@ -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!="/";
}
diff --git a/system/plugins/core.php b/system/plugins/core.php
@@ -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
diff --git a/system/plugins/language-de.txt b/system/plugins/language-de.txt
@@ -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
diff --git a/system/plugins/language-en.txt b/system/plugins/language-en.txt
@@ -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
diff --git a/system/plugins/language-fr.txt b/system/plugins/language-fr.txt
@@ -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
diff --git a/system/plugins/webinterface.css b/system/plugins/webinterface.css
@@ -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; }
diff --git a/system/plugins/webinterface.js b/system/plugins/webinterface.js
@@ -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 request string
+ getRequest: function(key, prefix)
+ {
+ if(!prefix) prefix = "request";
+ key = prefix + key;
+ return (key in yellow.page) ? yellow.page[key] : "";
+ },
+
// Return text string
- getText: function(key)
+ getText: function(key, prefix, postfix)
{
- return ("webinterface"+key in yellow.text) ? yellow.text["webinterface"+key] : "[webinterface"+key+"]";
+ 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+"]";
}
}
diff --git a/system/plugins/webinterface.php b/system/plugins/webinterface.php
@@ -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 "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 "": $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 "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;
+ $loginStatus = $this->users->checkRequest($email, $action, $expire, $id) ? "ok" : "done";
+ if($loginStatus=="done" && $expire<=time()) $loginStatus = "expire";
+ return $loginStatus;
+ }
+
+ // Return user account changes
+ function getUserAccount($email, $password, $action)
+ {
+ $loginStatus = NULL;
foreach($this->yellow->plugins->plugins as $key=>$value)
{
- if(method_exists($value["obj"], "onUserPermission"))
+ if(method_exists($value["obj"], "onUserAccount"))
{
- $userPermission = $value["obj"]->onUserPermission($location, $fileName, $this->users);
- if(!is_null($userPermission)) break;
+ $loginStatus = $value["obj"]->onUserAccount($email, $password, $action, $status, $this->users);
+ if(!is_null($loginStatus)) break;
}
}
- if(is_null($userPermission))
+ if(is_null($loginStatus))
{
- $userPermission = is_dir(dirname($fileName)) && strlenu(basename($fileName))<128;
- $userPermission &= substru($location, 0, strlenu($this->users->getHome())) == $this->users->getHome();
+ $loginStatus = "ok";
+ if(strlenu($password)<$this->yellow->config->get("webinterfaceUserPasswordMinLength")) $loginStatus = "weak";
+ if(!filter_var($email, FILTER_VALIDATE_EMAIL)) $loginStatus = "invalid";
}
- return $userPermission;
+ return $loginStatus;
}
- // Return user data
- function getUserData()
+ // Return user restrictions to change page
+ function getUserRestrictions($email, $location, $fileName)
{
- $data = array();
- foreach($this->users->users as $key=>$value)
+ $userRestrictions = 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"], "onUserRestrictions"))
+ {
+ $userRestrictions = $value["obj"]->onUserRestrictions($email, $location, $fileName, $this->users);
+ if(!is_null($userRestrictions)) break;
+ }
}
- usort($data, strnatcasecmp);
- return $data;
+ 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 = "")
{
diff --git a/system/themes/snippets/footer.php b/system/themes/snippets/footer.php
@@ -1,7 +1,7 @@
<div class="footer">
<a href="<?php echo $yellow->page->base."/" ?>">© 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") ?>