diff --git a/content/00-welcome/00-markdown-test.yaml b/content/00-welcome/00-markdown-test.yaml
index f9ec15c..043ea59 100644
--- a/content/00-welcome/00-markdown-test.yaml
+++ b/content/00-welcome/00-markdown-test.yaml
@@ -1,8 +1,18 @@
meta:
navtitle: 'markdown test'
+ title: 'Markdown is a simple and universal syntax for text formatting.'
+ description: 'Developers love markdown, because it is much cleaner and saver than HTML. And they can easily convert markdown to a lot of other document formats like HTML and'
+ heroimage: null
+ heroimagealt: null
owner: Sebastian
+ author: null
+ allowedrole: null
+ alloweduser: null
+ manualdate: null
+ modified: '2023-05-11'
created: '2023-06-12'
time: 22-36-41
- modified: '2023-05-11'
- title: 'Markdown is a simple and universal syntax for text formatting. More and more writers switch to markdown, because they can format their text during the writing process without using any format-buttons. Once they are familiar with the markdown syntax, they can write formatted text much easier and faster than with any standard HTML-editor.'
- description: 'Developers love markdown, because it is much cleaner and saver than HTML. And they can easily convert markdown to a lot of other document formats like HTML and'
+ reference: null
+ referencetype: null
+ hide: false
+ noindex: false
diff --git a/content/00-welcome/01-manage-access.yaml b/content/00-welcome/01-manage-access.yaml
index 6101b43..4ade9cc 100644
--- a/content/00-welcome/01-manage-access.yaml
+++ b/content/00-welcome/01-manage-access.yaml
@@ -1,6 +1,6 @@
meta:
navtitle: 'manage access'
- owner: Sebastian
+ owner: Unknown
created: '2023-06-12'
time: 22-36-36
modified: '2023-05-06'
diff --git a/content/00-welcome/03-setup-your-website.yaml b/content/00-welcome/03-setup-your-website.yaml
index 7d9343d..805e9b8 100644
--- a/content/00-welcome/03-setup-your-website.yaml
+++ b/content/00-welcome/03-setup-your-website.yaml
@@ -1,6 +1,6 @@
meta:
navtitle: 'setup your website'
- owner: Sebastian
+ owner: Unknown
created: '2023-06-12'
time: 22-36-14
modified: '2023-03-26'
diff --git a/content/00-welcome/04-write-content.yaml b/content/00-welcome/04-write-content.yaml
index 4538849..010a251 100644
--- a/content/00-welcome/04-write-content.yaml
+++ b/content/00-welcome/04-write-content.yaml
@@ -1,6 +1,6 @@
meta:
navtitle: 'write content'
- owner: Sebastian
+ owner: Unknown
created: '2023-06-12'
time: 22-09-48
modified: '2023-05-11'
diff --git a/content/00-welcome/05-todos.md b/content/00-welcome/05-todos.md
index 1bb08d5..a72a3db 100644
--- a/content/00-welcome/05-todos.md
+++ b/content/00-welcome/05-todos.md
@@ -33,6 +33,7 @@ Biig blocks:
* DONE: Media Library
* DONE: Posts
+* DONE: Setup
* Recover Password
Small features:
@@ -47,6 +48,7 @@ Small features:
* Editor: Warn if open another block
* Image generation on the fly
* Assets
+* Bug: Table of content duplicated for published pages
Cleanups:
diff --git a/content/00-welcome/05-todos.txt b/content/00-welcome/05-todos.txt
new file mode 100644
index 0000000..c30cc9d
--- /dev/null
+++ b/content/00-welcome/05-todos.txt
@@ -0,0 +1 @@
+["# ToDos Version 2","[TOC]","## Visual Editor","* FIXED: File is not published from tmp to media\/files if you save the block.","## Raw Editor","* DONE ready","## Medialib","* DONE","## Posts","* Setup","## Plugins","* Asset Class","## Frontend","* DONE\n* DONE: Test restrictions","## ToDos","Biig blocks:","* DONE: Media Library\n* DONE: Posts\n* DONE: Setup\n* DONE: Recover Password","Small features:","* Sitemap and ping\n* Captcha\n* Clear Cache\n* Security Log\n* Backend fields\n* Proxy\n* DONE: Session handling: csrf fail and session start error if restrictions are active\n* Editor: Warn if open another block\n* Image generation on the fly\n* Assets\n* Bug: Table of content duplicated for published pages\n* Bug: Navigation frontend if unpublished pages","Cleanups:","* Events\n* Error messages\n* Translations","## Select userroles","* Userroles for file restriction: in vue-blox-components loaded via api\n* Userroles for userfields: in php model user getUserFields()\n* Userroles for meta: in php controller apiAuthorMeta getMeta()\n* Plugins and themes: in php model extension getThemeDefinitions()","## License Check","* On activation in apiControllerExtension. It checks the license in yaml.\n* In plugin php code with setPremiumLicense\n* In static plugins, it checks manual premium list and method setPremiumLicense and more "]
\ No newline at end of file
diff --git a/content/00-welcome/05-todos.yaml b/content/00-welcome/05-todos.yaml
index 1a374d9..36bebfe 100644
--- a/content/00-welcome/05-todos.yaml
+++ b/content/00-welcome/05-todos.yaml
@@ -4,7 +4,7 @@ meta:
description: ' Visual Editor with more stuff'
heroimage: null
heroimagealt: null
- owner: Sebastian
+ owner: Unknown
author: null
allowedrole: contributor
alloweduser: null
diff --git a/content/01-cyanine-theme/00-new.md b/content/01-cyanine-theme/00-new.md
new file mode 100644
index 0000000..16bc8a3
--- /dev/null
+++ b/content/01-cyanine-theme/00-new.md
@@ -0,0 +1,51 @@
+# ToDo
+
+[TOC]
+
+## Visual Editor
+
+Das ist ein Intro. Es gibt noch viel zu tun, aber das ist am Ende des Tages nicht so schlimm denn wir machen einfach weiter.
+
+* DONE: Fix toc component in new block
+* DONE: Fix hr component in new block
+* DONE: finish shortcode component
+* DONE: Fix inline formats
+* DONE: fix lenght of page
+* DONE: Fix design of new block at the end (background color)
+* DONE: Move Block
+* DONE: Fix headline design
+* DONE: Fix save on two enter
+* DONE: fix quote design
+* DONE: Fix toc preview
+* DONE: disable enable
+* DONE: Add load sign (from navigation)
+* SHIT!!! fiinish youtube component
+
+## Navigation
+
+* DONE: fix status in navigation
+* fix error messages
+* DONE: refresh navigation after changes
+
+## Publish Controller
+
+* DONE: Create
+* DONE: publish
+* DONE: unpublish
+* DONE: discard
+* DONE: delete
+* DONE: save draft
+* DONE: switch to raw
+
+## Raw Editor
+
+* DONE:
+
+## Meta Tabs
+
+* Setup
+
+## Medialib
+
+* Setup
+
diff --git a/content/01-cyanine-theme/00-new.txt b/content/01-cyanine-theme/00-new.txt
deleted file mode 100644
index 82b2e4c..0000000
--- a/content/01-cyanine-theme/00-new.txt
+++ /dev/null
@@ -1 +0,0 @@
-["# ToDo","[TOC]","## Visual Editor","Das ist ein Intro. Es gibt noch viel zu tun, aber das ist am Ende des Tages nicht so schlimm denn wir machen einfach weiter.","* DONE: Fix toc component in new block\n* DONE: Fix hr component in new block\n* DONE: finish shortcode component\n* DONE: Fix inline formats\n* DONE: fix lenght of page\n* DONE: Fix design of new block at the end (background color)\n* DONE: Move Block\n* DONE: Fix headline design\n* DONE: Fix save on two enter\n* DONE: fix quote design\n* DONE: Fix toc preview\n* DONE: disable enable \n* DONE: Add load sign (from navigation)\n* SHIT!!! fiinish youtube component","## Navigation","* DONE: fix status in navigation\n* fix error messages\n* DONE: refresh navigation after changes","## Publish Controller","* DONE: Create \n* DONE: publish\n* DONE: unpublish\n* DONE: discard\n* DONE: delete\n* DONE: save draft\n* DONE: switch to raw","## Raw Editor","* DONE:","## Meta Tabs","* Setup","## Medialib","* Setup"]
\ No newline at end of file
diff --git a/content/01-cyanine-theme/00-new.yaml b/content/01-cyanine-theme/00-new.yaml
index 194e33a..4275f9e 100644
--- a/content/01-cyanine-theme/00-new.yaml
+++ b/content/01-cyanine-theme/00-new.yaml
@@ -1,2 +1,8 @@
meta:
navtitle: new
+ owner: Unknown
+ created: '2023-07-20'
+ time: 14-39-14
+ modified: '2023-07-20'
+ title: ToDo
+ description: ' Visual Editor'
diff --git a/content/01-cyanine-theme/01-landingpage.yaml b/content/01-cyanine-theme/01-landingpage.yaml
index 3cac26e..ecb9df8 100644
--- a/content/01-cyanine-theme/01-landingpage.yaml
+++ b/content/01-cyanine-theme/01-landingpage.yaml
@@ -4,7 +4,7 @@ meta:
description: "\nIntro with the content of the home page and an additional link/button.\nInfo with individual markdown content.\nTeaser with two elements. Each element has a"
heroimage: null
heroimagealt: null
- owner: Sebastian
+ owner: Unknown
author: null
allowedrole: null
alloweduser: null
diff --git a/data/navigation/navi-draft.txt b/data/navigation/navi-draft.txt
index 7b455b5..75c26a8 100644
--- a/data/navigation/navi-draft.txt
+++ b/data/navigation/navi-draft.txt
@@ -1 +1 @@
-a:2:{i:0;O:8:"stdClass":22:{s:12:"originalName";s:10:"00-welcome";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:7:"welcome";s:4:"slug";s:7:"welcome";s:4:"path";s:11:"/00-welcome";s:15:"pathWithoutType";s:17:"/00-welcome/index";s:9:"urlRelWoF";s:8:"/welcome";s:6:"urlRel";s:17:"/typemill/welcome";s:6:"urlAbs";s:33:"http://localhost/typemill/welcome";s:3:"key";i:0;s:7:"keyPath";i:0;s:12:"keyPathArray";a:1:{i:0;s:1:"0";}s:7:"chapter";i:1;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:6:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:19:"00-markdown-test.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:13:"markdown test";s:4:"slug";s:13:"markdown-test";s:4:"path";s:31:"/00-welcome/00-markdown-test.md";s:15:"pathWithoutType";s:28:"/00-welcome/00-markdown-test";s:3:"key";i:0;s:7:"keyPath";s:3:"0.0";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"0";}s:7:"chapter";s:3:"1.1";s:9:"urlRelWoF";s:22:"/welcome/markdown-test";s:6:"urlRel";s:31:"/typemill/welcome/markdown-test";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/markdown-test";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:19:"01-manage-access.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"manage access";s:4:"slug";s:13:"manage-access";s:4:"path";s:31:"/00-welcome/01-manage-access.md";s:15:"pathWithoutType";s:28:"/00-welcome/01-manage-access";s:3:"key";i:1;s:7:"keyPath";s:3:"0.1";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"1";}s:7:"chapter";s:3:"1.2";s:9:"urlRelWoF";s:22:"/welcome/manage-access";s:6:"urlRel";s:31:"/typemill/welcome/manage-access";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/manage-access";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:14:"02-get-help.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:8:"get help";s:4:"slug";s:8:"get-help";s:4:"path";s:26:"/00-welcome/02-get-help.md";s:15:"pathWithoutType";s:23:"/00-welcome/02-get-help";s:3:"key";i:2;s:7:"keyPath";s:3:"0.2";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"2";}s:7:"chapter";s:3:"1.3";s:9:"urlRelWoF";s:17:"/welcome/get-help";s:6:"urlRel";s:26:"/typemill/welcome/get-help";s:6:"urlAbs";s:42:"http://localhost/typemill/welcome/get-help";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:24:"03-setup-your-website.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:18:"setup your website";s:4:"slug";s:18:"setup-your-website";s:4:"path";s:36:"/00-welcome/03-setup-your-website.md";s:15:"pathWithoutType";s:33:"/00-welcome/03-setup-your-website";s:3:"key";i:3;s:7:"keyPath";s:3:"0.3";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"3";}s:7:"chapter";s:3:"1.4";s:9:"urlRelWoF";s:27:"/welcome/setup-your-website";s:6:"urlRel";s:36:"/typemill/welcome/setup-your-website";s:6:"urlAbs";s:52:"http://localhost/typemill/welcome/setup-your-website";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:4;O:8:"stdClass":20:{s:12:"originalName";s:19:"04-write-content.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"04";s:4:"name";s:13:"write content";s:4:"slug";s:13:"write-content";s:4:"path";s:31:"/00-welcome/04-write-content.md";s:15:"pathWithoutType";s:28:"/00-welcome/04-write-content";s:3:"key";i:4;s:7:"keyPath";s:3:"0.4";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"4";}s:7:"chapter";s:3:"1.5";s:9:"urlRelWoF";s:22:"/welcome/write-content";s:6:"urlRel";s:31:"/typemill/welcome/write-content";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/write-content";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:5;O:8:"stdClass":20:{s:12:"originalName";s:11:"05-todos.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"05";s:4:"name";s:6:"To Dos";s:4:"slug";s:5:"todos";s:4:"path";s:23:"/00-welcome/05-todos.md";s:15:"pathWithoutType";s:20:"/00-welcome/05-todos";s:3:"key";i:5;s:7:"keyPath";s:3:"0.5";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"5";}s:7:"chapter";s:3:"1.6";s:9:"urlRelWoF";s:14:"/welcome/todos";s:6:"urlRel";s:23:"/typemill/welcome/todos";s:6:"urlAbs";s:39:"http://localhost/typemill/welcome/todos";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}i:1;O:8:"stdClass":22:{s:12:"originalName";s:16:"01-cyanine-theme";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"cyanine theme";s:4:"slug";s:13:"cyanine-theme";s:4:"path";s:17:"/01-cyanine-theme";s:15:"pathWithoutType";s:23:"/01-cyanine-theme/index";s:9:"urlRelWoF";s:14:"/cyanine-theme";s:6:"urlRel";s:23:"/typemill/cyanine-theme";s:6:"urlAbs";s:39:"http://localhost/typemill/cyanine-theme";s:3:"key";i:1;s:7:"keyPath";i:1;s:12:"keyPathArray";a:1:{i:0;s:1:"1";}s:7:"chapter";i:2;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:5:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:10:"00-new.txt";s:11:"elementType";s:4:"file";s:6:"status";s:11:"unpublished";s:8:"fileType";s:3:"txt";s:5:"order";s:2:"00";s:4:"name";s:3:"new";s:4:"slug";s:3:"new";s:4:"path";s:28:"/01-cyanine-theme/00-new.txt";s:15:"pathWithoutType";s:24:"/01-cyanine-theme/00-new";s:3:"key";i:0;s:7:"keyPath";s:3:"1.0";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"0";}s:7:"chapter";s:3:"2.1";s:9:"urlRelWoF";s:18:"/cyanine-theme/new";s:6:"urlRel";s:27:"/typemill/cyanine-theme/new";s:6:"urlAbs";s:43:"http://localhost/typemill/cyanine-theme/new";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:17:"01-landingpage.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:11:"landingpage";s:4:"slug";s:11:"landingpage";s:4:"path";s:35:"/01-cyanine-theme/01-landingpage.md";s:15:"pathWithoutType";s:32:"/01-cyanine-theme/01-landingpage";s:3:"key";i:1;s:7:"keyPath";s:3:"1.1";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"1";}s:7:"chapter";s:3:"2.2";s:9:"urlRelWoF";s:26:"/cyanine-theme/landingpage";s:6:"urlRel";s:35:"/typemill/cyanine-theme/landingpage";s:6:"urlAbs";s:51:"http://localhost/typemill/cyanine-theme/landingpage";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:1;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:22:"02-content-elements.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:16:"content elements";s:4:"slug";s:16:"content-elements";s:4:"path";s:40:"/01-cyanine-theme/02-content-elements.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/02-content-elements";s:3:"key";i:2;s:7:"keyPath";s:3:"1.2";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"2";}s:7:"chapter";s:3:"2.3";s:9:"urlRelWoF";s:31:"/cyanine-theme/content-elements";s:6:"urlRel";s:40:"/typemill/cyanine-theme/content-elements";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/content-elements";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:22:"03-colors-and-fonts.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:16:"colors and fonts";s:4:"slug";s:16:"colors-and-fonts";s:4:"path";s:40:"/01-cyanine-theme/03-colors-and-fonts.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/03-colors-and-fonts";s:3:"key";i:3;s:7:"keyPath";s:3:"1.3";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"3";}s:7:"chapter";s:3:"2.4";s:9:"urlRelWoF";s:31:"/cyanine-theme/colors-and-fonts";s:6:"urlRel";s:40:"/typemill/cyanine-theme/colors-and-fonts";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/colors-and-fonts";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:4;O:8:"stdClass":20:{s:12:"originalName";s:12:"04-footer.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"04";s:4:"name";s:6:"footer";s:4:"slug";s:6:"footer";s:4:"path";s:30:"/01-cyanine-theme/04-footer.md";s:15:"pathWithoutType";s:27:"/01-cyanine-theme/04-footer";s:3:"key";i:4;s:7:"keyPath";s:3:"1.4";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"4";}s:7:"chapter";s:3:"2.5";s:9:"urlRelWoF";s:21:"/cyanine-theme/footer";s:6:"urlRel";s:30:"/typemill/cyanine-theme/footer";s:6:"urlAbs";s:46:"http://localhost/typemill/cyanine-theme/footer";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}}
\ No newline at end of file
+a:2:{i:0;O:8:"stdClass":22:{s:12:"originalName";s:10:"00-welcome";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:7:"welcome";s:4:"slug";s:7:"welcome";s:4:"path";s:11:"/00-welcome";s:15:"pathWithoutType";s:17:"/00-welcome/index";s:9:"urlRelWoF";s:8:"/welcome";s:6:"urlRel";s:17:"/typemill/welcome";s:6:"urlAbs";s:33:"http://localhost/typemill/welcome";s:3:"key";i:0;s:7:"keyPath";i:0;s:12:"keyPathArray";a:1:{i:0;s:1:"0";}s:7:"chapter";i:1;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:6:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:19:"00-markdown-test.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:13:"markdown test";s:4:"slug";s:13:"markdown-test";s:4:"path";s:31:"/00-welcome/00-markdown-test.md";s:15:"pathWithoutType";s:28:"/00-welcome/00-markdown-test";s:3:"key";i:0;s:7:"keyPath";s:3:"0.0";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"0";}s:7:"chapter";s:3:"1.1";s:9:"urlRelWoF";s:22:"/welcome/markdown-test";s:6:"urlRel";s:31:"/typemill/welcome/markdown-test";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/markdown-test";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:19:"01-manage-access.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"manage access";s:4:"slug";s:13:"manage-access";s:4:"path";s:31:"/00-welcome/01-manage-access.md";s:15:"pathWithoutType";s:28:"/00-welcome/01-manage-access";s:3:"key";i:1;s:7:"keyPath";s:3:"0.1";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"1";}s:7:"chapter";s:3:"1.2";s:9:"urlRelWoF";s:22:"/welcome/manage-access";s:6:"urlRel";s:31:"/typemill/welcome/manage-access";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/manage-access";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:14:"02-get-help.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:8:"get help";s:4:"slug";s:8:"get-help";s:4:"path";s:26:"/00-welcome/02-get-help.md";s:15:"pathWithoutType";s:23:"/00-welcome/02-get-help";s:3:"key";i:2;s:7:"keyPath";s:3:"0.2";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"2";}s:7:"chapter";s:3:"1.3";s:9:"urlRelWoF";s:17:"/welcome/get-help";s:6:"urlRel";s:26:"/typemill/welcome/get-help";s:6:"urlAbs";s:42:"http://localhost/typemill/welcome/get-help";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:24:"03-setup-your-website.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:18:"setup your website";s:4:"slug";s:18:"setup-your-website";s:4:"path";s:36:"/00-welcome/03-setup-your-website.md";s:15:"pathWithoutType";s:33:"/00-welcome/03-setup-your-website";s:3:"key";i:3;s:7:"keyPath";s:3:"0.3";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"3";}s:7:"chapter";s:3:"1.4";s:9:"urlRelWoF";s:27:"/welcome/setup-your-website";s:6:"urlRel";s:36:"/typemill/welcome/setup-your-website";s:6:"urlAbs";s:52:"http://localhost/typemill/welcome/setup-your-website";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:4;O:8:"stdClass":20:{s:12:"originalName";s:19:"04-write-content.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"04";s:4:"name";s:13:"write content";s:4:"slug";s:13:"write-content";s:4:"path";s:31:"/00-welcome/04-write-content.md";s:15:"pathWithoutType";s:28:"/00-welcome/04-write-content";s:3:"key";i:4;s:7:"keyPath";s:3:"0.4";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"4";}s:7:"chapter";s:3:"1.5";s:9:"urlRelWoF";s:22:"/welcome/write-content";s:6:"urlRel";s:31:"/typemill/welcome/write-content";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/write-content";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:5;O:8:"stdClass":20:{s:12:"originalName";s:14:"05-todos.txtmd";s:11:"elementType";s:4:"file";s:6:"status";s:8:"modified";s:8:"fileType";s:3:"txt";s:5:"order";s:2:"05";s:4:"name";s:6:"To Dos";s:4:"slug";s:5:"todos";s:4:"path";s:26:"/00-welcome/05-todos.txtmd";s:15:"pathWithoutType";s:20:"/00-welcome/05-todos";s:3:"key";i:5;s:7:"keyPath";s:3:"0.5";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"5";}s:7:"chapter";s:3:"1.6";s:9:"urlRelWoF";s:14:"/welcome/todos";s:6:"urlRel";s:23:"/typemill/welcome/todos";s:6:"urlAbs";s:39:"http://localhost/typemill/welcome/todos";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}i:1;O:8:"stdClass":22:{s:12:"originalName";s:16:"01-cyanine-theme";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"cyanine theme";s:4:"slug";s:13:"cyanine-theme";s:4:"path";s:17:"/01-cyanine-theme";s:15:"pathWithoutType";s:23:"/01-cyanine-theme/index";s:9:"urlRelWoF";s:14:"/cyanine-theme";s:6:"urlRel";s:23:"/typemill/cyanine-theme";s:6:"urlAbs";s:39:"http://localhost/typemill/cyanine-theme";s:3:"key";i:1;s:7:"keyPath";i:1;s:12:"keyPathArray";a:1:{i:0;s:1:"1";}s:7:"chapter";i:2;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:5:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:9:"00-new.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:3:"new";s:4:"slug";s:3:"new";s:4:"path";s:27:"/01-cyanine-theme/00-new.md";s:15:"pathWithoutType";s:24:"/01-cyanine-theme/00-new";s:3:"key";i:0;s:7:"keyPath";s:3:"1.0";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"0";}s:7:"chapter";s:3:"2.1";s:9:"urlRelWoF";s:18:"/cyanine-theme/new";s:6:"urlRel";s:27:"/typemill/cyanine-theme/new";s:6:"urlAbs";s:43:"http://localhost/typemill/cyanine-theme/new";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:17:"01-landingpage.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:11:"landingpage";s:4:"slug";s:11:"landingpage";s:4:"path";s:35:"/01-cyanine-theme/01-landingpage.md";s:15:"pathWithoutType";s:32:"/01-cyanine-theme/01-landingpage";s:3:"key";i:1;s:7:"keyPath";s:3:"1.1";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"1";}s:7:"chapter";s:3:"2.2";s:9:"urlRelWoF";s:26:"/cyanine-theme/landingpage";s:6:"urlRel";s:35:"/typemill/cyanine-theme/landingpage";s:6:"urlAbs";s:51:"http://localhost/typemill/cyanine-theme/landingpage";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:1;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:22:"02-content-elements.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:16:"content elements";s:4:"slug";s:16:"content-elements";s:4:"path";s:40:"/01-cyanine-theme/02-content-elements.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/02-content-elements";s:3:"key";i:2;s:7:"keyPath";s:3:"1.2";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"2";}s:7:"chapter";s:3:"2.3";s:9:"urlRelWoF";s:31:"/cyanine-theme/content-elements";s:6:"urlRel";s:40:"/typemill/cyanine-theme/content-elements";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/content-elements";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:22:"03-colors-and-fonts.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:16:"colors and fonts";s:4:"slug";s:16:"colors-and-fonts";s:4:"path";s:40:"/01-cyanine-theme/03-colors-and-fonts.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/03-colors-and-fonts";s:3:"key";i:3;s:7:"keyPath";s:3:"1.3";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"3";}s:7:"chapter";s:3:"2.4";s:9:"urlRelWoF";s:31:"/cyanine-theme/colors-and-fonts";s:6:"urlRel";s:40:"/typemill/cyanine-theme/colors-and-fonts";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/colors-and-fonts";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:4;O:8:"stdClass":20:{s:12:"originalName";s:12:"04-footer.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"04";s:4:"name";s:6:"footer";s:4:"slug";s:6:"footer";s:4:"path";s:30:"/01-cyanine-theme/04-footer.md";s:15:"pathWithoutType";s:27:"/01-cyanine-theme/04-footer";s:3:"key";i:4;s:7:"keyPath";s:3:"1.4";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"4";}s:7:"chapter";s:3:"2.5";s:9:"urlRelWoF";s:21:"/cyanine-theme/footer";s:6:"urlRel";s:30:"/typemill/cyanine-theme/footer";s:6:"urlAbs";s:46:"http://localhost/typemill/cyanine-theme/footer";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}}
\ No newline at end of file
diff --git a/data/navigation/navi-extended.txt b/data/navigation/navi-extended.txt
index d951ffa..85722fa 100644
--- a/data/navigation/navi-extended.txt
+++ b/data/navigation/navi-extended.txt
@@ -38,7 +38,7 @@
navtitle: 'To Dos'
hide: false
noindex: false
- path: /00-welcome/05-todos.md
+ path: /00-welcome/05-todos.txtmd
keyPath: '0.5'
/cyanine-theme:
navtitle: 'cyanine theme'
@@ -50,7 +50,7 @@
navtitle: new
hide: false
noindex: false
- path: /01-cyanine-theme/00-new.txt
+ path: /01-cyanine-theme/00-new.md
keyPath: '1.0'
/cyanine-theme/landingpage:
navtitle: landingpage
diff --git a/data/security/securitylog.txt b/data/security/securitylog.txt
new file mode 100644
index 0000000..4687ad8
--- /dev/null
+++ b/data/security/securitylog.txt
@@ -0,0 +1,4 @@
+127.0.0.1;2023-07-26 15:15:18;wrong input for password recovery
+127.0.0.1;2023-07-26 15:24:27;wrong input for password recovery
+127.0.0.1;2023-07-26 15:25:30;wrong input for password recovery
+127.0.0.1;2023-07-29 22:34:30;wrong login
diff --git a/system/typemill/Controllers/Controller.php b/system/typemill/Controllers/Controller.php
index 3d85cbd..b177230 100644
--- a/system/typemill/Controllers/Controller.php
+++ b/system/typemill/Controllers/Controller.php
@@ -101,7 +101,7 @@ abstract class Controller
}
protected function addDatasets(array $formDefinitions)
- {
+ {
foreach($formDefinitions as $fieldname => $field)
{
if(isset($field['type']) && $field['type'] == 'fieldset')
@@ -109,15 +109,25 @@ abstract class Controller
$formDefinitions[$fieldname]['fields'] = $this->addDatasets($field['fields']);
}
- if(isset($field['type']) && ($field['type'] == 'select' ) && isset($field['dataset']) && ($field['dataset'] == 'userroles' ) )
+ if(isset($field['type']) && ($field['type'] == 'select' ) )
{
- $userroles = [null => null];
- foreach($this->c->get('acl')->getRoles() as $userrole)
+ # always add null as first option in selectboxes.
+ $options = [null => null];
+
+ if(is_array($field['options']))
{
- $userroles[$userrole] = $userrole;
+ $options = array_merge($options, $field['options']);
}
- $formDefinitions[$fieldname]['options'] = $userroles;
+ if(isset($field['dataset']) && ($field['dataset'] == 'userroles' ))
+ {
+ foreach($this->c->get('acl')->getRoles() as $userrole)
+ {
+ $options[$userrole] = $userrole;
+ }
+ }
+
+ $formDefinitions[$fieldname]['options'] = $options;
}
}
@@ -178,6 +188,12 @@ abstract class Controller
{
$fieldvalue = $input[$fieldname];
+ # fix false or null values for selectboxes
+ if($fielddefinitions['type'] == "select" && ($fieldvalue === 'NULL' OR $fieldvalue === false))
+ {
+ $fieldvalue = NULL;
+ }
+
$validationresult = $validator->field($fieldname, $fieldvalue, $fielddefinitions);
if($validationresult === true)
diff --git a/system/typemill/Controllers/ControllerApiSystemExtensions.php b/system/typemill/Controllers/ControllerApiSystemExtensions.php
index b46de04..1b557fc 100644
--- a/system/typemill/Controllers/ControllerApiSystemExtensions.php
+++ b/system/typemill/Controllers/ControllerApiSystemExtensions.php
@@ -7,7 +7,7 @@ use Psr\Http\Message\ResponseInterface as Response;
use Typemill\Models\Validation;
use Typemill\Models\License;
use Typemill\Models\Extension;
-use Typemill\Static\Settings;
+use Typemill\Models\Settings;
class ControllerApiSystemExtensions extends Controller
{
@@ -79,7 +79,8 @@ class ControllerApiSystemExtensions extends Controller
}
# store updated settings here
- $updatedSettings = Settings::updateSettings($objectdata);
+ $settings = new Settings();
+ $updatedSettings = $settings->updateSettings($objectdata);
$response->getBody()->write(json_encode([
'message' => 'settings have been saved'
diff --git a/system/typemill/Controllers/ControllerApiSystemPlugins.php b/system/typemill/Controllers/ControllerApiSystemPlugins.php
index b35377b..a9bd73d 100644
--- a/system/typemill/Controllers/ControllerApiSystemPlugins.php
+++ b/system/typemill/Controllers/ControllerApiSystemPlugins.php
@@ -6,7 +6,7 @@ use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Typemill\Models\Validation;
use Typemill\Models\Extension;
-use Typemill\Static\Settings;
+use Typemill\Models\Settings;
class ControllerApiSystemPlugins extends Controller
{
@@ -43,7 +43,8 @@ class ControllerApiSystemPlugins extends Controller
$plugindata['plugins'][$pluginname] = $validatedOutput;
# store updated settings here
- $updatedSettings = Settings::updateSettings($plugindata);
+ $settings = new Settings();
+ $updatedSettings = $settings->updateSettings($plugindata);
$response->getBody()->write(json_encode([
'message' => 'settings have been saved'
diff --git a/system/typemill/Controllers/ControllerApiSystemSettings.php b/system/typemill/Controllers/ControllerApiSystemSettings.php
index 70c6d1a..f1ef5c8 100644
--- a/system/typemill/Controllers/ControllerApiSystemSettings.php
+++ b/system/typemill/Controllers/ControllerApiSystemSettings.php
@@ -7,7 +7,7 @@ use Psr\Http\Message\ResponseInterface as Response;
use Typemill\Models\Validation;
use Typemill\Models\Extension;
use Typemill\Models\User;
-use Typemill\Static\Settings;
+use Typemill\Models\Settings;
# how to translate results in API call ???
@@ -28,8 +28,9 @@ class ControllerApiSystemSettings extends Controller
{
$params = $request->getParsedBody();
$settingsinput = $params['settings'];
+ $settingsModel = new Settings();
- $formdefinitions = Settings::getSettingsDefinitions();
+ $formdefinitions = $settingsModel->getSettingsDefinitions();
# validate input
$validator = new Validation();
@@ -46,7 +47,7 @@ class ControllerApiSystemSettings extends Controller
}
# store updated settings here
- $updatedSettings = Settings::updateSettings($validatedOutput);
+ $updatedSettings = $settingsModel->updateSettings($validatedOutput);
$response->getBody()->write(json_encode([
'message' => 'settings have been saved',
diff --git a/system/typemill/Controllers/ControllerApiSystemThemes.php b/system/typemill/Controllers/ControllerApiSystemThemes.php
index ba17545..646fefa 100644
--- a/system/typemill/Controllers/ControllerApiSystemThemes.php
+++ b/system/typemill/Controllers/ControllerApiSystemThemes.php
@@ -6,7 +6,7 @@ use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Typemill\Models\Validation;
use Typemill\Models\Extension;
-use Typemill\Static\Settings;
+use Typemill\Models\Settings;
class ControllerApiSystemThemes extends Controller
{
@@ -36,7 +36,8 @@ class ControllerApiSystemThemes extends Controller
$themedata['themes'][$themename] = $validatedOutput;
# store updated settings here
- $updatedSettings = Settings::updateSettings($themedata);
+ $settings = new Settings();
+ $updatedSettings = $settings->updateSettings($themedata);
$response->getBody()->write(json_encode([
'message' => 'settings have been saved',
diff --git a/system/typemill/Controllers/ControllerWebAuth.php b/system/typemill/Controllers/ControllerWebAuth.php
index 481c38f..68f076c 100644
--- a/system/typemill/Controllers/ControllerWebAuth.php
+++ b/system/typemill/Controllers/ControllerWebAuth.php
@@ -22,6 +22,7 @@ class ControllerWebAuth extends Controller
if( ( null !== $request->getattribute('csrf_result') ) OR ( $request->getattribute('csrf_result') === false ) )
{
$this->c->flash->addMessage('error', 'The form has a timeout, please try again.');
+
return $response->withHeader('Location', $this->routeParser->urlFor('auth.show'));
}
@@ -53,9 +54,8 @@ class ControllerWebAuth extends Controller
$user->login();
-return $response->withHeader('Location', $this->routeParser->urlFor('settings.show'))->withStatus(302);
+# return $response->withHeader('Location', $this->routeParser->urlFor('settings.show'))->withStatus(302);
-/*
# if user is allowed to view content-area
$acl = $this->c->get('acl');
if($acl->hasRole($userdata['userrole']) && $acl->isAllowed($userdata['userrole'], 'content', 'view'))
@@ -66,7 +66,6 @@ return $response->withHeader('Location', $this->routeParser->urlFor('settings.sh
}
return $response->withHeader('Location', $this->routeParser->urlFor('user.account'))->withStatus(302);
-*/
}
}
diff --git a/system/typemill/Controllers/ControllerWebFrontend.php b/system/typemill/Controllers/ControllerWebFrontend.php
index e372e81..06613d2 100644
--- a/system/typemill/Controllers/ControllerWebFrontend.php
+++ b/system/typemill/Controllers/ControllerWebFrontend.php
@@ -19,12 +19,6 @@ use Typemill\Events\OnHtmlLoaded;
use Typemill\Events\OnRestrictionsLoaded;
-/*
-use Typemill\Models\Folder;
-use Typemill\Models\WriteMeta;
-use Typemill\Extensions\ParsedownExtension;
-*/
-
class ControllerWebFrontend extends Controller
{
public function index(Request $request, Response $response, $args)
@@ -131,7 +125,7 @@ class ControllerWebFrontend extends Controller
if($restrictions['defaultContent'])
{
# cut the restricted content
- $shortenedPage = $this->cutRestrictedContent($markdownBlocks);
+ $shortenedPage = $this->cutRestrictedContent($markdownArray);
# check if there is customized content
$restrictionnotice = $this->prepareRestrictionNotice();
diff --git a/system/typemill/Controllers/ControllerWebRecover.php b/system/typemill/Controllers/ControllerWebRecover.php
new file mode 100644
index 0000000..d3732b2
--- /dev/null
+++ b/system/typemill/Controllers/ControllerWebRecover.php
@@ -0,0 +1,338 @@
+c->get('view')->render($response, '/auth/recover.twig', [
+
+ ]);
+ }
+
+ public function recoverPassword(Request $request, Response $response)
+ {
+ $params = $request->getParsedBody();
+ $settings = $this->c->get('settings');
+ $urlinfo = $this->c->get('urlinfo');
+
+ if(!isset($params['email']) OR filter_var($params['email'], \FILTER_VALIDATE_EMAIL) === false )
+ {
+ $this->c->get('flash')->addMessage('error', 'Please enter a valid email.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.recoverform'))->withStatus(302);
+ }
+
+ $title = 'Please check your inbox';
+ $message = 'Dear user, please check the inbox of your email account for more instructions.';
+
+ $user = new User();
+ $requiredUser = $user->findUsersByEmail($params['email']);
+
+ if($requiredUser)
+ {
+ $user->setUserWithPassword($requiredUser[0]);
+
+ $requiredUser = $user->getUserData();
+ $recoverdate = date("Y-m-d H:i:s");
+ $recovertoken = bin2hex(random_bytes(32));
+
+ $url = $urlinfo['baseurl'] . '/tm/reset?username=' . $requiredUser['username'] . '&recovertoken=' . $recovertoken;
+ $link = '' . $url . '';
+
+ # define the headers
+ $headers = 'Content-Type: text/html; charset=utf-8' . "\r\n";
+ $headers .= 'Content-Transfer-Encoding: base64' . "\r\n";
+ if(isset($settings['recoverfrom']) && $settings['recoverfrom'] != '')
+ {
+ $headers .= 'From: ' . $settings['recoverfrom'];
+ }
+
+ $subjectline = (isset($settings['recoversubject']) && ($settings['recoversubject'] != '') ) ? $settings['recoversubject'] : 'Recover your password';
+ $subject = '=?UTF-8?B?' . base64_encode($subjectline) . '?=';
+
+ $messagetext = "Dear user,
please use the following link to set a new password:";
+ if(isset($settings['recovermessage']) && ($settings['recovermessage'] != ''))
+ {
+ $parsedown = new ParsedownExtension($urlinfo['baseurl']);
+ $parsedown->setSafeMode(true);
+
+ $contentArray = $parsedown->text($settings['recovermessage']);
+ $messagetext = $parsedown->markup($contentArray);
+ }
+
+ $message = base64_encode($messagetext . "
" . $link);
+
+ # $send = mail($requiredUser['email'], $subject, $message, $headers);
+
+ $send = false;
+
+ if($send == 'delete')
+ {
+ $title = 'Error sending email';
+ $message = 'Dear ' . $requiredUser['username'] . ', we could not send the email with the password instructions to your address. Please contact the website owner and ask for help.';
+ }
+ else
+ {
+ # update user
+ $user->setValue('recoverdate', $recoverdate);
+ $user->setValue('recovertoken', $recovertoken);
+ $user->updateUser();
+
+ $title = 'Please check your inbox';
+ $message = 'Dear ' . $requiredUser['username'] . ', please check the inbox of your email account for more instructions. Do not forget to check your spam-folder if your inbox is empty.';
+ }
+ }
+ elseif(isset($settings['securitylog']) && $settings['securitylog'])
+ {
+ \Typemill\Static\Helpers::addLogEntry('wrong input for password recovery');
+ }
+
+ return $this->c->get('view')->render($response, '/auth/recoverconf.twig', [
+ 'title' => $title,
+ 'message' => $message
+ ]);
+ }
+
+ public function showPasswordResetForm(Request $request, Response $response, $args)
+ {
+ $params = $request->getQueryParams();
+ $securitylog = ( isset($settings['securitylog']) && $settings['securitylog'] ) ? true : false;
+
+ if(!isset($params['username']) OR !isset($params['recovertoken']))
+ {
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('wrong password reset link');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'You tried to open the password reset page but the link was invalid.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+ $user = new User();
+ $requiredUser = $user->setUserWithPassword($params['username']);
+
+ if(!$requiredUser)
+ {
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('password reset link user not found');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'You tried to open the password reset page but the link was invalid.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+ $requiredUser = $user->getUserData();
+
+ if(!isset($requiredUser['recovertoken']) OR $requiredUser['recovertoken'] != $params['recovertoken'] )
+ {
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('password reset link wrong token');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'You tried to open the password reset page but the link was invalid.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+ $recoverdate = isset($requiredUser['recoverdate']) ? $requiredUser['recoverdate'] : false;
+
+ if(!$recoverdate)
+ {
+ $user->unsetValue('recovertoken');
+ $user->updateUser();
+
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('password reset link outdated');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'The link to recover the password was too old. Please create a new one.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+ $now = new \DateTime('NOW');
+ $recoverdate = new \DateTime($recoverdate);
+
+ if(!$recoverdate)
+ {
+ $user->unsetValue('recovertoken');
+ $user->unsetValue('recoverdate');
+ $user->updateUser();
+
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('password reset link wrong date format');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'The link to recover the password was too old. Please create a new one.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+# here we should make the interval editable
+ $validDate = $recoverdate->add(new \DateInterval('P1D'));
+
+ if($validDate <= $now)
+ {
+ $user->unsetValue('recovertoken');
+ $user->unsetValue('recoverdate');
+ $user->updateUser();
+
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('password reset link outdated');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'The link to recover the password was too old. Please create a new one.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+ return $this->c->get('view')->render($response, '/auth/reset.twig', [
+ 'recovertoken' => $params['recovertoken'],
+ 'username' => $requiredUser['username']
+ ]);
+ }
+
+ public function resetPassword(Request $request, Response $response, $args)
+ {
+ $params = $request->getParsedBody();
+ $settings = $this->c->get('settings');
+ $urlinfo = $this->c->get('urlinfo');
+
+ if(!isset($params['username']) OR !isset($params['recovertoken']))
+ {
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('create reset password username or token missing');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'You tried to set a new password but username or token was invalid.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+ $validation = new Validation();
+
+ if(!$validation->recoverPassword($params))
+ {
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('create reset password wrong input');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'Please correct your input.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.resetform', [], ['username' => $params['username'], 'recovertoken' => $params['recovertoken']]))->withStatus(302);
+ }
+
+ $user = new User();
+ $requiredUser = $user->setUserWithPassword($params['username']);
+ if(!$requiredUser)
+ {
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('create reset password user not found');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'You tried to open the password reset page but the link was invalid.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+ $requiredUser = $user->getUserData();
+
+ if(!isset($requiredUser['recovertoken']) OR $requiredUser['recovertoken'] != $params['recovertoken'] )
+ {
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('create reset password wrong token');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'You tried to open the password reset page but the link was invalid.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+ $recoverdate = isset($requiredUser['recoverdate']) ? $requiredUser['recoverdate'] : false;
+
+ if(!$recoverdate)
+ {
+ $user->unsetValue('recovertoken');
+ $user->updateUser();
+
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('create reset password date outdated');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'The link to recover the password was too old. Please create a new one.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+ $now = new \DateTime('NOW');
+ $recoverdate = new \DateTime($recoverdate);
+
+ if(!$recoverdate)
+ {
+ $user->unsetValue('recovertoken');
+ $user->unsetValue('recoverdate');
+ $user->updateUser();
+
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('create reset password wrong date format');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'The link to recover the password was too old. Please create a new one.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+# here we should make the interval editable
+ $validDate = $recoverdate->add(new \DateInterval('P1D'));
+
+ if($validDate <= $now)
+ {
+ $user->unsetValue('recovertoken');
+ $user->unsetValue('recoverdate');
+ $user->updateUser();
+
+ if($securitylog)
+ {
+ \Typemill\Static\Helpers::addLogEntry('create reset password outdated');
+ }
+
+ $this->c->get('flash')->addMessage('error', 'The link to recover the password was too old. Please create a new one.');
+
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+
+ $user->unsetValue('recovertoken');
+ $user->unsetValue('recoverdate');
+ $password = $user->generatePassword($params['password']);
+ $user->setValue('password', $password);
+ $user->updateUser();
+
+ unset($_SESSION['old']);
+
+ $this->c->get('flash')->addMessage('info', 'Please login with your new password.');
+ return $response->withHeader('Location', $this->routeParser->urlFor('auth.login'))->withStatus(302);
+ }
+}
\ No newline at end of file
diff --git a/system/typemill/Controllers/ControllerWebSetup.php b/system/typemill/Controllers/ControllerWebSetup.php
new file mode 100644
index 0000000..cf65c18
--- /dev/null
+++ b/system/typemill/Controllers/ControllerWebSetup.php
@@ -0,0 +1,99 @@
+checkFolder('settingsFolder'))
+ {
+ $systemerrors[] = $storage->getError();
+ }
+ if( !$storage->checkFolder('settingsFolder', 'users')){ $systemerrors[] = $storage->getError(); }
+ if( !$storage->checkFolder('contentFolder')){ $systemerrors[] = $storage->getError(); }
+ if( !$storage->checkFolder('dataFolder')){ $systemerrors[] = $storage->getError(); }
+ if( !$storage->checkFolder('cacheFolder')){ $systemerrors[] = $storage->getError(); }
+ if( !$storage->checkFolder('tmpFolder')){ $systemerrors[] = $storage->getError(); }
+ if( !$storage->checkFolder('originalFolder')){ $systemerrors[] = $storage->getError(); }
+ if( !$storage->checkFolder('liveFolder')){ $systemerrors[] = $storage->getError(); }
+ if( !$storage->checkFolder('thumbsFolder')){ $systemerrors[] = $storage->getError(); }
+ if( !$storage->checkFolder('customFolder')){ $systemerrors[] = $storage->getError(); }
+ if( !$storage->checkFolder('fileFolder')){ $systemerrors[] = $storage->getError(); }
+
+ # check php-version
+ if (version_compare(phpversion(), '8.3.0', '<'))
+ {
+ $systemerrors[] = 'The PHP-version of your server is ' . phpversion() . ' and Typemill needs at least 8.0.0';
+ }
+
+ # check if extensions are loaded
+ if(!extension_loaded('gd')){ $systemerrors[] = 'The php-extension GD for image manipulation is not enabled.'; }
+ if(!extension_loaded('mbstring')){ $systemerrors[] = 'The php-extension mbstring is not enabled.'; }
+ if(!extension_loaded('fileinfo')){ $systemerrors[] = 'The php-extension fileinfo is not enabled.'; }
+ if(!extension_loaded('session')){ $systemerrors[] = 'The php-extension session is not enabled.'; }
+ if(!extension_loaded('iconv')){ $systemerrors[] = 'The php-extension iconv is not enabled.'; }
+
+ $systemerrors = empty($systemerrors) ? false : $systemerrors;
+
+ return $this->c->get('view')->render($response, 'auth/setup.twig', [
+ 'systemerrors' => $systemerrors
+ ]);
+ }
+
+ public function create(Request $request, Response $response, $args)
+ {
+ $params = $request->getParsedBody();
+ $params['userrole'] = 'administrator';
+ $validate = new Validation();
+ $user = new User();
+
+ # get userroles for validation
+ $userroles = $this->c->get('acl')->getRoles();
+
+ # validate user
+ if($validate->newUser($params, $userroles))
+ {
+ $userdata = [
+ 'username' => $params['username'],
+ 'email' => $params['email'],
+ 'userrole' => $params['userrole'],
+ 'password' => $params['password']
+ ];
+
+ $user = new User();
+
+ # create initial user
+ $username = $user->createUser($userdata);
+
+ if($username)
+ {
+ $user->setUser($username);
+
+ $user->login();
+
+ # create initial settings file
+ $settingsModel = new Settings();
+ $settingsModel->createSettings();
+
+ $urlinfo = $this->c->get('urlinfo');
+ $route = $urlinfo['baseurl'] . '/tm/system';
+
+ return $response->withHeader('Location', $route)->withStatus(302);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/system/typemill/Controllers/ControllerWebSystem.php b/system/typemill/Controllers/ControllerWebSystem.php
index 8f371ce..e97de6e 100644
--- a/system/typemill/Controllers/ControllerWebSystem.php
+++ b/system/typemill/Controllers/ControllerWebSystem.php
@@ -6,7 +6,7 @@ use Typemill\Models\Navigation;
use Typemill\Models\Extension;
use Typemill\Models\User;
use Typemill\Models\License;
-use Typemill\Static\Settings;
+use Typemill\Models\Settings;
class ControllerWebSystem extends Controller
{
@@ -26,7 +26,9 @@ class ControllerWebSystem extends Controller
$urlinfo = $this->c->get('urlinfo')
);
- $systemfields = Settings::getSettingsDefinitions();
+ $settingsModel = new Settings();
+ $systemfields = $settingsModel->getSettingsDefinitions();
+ $systemfields = $this->addDatasets($systemfields);
# add full url for sitemap to settings
$this->settings['sitemap'] = $this->c->get('urlinfo')['baseurl'] . '/cache/sitemap.xml';
diff --git a/system/typemill/Middleware/OldInputMiddleware.php b/system/typemill/Middleware/OldInputMiddleware.php
new file mode 100644
index 0000000..fbbc619
--- /dev/null
+++ b/system/typemill/Middleware/OldInputMiddleware.php
@@ -0,0 +1,36 @@
+view = $view;
+ }
+
+ public function __invoke(Request $request, RequestHandler $handler)
+ {
+ if(isset($_SESSION))
+ {
+ if(isset($_SESSION['old']))
+ {
+ $this->view->getEnvironment()->addGlobal('old', $_SESSION['old']);
+ }
+ if(!empty($request->getParsedBody()))
+ {
+ $_SESSION['old'] = $request->getParsedBody();
+ }
+ }
+
+ $response = $handler->handle($request);
+
+ return $response;
+ }
+}
\ No newline at end of file
diff --git a/system/typemill/Middleware/SessionMiddleware.php b/system/typemill/Middleware/SessionMiddleware.php
index 4e2614a..32e45f1 100644
--- a/system/typemill/Middleware/SessionMiddleware.php
+++ b/system/typemill/Middleware/SessionMiddleware.php
@@ -24,7 +24,7 @@ class SessionMiddleware implements MiddlewareInterface
public function process(Request $request, RequestHandler $handler) :response
{
- # start session for routes
+ # start session
Session::startSessionForSegments($this->segments, $this->route);
$authenticated = (
diff --git a/system/typemill/Middleware/ValidationErrorsMiddleware.php b/system/typemill/Middleware/ValidationErrorsMiddleware.php
new file mode 100644
index 0000000..74c8a79
--- /dev/null
+++ b/system/typemill/Middleware/ValidationErrorsMiddleware.php
@@ -0,0 +1,38 @@
+view = $view;
+ }
+
+ public function __invoke(Request $request, RequestHandler $handler)
+ {
+ if(isset($_SESSION['errors']))
+ {
+ $this->view->getEnvironment()->addGlobal('errors', $_SESSION['errors']);
+
+ unset($_SESSION['errors']);
+ }
+
+ if(isset($_SESSION['phrase']))
+ {
+ $this->view->getEnvironment()->addGlobal('errors', ['captcha' => 'the captcha is wrong, please try again']);
+
+ unset($_SESSION['phrase']);
+ }
+
+ $response = $handler->handle($request);
+
+ return $response;
+ }
+}
\ No newline at end of file
diff --git a/system/typemill/Models/Extension.php b/system/typemill/Models/Extension.php
index 6ff17a4..dd90fa5 100644
--- a/system/typemill/Models/Extension.php
+++ b/system/typemill/Models/Extension.php
@@ -40,7 +40,7 @@ class Extension
public function getThemes()
{
- $themeFolder = $this->storage->getFolderPath('themeFolder');
+ $themeFolder = $this->storage->getFolderPath('themesFolder');
$themeFolderC = scandir($themeFolder);
$themes = [];
foreach ($themeFolderC as $key => $theme)
@@ -59,7 +59,7 @@ class Extension
public function getThemeDefinition($themeName)
{
- $themeSettings = $this->storage->getYaml('themeFolder', $themeName, $themeName . '.yaml');
+ $themeSettings = $this->storage->getYaml('themesFolder', $themeName, $themeName . '.yaml');
# add standard-textarea for custom css
$themeSettings['forms']['fields']['customcss'] = [
@@ -101,7 +101,7 @@ class Extension
public function getPlugins()
{
- $pluginFolder = $this->storage->getFolderPath('pluginFolder');
+ $pluginFolder = $this->storage->getFolderPath('pluginsFolder');
$pluginFolderC = scandir($pluginFolder);
$plugins = [];
foreach ($pluginFolderC as $key => $plugin)
@@ -120,7 +120,7 @@ class Extension
public function getPluginDefinition($pluginName)
{
- $pluginSettings = $this->storage->getYaml('pluginFolder', $pluginName, $pluginName . '.yaml');
+ $pluginSettings = $this->storage->getYaml('pluginsFolder', $pluginName, $pluginName . '.yaml');
return $pluginSettings;
}
diff --git a/system/typemill/Models/Meta.php b/system/typemill/Models/Meta.php
index cf62be2..4bfeaa8 100644
--- a/system/typemill/Models/Meta.php
+++ b/system/typemill/Models/Meta.php
@@ -4,6 +4,7 @@ namespace Typemill\Models;
use Typemill\Models\StorageWrapper;
use Typemill\Models\Content;
+use Typemill\Models\Settings;
class Meta
{
@@ -36,7 +37,8 @@ class Meta
public function getMetaDefinitions($settings, $folder)
{
- $metadefinitions = $this->storage->getYaml('systemSettings', '', 'metatabs.yaml');
+ $metadefinitions = $this->storage->getYaml('systemSettings', '', 'metatabs.yaml');
+ $settingsModel = new Settings();
# loop through all plugins
if(!empty($settings['plugins']))
@@ -45,7 +47,7 @@ class Meta
{
if($plugin['active'])
{
- $pluginSettings = \Typemill\Static\Settings::getObjectSettings('plugins', $name);
+ $pluginSettings = $settingsModel->getObjectSettings('pluginsFolder', $name);
if($pluginSettings && isset($pluginSettings['metatabs']))
{
$metadefinitions = array_merge_recursive($metadefinitions, $pluginSettings['metatabs']);
@@ -55,7 +57,7 @@ class Meta
}
# add the meta from theme settings here
- $themeSettings = \Typemill\Static\Settings::getObjectSettings('themes', $settings['theme']);
+ $themeSettings = $settingsModel->getObjectSettings('themesFolder', $settings['theme']);
if($themeSettings && isset($themeSettings['metatabs']))
{
diff --git a/system/typemill/Models/Settings.php b/system/typemill/Models/Settings.php
new file mode 100644
index 0000000..290a63f
--- /dev/null
+++ b/system/typemill/Models/Settings.php
@@ -0,0 +1,160 @@
+storage = new StorageWrapper('\Typemill\Models\Storage');
+ }
+
+ public function loadSettings()
+ {
+ $defaultsettings = $this->getDefaultSettings();
+ $usersettings = $this->getUserSettings();
+
+ $settings = $defaultsettings;
+ $settings['setup'] = true;
+
+ if($usersettings)
+ {
+ $settings = array_merge($defaultsettings, $usersettings);
+
+ # make sure all image-size information are there
+ if(isset($usersettings['images']))
+ {
+ $images = array_merge($defaultsettings['images'], $settings['images']);
+ $settings['images'] = $images;
+ }
+ }
+####
+ $settings['rootPath'] = getcwd();
+####
+ $settings = self::addThemeSettings($settings);
+
+ return $settings;
+ }
+
+ public function addThemeSettings($settings)
+ {
+ # we have to check if the theme has been deleted
+ $themefolder = $this->storage->getFolderPath('themesFolder');
+
+ # if there is no theme in settings or theme has been deleted
+ if(!isset($settings['theme']) OR !file_exists($themefolder . $settings['theme']))
+ {
+ # scan theme folder and get the first theme
+ $themes = array_filter(scandir($themefolder), function ($item) use($themefolder)
+ {
+ return is_dir($themefolder . $item) && strpos($item, '.') !== 0;
+ });
+
+ $firsttheme = reset($themes);
+
+ # if there is a theme with an index.twig-file
+ if($firsttheme && file_exists($themefolder . $firsttheme . DIRECTORY_SEPARATOR . 'index.twig'))
+ {
+ $settings['theme'] = $firsttheme;
+ }
+ else
+ {
+ die('You need at least one theme with an index.twig-file in your theme-folder.');
+ }
+ }
+
+ # We have the theme so create the theme path
+# $settings['themePath'] = $settings['rootPath'] . $settings['themeFolder'] . DIRECTORY_SEPARATOR . $settings['theme'];
+
+ # if there are no theme settings yet (e.g. no setup yet) use default theme settings
+ if(!isset($settings['themes']))
+ {
+ $themeSettings = $this->getObjectSettings('themes', $settings['theme']);
+ $settings['themes'][$settings['theme']] = isset($themeSettings['settings']) ? $themeSettings['settings'] : false;
+ }
+
+ return $settings;
+ }
+
+ public function getDefaultSettings()
+ {
+ $defaultSettings = $this->storage->getYaml('systemSettings', '', 'defaults.yaml');
+
+ if($defaultSettings)
+ {
+ $defaultSettings['systemSettingsPath'] = $this->storage->getFolderPath('systemSettings');
+
+ return $defaultSettings;
+ }
+
+ return false;
+ }
+
+ public function getUserSettings()
+ {
+ $userSettings = $this->storage->getYaml('settingsFolder', '', 'settings.yaml');
+
+ if($userSettings)
+ {
+ return $userSettings;
+ }
+
+ return false;
+ }
+
+ public function getObjectSettings($objectType, $objectName)
+ {
+ $objectSettings = $this->storage->getYaml($objectType, $objectName, $objectName . '.yaml');
+
+ if($objectSettings)
+ {
+ return $objectSettings;
+ }
+
+ return false;
+ }
+
+ public function updateSettings(array $newSettings)
+ {
+ $userSettings = $this->getUserSettings();
+
+ # only allow if usersettings already exists (setup has been done)
+ if($userSettings)
+ {
+ # merge usersettings with new settings
+ $settings = array_merge($userSettings, $newSettings);
+
+ if($this->storage->updateYaml('settingsFolder', '', 'settings.yaml', $settings))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function getSettingsDefinitions()
+ {
+ return $this->storage->getYaml('systemSettings', '', 'system.yaml');
+ }
+
+ public function createSettings()
+ {
+ $language = Translations::whichLanguage();
+
+ $initialSettings = $this->storage->updateYaml('settingsFolder', '', 'settings.yaml', [
+ 'language' => $language
+ ]);
+
+ if($initialSettings)
+ {
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/system/typemill/Models/Storage.php b/system/typemill/Models/Storage.php
index 1cbb588..1eae04a 100644
--- a/system/typemill/Models/Storage.php
+++ b/system/typemill/Models/Storage.php
@@ -8,7 +8,7 @@ class Storage
{
public $error = false;
- protected $basepath = false;
+ private $basepath = false;
protected $tmpFolder = false;
@@ -30,9 +30,9 @@ class Storage
protected $settingsFolder = false;
- protected $themeFolder = false;
+ protected $themesFolder = false;
- protected $pluginFolder = false;
+ protected $pluginsFolder = false;
protected $translationFolder = false;
@@ -62,9 +62,9 @@ class Storage
$this->settingsFolder = $this->basepath . 'settings';
- $this->pluginFolder = $this->basepath . 'plugins';
+ $this->pluginsFolder = $this->basepath . 'plugins';
- $this->themeFolder = $this->basepath . 'themes';
+ $this->themesFolder = $this->basepath . 'themes';
$this->translationFolder = $this->basepath . 'system' . DIRECTORY_SEPARATOR . 'typemill' . DIRECTORY_SEPARATOR . 'author' . DIRECTORY_SEPARATOR . 'translations' . DIRECTORY_SEPARATOR;
@@ -78,6 +78,10 @@ class Storage
public function getFolderPath($location, $folder = NULL)
{
+ # security: remove ../ from location
+ # security: make sure user does not write into basepath
+ # security: write only into certain folders
+
if(isset($this->$location))
{
$path = rtrim($this->$location, DIRECTORY_SEPARATOR);
@@ -97,7 +101,7 @@ class Storage
return false;
}
- public function checkFolder($location, $folder)
+ public function checkFolder($location, $folder = NULL)
{
$folderpath = $this->getFolderPath($location, $folder);
@@ -367,6 +371,12 @@ class Storage
$extension = isset($pathinfo['extension']) ? strtolower($pathinfo['extension']) : false;
$imagename = isset($pathinfo['filename']) ? $pathinfo['filename'] : false;
+ if(!$extension OR !$imagename)
+ {
+ $this->error = "Extension or name for image is missing.";
+ return false;
+ }
+
$imagesInTmp = glob($this->tmpFolder . "*$imagename.*");
if(empty($imagesInTmp) OR !$imagesInTmp)
{
diff --git a/system/typemill/Models/User.php b/system/typemill/Models/User.php
index b8bcdba..a7acf1e 100644
--- a/system/typemill/Models/User.php
+++ b/system/typemill/Models/User.php
@@ -116,7 +116,7 @@ class User
}
public function updateUser()
- {
+ {
if($this->storage->updateYaml('settingsFolder', 'users', $this->user['username'] . '.yaml', $this->user))
{
$this->deleteUserIndex();
diff --git a/system/typemill/Models/Validation.php b/system/typemill/Models/Validation.php
index 8ddd6b3..6369173 100644
--- a/system/typemill/Models/Validation.php
+++ b/system/typemill/Models/Validation.php
@@ -559,11 +559,11 @@ class Validation
* @return obj $v the validation object passed to a result method.
*/
- public function recoverPasswordBREAK(array $params)
+ public function recoverPassword(array $params)
{
$v = new Validator($params);
$v->rule('required', ['password', 'passwordrepeat']);
- $v->rule('lengthBetween', 'password', 5, 20);
+ $v->rule('lengthBetween', 'password', 5, 50);
$v->rule('equals', 'passwordrepeat', 'password');
return $this->validationResult($v);
diff --git a/system/typemill/Static/Helpers.php b/system/typemill/Static/Helpers.php
index b95cd6f..f3c443d 100644
--- a/system/typemill/Static/Helpers.php
+++ b/system/typemill/Static/Helpers.php
@@ -59,7 +59,7 @@ class Helpers{
$line .= ';' . $action;
$storage = new StorageWrapper('\Typemill\Models\Storage');
- $logfile = $storage->getFile('basepath', 'cache', 'securitylog.txt');
+ $logfile = $storage->getFile('dataFolder', 'security', 'securitylog.txt');
if($logfile)
{
@@ -70,7 +70,14 @@ class Helpers{
$logfile = $line . PHP_EOL;
}
- $storage->writeFile('basepath', 'cache', 'securitylog.txt', $logfile);
+ $result = $storage->writeFile('dataFolder', 'security', 'securitylog.txt', $logfile);
+
+ if($result)
+ {
+ return true;
+ }
+
+ return $storage->getError();
}
public static function array_sort($array, $on, $order=SORT_ASC)
diff --git a/system/typemill/Static/Settings.php b/system/typemill/Static/Settings.php
index 09eaf3e..f767d19 100644
--- a/system/typemill/Static/Settings.php
+++ b/system/typemill/Static/Settings.php
@@ -3,15 +3,19 @@
namespace Typemill\Static;
use Typemill\Models\StorageWrapper;
+use Typemill\Static\Translations;
class Settings
{
public static function loadSettings()
{
+ echo debug_backtrace()[1]['function'];
+ die('use model load settings instead');
$defaultsettings = self::getDefaultSettings();
$usersettings = self::getUserSettings();
$settings = $defaultsettings;
+ $settings['setup'] = true;
if($usersettings)
{
@@ -33,6 +37,9 @@ class Settings
public static function addThemeSettings($settings)
{
+ echo debug_backtrace()[1]['function'];
+ die('use model addThemeSettings instead');
+
# we have to check if the theme has been deleted
$rootpath = getcwd();
$themefolder = $rootpath . DIRECTORY_SEPARATOR . $settings['themeFolder'] . DIRECTORY_SEPARATOR;
@@ -74,6 +81,9 @@ class Settings
public static function getDefaultSettings()
{
+ echo debug_backtrace()[1]['function'];
+ die('use model getDefaultSettings instead');
+
$rootpath = getcwd();
$defaultsettingspath = $rootpath . DIRECTORY_SEPARATOR . 'system' . DIRECTORY_SEPARATOR . 'typemill' . DIRECTORY_SEPARATOR . 'settings' . DIRECTORY_SEPARATOR;
$defaultsettingsfile = $defaultsettingspath . 'defaults.yaml';
@@ -92,6 +102,9 @@ class Settings
public static function getUserSettings()
{
+ echo debug_backtrace()[1]['function'];
+ die('use model getUserSettings instead');
+
$rootpath = getcwd();
$usersettingsfile = $rootpath . DIRECTORY_SEPARATOR . 'settings' . DIRECTORY_SEPARATOR . 'settings.yaml';
@@ -106,10 +119,22 @@ class Settings
return false;
}
- public static function getObjectSettings($objectType, $objectName)
+ public static function getObjectSettings($objectType, $objectName, $storagepath = '\Typemill\Models\Storage')
{
-# $yaml = new Models\WriteYaml();
-
+ echo debug_backtrace()[1]['function'];
+ die('use model getObjectSettings instead');
+
+ $storage = new StorageWrapper($storagepath);
+
+ $objectSettings = $storage->getYaml($objectType, $objectName, $objectName . '.yaml');
+
+ if($objectSettings)
+ {
+ return $objectSettings;
+ }
+ return false;
+
+/*
$rootpath = getcwd();
$objectfile = $rootpath . DIRECTORY_SEPARATOR . $objectType . DIRECTORY_SEPARATOR . $objectName . DIRECTORY_SEPARATOR . $objectName . '.yaml';
@@ -122,116 +147,52 @@ class Settings
}
return false;
+ */
}
- public static function updateSettings(array $newSettings)
+ public static function updateSettings(array $newSettings, $storagepath = '\Typemill\Models\Storage')
{
+ echo debug_backtrace()[1]['function'];
+ die('use model updateSettings instead');
+
+ $storage = new StorageWrapper($storagepath);
+
# only allow if usersettings already exists (setup has been done)
$userSettings = self::getUserSettings();
# merge usersettings with new settings
$settings = array_merge($userSettings, $newSettings);
-
- $storage = new StorageWrapper('\Typemill\Models\Storage');
-
- $storage->updateYaml('basepath', 'settings', 'settings.yaml', $settings);
+
+ $storage->updateYaml('settingsFolder', '', 'settings.yaml', $settings);
}
- public static function getSettingsDefinitions()
+ public static function getSettingsDefinitions($storagepath = '\Typemill\Models\Storage')
{
- $storage = new StorageWrapper('\Typemill\Models\Storage');
+ echo debug_backtrace()[1]['function'];
+ die('use model getSettingsDefinitions instead');
+
+ $storage = new StorageWrapper($storagepath);
return $storage->getYaml('systemSettings', '', 'system.yaml');
}
-
-
-
-
-
-
-
-### refactor
-
- public static function createSettings()
+ public static function createSettings($storagepath = '\Typemill\Models\Storage')
{
- $yaml = new Models\WriteYaml();
+ echo debug_backtrace()[1]['function'];
+ die('use model createSettings instead');
- $language = self::whichLanguage();
+ $storage = new StorageWrapper($storagepath);
+
+ $language = Translations::whichLanguage();
- # create initial settings file with only setup false
- if($yaml->updateYaml('settings', 'settings.yaml', array('setup' => false, 'language' => $language)))
+ $initialSettings = $storage->updateYaml('settingsFolder', '', 'settings.yaml', [
+ 'language' => $language
+ ]);
+
+ if($initialSettings)
{
return true;
}
return false;
- }
-
- public static function oldupdateSettings($settings)
- {
- # only allow if usersettings already exists (setup has been done)
- $userSettings = self::getUserSettings();
-
- if($userSettings)
- {
- # whitelist settings that can be stored in usersettings (values are not relevant here, only keys)
- $allowedUserSettings = ['displayErrorDetails' => true,
- 'title' => true,
- 'copyright' => true,
- 'language' => true,
- 'langattr' => true,
- 'startpage' => true,
- 'author' => true,
- 'year' => true,
- 'access' => true,
- 'pageaccess' => true,
- 'hrdelimiter' => true,
- 'restrictionnotice' => true,
- 'wraprestrictionnotice' => true,
- 'headlineanchors' => true,
- 'theme' => true,
- 'editor' => true,
- 'formats' => true,
- 'setup' => true,
- 'welcome' => true,
- 'images' => true,
- 'live' => true,
- 'width' => true,
- 'height' => true,
- 'plugins' => true,
- 'themes' => true,
- 'latestVersion' => true,
- 'logo' => true,
- 'favicon' => true,
- 'twigcache' => true,
- 'proxy' => true,
- 'trustedproxies' => true,
- 'headersoff' => true,
- 'urlschemes' => true,
- 'svg' => true,
- 'recoverpw' => true,
- 'recoversubject' => true,
- 'recovermessage' => true,
- 'recoverfrom' => true,
- 'securitylog' => true,
- 'oldslug' => true,
- 'refreshcache' => true,
- 'pingsitemap' => true,
- ];
-
- # cleanup the existing usersettings
- $userSettings = array_intersect_key($userSettings, $allowedUserSettings);
-
- # cleanup the new settings passed as an argument
- $settings = array_intersect_key($settings, $allowedUserSettings);
-
- # merge usersettings with new settings
- $settings = array_merge($userSettings, $settings);
-
- # write settings to yaml
- $yaml = new Models\WriteYaml();
- $yaml->updateYaml('settings', 'settings.yaml', $settings);
- }
- }
-
+ }
}
\ No newline at end of file
diff --git a/system/typemill/author/auth/login.twig b/system/typemill/author/auth/login.twig
index 0a7de05..158b572 100644
--- a/system/typemill/author/auth/login.twig
+++ b/system/typemill/author/auth/login.twig
@@ -9,7 +9,7 @@