forked from Business/AccountHub
Merge ../BusinessAppTemplate
# Conflicts: # README.md # action.php # api/functions.php # lib/User.lib.php # mobile/index.php # pages/form.php # settings.template.php # static/js/form.js
This commit is contained in:
commit
59136bd8eb
18
LICENSE.md
18
LICENSE.md
@ -1,19 +1,7 @@
|
||||
Copyright (c) 2018 Netsyms Technologies.
|
||||
Copyright (c) 2017-2019 Netsyms Technologies. Some rights reserved.
|
||||
|
||||
If you modify and redistribute this project, you must replace the branding
|
||||
assets with your own.
|
||||
|
||||
The branding assets include:
|
||||
* the application icon
|
||||
* the Netsyms N punchcard logo
|
||||
* the Netsyms for Business graph logo
|
||||
|
||||
If you are unsure if your usage is allowed, please contact us:
|
||||
https://netsyms.com/contact
|
||||
legal@netsyms.com
|
||||
|
||||
All other portions of this application,
|
||||
unless otherwise noted (in comments, headers, etc), are licensed as follows:
|
||||
Licensed under the Mozilla Public License Version 2.0. Files without MPL header
|
||||
comments, including third party code, may be under a different license.
|
||||
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
@ -23,11 +23,11 @@ dieifnotloggedin();
|
||||
|
||||
function returnToSender($msg, $arg = "") {
|
||||
global $VARS;
|
||||
if ($arg == "") {
|
||||
header("Location: app.php?page=" . urlencode($VARS['source']) . "&msg=$msg");
|
||||
} else {
|
||||
header("Location: app.php?page=" . urlencode($VARS['source']) . "&msg=$msg&arg=" . urlencode($arg));
|
||||
$header = "Location: app.php?page=" . urlencode($VARS['source']) . "&msg=$msg";
|
||||
if ($arg != "") {
|
||||
$header .= "&arg=$arg";
|
||||
}
|
||||
header($header);
|
||||
die();
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,9 @@ function authenticate(): bool {
|
||||
Log::insert(LogType::API_BAD_KEY, null, "Key: " . $key);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkVars($vars, $or = false) {
|
||||
@ -160,4 +161,4 @@ function checkkeytype(string $type): bool {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ require __DIR__ . '/../required.php';
|
||||
require __DIR__ . '/functions.php';
|
||||
require __DIR__ . '/apisettings.php';
|
||||
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
|
||||
$VARS = $_GET;
|
||||
if ($_SERVER['REQUEST_METHOD'] != "GET") {
|
||||
$VARS = array_merge($VARS, $_POST);
|
||||
|
@ -116,6 +116,41 @@ class FormBuilder {
|
||||
$this->items[] = $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a text input.
|
||||
*
|
||||
* @param string $name Element name
|
||||
* @param string $value Element value
|
||||
* @param bool $required If the element is required for form submission.
|
||||
* @param string $id Element ID
|
||||
* @param string $label Text label to display near the input
|
||||
* @param string $icon FontAwesome icon (example: "fas fa-toilet-paper")
|
||||
* @param int $width Bootstrap column width for the input, out of 12.
|
||||
* @param int $minlength Minimum number of characters for the input.
|
||||
* @param int $maxlength Maximum number of characters for the input.
|
||||
* @param string $pattern Regex pattern for custom client-side validation.
|
||||
* @param string $error Message to show if the input doesn't validate.
|
||||
*/
|
||||
public function addTextInput(string $name, string $value = "", bool $required = true, string $id = "", string $label = "", string $icon = "", int $width = 4, int $minlength = 1, int $maxlength = 100, string $pattern = "", string $error = "") {
|
||||
$this->addInput($name, $value, "text", $required, $id, null, $label, $icon, $width, $minlength, $maxlength, $pattern, $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a select dropdown.
|
||||
*
|
||||
* @param string $name Element name
|
||||
* @param string $value Element value
|
||||
* @param bool $required If the element is required for form submission.
|
||||
* @param string $id Element ID
|
||||
* @param array $options Array of [value => text] pairs for a select element
|
||||
* @param string $label Text label to display near the input
|
||||
* @param string $icon FontAwesome icon (example: "fas fa-toilet-paper")
|
||||
* @param int $width Bootstrap column width for the input, out of 12.
|
||||
*/
|
||||
public function addSelect(string $name, string $value = "", bool $required = true, string $id = null, array $options = null, string $label = "", string $icon = "", int $width = 4) {
|
||||
$this->addInput($name, $value, "select", $required, $id, $options, $label, $icon, $width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a button to the form.
|
||||
*
|
||||
@ -178,7 +213,10 @@ HTMLTOP;
|
||||
}
|
||||
$itemhtml = "";
|
||||
$itemlabel = "";
|
||||
if ($item['type'] != "checkbox") {
|
||||
|
||||
if ($item['type'] == "textarea") {
|
||||
$itemlabel = "<label class=\"mb-0\"><i class=\"$item[icon]\"></i> $item[label]:</label>";
|
||||
} else if ($item['type'] != "checkbox") {
|
||||
$itemlabel = "<label class=\"mb-0\">$item[label]:</label>";
|
||||
}
|
||||
$strippedlabel = strip_tags($item['label']);
|
||||
@ -186,13 +224,16 @@ HTMLTOP;
|
||||
\n\n <div class="col-12 col-md-$item[width]">
|
||||
<div class="form-group mb-3">
|
||||
$itemlabel
|
||||
<div class="input-group">
|
||||
ITEMTOP;
|
||||
$inputgrouptop = <<<INPUTG
|
||||
\n <div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="$item[icon]"></i></span>
|
||||
</div>
|
||||
ITEMTOP;
|
||||
INPUTG;
|
||||
switch ($item['type']) {
|
||||
case "select":
|
||||
$itemhtml .= $inputgrouptop;
|
||||
$itemhtml .= <<<SELECT
|
||||
\n <select class="form-control" name="$item[name]" aria-label="$strippedlabel" $required>
|
||||
SELECT;
|
||||
@ -206,6 +247,7 @@ SELECT;
|
||||
$itemhtml .= "\n </select>";
|
||||
break;
|
||||
case "checkbox":
|
||||
$itemhtml .= $inputgrouptop;
|
||||
$itemhtml .= <<<CHECKBOX
|
||||
\n <div class="form-group form-check">
|
||||
<input type="checkbox" name="$item[name]" $id class="form-check-input" value="$item[value]" $required aria-label="$strippedlabel">
|
||||
@ -213,7 +255,14 @@ SELECT;
|
||||
</div>
|
||||
CHECKBOX;
|
||||
break;
|
||||
case "textarea":
|
||||
$val = htmlentities($item['value']);
|
||||
$itemhtml .= <<<TEXTAREA
|
||||
\n <textarea class="form-control" id="info" name="$item[name]" aria-label="$strippedlabel" minlength="$item[minlength]" maxlength="$item[maxlength]" $required>$val</textarea>
|
||||
TEXTAREA;
|
||||
break;
|
||||
default:
|
||||
$itemhtml .= $inputgrouptop;
|
||||
$itemhtml .= <<<INPUT
|
||||
\n <input type="$item[type]" name="$item[name]" $id class="form-control" aria-label="$strippedlabel" minlength="$item[minlength]" maxlength="$item[maxlength]" $pattern value="$item[value]" $required />
|
||||
INPUT;
|
||||
@ -227,9 +276,11 @@ INPUT;
|
||||
</div>
|
||||
ERROR;
|
||||
}
|
||||
if ($item["type"] != "textarea") {
|
||||
$itemhtml .= "\n </div>";
|
||||
}
|
||||
$itemhtml .= <<<ITEMBOTTOM
|
||||
\n </div>
|
||||
</div>
|
||||
\n </div>
|
||||
</div>\n
|
||||
ITEMBOTTOM;
|
||||
$html .= $itemhtml;
|
||||
@ -242,7 +293,7 @@ ITEMBOTTOM;
|
||||
HTMLBOTTOM;
|
||||
|
||||
if (!empty($this->buttons)) {
|
||||
$html .= "\n <div class=\"card-footer\">";
|
||||
$html .= "\n <div class=\"card-footer d-flex\">";
|
||||
foreach ($this->buttons as $btn) {
|
||||
$btnhtml = "";
|
||||
$inner = "<i class=\"$btn[icon]\"></i> $btn[text]";
|
||||
|
@ -103,6 +103,7 @@ class User {
|
||||
/**
|
||||
* Check the given plaintext password against the stored hash.
|
||||
* @param string $password
|
||||
* @param bool $apppass Set to true to enforce app passwords when 2fa is on.
|
||||
* @return bool
|
||||
*/
|
||||
function checkPassword(string $password): bool {
|
||||
@ -162,6 +163,7 @@ class User {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function check2fa(string $code): bool {
|
||||
if (!$this->has2fa) {
|
||||
return true;
|
||||
|
@ -132,7 +132,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
define("GET", true);
|
||||
}
|
||||
|
||||
|
||||
function dieifnotloggedin() {
|
||||
if ($_SESSION['loggedin'] != true) {
|
||||
sendError("Session expired. Please log out and log in again.");
|
||||
@ -157,6 +156,7 @@ function checkDBError($specials = []) {
|
||||
}
|
||||
|
||||
function redirectIfNotLoggedIn() {
|
||||
global $SETTINGS;
|
||||
if ($_SESSION['loggedin'] !== TRUE) {
|
||||
header('Location: ' . $SETTINGS['url'] . '/index.php');
|
||||
die();
|
||||
|
12
static/css/bootstrap.min.css
vendored
12
static/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
6
static/css/svg-with-js.min.css
vendored
6
static/css/svg-with-js.min.css
vendored
@ -1,5 +1 @@
|
||||
/*!
|
||||
* Font Awesome Free 5.6.0 by @fontawesome - https://fontawesome.com
|
||||
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
*/
|
||||
.svg-inline--fa,svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;transform:translate(-50%,-50%);transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;box-sizing:border-box;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;transform:scale(.25);transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;transform:scale(.25);transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;transform:scale(.25);transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;transform:scale(.25);transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;transform:scale(.25);transform-origin:top left}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{animation:fa-spin 2s infinite linear}.fa-pulse{animation:fa-spin 1s infinite steps(8)}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}
|
||||
.svg-inline--fa,svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;transform:translate(-50%,-50%);transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;box-sizing:border-box;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;transform:scale(.25);transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;transform:scale(.25);transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;transform:scale(.25);transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;transform:scale(.25);transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;transform:scale(.25);transform-origin:top left}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{animation:fa-spin 2s infinite linear}.fa-pulse{animation:fa-spin 1s infinite steps(8)}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}
|
@ -13,7 +13,7 @@ $(document).ready(function () {
|
||||
var gone = 20;
|
||||
|
||||
var msgticker = setInterval(function () {
|
||||
if ($('#msg-alert-box .alert:hover').length) {
|
||||
if ($("#msg-alert-box .alert:hover").length) {
|
||||
msginteractiontick = 0;
|
||||
} else {
|
||||
msginteractiontick++;
|
||||
@ -55,7 +55,6 @@ $(document).ready(function () {
|
||||
$("#msg-alert-box").on("mouseenter", function () {
|
||||
$("#msg-alert-box").css("opacity", "1");
|
||||
msginteractiontick = 0;
|
||||
console.log("👈😎👈 zoop");
|
||||
});
|
||||
$("#msg-alert-box").on("click", ".close", function (e) {
|
||||
$("#msg-alert-box").fadeOut("slow");
|
||||
|
6
static/js/bootstrap.bundle.min.js
vendored
6
static/js/bootstrap.bundle.min.js
vendored
File diff suppressed because one or more lines are too long
6
static/js/fontawesome-all.min.js
vendored
6
static/js/fontawesome-all.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user