Skip to content

Commit 3a0e593

Browse files
committed
Releasing 0.9.4-Beta
2 parents d79a602 + 95485b6 commit 3a0e593

File tree

85 files changed

+3159
-340
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+3159
-340
lines changed

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"php" : ">=7.0.0",
1515
"technicalguru/vault" : "^1",
1616
"technicalguru/utils" : "^1",
17-
"technicalguru/database" : "^1",
17+
"technicalguru/database" : "^1.1",
1818
"technicalguru/i18n" : "^1",
1919
"technicalguru/rest-client" : "^1",
2020
"technicalguru/email" : "^1",

css/filter-multi-select.css

+222
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
/*!
2+
* Multiple select dropdown with filter jQuery plugin.
3+
* Copyright (C) 2020 Andrew Wagner github.com/andreww1011
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 2.1 of the License, or (at your option) any later version.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18+
* USA
19+
*/
20+
:root {
21+
--fms-badge-text-color: white;
22+
--fms-badge-color: var(--primary)
23+
}
24+
25+
.filter-multi-select.dropup, .filter-multi-select.dropdown {
26+
position: relative;
27+
}
28+
29+
.filter-multi-select .dropdown-toggle::after {
30+
all: unset;
31+
}
32+
33+
.filter-multi-select .dropdown-toggle:empty::after {
34+
all: unset;
35+
}
36+
37+
.filter-multi-select > .dropdown-toggle::before {
38+
display: inline-block;
39+
margin-right: 0.255em;
40+
vertical-align: middle;
41+
content: "";
42+
border-top: 0.3em solid;
43+
border-right: 0.3em solid transparent;
44+
border-bottom: 0;
45+
border-left: 0.3em solid transparent;
46+
}
47+
48+
.filter-multi-select > .dropdown-toggle:empty::before {
49+
margin-right: 0.255em;
50+
}
51+
52+
.filter-multi-select > .viewbar {
53+
white-space: normal;
54+
font-size: 0.875rem;
55+
font-weight: 400;
56+
height: auto;
57+
cursor: pointer;
58+
}
59+
60+
.filter-multi-select > .viewbar > .selected-items > .item {
61+
margin: .125rem .25rem .125rem 0;
62+
padding: 0px 0px 0px .5em;
63+
display: inline-flex;
64+
height: 1.875em;
65+
color: var(--fms-badge-text-color);
66+
background-color: var(--fms-badge-color);
67+
border-radius: 1.1em;
68+
align-items: center;
69+
vertical-align: baseline;
70+
}
71+
72+
.filter-multi-select > .viewbar > .selected-items > .item > button {
73+
background-color: transparent;
74+
color: var(--fms-badge-text-color);
75+
border: 0;
76+
font-weight: 900;
77+
cursor: pointer;
78+
}
79+
80+
.filter-multi-select > .viewbar > .selected-items > .item > button:hover {
81+
filter: contrast(50%);
82+
}
83+
84+
.filter-multi-select > .viewbar > .selected-items > .item.disabled {
85+
display: inline-flex;
86+
padding: 0px .5em 0px .5em;
87+
filter: grayscale(80%) brightness(150%);
88+
}
89+
90+
.filter-multi-select > .viewbar > .selected-items > .item.disabled > button {
91+
display: none;
92+
}
93+
94+
.filter-multi-select > .dropdown-menu {
95+
position: absolute;
96+
top: 100%;
97+
left: 0%;
98+
z-index: 1000;
99+
display: none;
100+
float: left;
101+
max-height: 50vh;
102+
min-width: 10rem;
103+
overflow-y: auto;
104+
padding: 0.5rem 0;
105+
margin: 0.125rem 0 0;
106+
font-size: 0.875rem;
107+
text-align: left;
108+
list-style: none;
109+
background-color: #FFFFFF;
110+
background-clip: padding-box;
111+
border: 1px solid rgba(0, 0, 0, 0.15);
112+
border-radius: 0.25rem;
113+
}
114+
115+
.filter-multi-select > .dropdown-menu.show {
116+
display: block;
117+
}
118+
119+
.filter-multi-select > .dropdown-menu > .filter > input {
120+
font-size: 0.875rem;
121+
}
122+
123+
.filter-multi-select > .dropdown-menu > .filter > button {
124+
position: absolute;
125+
border: 0;
126+
background-color: transparent;
127+
font-weight: 900;
128+
color: #ccc;
129+
right: 2rem;
130+
top: 1rem;
131+
}
132+
133+
.filter-multi-select > .dropdown-menu > .filter > button:hover {
134+
color: #aaa;
135+
}
136+
137+
.filter-multi-select .dropdown-item {
138+
display: block;
139+
width: 100%;
140+
padding: 0.25rem 1.5rem;
141+
clear: both;
142+
font-weight: 400;
143+
color: #212529;
144+
text-align: inherit;
145+
white-space: nowrap;
146+
background-color: transparent;
147+
border: 0;
148+
}
149+
150+
.filter-multi-select .dropdown-item.disabled, .filter-multi-select .dropdown-item:disabled {
151+
color: #6c757d;
152+
pointer-events: none;
153+
background-color: transparent;
154+
}
155+
156+
.filter-multi-select .dropdown-item:hover, .filter-multi-select .dropdown-item:focus {
157+
background-color: inherit;
158+
}
159+
160+
.filter-multi-select .dropdown-item.active, .filter-multi-select .dropdown-item:active {
161+
color: inherit;
162+
}
163+
164+
.filter-multi-select .dropdown-item .custom-control-input {
165+
position: absolute;
166+
z-index: -1;
167+
opacity: 0;
168+
}
169+
170+
.filter-multi-select .dropdown-item .custom-control-label {
171+
position: relative;
172+
margin-bottom: 0;
173+
vertical-align: top;
174+
display: inline-block;
175+
}
176+
177+
.filter-multi-select .dropdown-item .custom-control-label::before {
178+
border-radius: 0.25rem;
179+
transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
180+
position: absolute;
181+
top: 0.15625rem;
182+
left: -1.5rem;
183+
display: block;
184+
width: 1rem;
185+
height: 1rem;
186+
pointer-events: none;
187+
content: "";
188+
background-color: #FFFFFF;
189+
border: #adb5bd solid 1px
190+
}
191+
192+
.filter-multi-select .dropdown-item .custom-control-label::after {
193+
position: absolute;
194+
top: 0.15625rem;
195+
left: -1.5rem;
196+
display: block;
197+
width: 1rem;
198+
height: 1rem;
199+
content: "";
200+
background: no-repeat 50% / 50% 50%;
201+
}
202+
203+
.filter-multi-select .dropdown-item .custom-checkbox:checked ~ .custom-control-label::before,
204+
.filter-multi-select .dropdown-item .custom-checkbox:indeterminate ~ .custom-control-label::before {
205+
border-color: var(--fms-badge-color);
206+
background-color: var(--fms-badge-color);
207+
}
208+
209+
.filter-multi-select .dropdown-item .custom-checkbox:checked:disabled ~ .custom-control-label::before,
210+
.filter-multi-select .dropdown-item .custom-checkbox:indeterminate:disabled ~ .custom-control-label::before {
211+
border-color: var(--fms-badge-color);
212+
background-color: var(--fms-badge-color);
213+
filter: grayscale(80%) brightness(150%);
214+
}
215+
216+
.filter-multi-select .dropdown-item .custom-checkbox:checked ~ .custom-control-label::after {
217+
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23FFFFFF' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e");
218+
}
219+
220+
.filter-multi-select .dropdown-item .custom-checkbox:indeterminate ~ .custom-control-label::after {
221+
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23FFFFFF' d='M0 2h4'/%3e%3c/svg%3e");
222+
}

