Bläddra i källkod

Version 1.4.4: Finished Access Controle

trendschau 4 år sedan
förälder
incheckning
f45da5e56f

+ 6 - 6
composer.lock

@@ -852,16 +852,16 @@
         },
         {
             "name": "symfony/polyfill-ctype",
-            "version": "v1.20.0",
+            "version": "v1.22.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-ctype.git",
-                "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41"
+                "reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41",
-                "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
+                "reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
                 "shasum": ""
             },
             "require": {
@@ -873,7 +873,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.20-dev"
+                    "dev-main": "1.22-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -924,7 +924,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2020-10-23T14:02:19+00:00"
+            "time": "2021-01-07T16:49:33+00:00"
         },
         {
             "name": "symfony/yaml",

+ 2 - 0
content/00-welcome/00-setup.md

@@ -4,6 +4,8 @@ Congratulations! If you see this page, then the setup of the system has worked s
 
 If you face any problems during the installation, then please make sure, that your system supports these features:
 
+---
+
 - PHP version 7+.
 - Apache server.
 - The module `mod_rewrite` and `htaccess`.

+ 13 - 4
system/Controllers/ArticleApiController.php

@@ -973,19 +973,24 @@ class ArticleApiController extends ContentController
 		# fix footnotes in parsedown, might break with complicated footnotes
 		$parsedown->setVisualMode();
 
+		# flag for TOC
+		$toc = false;
+
+		$tocMarkup = false;
+
 		# if content is not an array, then transform it
 		if(!is_array($content))
 		{
 			# turn markdown into an array of markdown-blocks
 			$content = $parsedown->markdownToArrayBlocks($content);
+
+			# build toc here to avoid duplicated toc for live content
+			$tocMarkup = $parsedown->buildTOC($parsedown->headlines);
 		}
 				
 		# needed for ToC links
 		$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
 		
-		# flag for TOC
-		$toc = false;
-
 		# loop through mardkown-array and create html-blocks
 		foreach($content as $key => $block)
 		{
@@ -1003,7 +1008,11 @@ class ArticleApiController extends ContentController
 
 		if($toc)
 		{
-			$tocMarkup = $parsedown->buildTOC($parsedown->headlines);
+			if(!$tocMarkup)
+			{
+				$tocMarkup = $parsedown->buildTOC($parsedown->headlines);
+			}
+
 			$content[$toc] = ['id' => $toc, 'html' => $tocMarkup];
 		}
 

+ 25 - 1
system/Controllers/MetaApiController.php

@@ -129,6 +129,18 @@ class MetaApiController extends ContentController
 				$metascheme[$tabname][$fieldname] = true;
 				$metadata[$tabname][$fieldname] = isset($pagemeta[$tabname][$fieldname]) ? $pagemeta[$tabname][$fieldname] : null;
 
+				
+				# check if there is a selectfield for userroles
+				if(isset($fielddefinitions['type']) && ($fielddefinitions['type'] == 'select' ) && isset($fielddefinitions['dataset']) && ($fielddefinitions['dataset'] == 'userroles' ) )
+				{
+					$userroles = [null => null];
+					foreach($this->c->acl->getRoles() as $userrole)
+					{
+						$userroles[$userrole] = $userrole;
+					}
+					$metadefinitions[$tabname]['fields'][$fieldname]['options'] = $userroles;
+				}
+
 				/*
 				# special treatment for customfields
 				if(isset($fielddefinitions['type']) && ($fielddefinitions['type'] == 'customfields' ) && $metadata[$tabname][$fieldname] )
@@ -189,7 +201,7 @@ class MetaApiController extends ContentController
 		}
 
 		# if item is a folder
-		if($this->item->elementType == "folder")
+		if($this->item->elementType == "folder" && isset($this->item->contains))
 		{
 			$pagemeta['meta']['contains'] = isset($pagemeta['meta']['contains']) ? $pagemeta['meta']['contains'] : $this->item->contains;
 
@@ -217,6 +229,18 @@ class MetaApiController extends ContentController
 			}
 			else
 			{
+
+				if($fieldDefinition && isset($fieldDefinition['type']) && ($fieldDefinition['type'] == 'select' ) && isset($fieldDefinition['dataset']) && ($fieldDefinition['dataset'] == 'userroles' ) )
+				{
+					$userroles = [null => null];
+					foreach($this->c->acl->getRoles() as $userrole)
+					{
+						$userroles[$userrole] = $userrole;
+					}
+					$fieldDefinition['options'] = $userroles;
+				}
+
+
 				# validate user input for this field
 				$result = $validate->objectField($fieldName, $fieldValue, $objectName, $fieldDefinition);
 

+ 36 - 2
system/Controllers/PageController.php

@@ -241,7 +241,7 @@ class PageController extends Controller
 				$shortenedPage = $this->cutRestrictedContent($markdownBlocks);
 
 				# check if there is customized content
-				$restrictionnotice = ( isset($this->settings['restrictionnotice']) && $this->settings['restrictionnotice'] != '' ) ? $this->settings['restrictionnotice'] : 'You are not allowed to access this content.';
+				$restrictionnotice = $this->prepareRestrictionNotice();
 
 				# add notice to shortened content
 				$shortenedPage[] = $restrictionnotice;
@@ -478,7 +478,8 @@ class PageController extends Controller
 			# check if page is restricted to certain user
 			if(isset($meta['alloweduser']) && $meta['alloweduser'] && $meta['alloweduser'] !== '' )
 			{
-				if(isset($_SESSION['user']) && $_SESSION['user'] == $meta['alloweduser'])
+				$alloweduser = array_map('trim', explode(",", $meta['alloweduser']));
+				if(isset($_SESSION['user']) && in_array($_SESSION['user'], $alloweduser))
 				{
 					# user has access to the page, so there are no restrictions
 					return false;
@@ -539,4 +540,37 @@ class PageController extends Controller
 
 		return $restrictedMarkdown;
 	}
+
+	protected function prepareRestrictionNotice()
+	{
+		if( isset($this->settings['restrictionnotice']) && $this->settings['restrictionnotice'] != '' )
+		{
+			$restrictionNotice = $this->settings['restrictionnotice'];
+		}
+		else
+		{
+			$restrictionNotice = 'You are not allowed to access this content.';
+		}
+
+		if( isset($this->settings['wraprestrictionnotice']) && $this->settings['wraprestrictionnotice'] )
+		{
+	        # standardize line breaks
+	        $text = str_replace(array("\r\n", "\r"), "\n", $restrictionNotice);
+
+	        # remove surrounding line breaks
+	        $text = trim($text, "\n");
+
+	        # split text into lines
+	        $lines = explode("\n", $text);
+
+	        $restrictionNotice = '';
+
+	        foreach($lines as $key => $line)
+	        {
+	        	$restrictionNotice .= "!!!! " . $line . "\n";
+	        }
+		}
+
+		return $restrictionNotice;
+	}
 }

+ 1 - 0
system/Controllers/SettingsController.php

@@ -95,6 +95,7 @@ class SettingsController extends Controller
 					'pageaccess'			=> isset($newSettings['pageaccess']) ? true : null,
 					'hrdelimiter'			=> isset($newSettings['hrdelimiter']) ? true : null,
 					'restrictionnotice'		=> $newSettings['restrictionnotice'],
+					'wraprestrictionnotice'	=> isset($newSettings['wraprestrictionnotice']) ? true : null,
 					'headlineanchors'		=> isset($newSettings['headlineanchors']) ? $newSettings['headlineanchors'] : null,
 					'displayErrorDetails'	=> isset($newSettings['displayErrorDetails']) ? true : null,
 					'twigcache'				=> isset($newSettings['twigcache']) ? true : null,

+ 6 - 5
system/Settings.php

@@ -82,7 +82,7 @@ class Settings
 			'editor'								=> 'visual',
 			'formats'								=> ['markdown', 'headline', 'ulist', 'olist', 'table', 'quote', 'notice', 'image', 'video', 'file', 'toc', 'hr', 'definition', 'code'],
 			'contentFolder'							=> 'content',
-			'version'								=> '1.4.3',
+			'version'								=> '1.4.4',
 			'setup'									=> true,
 			'welcome'								=> true,
 			'images'								=> ['live' => ['width' => 820], 'thumbs' => ['width' => 250, 'height' => 150]],
@@ -162,6 +162,7 @@ class Settings
 									'pageaccess' => true,
 									'hrdelimiter' => true,
 									'restrictionnotice' => true,
+									'wraprestrictionnotice' => true,
 									'headlineanchors' => true,
 									'theme' => true,
 									'editor' => true,
@@ -236,10 +237,6 @@ class Settings
 			$acl->addResource(new Resource($resource));
 		}
 
-		# add administrator role
-		$acl->addRole(new Role('administrator'));
-		$acl->allow('administrator');
-
 		# add all other roles dynamically
 		foreach($roles as $role)
 		{
@@ -251,6 +248,10 @@ class Settings
 			}
 		}
 
+		# add administrator role
+		$acl->addRole(new Role('administrator'));
+		$acl->allow('administrator');
+
 		return $acl;
 	}
 }

+ 4 - 4
system/author/js/typemillutils.js

@@ -19,13 +19,13 @@ let typemillUtilities = {
 
 	addYoutubePlayButton: function(element)
 	{
-		element.parentNode.classList.add("video-container");
-		
+		element.classList.add("video-container");
+
 		var youtubePlaybutton = document.createElement("button");
 		youtubePlaybutton.classList.add("play-video");
 		youtubePlaybutton.value = "Play";
 
-		element.parentNode.appendChild(youtubePlaybutton);
+		element.appendChild(youtubePlaybutton);
 	},
 
 	listenToClick: function(){
@@ -34,7 +34,7 @@ let typemillUtilities = {
 			/* listen to youtube */
 			if (event.target.matches('.play-video')) {
 
-				var youtubeID = event.target.parentNode.getElementsByClassName('youtube')[0].id;
+				var youtubeID = event.target.parentNode.id;
 
 				event.preventDefault();
 				event.stopPropagation();

+ 12 - 1
system/author/js/vue-blox.js

@@ -1,5 +1,16 @@
 const eventBus = new Vue();
 
+Vue.filter('translate', function (value) {
+  if (!value) return ''
+  transvalue = value.replace(/[ ]/g,"_").replace(/[.]/g, "_").replace(/[,]/g, "_").replace(/[-]/g, "_").replace(/[,]/g,"_").toUpperCase()
+  translated_string = labels[transvalue]
+  if(!translated_string || translated_string.length === 0){
+    return value
+  } else {
+    return labels[transvalue]
+  }
+})
+
 const contentComponent = Vue.component('content-block', {
 	props: ['body', 'load'],
 	template: '<div ref="bloxcomponent" class="blox-editor" :class="newblock">' +
@@ -19,7 +30,7 @@ const contentComponent = Vue.component('content-block', {
 				    '<button class="cancel" :disabled="disabled" @click.prevent="cancel">{{ \'cancel\'|translate }}</button>' +
 				   '</div>' +
 				  '</div>' +
-				  '<div :class="preview" ref="preview"><slot><format-component></format-component></slot></div>' +
+				  '<div :class="preview" ref="preview"><slot></slot></div>' +
 				 '</div>' +
 				'</div>' +
 				'<div v-if="load" class="loadoverlay"><span class="load"></span></div>' +

+ 5 - 1
system/author/js/vue-meta.js

@@ -13,13 +13,14 @@ Vue.filter('translate', function (value) {
 
 
 Vue.component('tab-meta', {
-	props: ['saved', 'errors', 'formdata', 'schema'],
+	props: ['saved', 'errors', 'formdata', 'schema', 'userroles'],
 	template: '<section><form>' +
 				'<component v-for="(field, index) in schema.fields"' +
             	    ':key="index"' +
                 	':is="selectComponent(field)"' +
                 	':errors="errors"' +
                 	':name="index"' +
+                	':userroles="userroles"' +
                 	'v-model="formdata[index]"' +
                 	'v-bind="field">' +
 				'</component>' + 
@@ -52,6 +53,7 @@ let meta = new Vue({
 			formErrors: {},
 			formErrorsReset: {},
 			item: false,
+			userroles: false,
 			saved: false,
 		}
 	},
@@ -97,6 +99,8 @@ let meta = new Vue({
 
         	self.formData = response.data.metadata;
 
+        	self.userroles = response.data.userroles;
+
         	self.item = response.data.item;
         	if(self.item.elementType == "folder" && self.item.contains == "posts")
         	{

+ 2 - 2
system/author/js/vue-navi.js

@@ -1,6 +1,6 @@
 const navcomponent = Vue.component('navigation', {
 	template: '#navigation-template',
-	props: ['homepage', 'showForm', 'name', 'hide', 'newItem', 'parent', 'active', 'filetype', 'status', 'elementtype', 'contains', 'element', 'folder', 'level', 'url', 'root', 'freeze'],
+	props: ['homepage', 'name', 'hide', 'newItem', 'parent', 'active', 'filetype', 'status', 'elementtype', 'contains', 'element', 'folder', 'level', 'url', 'root', 'freeze'],
 	data: function () {
 		return {
 			showForm: false,
@@ -221,7 +221,7 @@ let navi = new Vue({
 		hideModal: function(e){
 			this.modalWindow = false;
 		},
-		toggleForm : function()
+		toggleForm: function()
 		{
 			this.showForm = !this.showForm;
 		},

+ 1 - 1
system/author/js/vue-shared.js

@@ -257,7 +257,7 @@ Vue.component('component-color', {
 })
 
 Vue.component('component-select', {
-	props: ['class', 'id', 'description', 'readonly', 'required', 'disabled', 'label', 'name', 'type', 'options', 'value', 'errors'],
+	props: ['class', 'id', 'description', 'readonly', 'required', 'disabled', 'label', 'name', 'type', 'options', 'value', 'errors', 'dataset', 'userroles'],
 	template: '<div class="large">' +
 				'<label>{{ label|translate }}</label>' +
 			    '<select' + 

+ 8 - 8
system/author/layouts/layout.twig

@@ -16,8 +16,8 @@
 		<link rel="apple-touch-icon" sizes="144x144" href="{{ base_url }}/system/author/img/favicon-144.png" />
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 		
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/tachyons.min.css?20210108" />
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20210108" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/tachyons.min.css?20210202" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20210202" />
 
 		{{ assets.renderCSS() }}
 		
@@ -39,16 +39,16 @@
 			</article>
 			<footer></footer>
 		</div>
-		<script src="{{ base_url }}/system/author/js/axios.min.js?20210108"></script>
+		<script src="{{ base_url }}/system/author/js/axios.min.js?20210202"></script>
 		<script>
 			const myaxios = axios.create();
 			myaxios.defaults.baseURL =  "{{ base_url }}";
 		</script>
-		<script src="{{ base_url }}/system/author/js/autosize.min.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vue.min.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vue-shared.js?20210108"></script>		
-		<script src="{{ base_url }}/system/author/js/author.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/typemillutils.js?20210108"></script>
+		<script src="{{ base_url }}/system/author/js/autosize.min.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vue.min.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vue-shared.js?20210202"></script>		
+		<script src="{{ base_url }}/system/author/js/author.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/typemillutils.js?20210202"></script>
 		<script>
 			typemillUtilities.start()
 		</script>

+ 2 - 2
system/author/layouts/layoutAuth.twig

@@ -17,7 +17,7 @@
 		<link rel="apple-touch-icon" sizes="144x144" href="{{ base_url }}/system/author/img/favicon-144.png" />
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20210108" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20210202" />
 
 		{{ assets.renderCSS() }}
 		
@@ -31,6 +31,6 @@
 			{% block content %}{% endblock %}
 
 		</div>
-		<script src="{{ base_url }}/system/author/js/auth.js?20210108"></script>
+		<script src="{{ base_url }}/system/author/js/auth.js?20210202"></script>
 	</body>
 </html>

+ 1 - 1
system/author/layouts/layoutBlank.twig

@@ -16,7 +16,7 @@
 		<link rel="apple-touch-icon" sizes="144x144" href="{{ base_url }}/system/author/img/favicon-144.png" />
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20210108" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20210202" />
 
 	</head>
 	<body>

+ 15 - 15
system/author/layouts/layoutBlox.twig

@@ -17,7 +17,7 @@
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 		
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/tachyons.min.css" />
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20210108" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20210202" />
 
 		{{ assets.renderCSS() }}
 
@@ -41,17 +41,17 @@
 			</article>
 			<footer></footer>
 		</div>
-		<script src="{{ base_url }}/system/author/js/axios.min.js?20210108"></script>
+		<script src="{{ base_url }}/system/author/js/axios.min.js?20210202"></script>
 		<script>
 			const myaxios = axios.create();
 			myaxios.defaults.baseURL =  "{{ base_url }}";
 		</script>
-		<script src="{{ base_url }}/system/author/js/typemillutils.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vue.min.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/autosize.min.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/author.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vue-publishcontroller.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vue-blox-config.js?20210108"></script>
+		<script src="{{ base_url }}/system/author/js/typemillutils.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vue.min.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/autosize.min.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/author.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vue-publishcontroller.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vue-blox-config.js?20210202"></script>
 		<script>
 			let formatConfig = {{ settings.formats|json_encode() }};
       		let language = {{ settings.language|json_encode() }};
@@ -61,13 +61,13 @@
 
 		{{ assets.renderEditorJS() }}
 
-		<script src="{{ base_url }}/system/author/js/vue-blox.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vue-posts.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/sortable.min.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vuedraggable.umd.min.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vue-navi.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vue-shared.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vue-meta.js?20210108"></script>
+		<script src="{{ base_url }}/system/author/js/vue-blox.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vue-posts.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/sortable.min.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vuedraggable.umd.min.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vue-navi.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vue-shared.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vue-meta.js?20210202"></script>
 
 		{{ assets.renderJS() }}
 

+ 12 - 12
system/author/layouts/layoutEditor.twig

@@ -16,7 +16,7 @@
 		<link rel="apple-touch-icon" sizes="144x144" href="{{ base_url }}/system/author/img/favicon-144.png" />
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20210108" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20210202" />
 
 		{{ assets.renderCSS() }}
 
@@ -40,16 +40,16 @@
 			</article>
 			<footer></footer>
 		</div>
-		<script src="{{ base_url }}/system/author/js/axios.min.js?20210108"></script>
+		<script src="{{ base_url }}/system/author/js/axios.min.js?20210202"></script>
 		<script>
 			const myaxios = axios.create();
 			myaxios.defaults.baseURL =  "{{ base_url }}";
-		</script>		
-		<script src="{{ base_url }}/system/author/js/vue.min.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/autosize.min.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/sortable.min.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vuedraggable.umd.min.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/author.js?20210108"></script>
+		</script>
+		<script src="{{ base_url }}/system/author/js/vue.min.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/autosize.min.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/sortable.min.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vuedraggable.umd.min.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/author.js?20210202"></script>
 
 	    <script>
     	  	let language = {{ settings.language|json_encode() }};
@@ -59,10 +59,10 @@
     
 		{{ assets.renderEditorJS() }}		
 		
-		<script src="{{ base_url }}/system/author/js/vue-publishcontroller.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vue-editor.js?20210108"></script>
-		<script src="{{ base_url }}/system/author/js/vue-meta.js?20210108"></script>		
-		<script src="{{ base_url }}/system/author/js/vue-navi.js?20210108"></script>
+		<script src="{{ base_url }}/system/author/js/vue-publishcontroller.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vue-editor.js?20210202"></script>
+		<script src="{{ base_url }}/system/author/js/vue-meta.js?20210202"></script>		
+		<script src="{{ base_url }}/system/author/js/vue-navi.js?20210202"></script>
 
 		{{ assets.renderJS() }}
 		

+ 3 - 7
system/author/metatabs.yaml

@@ -62,18 +62,14 @@ meta:
       type: select
       label: For access the user must have this minimum role
       class: medium
+      dataset: userroles
       options:
-        false: All
-        member: Member
-        author: Author
-        editor: Editor
-        administrator: Administrator
       description: Select the lowest userrole. Higher roles will have access too.
     alloweduser:
       type: text
-      label: Only the following user has access
+      label: Only the following users have access
       class: medium
-      description: Only this certain user will have access to this site.
+      description: Add one or more usernames separated with comma.
     contains:
       type: radio
       label: This folder contains

+ 1 - 1
system/author/partials/editorNavi.twig

@@ -1,7 +1,7 @@
 <nav id="sidebar-menu" class="sidebar-menu--content">
 	<div id="data-navi" data-homepage='{{ homepage|json_encode() }}' data-editormode="{{settings.editor}}"></div>
 	<div id="mobile-menu" class="menu-action">{{ __('Menu') }} <span class="button-arrow"></span></div>
-	<div id="navi" class="content-navi" v-model="freeze" v-cloak>
+	<div id="navi" class="content-navi" :value.sync="freeze" v-cloak>
 		<div class="navi-list">
 			<div class="navi-item folder">
 				<div class="status" :class="homepage.status"></div>

+ 7 - 0
system/author/settings/system.twig

@@ -171,6 +171,13 @@
 							<span class="error">{{ errors.settings.restrictionnotice | first }}</span>
 						{% endif %}
 					</div>
+					<div class="large{{ errors.settings.wraprestrictionnotice ? ' error' : '' }}">
+						<label for="settings[wraprestrictionnotice]">{{ __('Page Restrictions - Wrap Notice into a Box') }}</label>
+						<label class="control-group">{{ __('Wrap the restriction notice above into a notice-4 element (which can be designed as special box)') }}
+							<input name="settings[wraprestrictionnotice]" type="checkbox" {% if (settings.wraprestrictionnotice or old.settings.wraprestrictionnotice) %} checked {% endif %}>
+							<span class="checkmark"></span>
+						</label>
+					</div>
 					<hr>
 					<header class="headline">
 						<h2>{{ __('Developer') }}</h2>

+ 10 - 5
themes/cyanine/css/style.css

@@ -67,7 +67,7 @@ article h1, article h2, article h3, article h4, article h5, article h6{
 	line-height: 1em; 
 	position: relative;
 }
-article h1{ font-size: 2.2em; margin: 1.4em 0 0.6em; }
+article h1{ font-size: 2.2em; margin: 1.4em 0 0.6em; z-index:1; }
 article h2{ font-size: 1.6em; margin: 1.8em 0 0.6em; }
 article h3{	font-size: 1.3em; margin: 1.6em 0 0.6em; }
 article h4{	font-size: 1.1em; margin: 1.4em 0 0.6em; }
@@ -213,16 +213,21 @@ ul.TOC,.TOC ul{
     margin: 1em 0;
     padding: 10px 1em;
 }
-.notice3,
-.notice4,
-.notice5,
-.notice6 {
+.notice3{
     margin: 1em 0;
     padding: 10px 1em;
     background-color: #d4e0ff;
     border-left: 4px solid #3c7bf6;	
 }
 
+/* used for pro content box */
+.notice4{
+  position: relative;
+  text-align: center;
+  padding: 1em;
+  border: 1px solid;
+}
+
 /* Style the optional anchor-links for headlines */
 a.tm-heading-anchor {
     position: absolute;

+ 1 - 10
themes/cyanine/cyanine.yaml

@@ -1,5 +1,5 @@
 name: Cyanine Theme
-version: 1.1.1
+version: 1.1.2
 description: Cyanine is a modern and flexible multi-purpose theme and the standard theme for typemill. 
 author: Trendschau
 homepage: https://trendschau.net
@@ -163,15 +163,6 @@ forms:
           label: Label for read more link
           placeholder: All News
 
-    fieldsetUsers:
-      type: fieldset
-      legend: Users
-      fields:
-        accountButton:
-          type: checkbox
-          label: Show Account Button
-          checkboxlabel: Show account button in frontend for authenticated users?
-
     fieldsetAuthor:
       type: fieldset
       legend: Article Author

+ 1 - 1
themes/cyanine/home/landingpageInfo.twig

@@ -1,6 +1,6 @@
 	<section class="landingpageinfo w-100 dib tc bl br bb">
 		
-		<div class="f5 f4-ns mw7 pv6 ph3 center">
+		<div class="f5 f4-ns mw7 pv6 ph3 fw3 lh-copy center">
 			
 			{{ markdown(settings.themes.cyanine.infoMarkdown) }}
 

+ 9 - 12
themes/cyanine/layout.twig

@@ -110,12 +110,15 @@
 					color: {{ settings.themes.cyanine.fontcolorprimary|default('#F7F7F7') }};
 				}
 				.landingpagecontrast a, .landingpagecontrast a:link, .landingpagecontrast a:visited{
-					border-color: {{ settings.themes.cyanine.fontcolorprimary|default('#F7F7F7') }};					
+					border-color: {{ settings.themes.cyanine.fontcolorprimary|default('#F7F7F7') }};
 				}
 
-				main, footer, .landingpageintro, .landingpageinfo, .landingpageteaser, .landingpagenavi, .landingpagenews,button.expander{
+				main, footer, .landingpageintro, .landingpageinfo, .landingpageteaser, .landingpagenavi, .landingpagenews,button.expander, .notice4{
 					background: {{ settings.themes.cyanine.brandcolorsecondary|default('#f7f7f7') }};
 				}
+				.notice4{
+					box-shadow: 0 -100px 80px 0px {{ settings.themes.cyanine.brandcolorsecondary|default('#f7f7f7') }};
+				}
 				main, footer, .landingpageintro, .landingpageinfo, .landingpageteaser, .landingpagenavi, .landingpagenews, .logo a, button.expander{
 					color: {{ settings.themes.cyanine.fontcolorsecondary|default('#333') }};					
 				}
@@ -158,7 +161,7 @@
 				.landingpagenews li a{
 					color: {{ settings.themes.cyanine.newscolor|default('#333') }};
 				}
-				.mainnavigation li, tr, hr{
+				.mainnavigation li, tr, hr, .notice4{
 					border-color: {{ settings.themes.cyanine.thinbordercolor|default('lightgray') }};
 				}
 				a.tm-download::before{
@@ -178,10 +181,7 @@
 					background-color: #fff3d4;
 					border-left: 4px solid #f6b73c;
 				}
-				.notice3,
-				.notice4,
-				.notice5,
-				.notice6 {
+				.notice3{
 				    background-color: #d4e0ff;
 				    border-left: 4px solid #3c7bf6;	
 				}
@@ -197,10 +197,7 @@
 						border-left: 10px solid #999;
 						color: #333;
 					}
-					.notice3,
-					.notice4,
-					.notice5,
-					.notice6 {
+					.notice3{
 						background-color: #444;
 						border-left: 10px solid #ccc;
 						color: #fff;
@@ -217,7 +214,7 @@
 	<body class="optimize-text pa2">
 
 
-		{% if ( settings.themes.cyanine.accountButton ) and ( is_loggedin() ) %}
+		{% if is_loggedin() %}
 			<svg style="position: absolute; width: 0; height: 0; overflow: hidden" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 				<defs>
 					<symbol id="icon-user" viewBox="0 0 20 28">