1
0
mirror of https://github.com/typemill/typemill.git synced 2025-07-25 00:02:28 +02:00

Version 1.3.8: User Rights

This commit is contained in:
trendschau
2020-07-15 10:53:27 +02:00
parent 4f80e07810
commit 489f1e268e
16 changed files with 147 additions and 14 deletions

View File

@@ -10,6 +10,7 @@ RewriteEngine On
# Protect your system files from prying eyes
RewriteRule ^(system\/author\/) - [L]
RewriteRule ^(system) - [F,L]
RewriteRule ^(data) - [F,L]
RewriteRule ^(content) - [F,L]
RewriteRule ^(settings) - [F,L]
RewriteRule ^(.*)?\.yml$ - [F,L]

1
cache/index.json vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -14,6 +14,27 @@ use Typemill\Events\OnSystemnaviLoaded;
class SettingsController extends Controller
{
public function showBlank($request, $response, $args)
{
$user = new User();
$settings = $this->c->get('settings');
# $users = $user->getUsers();
$route = $request->getAttribute('route');
$navigation = $this->getNavigation();
$content = '<h1>Hello</h1>';
return $this->render($response, 'settings/blank.twig', array(
'settings' => $settings,
'acl' => $this->c->acl,
'navigation' => $navigation,
'content' => $content,
# 'users' => $users,
'route' => $route->getName()
));
}
/*********************
** BASIC SETTINGS **
*********************/
@@ -26,13 +47,15 @@ class SettingsController extends Controller
$copyright = $this->getCopyright();
$languages = $this->getLanguages();
$locale = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2) : 'en';
$users = $user->getUsers();
$route = $request->getAttribute('route');
$navigation = $this->getNavigation();
# set navigation active
$navigation['System']['active'] = true;
# set option for registered website
$options = ['' => 'all', 'registered' => 'registered users only'];
return $this->render($response, 'settings/system.twig', array(
'settings' => $settings,
'acl' => $this->c->acl,
@@ -41,7 +64,7 @@ class SettingsController extends Controller
'languages' => $languages,
'locale' => $locale,
'formats' => $defaultSettings['formats'],
'users' => $users,
'access' => $options,
'route' => $route->getName()
));
}
@@ -68,7 +91,8 @@ class SettingsController extends Controller
'year' => $newSettings['year'],
'language' => $newSettings['language'],
'langattr' => $newSettings['langattr'],
'editor' => $newSettings['editor'],
'editor' => $newSettings['editor'],
'access' => $newSettings['access'],
'formats' => $newSettings['formats'],
'headlineanchors' => isset($newSettings['headlineanchors']) ? $newSettings['headlineanchors'] : null,
);

View File

@@ -20,6 +20,12 @@ class accessController
public function __invoke(Request $request, Response $response, $next)
{
if($this->resource == NULL && $this->privilege == NULL)
{
return $next($request, $response);
}
if(!isset($_SESSION['login']))
{
return $response->withRedirect($this->router->pathFor('auth.show'));

View File

@@ -79,6 +79,10 @@ if($settings['settings']['setup'])
{
$app->get('/[{params:.*}]', SetupController::class . ':redirect');
}
elseif(isset($settings['settings']['access']) && $settings['settings']['access'] != '')
{
$app->get('/[{params:.*}]', PageController::class . ':index')->setName('home')->add(new accessController($container['router'], $container['acl'], 'user', 'view'));
}
else
{
$app->get('/[{params:.*}]', PageController::class . ':index')->setName('home');

View File

@@ -111,7 +111,7 @@ class Settings
}
# Detect browser language
$accept_lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
$accept_lang = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) : false;
$lang = in_array($accept_lang, $langs) ? $accept_lang : 'en';
return $lang;
@@ -158,6 +158,7 @@ class Settings
'startpage' => true,
'author' => true,
'year' => true,
'access' => true,
'headlineanchors' => true,
'theme' => true,
'editor' => true,
@@ -169,7 +170,7 @@ class Settings
'themes' => true,
'latestVersion' => true,
'logo' => true,
'favicon' => true,
'favicon' => true
];
# cleanup the existing usersettings

View File

