Merge ssh://source.netsyms.com:2322/Business/BusinessAppTemplate
# Conflicts: # .gitignore # LICENSE.md # README.md # api.php # app.php # composer.json # composer.lock # lang/en_us.php # lib/login.php # lib/userinfo.php # mobile/index.php # pages.php # pages/404.php # required.php # settings.template.php # static/css/app.css # static/img/logo.png # static/js/app.js
This commit is contained in:
commit
c99b739532
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,4 +2,4 @@ vendor
|
||||
settings.php
|
||||
nbproject/private
|
||||
database.mwb.bak
|
||||
*.sync-conflict*
|
||||
*.sync-conflict*
|
||||
|
40
LICENSE.md
40
LICENSE.md
@ -1,18 +1,18 @@
|
||||
Copyright (c) 2017 Netsyms Technologies.
|
||||
Copyright (c) 2018 Netsyms Technologies.
|
||||
|
||||
If you modify and redistribute this project, you must replace the branding
|
||||
If you modify and redistribute this project, you must replace the branding
|
||||
assets with your own.
|
||||
|
||||
The branding assets include:
|
||||
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:
|
||||
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,
|
||||
All other portions of this application,
|
||||
unless otherwise noted (in comments, headers, etc), are licensed as follows:
|
||||
|
||||
Mozilla Public License Version 2.0
|
||||
@ -20,24 +20,24 @@ Mozilla Public License Version 2.0
|
||||
|
||||
### 1. Definitions
|
||||
|
||||
**1.1. “Contributor”**
|
||||
**1.1. “Contributor”**
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
**1.2. “Contributor Version”**
|
||||
**1.2. “Contributor Version”**
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
**1.3. “Contribution”**
|
||||
**1.3. “Contribution”**
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
**1.4. “Covered Software”**
|
||||
**1.4. “Covered Software”**
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
**1.5. “Incompatible With Secondary Licenses”**
|
||||
**1.5. “Incompatible With Secondary Licenses”**
|
||||
means
|
||||
|
||||
* **(a)** that the initial Contributor has attached the notice described
|
||||
@ -46,22 +46,22 @@ Mozilla Public License Version 2.0
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
**1.6. “Executable Form”**
|
||||
**1.6. “Executable Form”**
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
**1.7. “Larger Work”**
|
||||
means a work that combines Covered Software with other material, in
|
||||
**1.7. “Larger Work”**
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
**1.8. “License”**
|
||||
**1.8. “License”**
|
||||
means this document.
|
||||
|
||||
**1.9. “Licensable”**
|
||||
**1.9. “Licensable”**
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
**1.10. “Modifications”**
|
||||
**1.10. “Modifications”**
|
||||
means any of the following:
|
||||
|
||||
* **(a)** any file in Source Code Form that results from an addition to,
|
||||
@ -70,7 +70,7 @@ Mozilla Public License Version 2.0
|
||||
* **(b)** any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
**1.11. “Patent Claims” of a Contributor**
|
||||
**1.11. “Patent Claims” of a Contributor**
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
@ -78,16 +78,16 @@ Mozilla Public License Version 2.0
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
**1.12. “Secondary License”**
|
||||
**1.12. “Secondary License”**
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
**1.13. “Source Code Form”**
|
||||
**1.13. “Source Code Form”**
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
**1.14. “You” (or “Your”)**
|
||||
**1.14. “You” (or “Your”)**
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, “You” includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
|
@ -17,6 +17,12 @@ if ($VARS['action'] !== "signout") {
|
||||
dieifnotloggedin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects back to the page ID in $_POST/$_GET['source'] with the given message ID.
|
||||
* The message will be displayed by the app.
|
||||
* @param string $msg message ID (see lang/messages.php)
|
||||
* @param string $arg If set, replaces "{arg}" in the message string when displayed to the user.
|
||||
*/
|
||||
function returnToSender($msg, $arg = "") {
|
||||
global $VARS;
|
||||
if ($arg == "") {
|
||||
|
2
api.php
2
api.php
@ -165,4 +165,4 @@ switch ($VARS['action']) {
|
||||
default:
|
||||
header("HTTP/1.1 400 Bad Request");
|
||||
die("\"400 Bad Request\"");
|
||||
}
|
||||
}
|
||||
|
10
app.php
10
app.php
@ -18,6 +18,12 @@ if (!is_empty($_GET['page'])) {
|
||||
$pageid = "404";
|
||||
}
|
||||
}
|
||||
|
||||
header("Link: <static/css/bootstrap.min.css>; rel=preload; as=style", false);
|
||||
header("Link: <static/css/material-color/material-color.min.css>; rel=preload; as=style", false);
|
||||
header("Link: <static/css/app.css>; rel=preload; as=style", false);
|
||||
header("Link: <static/js/jquery-3.3.1.min.js>; rel=preload; as=script", false);
|
||||
header("Link: <static/js/bootstrap.min.js>; rel=preload; as=script", false);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -43,6 +49,7 @@ if (!is_empty($_GET['page'])) {
|
||||
if (isset(PAGES[$pageid]['styles'])) {
|
||||
foreach (PAGES[$pageid]['styles'] as $style) {
|
||||
echo "<link href=\"$style\" rel=\"stylesheet\">\n";
|
||||
header("Link: <$style>; rel=preload; as=style", false);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -169,8 +176,9 @@ END;
|
||||
if (isset(PAGES[$pageid]['scripts'])) {
|
||||
foreach (PAGES[$pageid]['scripts'] as $script) {
|
||||
echo "<script src=\"$script\"></script>\n";
|
||||
header("Link: <$script>; rel=preload; as=script", false);
|
||||
}
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -72,6 +72,11 @@ if (checkLoginServer()) {
|
||||
} else {
|
||||
$alert = lang("login server unavailable", false);
|
||||
}
|
||||
header("Link: <static/css/bootstrap.min.css>; rel=preload; as=style", false);
|
||||
header("Link: <static/css/material-color/material-color.min.css>; rel=preload; as=style", false);
|
||||
header("Link: <static/css/index.css>; rel=preload; as=style", false);
|
||||
header("Link: <static/js/jquery-3.3.1.min.js>; rel=preload; as=script", false);
|
||||
header("Link: <static/js/bootstrap.min.js>; rel=preload; as=script", false);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
@ -82,4 +82,4 @@ define("STRINGS", [
|
||||
"finished on" => "Finished on: {date}",
|
||||
"started on" => "Started on: {date}",
|
||||
"add task" => "Add Task"
|
||||
]);
|
||||
]);
|
||||
|
127
lib/iputils.php
Normal file
127
lib/iputils.php
Normal file
@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Check if a given ipv4 address is in a given cidr
|
||||
* @param string $ip IP to check in IPV4 format eg. 127.0.0.1
|
||||
* @param string $range IP/CIDR netmask eg. 127.0.0.0/24, also 127.0.0.1 is accepted and /32 assumed
|
||||
* @return boolean true if the ip is in this range / false if not.
|
||||
* @author Thorsten Ott <https://gist.github.com/tott/7684443>
|
||||
*/
|
||||
function ip4_in_cidr($ip, $cidr) {
|
||||
if (strpos($cidr, '/') == false) {
|
||||
$cidr .= '/32';
|
||||
}
|
||||
// $range is in IP/CIDR format eg 127.0.0.1/24
|
||||
list( $cidr, $netmask ) = explode('/', $cidr, 2);
|
||||
$range_decimal = ip2long($cidr);
|
||||
$ip_decimal = ip2long($ip);
|
||||
$wildcard_decimal = pow(2, ( 32 - $netmask)) - 1;
|
||||
$netmask_decimal = ~ $wildcard_decimal;
|
||||
return ( ( $ip_decimal & $netmask_decimal ) == ( $range_decimal & $netmask_decimal ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given ipv6 address is in a given cidr
|
||||
* @param string $ip IP to check in IPV6 format
|
||||
* @param string $cidr CIDR netmask
|
||||
* @return boolean true if the IP is in this range, false otherwise.
|
||||
* @author MW. <https://stackoverflow.com/a/7952169>
|
||||
*/
|
||||
function ip6_in_cidr($ip, $cidr) {
|
||||
$address = inet_pton($ip);
|
||||
$subnetAddress = inet_pton(explode("/", $cidr)[0]);
|
||||
$subnetMask = explode("/", $cidr)[1];
|
||||
|
||||
$addr = str_repeat("f", $subnetMask / 4);
|
||||
switch ($subnetMask % 4) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
$addr .= "8";
|
||||
break;
|
||||
case 2:
|
||||
$addr .= "c";
|
||||
break;
|
||||
case 3:
|
||||
$addr .= "e";
|
||||
break;
|
||||
}
|
||||
$addr = str_pad($addr, 32, '0');
|
||||
$addr = pack("H*", $addr);
|
||||
|
||||
$binMask = $addr;
|
||||
return ($address & $binMask) == $subnetAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the REMOTE_ADDR is on Cloudflare's network.
|
||||
* @return boolean true if it is, otherwise false
|
||||
*/
|
||||
function validateCloudflare() {
|
||||
if (filter_var($_SERVER["REMOTE_ADDR"], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
// Using IPv6
|
||||
$cloudflare_ips_v6 = [
|
||||
"2400:cb00::/32",
|
||||
"2405:8100::/32",
|
||||
"2405:b500::/32",
|
||||
"2606:4700::/32",
|
||||
"2803:f800::/32",
|
||||
"2c0f:f248::/32",
|
||||
"2a06:98c0::/29"
|
||||
];
|
||||
$valid = false;
|
||||
foreach ($cloudflare_ips_v6 as $cidr) {
|
||||
if (ip6_in_cidr($_SERVER["REMOTE_ADDR"], $cidr)) {
|
||||
$valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Using IPv4
|
||||
$cloudflare_ips_v4 = [
|
||||
"103.21.244.0/22",
|
||||
"103.22.200.0/22",
|
||||
"103.31.4.0/22",
|
||||
"104.16.0.0/12",
|
||||
"108.162.192.0/18",
|
||||
"131.0.72.0/22",
|
||||
"141.101.64.0/18",
|
||||
"162.158.0.0/15",
|
||||
"172.64.0.0/13",
|
||||
"173.245.48.0/20",
|
||||
"188.114.96.0/20",
|
||||
"190.93.240.0/20",
|
||||
"197.234.240.0/22",
|
||||
"198.41.128.0/17"
|
||||
];
|
||||
$valid = false;
|
||||
foreach ($cloudflare_ips_v4 as $cidr) {
|
||||
if (ip4_in_cidr($_SERVER["REMOTE_ADDR"], $cidr)) {
|
||||
$valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a good guess at the client's real IP address.
|
||||
*
|
||||
* @return string Client IP or `0.0.0.0` if we can't find anything
|
||||
*/
|
||||
function getClientIP() {
|
||||
// If CloudFlare is in the mix, we should use it.
|
||||
// Check if the request is actually from CloudFlare before trusting it.
|
||||
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
|
||||
if (validateCloudflare()) {
|
||||
return $_SERVER["HTTP_CF_CONNECTING_IP"];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_SERVER["REMOTE_ADDR"])) {
|
||||
return $_SERVER["REMOTE_ADDR"];
|
||||
}
|
||||
|
||||
return "0.0.0.0"; // This will not happen unless we aren't a web server
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
/**
|
||||
* Authentication and account functions. Connects to a Portal instance.
|
||||
* Authentication and account functions. Connects to an AccountHub instance.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -124,4 +124,4 @@ function getManagedUIDs($manageruid) {
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,10 @@
|
||||
* Mobile app API
|
||||
*/
|
||||
|
||||
// The name of the permission needed to log in.
|
||||
// Set to null if you don't need it.
|
||||
$access_permission = "TASKFLOOR";
|
||||
|
||||
require __DIR__ . "/../required.php";
|
||||
|
||||
require __DIR__ . "/../lib/login.php";
|
||||
@ -93,7 +97,7 @@ switch ($VARS['action']) {
|
||||
if (user_exists($VARS['username'])) {
|
||||
if (get_account_status($VARS['username']) == "NORMAL") {
|
||||
if (authenticate_user($VARS['username'], $VARS['password'], $autherror)) {
|
||||
if (account_has_permission($VARS['username'], "TASKFLOOR")) {
|
||||
if (is_null($access_permission) || account_has_permission($VARS['username'], $access_permission)) {
|
||||
doLoginUser($VARS['username'], $VARS['password']);
|
||||
$_SESSION['mobile'] = true;
|
||||
exit(json_encode(["status" => "OK"]));
|
||||
@ -107,4 +111,4 @@ switch ($VARS['action']) {
|
||||
default:
|
||||
http_response_code(404);
|
||||
die(json_encode(["status" => "ERROR", "msg" => "The requested action is not available."]));
|
||||
}
|
||||
}
|
||||
|
@ -9,4 +9,4 @@
|
||||
<div class="col-12 col-sm-6 col-md-4 col-lg-4">
|
||||
<div class="alert alert-warning"><b><?php lang("404 error");?></b><br /> <?php lang("page not found"); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -12,10 +12,12 @@ ob_start(); // allow sending headers after content
|
||||
// Unicode, solves almost all stupid encoding problems
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
|
||||
// l33t $ecurity h4x
|
||||
// Strip PHP version
|
||||
header('X-Powered-By: PHP');
|
||||
|
||||
// Security
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
header('X-XSS-Protection: 1; mode=block');
|
||||
header('X-Powered-By: PHP'); // no versions makes it harder to find vulns
|
||||
header('X-Frame-Options: "DENY"');
|
||||
header('Referrer-Policy: "no-referrer, strict-origin-when-cross-origin"');
|
||||
$SECURE_NONCE = base64_encode(random_bytes(8));
|
||||
@ -80,7 +82,7 @@ function sendError($error) {
|
||||
. "<h1>A fatal application error has occurred.</h1>"
|
||||
. "<i>(This isn't your fault.)</i>"
|
||||
. "<h2>Details:</h2>"
|
||||
. "<p>". htmlspecialchars($error) . "</p>");
|
||||
. "<p>" . htmlspecialchars($error) . "</p>");
|
||||
}
|
||||
|
||||
date_default_timezone_set(TIMEZONE);
|
||||
|
@ -57,4 +57,4 @@ define('LANGUAGE', "en_us");
|
||||
|
||||
|
||||
define("FOOTER_TEXT", "");
|
||||
define("COPYRIGHT_NAME", "Netsyms Technologies");
|
||||
define("COPYRIGHT_NAME", "Netsyms Technologies");
|
||||
|
@ -122,4 +122,4 @@ body {
|
||||
|
||||
.easy-autocomplete input {
|
||||
border-radius: 0px !important;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ function setupTooltips() {
|
||||
$(document).ready(function () {
|
||||
/* Fade out alerts */
|
||||
$(".alert .close").click(function (e) {
|
||||
$(this).parent().fadeOut('slow');
|
||||
$(this).parent().fadeOut("slow");
|
||||
});
|
||||
|
||||
/* Activate tooltips */
|
||||
@ -31,4 +31,4 @@ try {
|
||||
window.history.replaceState("", "", getniceurl());
|
||||
} catch (ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user