js/filter-multi-select.bundle.js

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/filter-multi-select.bundle.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/WebApp/Application.php

+39-9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Application {
1717
public $sessionHandler;
1818
public $router;
1919
public $mailQueue;
20+
public $theme;
2021
protected $principal;
2122

2223
public function __construct($config) {
@@ -70,10 +71,21 @@ protected function initDataModel() {
7071

7172
protected function initAuthentication() {
7273
if ($this->config->has('authentication')) {
73-
$className = $this->config->get('authentication');
74+
$authConfig = $this->config->get('authentication');
75+
$className = NULL;
76+
$config = NULL;
77+
if (is_object($authConfig)) {
78+
$className = $authConfig->class;
79+
if (isset($authConfig->config)) $config = $authConfig->config;
80+
} else if (is_array($authConfig)) {
81+
$className = $authConfig['class'];
82+
if (isset($authConfig['config'])) $config = $authConfig['config'];
83+
} else {
84+
$className = $authConfig;
85+
}
7486
if (substr($className, 0, 1) != '\\') $classname = '\\'.$className;
7587
if (class_exists($className)) {
76-
$this->authentication = new $className($this);
88+
$this->authentication = new $className($this, $config);
7789
} else {
7890
throw new WebAppException('Cannot find Authentication class: '.$className);
7991
}
@@ -82,18 +94,33 @@ protected function initAuthentication() {
8294

8395
protected function initAuthorization() {
8496
if ($this->config->has('authorization')) {
85-
$className = $this->config->get('authorization');
97+
$authConfig = $this->config->get('authorization');
98+
$className = NULL;
99+
$config = NULL;
100+
if (is_object($authConfig)) {
101+
$className = $authConfig->class;
102+
if (isset($authConfig->config)) $config = $authConfig->config;
103+
} else if (is_array($authConfig)) {
104+
$className = $authConfig['class'];
105+
if (isset($authConfig['config'])) $config = $authConfig['config'];
106+
} else {
107+
$className = $authConfig;
108+
}
86109
if (substr($className, 0, 1) != '\\') $classname = '\\'.$className;
87110
if (class_exists($className)) {
88-
$this->authorization = new $className($this);
111+
$this->authorization = new $className($this, $config);
89112
} else {
90113
throw new WebAppException('Cannot find Authorization class: '.$className);
91114
}
92115
}
93116
}
94117

118+
protected function getSessionCookieName() {
119+
return preg_replace( '/[\W]/', '', 'WebApp'.$this->request->webRoot);
120+
}
121+
95122
protected function initSession() {
96-
$cookieName = preg_replace( '/[\W]/', '', $this->getName());
123+
$cookieName = $this->getSessionCookieName();
97124
if ($this->database) {
98125
if ($this->dataModel) {
99126
$this->sessionHandler = Session\Utils::create($cookieName, $this->dataModel);
@@ -135,7 +162,7 @@ protected function initMailQueue() {
135162
if ($credentialsProvider != NULL) {
136163
$mailConfig->getSmtpConfig()->setCredentialsProvider($credentialsProvider);
137164
}
138-
$this->mailQueue = new \TgEmail\EmailQueue($mainConfig, $mailDAO);
165+
$this->mailQueue = new \TgEmail\EmailQueue($mailConfig, $mailDAO);
139166
}
140167
}
141168

@@ -209,9 +236,12 @@ public function setPrincipal($principal, $persist = FALSE) {
209236

210237
public function authenticate($id, $secret, $persist = FALSE) {
211238
if ($this->authentication != NULL) {
212-
$this->setPrincipal($this->authentication->authenticate($id, $secret), $persist);
213-
$this->sessionHandler->gc(3600);
214-
return $this->principal != NULL;
239+
$result = $this->authentication->authenticate($id, $secret);
240+
if (!is_a($result, 'WebApp\\Auth\\AuthError')) {
241+
$this->setPrincipal($result, $persist);
242+
$this->sessionHandler->gc(3600);
243+
}
244+
return $result;
215245
}
216246
return FALSE;
217247
}

src/WebApp/Auth/AbstractAuthenticator.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
abstract class AbstractAuthenticator implements Authenticator {
1111

1212
protected $app;
13+
protected $config;
1314

14-
public function __construct(Application $app) {
15-
$this->app = $app;
15+
public function __construct(Application $app, $config = NULL) {
16+
$this->app = $app;
17+
if (is_object($config)) $config = get_object_vars($config);
18+
$this->config = $config;
1619
$this->init();
1720
}
1821

src/WebApp/Auth/AbstractAuthorizator.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
abstract class AbstractAuthorizator implements Authorizator {
1111

1212
protected $app;
13+
protected $config;
1314

14-
public function __construct(Application $app) {
15-
$this->app = $app;
15+
public function __construct(Application $app, $config = NULL) {
16+
$this->app = $app;
17+
if (is_object($config)) $config = get_object_vars($config);
18+
$this->config = $config;
1619
$this->init();
1720
}
1821

src/WebApp/Auth/AuthError.php

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace WebApp\Auth;
4+
5+
class AuthError {
6+
7+
public const USER_NOT_FOUND = 1;
8+
public const USER_BLOCKED = 2;
9+
public const USER_TEMPORARILY_BLOCKED = 3;
10+
public const PASSWORD_INVALID = 4;
11+
12+
public $errorCode;
13+
public $errorMessage;
14+
15+
public function __construct($errorCode, $errorMessage) {
16+
$this->errorCode = $errorCode;
17+
$this->errorMessage = $errorMessage;
18+
}
19+
20+
public function getMessage() {
21+
return \TgI18n\I18N::_($this->errorMessage);
22+
}
23+
}
24+

0 commit comments

Comments
 (0)