@@ -165,7 +165,11 @@ const contentComponent = Vue.component('content-block', {
},
submitBlock: function(){
var emptyline = /^\s*$(?:\r\n?|\n)/gm;
/* allow empty lines for these components */
if(this.componentType == "code-component" || this.componentType == "math-component" || this.componentType == "notice-component"){ }
/* add new line with markup for these components */
else if(this.componentType == "ulist-component" || this.componentType == "olist-component")
{
var listend = (this.componentType == "ulist-component") ? '* \n' : '1. \n';
@@ -194,6 +198,7 @@ const contentComponent = Vue.component('content-block', {
}
}
}
/* save or close for all other components */
else if(this.compmarkdown.search(emptyline) > -1)
{
var checkempty = this.compmarkdown.replace(/(\r\n|\n|\r|\s)/gm,"");
@@ -1014,21 +1019,21 @@ const tableComponent = Vue.component('table-component', {
'</colgroup>' +
'<tbody>' +
'<tr v-for="(row, rowindex) in table">' +
'<td v-if="rowindex === 0" v-for="(value,colindex) in row" contenteditable="false" class="noteditable" @click="switchcolumnbar(value)">{{value}} ' +
'<td v-if="rowindex === 0" v-for="(value,colindex) in row" contenteditable="false" class="noteditable" @click="switchcolumnbar(value)" @keydown.13.prevent="enter">{{value}} ' +
'<div v-if="columnbar === value" class="columnaction">' +
'<div class="actionline" @click="addrightcolumn(value)">{{ \'add right column\'|translate }}</div>' +
'<div class="actionline" @click="addleftcolumn(value)">{{ \'add left column\'|translate }}</div>' +
'<div class="actionline" @click="deletecolumn(value)">{{ \'delete column\'|translate }}</div>' +
'</div>' +
'</td>' +
'<th v-if="rowindex === 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' +
'<th v-if="rowindex === 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @keydown.13.prevent="enter" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' +
'<div v-if="colindex === 0 && rowbar === value" class="rowaction">' +
'<div class="actionline" @click="addaboverow(value)">{{ \'add row above\'|translate }}</div>' +
'<div class="actionline" @click="addbelowrow(value)">{{ \'add row below\'|translate }}</div>' +
'<div class="actionline" @click="deleterow(value)">{{ \'delete row\'|translate }}</div>' +
'</div>' +
'{{ value }}</th>' +
'<td v-if="rowindex > 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' +
'<td v-if="rowindex > 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @keydown.13.prevent="enter" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' +
'<div v-if="colindex === 0 && rowbar === value" class="rowaction">' +
'<div class="actionline" @click="addaboverow(value)">{{ \'add row above\'|translate }}</div>' +
'<div class="actionline" @click="addbelowrow(value)">{{ \'add row below\'|translate }}</div>' +
@@ -1073,6 +1078,10 @@ const tableComponent = Vue.component('table-component', {
}
},
methods: {
enter: function()
{
return false;
},
updatedata: function(event,col,row)
{
this.table[row][col] = event.target.innerText;
@@ -1215,7 +1224,7 @@ const definitionComponent = Vue.component('definition-component', {
'<svg class="icon icon-arrows-v"><use xlink:href="#icon-arrows-v"></use></svg>' +
'<input type="text" class="definitionTerm" v-bind:placeholder="\'term\'|translate" :value="definition.term" :disabled="disabled" @input="updateterm($event,dindex)" @blur="updateMarkdown">' +
'<svg class="icon icon-dots-two-vertical"><use xlink:href="#icon-dots-two-vertical"></use></svg>' +
'<textarea class="definitionDescription" v-bind:placeholder="\'description\'|translate" v-html="definition.description" :disabled="disabled" @input="updatedescription($event, dindex)" @blur="updateMarkdown"></textarea>' +
'<textarea class="definitionDescription" v-bind:placeholder="\'description\'|translate" v-html="definition.description" :disabled="disabled" @input="updatedescription($event, dindex)" @keydown.13.prevent="enter" @blur="updateMarkdown"></textarea>' +
'<button class="delDL" @click.prevent="deleteDefinition(dindex)"><svg class="icon icon-minus"><use xlink:href="#icon-minus"></use></svg></button>' +
'</div>' +
'</draggable>' +
@@ -1249,6 +1258,10 @@ const definitionComponent = Vue.component('definition-component', {
}
},
methods: {
enter: function()
{
return false;
},
updateterm: function(event, dindex)
{
this.definitionList[dindex].term = event.target.value;

View File

@@ -74,6 +74,12 @@
<footer></footer>
</div>
<!-- <script src="{{ base_url }}/system/author/js/color-picker.min.js?20200505"></script> -->
<script src="{{ base_url }}/system/author/js/axios.min.js?20200226"></script>
<script>
const myaxios = axios.create();
myaxios.defaults.baseURL = "{{ base_url }}";
</script>
<script src="{{ base_url }}/system/author/js/vue.min.js?20200614"></script>
<script src="{{ base_url }}/system/author/js/author.js?20200614"></script>
<script src="{{ base_url }}/system/author/js/typemillutils.js?20200614"></script>
<script>

View File

@@ -0,0 +1,14 @@
{% extends 'layouts/layout.twig' %}
{% block title %}Blank{% endblock %}
{% block content %}
<div class="formWrapper">
<section class="settings">
{{ content }}
</section>
</div>
{% endblock %}

View File

@@ -69,6 +69,16 @@
</div><div class="medium">
<label for="settings[sitemap]">{{ __('Google Sitemap') }} <small>({{ __('Readonly') }})</small></label>
<input type="text" name="settings[sitemap]" id="sitemap" readonly value="{{ base_url }}/cache/sitemap.xml" />
</div><div class="medium{{ errors.settings.access ? ' error' : '' }}">
<label for="settings[access]">{{ __('Website visible for') }}</label>
<select name="settings[access]" id="access">
{% for key,option in access %}
<option value="{{ key }}"{% if (key == old.settings.access or key == settings.access) %} selected{% endif %}>{{ __(option) }}</option>
{% endfor %}
</select>
{% if errors.settings.access %}
<span class="error">{{ errors.settings.access | first }}</span>
{% endif %}
</div>
<hr>
<header class="headline">

View File

@@ -172,6 +172,13 @@ $path = $uri->getPath();
$container['flash'] = false;
$container['csrf'] = false;
# if website is restricted to registered user
if(isset($settings['settings']['access']) && $settings['settings']['access'] == 'registered')
{
# activate session for all routes
$session_segments = [$path];
}
foreach($session_segments as $segment)
{
if(substr( $path, 0, strlen($segment) ) === $segment)

View File

@@ -398,6 +398,12 @@ button.play-video::after {
right: 0;
top: 0;
}
.contentnav.collapse .folder > ul{
display: none;
}
.contentnav .folder.active > ul,.contentnav .folder.activeParent > ul{
display: block;
}
.burgerbutton{
display: inline-block;
font-size: 2em;

View File

@@ -211,10 +211,14 @@ forms:
type: fieldset
legend: Navigations and Chapters
fields:
collapseNav:
type: checkbox
label: Collapse navigation
checkboxlabel: Collapse and expand navigation?
chapnum:
type: checkbox
label: Show Chapter Numbers
checkboxlabel: Count chapters in navigation?
label: Chapter Numbers
checkboxlabel: Show chapter numbers in navigation?
fieldsetfooter:
type: fieldset

View File

@@ -119,6 +119,30 @@
<script src="{{ base_url }}/system/author/js/typemillutils.js?20200418"></script>
<script>typemillUtilities.start();</script>
{% if settings.themes.cyanine.collapseNav %}
<script>
var expandButton = document.getElementById("expander");
if(expandButton)
{
expandButton.addEventListener('click', function(e)
{
var contentnav = document.getElementById("contentnav");
contentnav.classList.toggle("collapse");
if(contentnav.classList.contains("collapse"))
{
expandButton.innerHTML = "expand navigation";
}
else
{
expandButton.innerHTML = "collapse navigation";
}
});
}
</script>
{% endif %}
{{ assets.renderJS() }}

View File

@@ -5,7 +5,7 @@
<div class="w-100 mw8 center grid-container">
<aside class="grid-header ph3 pv3">
<header>
<div class="logo">
@@ -22,6 +22,14 @@
</header>
{% if widgets %}
{% for index,widget in widgets %}
<div id="{{ index }}" class="mt4-l mt3">
{{ widget }}
</div>
{% endfor %}
{% endif %}
</aside>
<div class="grid-main ph3 ph4-l pv3 lh-copy f4 fw3">
@@ -105,9 +113,9 @@
</div>
<aside class="grid-sidebar ph3 pv4">
<aside class="grid-sidebar ph3 pv3">
<nav class="contentnav" aria-label="Menu">
<nav id="contentnav" class="contentnav{{ settings.themes.cyanine.collapseNav ? ' collapse' : '' }}" aria-label="Menu">
<!-- burger menu controlled by invisible checkbox -->
<input type="checkbox" id="burger" class="dn">

View File

@@ -30,6 +30,10 @@
{% import _self as macros %}
{% if settings.themes.cyanine.collapseNav %}
<button id="expander" class=" dn db-l link pointer w-100 bg-secondary ba b--tertiary pa2 mb1 f7">expand navigation</button>
{% endif %}
<ul class="list pa0 menu {{ settings.themes.cyanine.fontnavi }}">
{{ macros.loop_over(navigation, settings.themes.cyanine.chapnum ) }}
</ul>