forked from Business/BinStack
		
	Add Portal API integration, add icon/style settings, add navbar and icon
options to PAGES
This commit is contained in:
		
							parent
							
								
									16cbf2a5f1
								
							
						
					
					
						commit
						3110011596
					
				
							
								
								
									
										70
									
								
								app.php
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								app.php
									
									
									
									
									
								
							@ -36,10 +36,18 @@ if (!is_empty($_GET['page'])) {
 | 
				
			|||||||
        <div class="container">
 | 
					        <div class="container">
 | 
				
			||||||
            <div class="row">
 | 
					            <div class="row">
 | 
				
			||||||
                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 col-sm-offset-3 col-md-offset-4 col-lg-offset-4">
 | 
					                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 col-sm-offset-3 col-md-offset-4 col-lg-offset-4">
 | 
				
			||||||
                    <img class="img-responsive banner-image" src="static/img/banner.png" />
 | 
					                    <?php
 | 
				
			||||||
 | 
					                    if ((SHOW_ICON == "both" || SHOW_ICON == "app") && ICON_POSITION != "menu") {
 | 
				
			||||||
 | 
					                        if (MENU_BAR_STYLE != "fixed") {
 | 
				
			||||||
 | 
					                            ?>
 | 
				
			||||||
 | 
					                            <img class="img-responsive banner-image" src="static/img/logo.png" />
 | 
				
			||||||
 | 
					                            <?php
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    ?>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <nav class="navbar navbar-inverse">
 | 
					            <nav class="navbar navbar-inverse navbar-<?php echo MENU_BAR_STYLE; ?>-top">
 | 
				
			||||||
                <div class="container-fluid">
 | 
					                <div class="container-fluid">
 | 
				
			||||||
                    <div class="navbar-header">
 | 
					                    <div class="navbar-header">
 | 
				
			||||||
                        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse">
 | 
					                        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse">
 | 
				
			||||||
@ -48,34 +56,70 @@ if (!is_empty($_GET['page'])) {
 | 
				
			|||||||
                            <span class="icon-bar"></span>
 | 
					                            <span class="icon-bar"></span>
 | 
				
			||||||
                            <span class="icon-bar"></span>
 | 
					                            <span class="icon-bar"></span>
 | 
				
			||||||
                        </button>
 | 
					                        </button>
 | 
				
			||||||
                        <a class="navbar-brand" href="app.php?page=home">
 | 
					                        <?php
 | 
				
			||||||
 | 
					                        if (SHOW_ICON == "both" || SHOW_ICON == "app") {
 | 
				
			||||||
 | 
					                            if (MENU_BAR_STYLE == "fixed" || ICON_POSITION == "menu") {
 | 
				
			||||||
 | 
					                                ?>
 | 
				
			||||||
 | 
					                                <a class="navbar-brand" href="app.php">
 | 
				
			||||||
 | 
					                                    <img style="height: 35px; padding-bottom: 12px; padding-left: 5px;" src="static/img/logo.png" />
 | 
				
			||||||
 | 
					                                </a>
 | 
				
			||||||
 | 
					                                <?php
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        ?>
 | 
				
			||||||
 | 
					                        <a class="navbar-brand" href="app.php">
 | 
				
			||||||
                            <?php
 | 
					                            <?php
 | 
				
			||||||
 | 
					                            echo SITE_TITLE;
 | 
				
			||||||
                            // add breadcrumb-y thing
 | 
					                            // add breadcrumb-y thing
 | 
				
			||||||
                            //lang("home");
 | 
					                            //lang("home");
 | 
				
			||||||
                            //echo " <i class=\"fa fa-caret-right\"></i> ";
 | 
					                            //echo " <i class=\"fa fa-caret-right\"></i> ";
 | 
				
			||||||
                            lang(PAGES[$pageid]['title']);
 | 
					                            //lang(PAGES[$pageid]['title']);
 | 
				
			||||||
                            ?>
 | 
					                            ?>
 | 
				
			||||||
                        </a>
 | 
					                        </a>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <div class="collapse navbar-collapse" id="navbar-collapse">
 | 
					                    <div class="collapse navbar-collapse" id="navbar-collapse">
 | 
				
			||||||
                        <ul class="nav navbar-nav">
 | 
					                        <ul class="nav navbar-nav">
 | 
				
			||||||
 | 
					                            <?php
 | 
				
			||||||
 | 
					                            foreach (PAGES as $id => $pg) {
 | 
				
			||||||
 | 
					                                if ($pg['navbar'] === TRUE) {
 | 
				
			||||||
 | 
					                                    if ($pageid == $id) {
 | 
				
			||||||
 | 
					                                        ?>
 | 
				
			||||||
 | 
					                                        <li class="active">
 | 
				
			||||||
 | 
					                                            <?php
 | 
				
			||||||
 | 
					                                        } else {
 | 
				
			||||||
 | 
					                                            ?>
 | 
				
			||||||
 | 
					                                        <li>
 | 
				
			||||||
 | 
					                                        <?php } ?>
 | 
				
			||||||
 | 
					                                        <a href="app.php?page=<?php echo $id; ?>">
 | 
				
			||||||
 | 
					                                            <?php
 | 
				
			||||||
 | 
					                                            if (isset($pg['icon'])) {
 | 
				
			||||||
 | 
					                                                ?>
 | 
				
			||||||
 | 
					                                                <i class="fa fa-<?php echo $pg['icon']; ?> fa-fw"></i> 
 | 
				
			||||||
 | 
					                                            <?php } ?>
 | 
				
			||||||
 | 
					                                            <?php lang($pg['title']) ?>
 | 
				
			||||||
 | 
					                                        </a>
 | 
				
			||||||
 | 
					                                    </li>
 | 
				
			||||||
 | 
					                                    <?php
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            ?>
 | 
				
			||||||
                        </ul>
 | 
					                        </ul>
 | 
				
			||||||
                        <ul class="nav navbar-nav navbar-right">
 | 
					                        <ul class="nav navbar-nav navbar-right">
 | 
				
			||||||
                            <li class="dropdown">
 | 
					                            <li><a href="action.php?action=signout"><i class="fa fa-sign-out fa-fw"></i> <?php lang("sign out") ?></a></li>
 | 
				
			||||||
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-gears fa-fw"></i> <?php lang("options") ?> <span class="caret"></span></a>
 | 
					 | 
				
			||||||
                                <ul class="dropdown-menu" role="menu">
 | 
					 | 
				
			||||||
                                    <li><a href="app.php?page=security"><i class="fa fa-lock fa-fw"></i> <?php lang("account security") ?></a></li>
 | 
					 | 
				
			||||||
                                    <li class="divider"></li>
 | 
					 | 
				
			||||||
                                    <li><a href="action.php?action=signout"><i class="fa fa-sign-out fa-fw"></i> <?php lang("sign out") ?></a></li>
 | 
					 | 
				
			||||||
                                </ul>
 | 
					 | 
				
			||||||
                            </li>
 | 
					 | 
				
			||||||
                        </ul>
 | 
					                        </ul>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </nav>
 | 
					            </nav>
 | 
				
			||||||
            <?php
 | 
					            <?php
 | 
				
			||||||
            // Alert messages
 | 
					            if (MENU_BAR_STYLE == "fixed") {
 | 
				
			||||||
 | 
					                ?>
 | 
				
			||||||
 | 
					                <div style="height: 75px;"></div>
 | 
				
			||||||
 | 
					                <?php
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            ?>
 | 
				
			||||||
 | 
					            <?php
 | 
				
			||||||
 | 
					// Alert messages
 | 
				
			||||||
            if (!is_empty($_GET['msg']) && array_key_exists($_GET['msg'], MESSAGES)) {
 | 
					            if (!is_empty($_GET['msg']) && array_key_exists($_GET['msg'], MESSAGES)) {
 | 
				
			||||||
                // optional string generation argument
 | 
					                // optional string generation argument
 | 
				
			||||||
                if (is_empty($_GET['arg'])) {
 | 
					                if (is_empty($_GET['arg'])) {
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,8 @@
 | 
				
			|||||||
    "type": "project",
 | 
					    "type": "project",
 | 
				
			||||||
    "require": {
 | 
					    "require": {
 | 
				
			||||||
        "catfan/medoo": "^1.2",
 | 
					        "catfan/medoo": "^1.2",
 | 
				
			||||||
        "spomky-labs/otphp": "^8.3"
 | 
					        "spomky-labs/otphp": "^8.3",
 | 
				
			||||||
 | 
					        "guzzlehttp/guzzle": "^6.2"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "license": "MIT",
 | 
					    "license": "MIT",
 | 
				
			||||||
    "authors": [
 | 
					    "authors": [
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										230
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										230
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							@ -4,7 +4,7 @@
 | 
				
			|||||||
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
 | 
					        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
 | 
				
			||||||
        "This file is @generated automatically"
 | 
					        "This file is @generated automatically"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "content-hash": "51c1672b4dea32e60865b4c0cd9ff8e1",
 | 
					    "content-hash": "e0730a4c33d1a1cbf8738481ba9a1f1e",
 | 
				
			||||||
    "packages": [
 | 
					    "packages": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "beberlei/assert",
 | 
					            "name": "beberlei/assert",
 | 
				
			||||||
@ -170,6 +170,184 @@
 | 
				
			|||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "time": "2016-05-05T11:49:03+00:00"
 | 
					            "time": "2016-05-05T11:49:03+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "name": "guzzlehttp/guzzle",
 | 
				
			||||||
 | 
					            "version": "6.2.3",
 | 
				
			||||||
 | 
					            "source": {
 | 
				
			||||||
 | 
					                "type": "git",
 | 
				
			||||||
 | 
					                "url": "https://github.com/guzzle/guzzle.git",
 | 
				
			||||||
 | 
					                "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "dist": {
 | 
				
			||||||
 | 
					                "type": "zip",
 | 
				
			||||||
 | 
					                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/8d6c6cc55186db87b7dc5009827429ba4e9dc006",
 | 
				
			||||||
 | 
					                "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006",
 | 
				
			||||||
 | 
					                "shasum": ""
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require": {
 | 
				
			||||||
 | 
					                "guzzlehttp/promises": "^1.0",
 | 
				
			||||||
 | 
					                "guzzlehttp/psr7": "^1.4",
 | 
				
			||||||
 | 
					                "php": ">=5.5"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require-dev": {
 | 
				
			||||||
 | 
					                "ext-curl": "*",
 | 
				
			||||||
 | 
					                "phpunit/phpunit": "^4.0",
 | 
				
			||||||
 | 
					                "psr/log": "^1.0"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "type": "library",
 | 
				
			||||||
 | 
					            "extra": {
 | 
				
			||||||
 | 
					                "branch-alias": {
 | 
				
			||||||
 | 
					                    "dev-master": "6.2-dev"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "autoload": {
 | 
				
			||||||
 | 
					                "files": [
 | 
				
			||||||
 | 
					                    "src/functions_include.php"
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "psr-4": {
 | 
				
			||||||
 | 
					                    "GuzzleHttp\\": "src/"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "notification-url": "https://packagist.org/downloads/",
 | 
				
			||||||
 | 
					            "license": [
 | 
				
			||||||
 | 
					                "MIT"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "authors": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "name": "Michael Dowling",
 | 
				
			||||||
 | 
					                    "email": "mtdowling@gmail.com",
 | 
				
			||||||
 | 
					                    "homepage": "https://github.com/mtdowling"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "description": "Guzzle is a PHP HTTP client library",
 | 
				
			||||||
 | 
					            "homepage": "http://guzzlephp.org/",
 | 
				
			||||||
 | 
					            "keywords": [
 | 
				
			||||||
 | 
					                "client",
 | 
				
			||||||
 | 
					                "curl",
 | 
				
			||||||
 | 
					                "framework",
 | 
				
			||||||
 | 
					                "http",
 | 
				
			||||||
 | 
					                "http client",
 | 
				
			||||||
 | 
					                "rest",
 | 
				
			||||||
 | 
					                "web service"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "time": "2017-02-28T22:50:30+00:00"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "name": "guzzlehttp/promises",
 | 
				
			||||||
 | 
					            "version": "v1.3.1",
 | 
				
			||||||
 | 
					            "source": {
 | 
				
			||||||
 | 
					                "type": "git",
 | 
				
			||||||
 | 
					                "url": "https://github.com/guzzle/promises.git",
 | 
				
			||||||
 | 
					                "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "dist": {
 | 
				
			||||||
 | 
					                "type": "zip",
 | 
				
			||||||
 | 
					                "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
 | 
				
			||||||
 | 
					                "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
 | 
				
			||||||
 | 
					                "shasum": ""
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require": {
 | 
				
			||||||
 | 
					                "php": ">=5.5.0"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require-dev": {
 | 
				
			||||||
 | 
					                "phpunit/phpunit": "^4.0"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "type": "library",
 | 
				
			||||||
 | 
					            "extra": {
 | 
				
			||||||
 | 
					                "branch-alias": {
 | 
				
			||||||
 | 
					                    "dev-master": "1.4-dev"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "autoload": {
 | 
				
			||||||
 | 
					                "psr-4": {
 | 
				
			||||||
 | 
					                    "GuzzleHttp\\Promise\\": "src/"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "files": [
 | 
				
			||||||
 | 
					                    "src/functions_include.php"
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "notification-url": "https://packagist.org/downloads/",
 | 
				
			||||||
 | 
					            "license": [
 | 
				
			||||||
 | 
					                "MIT"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "authors": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "name": "Michael Dowling",
 | 
				
			||||||
 | 
					                    "email": "mtdowling@gmail.com",
 | 
				
			||||||
 | 
					                    "homepage": "https://github.com/mtdowling"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "description": "Guzzle promises library",
 | 
				
			||||||
 | 
					            "keywords": [
 | 
				
			||||||
 | 
					                "promise"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "time": "2016-12-20T10:07:11+00:00"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "name": "guzzlehttp/psr7",
 | 
				
			||||||
 | 
					            "version": "1.4.2",
 | 
				
			||||||
 | 
					            "source": {
 | 
				
			||||||
 | 
					                "type": "git",
 | 
				
			||||||
 | 
					                "url": "https://github.com/guzzle/psr7.git",
 | 
				
			||||||
 | 
					                "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "dist": {
 | 
				
			||||||
 | 
					                "type": "zip",
 | 
				
			||||||
 | 
					                "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
 | 
				
			||||||
 | 
					                "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
 | 
				
			||||||
 | 
					                "shasum": ""
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require": {
 | 
				
			||||||
 | 
					                "php": ">=5.4.0",
 | 
				
			||||||
 | 
					                "psr/http-message": "~1.0"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "provide": {
 | 
				
			||||||
 | 
					                "psr/http-message-implementation": "1.0"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require-dev": {
 | 
				
			||||||
 | 
					                "phpunit/phpunit": "~4.0"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "type": "library",
 | 
				
			||||||
 | 
					            "extra": {
 | 
				
			||||||
 | 
					                "branch-alias": {
 | 
				
			||||||
 | 
					                    "dev-master": "1.4-dev"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "autoload": {
 | 
				
			||||||
 | 
					                "psr-4": {
 | 
				
			||||||
 | 
					                    "GuzzleHttp\\Psr7\\": "src/"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "files": [
 | 
				
			||||||
 | 
					                    "src/functions_include.php"
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "notification-url": "https://packagist.org/downloads/",
 | 
				
			||||||
 | 
					            "license": [
 | 
				
			||||||
 | 
					                "MIT"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "authors": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "name": "Michael Dowling",
 | 
				
			||||||
 | 
					                    "email": "mtdowling@gmail.com",
 | 
				
			||||||
 | 
					                    "homepage": "https://github.com/mtdowling"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "name": "Tobias Schultze",
 | 
				
			||||||
 | 
					                    "homepage": "https://github.com/Tobion"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "description": "PSR-7 message implementation that also provides common utility methods",
 | 
				
			||||||
 | 
					            "keywords": [
 | 
				
			||||||
 | 
					                "http",
 | 
				
			||||||
 | 
					                "message",
 | 
				
			||||||
 | 
					                "request",
 | 
				
			||||||
 | 
					                "response",
 | 
				
			||||||
 | 
					                "stream",
 | 
				
			||||||
 | 
					                "uri",
 | 
				
			||||||
 | 
					                "url"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "time": "2017-03-20T17:10:46+00:00"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "paragonie/random_compat",
 | 
					            "name": "paragonie/random_compat",
 | 
				
			||||||
            "version": "v2.0.10",
 | 
					            "version": "v2.0.10",
 | 
				
			||||||
@ -218,6 +396,56 @@
 | 
				
			|||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "time": "2017-03-13T16:27:32+00:00"
 | 
					            "time": "2017-03-13T16:27:32+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "name": "psr/http-message",
 | 
				
			||||||
 | 
					            "version": "1.0.1",
 | 
				
			||||||
 | 
					            "source": {
 | 
				
			||||||
 | 
					                "type": "git",
 | 
				
			||||||
 | 
					                "url": "https://github.com/php-fig/http-message.git",
 | 
				
			||||||
 | 
					                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "dist": {
 | 
				
			||||||
 | 
					                "type": "zip",
 | 
				
			||||||
 | 
					                "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
 | 
				
			||||||
 | 
					                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
 | 
				
			||||||
 | 
					                "shasum": ""
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require": {
 | 
				
			||||||
 | 
					                "php": ">=5.3.0"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "type": "library",
 | 
				
			||||||
 | 
					            "extra": {
 | 
				
			||||||
 | 
					                "branch-alias": {
 | 
				
			||||||
 | 
					                    "dev-master": "1.0.x-dev"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "autoload": {
 | 
				
			||||||
 | 
					                "psr-4": {
 | 
				
			||||||
 | 
					                    "Psr\\Http\\Message\\": "src/"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "notification-url": "https://packagist.org/downloads/",
 | 
				
			||||||
 | 
					            "license": [
 | 
				
			||||||
 | 
					                "MIT"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "authors": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "name": "PHP-FIG",
 | 
				
			||||||
 | 
					                    "homepage": "http://www.php-fig.org/"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "description": "Common interface for HTTP messages",
 | 
				
			||||||
 | 
					            "homepage": "https://github.com/php-fig/http-message",
 | 
				
			||||||
 | 
					            "keywords": [
 | 
				
			||||||
 | 
					                "http",
 | 
				
			||||||
 | 
					                "http-message",
 | 
				
			||||||
 | 
					                "psr",
 | 
				
			||||||
 | 
					                "psr-7",
 | 
				
			||||||
 | 
					                "request",
 | 
				
			||||||
 | 
					                "response"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "time": "2016-08-06T14:39:51+00:00"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "spomky-labs/otphp",
 | 
					            "name": "spomky-labs/otphp",
 | 
				
			||||||
            "version": "v8.3.0",
 | 
					            "version": "v8.3.0",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										15
									
								
								index.php
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								index.php
									
									
									
									
									
								
							@ -39,9 +39,12 @@ if ($VARS['progress'] == "1") {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
} else if ($VARS['progress'] == "2") {
 | 
					} else if ($VARS['progress'] == "2") {
 | 
				
			||||||
    if (verifyTOTP($VARS['username'], $VARS['authcode'])) {
 | 
					    if (verifyTOTP($VARS['username'], $VARS['authcode'])) {
 | 
				
			||||||
        doLoginUser($VARS['username'], $VARS['password']);
 | 
					        if (doLoginUser($VARS['username'])) {
 | 
				
			||||||
        header('Location: app.php');
 | 
					            header('Location: app.php');
 | 
				
			||||||
        die("Logged in, go to app.php");
 | 
					            die("Logged in, go to app.php");
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $alert = lang("login server user data error", false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        $alert = lang("2fa incorrect", false);
 | 
					        $alert = lang("2fa incorrect", false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -64,7 +67,11 @@ if ($VARS['progress'] == "1") {
 | 
				
			|||||||
            <div class="row">
 | 
					            <div class="row">
 | 
				
			||||||
                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 col-sm-offset-3 col-md-offset-4 col-lg-offset-4">
 | 
					                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 col-sm-offset-3 col-md-offset-4 col-lg-offset-4">
 | 
				
			||||||
                    <div>
 | 
					                    <div>
 | 
				
			||||||
                        <img class="img-responsive banner-image" src="static/img/banner.png" />
 | 
					                        <?php
 | 
				
			||||||
 | 
					                        if (SHOW_ICON == "both" || SHOW_ICON == "index") {
 | 
				
			||||||
 | 
					                            ?>
 | 
				
			||||||
 | 
					                            <img class="img-responsive banner-image" src="static/img/logo.png" />
 | 
				
			||||||
 | 
					                        <?php } ?>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                    <div class="panel panel-primary">
 | 
					                    <div class="panel panel-primary">
 | 
				
			||||||
                        <div class="panel-heading">
 | 
					                        <div class="panel-heading">
 | 
				
			||||||
 | 
				
			|||||||
@ -13,30 +13,14 @@ define("STRINGS", [
 | 
				
			|||||||
    "password expired" => "You must change your password before continuing.",
 | 
					    "password expired" => "You must change your password before continuing.",
 | 
				
			||||||
    "account terminated" => "Account terminated.  Access denied.",
 | 
					    "account terminated" => "Account terminated.  Access denied.",
 | 
				
			||||||
    "account state error" => "Your account state is not stable.  Log out, restart your browser, and try again.",
 | 
					    "account state error" => "Your account state is not stable.  Log out, restart your browser, and try again.",
 | 
				
			||||||
    "password on 500 list" => "The given password is ranked number {arg} out of the 500 most common passwords.  Try a different one.",
 | 
					 | 
				
			||||||
    "welcome user" => "Welcome, {user}!",
 | 
					    "welcome user" => "Welcome, {user}!",
 | 
				
			||||||
    "change password" => "Change password",
 | 
					 | 
				
			||||||
    "security options" => "Security options",
 | 
					 | 
				
			||||||
    "account security" => "Account security",
 | 
					 | 
				
			||||||
    "sign out" => "Sign out",
 | 
					    "sign out" => "Sign out",
 | 
				
			||||||
    "settings" => "Settings",
 | 
					    "settings" => "Settings",
 | 
				
			||||||
    "options" => "Options",
 | 
					    "options" => "Options",
 | 
				
			||||||
    "404 error" => "404 Error",
 | 
					    "404 error" => "404 Error",
 | 
				
			||||||
    "page not found" => "Page not found.",
 | 
					    "page not found" => "Page not found.",
 | 
				
			||||||
    "current password incorrect" => "The current password is incorrect.  Try again.",
 | 
					 | 
				
			||||||
    "new password mismatch" => "The new passwords did not match.  Try again.",
 | 
					 | 
				
			||||||
    "weak password" => "Password does not meet requirements.",
 | 
					 | 
				
			||||||
    "password updated" => "Password updated successfully.",
 | 
					 | 
				
			||||||
    "setup 2fa" => "Setup 2-factor authentication",
 | 
					 | 
				
			||||||
    "2fa removed" => "2-factor authentication disabled.",
 | 
					 | 
				
			||||||
    "2fa enabled" => "2-factor authentication activated.",
 | 
					 | 
				
			||||||
    "remove 2fa" => "Disable 2-factor authentication",
 | 
					 | 
				
			||||||
    "2fa explained" => "2-factor authentication adds more security to your account. You'll need an app such as Google Authenticator on your smartphone. When you have the app installed, you can enable 2-factor authentication by clicking the button below and scanning a QR code with the app. Whenever you sign in in the future, you'll need to input a six-digit code from your phone into the login page when prompted. You can disable 2-factor authentication from this page if you change your mind.",
 | 
					 | 
				
			||||||
    "2fa active" => "2-factor authentication is active on your account.  To remove 2fa, reset your authentication secret, or change to a new security device, click the button below.",
 | 
					 | 
				
			||||||
    "enable 2fa" => "Enable 2-factor authentication",
 | 
					 | 
				
			||||||
    "scan 2fa qrcode" => "Scan the QR Code with the authenticator app, or enter the secret key manually.",
 | 
					 | 
				
			||||||
    "confirm 2fa" => "Finish setup",
 | 
					 | 
				
			||||||
    "invalid parameters" => "Invalid request parameters.",
 | 
					    "invalid parameters" => "Invalid request parameters.",
 | 
				
			||||||
    "ldap server error" => "The LDAP server returned an error: {arg}",
 | 
					    "login server error" => "The login server returned an error: {arg}",
 | 
				
			||||||
 | 
					    "login server user data error" => "The login server refused to provide account information.  Try again or contact technical support.",
 | 
				
			||||||
    "home" => "Home",
 | 
					    "home" => "Home",
 | 
				
			||||||
]);
 | 
					]);
 | 
				
			||||||
							
								
								
									
										369
									
								
								lib/login.php
									
									
									
									
									
								
							
							
						
						
									
										369
									
								
								lib/login.php
									
									
									
									
									
								
							@ -1,147 +1,98 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Authentication and account functions
 | 
					 * Authentication and account functions.  Connects to a Portal instance.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
use Base32\Base32;
 | 
					 | 
				
			||||||
use OTPHP\TOTP;
 | 
					 | 
				
			||||||
use LdapTools\LdapManager;
 | 
					 | 
				
			||||||
use LdapTools\Connection\ADResponseCodes;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
//                           Account handling                                 //
 | 
					//                           Account handling                                 //
 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Add a user to the system.  /!\ Assumes input is OK /!\
 | 
					 * Checks the given credentials against the API.
 | 
				
			||||||
 * @param string $username Username, saved in lowercase.
 | 
					 | 
				
			||||||
 * @param string $password Password, will be hashed before saving.
 | 
					 | 
				
			||||||
 * @param string $realname User's real legal name
 | 
					 | 
				
			||||||
 * @param string $email User's email address.
 | 
					 | 
				
			||||||
 * @return int The new user's ID number in the database.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
function adduser($username, $password, $realname, $email = null, $phone1 = "", $phone2 = "") {
 | 
					 | 
				
			||||||
    global $database;
 | 
					 | 
				
			||||||
    $database->debug()->insert('accounts', [
 | 
					 | 
				
			||||||
        'username' => strtolower($username),
 | 
					 | 
				
			||||||
        'password' => (is_null($password) ? null : encryptPassword($password)),
 | 
					 | 
				
			||||||
        'realname' => $realname,
 | 
					 | 
				
			||||||
        'email' => $email,
 | 
					 | 
				
			||||||
        'phone1' => $phone1,
 | 
					 | 
				
			||||||
        'phone2' => $phone2,
 | 
					 | 
				
			||||||
        'acctstatus' => 1
 | 
					 | 
				
			||||||
    ]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return $database->id();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Get where a user's account actually is.
 | 
					 | 
				
			||||||
 * @param string $username
 | 
					 | 
				
			||||||
 * @return string "LDAP", "LOCAL", "LDAP_ONLY", or "NONE".
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
function account_location($username, $password) {
 | 
					 | 
				
			||||||
    global $database;
 | 
					 | 
				
			||||||
    $user_exists = user_exists($username);
 | 
					 | 
				
			||||||
    if (!$user_exists && !LDAP_ENABLED) {
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if ($user_exists) {
 | 
					 | 
				
			||||||
        $userinfo = $database->select('accounts', ['password'], ['username' => $username])[0];
 | 
					 | 
				
			||||||
        // if password empty, it's an LDAP user
 | 
					 | 
				
			||||||
        if (is_empty($userinfo['password']) && LDAP_ENABLED) {
 | 
					 | 
				
			||||||
            return "LDAP";
 | 
					 | 
				
			||||||
        } else if (is_empty($userinfo['password']) && !LDAP_ENABLED) {
 | 
					 | 
				
			||||||
            return "NONE";
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return "LOCAL";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        if (user_exists_ldap($username, $password)) {
 | 
					 | 
				
			||||||
            return "LDAP_ONLY";
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return "NONE";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Checks the given credentials against the database.
 | 
					 | 
				
			||||||
 * @param string $username
 | 
					 * @param string $username
 | 
				
			||||||
 * @param string $password
 | 
					 * @param string $password
 | 
				
			||||||
 * @return boolean True if OK, else false
 | 
					 * @return boolean True if OK, else false
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function authenticate_user($username, $password) {
 | 
					function authenticate_user($username, $password) {
 | 
				
			||||||
    global $database;
 | 
					    $client = new GuzzleHttp\Client();
 | 
				
			||||||
    global $ldap_config;
 | 
					
 | 
				
			||||||
    if (is_empty($username) || is_empty($password)) {
 | 
					    $response = $client
 | 
				
			||||||
        return false;
 | 
					            ->request('POST', PORTAL_API, [
 | 
				
			||||||
 | 
					        'form_params' => [
 | 
				
			||||||
 | 
					            'key' => PORTAL_KEY,
 | 
				
			||||||
 | 
					            'action' => "auth",
 | 
				
			||||||
 | 
					            'username' => $username,
 | 
				
			||||||
 | 
					            'password' => $password
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($response->getStatusCode() > 299) {
 | 
				
			||||||
 | 
					        sendError("Login server error: " . $response->getBody());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $loc = account_location($username, $password);
 | 
					
 | 
				
			||||||
    if ($loc == "NONE") {
 | 
					    $resp = json_decode($response->getBody(), TRUE);
 | 
				
			||||||
        return false;
 | 
					    if ($resp['status'] == "OK") {
 | 
				
			||||||
    } else if ($loc == "LOCAL") {
 | 
					        return true;
 | 
				
			||||||
        $hash = $database->select('accounts', ['password'], ['username' => $username, "LIMIT" => 1])[0]['password'];
 | 
					 | 
				
			||||||
        return (comparePassword($password, $hash));
 | 
					 | 
				
			||||||
    } else if ($loc == "LDAP") {
 | 
					 | 
				
			||||||
        return authenticate_user_ldap($username, $password);
 | 
					 | 
				
			||||||
    } else if ($loc == "LDAP_ONLY") {
 | 
					 | 
				
			||||||
        if (authenticate_user_ldap($username, $password) === TRUE) {
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                $user = (new LdapManager($ldap_config))->getRepository('user')->findOneByUsername($username);
 | 
					 | 
				
			||||||
                var_dump($user);
 | 
					 | 
				
			||||||
                adduser($user->getUsername(), null, $user->getName(), ($user->hasEmailAddress() ? $user->getEmailAddress() : null));
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            } catch (Exception $e) {
 | 
					 | 
				
			||||||
                sendError("LDAP error: " . $e->getMessage());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Check if a username exists in the local database.
 | 
					 * Check if a username exists.
 | 
				
			||||||
 * @param String $username
 | 
					 * @param String $username
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function user_exists($username) {
 | 
					function user_exists($username) {
 | 
				
			||||||
    global $database;
 | 
					    $client = new GuzzleHttp\Client();
 | 
				
			||||||
    return $database->has('accounts', ['username' => $username, "LIMIT" => QUERY_LIMIT]);
 | 
					
 | 
				
			||||||
 | 
					    $response = $client
 | 
				
			||||||
 | 
					            ->request('POST', PORTAL_API, [
 | 
				
			||||||
 | 
					        'form_params' => [
 | 
				
			||||||
 | 
					            'key' => PORTAL_KEY,
 | 
				
			||||||
 | 
					            'action' => "userexists",
 | 
				
			||||||
 | 
					            'username' => $username
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($response->getStatusCode() > 299) {
 | 
				
			||||||
 | 
					        sendError("Login server error: " . $response->getBody());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $resp = json_decode($response->getBody(), TRUE);
 | 
				
			||||||
 | 
					    if ($resp['status'] == "OK" && $resp['exists'] === true) {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Get the account status: NORMAL, TERMINATED, LOCKED_OR_DISABLED,
 | 
					 * Get the account status: NORMAL, TERMINATED, LOCKED_OR_DISABLED,
 | 
				
			||||||
 * CHANGE_PASSWORD, or ALERT_ON_ACCESS
 | 
					 * CHANGE_PASSWORD, or ALERT_ON_ACCESS
 | 
				
			||||||
 * @global $database $database
 | 
					 | 
				
			||||||
 * @param string $username
 | 
					 * @param string $username
 | 
				
			||||||
 * @return string
 | 
					 * @return string
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function get_account_status($username) {
 | 
					function get_account_status($username) {
 | 
				
			||||||
    global $database;
 | 
					    $client = new GuzzleHttp\Client();
 | 
				
			||||||
    $loc = account_location($username);
 | 
					
 | 
				
			||||||
    if ($loc == "LOCAL") {
 | 
					    $response = $client
 | 
				
			||||||
        $statuscode = $database->select('accounts', [
 | 
					            ->request('POST', PORTAL_API, [
 | 
				
			||||||
                    '[>]acctstatus' => [
 | 
					        'form_params' => [
 | 
				
			||||||
                        'acctstatus' => 'statusid'
 | 
					            'key' => PORTAL_KEY,
 | 
				
			||||||
                    ]
 | 
					            'action' => "acctstatus",
 | 
				
			||||||
                        ], [
 | 
					            'username' => $username
 | 
				
			||||||
                    'accounts.acctstatus',
 | 
					        ]
 | 
				
			||||||
                    'acctstatus.statuscode'
 | 
					    ]);
 | 
				
			||||||
                        ], [
 | 
					
 | 
				
			||||||
                    'username' => $username,
 | 
					    if ($response->getStatusCode() > 299) {
 | 
				
			||||||
                    "LIMIT" => 1
 | 
					        sendError("Login server error: " . $response->getBody());
 | 
				
			||||||
                        ]
 | 
					    }
 | 
				
			||||||
                )[0]['statuscode'];
 | 
					
 | 
				
			||||||
        return $statuscode;
 | 
					    $resp = json_decode($response->getBody(), TRUE);
 | 
				
			||||||
    } else if ($loc == "LDAP") {
 | 
					    if ($resp['status'] == "OK") {
 | 
				
			||||||
        // TODO: Read actual account status from AD servers
 | 
					        return $resp['account'];
 | 
				
			||||||
        return "NORMAL";
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        // account isn't setup properly
 | 
					        return false;
 | 
				
			||||||
        return "LOCKED_OR_DISABLED";
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -150,93 +101,64 @@ function get_account_status($username) {
 | 
				
			|||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Setup $_SESSION values to log in a user
 | 
					 * Setup $_SESSION values with user data and set loggedin flag to true
 | 
				
			||||||
 * @param string $username
 | 
					 * @param string $username
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function doLoginUser($username, $password) {
 | 
					function doLoginUser($username) {
 | 
				
			||||||
    global $database;
 | 
					    $client = new GuzzleHttp\Client();
 | 
				
			||||||
    $userinfo = $database->select('accounts', ['email', 'uid', 'realname'], ['username' => $username])[0];
 | 
					 | 
				
			||||||
    $_SESSION['username'] = $username;
 | 
					 | 
				
			||||||
    $_SESSION['uid'] = $userinfo['uid'];
 | 
					 | 
				
			||||||
    $_SESSION['email'] = $userinfo['email'];
 | 
					 | 
				
			||||||
    $_SESSION['realname'] = $userinfo['realname'];
 | 
					 | 
				
			||||||
    $_SESSION['password'] = $password; // needed for things like EWS
 | 
					 | 
				
			||||||
    $_SESSION['loggedin'] = true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					    $response = $client
 | 
				
			||||||
 * Send an alert email to the system admin
 | 
					            ->request('POST', PORTAL_API, [
 | 
				
			||||||
 * 
 | 
					        'form_params' => [
 | 
				
			||||||
 * Used when an account with the status ALERT_ON_ACCESS logs in
 | 
					            'key' => PORTAL_KEY,
 | 
				
			||||||
 * @param String $username the account username
 | 
					            'action' => "userinfo",
 | 
				
			||||||
 */
 | 
					            'username' => $username
 | 
				
			||||||
function sendLoginAlertEmail($username) {
 | 
					        ]
 | 
				
			||||||
    // TODO: add email code
 | 
					    ]);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					    if ($response->getStatusCode() > 299) {
 | 
				
			||||||
//                              LDAP handling                                 //
 | 
					        sendError("Login server error: " . $response->getBody());
 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Checks the given credentials against the LDAP server.
 | 
					 | 
				
			||||||
 * @param string $username
 | 
					 | 
				
			||||||
 * @param string $password
 | 
					 | 
				
			||||||
 * @return mixed True if OK, else false or the error code from the server
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
function authenticate_user_ldap($username, $password) {
 | 
					 | 
				
			||||||
    global $ldap_config;
 | 
					 | 
				
			||||||
    if (is_empty($username) || is_empty($password)) {
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $ldapManager = new LdapManager($ldap_config);
 | 
					
 | 
				
			||||||
    $msg = "";
 | 
					    $resp = json_decode($response->getBody(), TRUE);
 | 
				
			||||||
    $code = 0;
 | 
					    var_dump($resp);
 | 
				
			||||||
    if ($ldapManager->authenticate($username, $password, $msg, $code)) {
 | 
					    if ($resp['status'] == "OK") {
 | 
				
			||||||
 | 
					        $userinfo = $resp['data'];
 | 
				
			||||||
 | 
					        $_SESSION['username'] = $username;
 | 
				
			||||||
 | 
					        $_SESSION['uid'] = $userinfo['uid'];
 | 
				
			||||||
 | 
					        $_SESSION['email'] = $userinfo['email'];
 | 
				
			||||||
 | 
					        $_SESSION['realname'] = $userinfo['name'];
 | 
				
			||||||
 | 
					        $_SESSION['password'] = $password;
 | 
				
			||||||
 | 
					        $_SESSION['loggedin'] = true;
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        return $code;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					function simLogin($username, $password) {
 | 
				
			||||||
 * Check if a username exists on the LDAP server.
 | 
					    $client = new GuzzleHttp\Client();
 | 
				
			||||||
 * @global type $ldap_config
 | 
					
 | 
				
			||||||
 * @param type $username
 | 
					    $response = $client
 | 
				
			||||||
 * @return boolean true if yes, else false
 | 
					            ->request('POST', PORTAL_API, [
 | 
				
			||||||
 */
 | 
					        'form_params' => [
 | 
				
			||||||
function user_exists_ldap($username, $password) {
 | 
					            'key' => PORTAL_KEY,
 | 
				
			||||||
    global $ldap_config;
 | 
					            'action' => "login",
 | 
				
			||||||
    $ldap = new LdapManager($ldap_config);
 | 
					            'username' => $username,
 | 
				
			||||||
    if (!$ldap->authenticate($username, $password, $message, $code)) {
 | 
					            'password' => $password
 | 
				
			||||||
        switch ($code) {
 | 
					        ]
 | 
				
			||||||
            case ADResponseCodes::ACCOUNT_INVALID:
 | 
					    ]);
 | 
				
			||||||
                return false;
 | 
					
 | 
				
			||||||
            case ADResponseCodes::ACCOUNT_CREDENTIALS_INVALID:
 | 
					    if ($response->getStatusCode() > 299) {
 | 
				
			||||||
                return true;
 | 
					        sendError("Login server error: " . $response->getBody());
 | 
				
			||||||
            case ADResponseCodes::ACCOUNT_RESTRICTIONS:
 | 
					    }
 | 
				
			||||||
                return true;
 | 
					
 | 
				
			||||||
            case ADResponseCodes::ACCOUNT_RESTRICTIONS_TIME:
 | 
					    $resp = json_decode($response->getBody(), TRUE);
 | 
				
			||||||
                return true;
 | 
					    if ($resp['status'] == "OK") {
 | 
				
			||||||
            case ADResponseCodes::ACCOUNT_RESTRICTIONS_DEVICE:
 | 
					        return true;
 | 
				
			||||||
                return true;
 | 
					    } else {
 | 
				
			||||||
            case ADResponseCodes::ACCOUNT_PASSWORD_EXPIRED:
 | 
					        return $resp['msg'];
 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            case ADResponseCodes::ACCOUNT_DISABLED:
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            case ADResponseCodes::ACCOUNT_CONTEXT_IDS:
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            case ADResponseCodes::ACCOUNT_EXPIRED:
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            case ADResponseCodes::ACCOUNT_PASSWORD_MUST_CHANGE:
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            case ADResponseCodes::ACCOUNT_LOCKED:
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            default:
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
@ -245,43 +167,31 @@ function user_exists_ldap($username, $password) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Check if a user has TOTP setup
 | 
					 * Check if a user has TOTP setup
 | 
				
			||||||
 * @global $database $database
 | 
					 | 
				
			||||||
 * @param string $username
 | 
					 * @param string $username
 | 
				
			||||||
 * @return boolean true if TOTP secret exists, else false
 | 
					 * @return boolean true if TOTP secret exists, else false
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function userHasTOTP($username) {
 | 
					function userHasTOTP($username) {
 | 
				
			||||||
    global $database;
 | 
					    $client = new GuzzleHttp\Client();
 | 
				
			||||||
    $secret = $database->select('accounts', 'authsecret', ['username' => $username])[0];
 | 
					
 | 
				
			||||||
    if (is_empty($secret)) {
 | 
					    $response = $client
 | 
				
			||||||
 | 
					            ->request('POST', PORTAL_API, [
 | 
				
			||||||
 | 
					        'form_params' => [
 | 
				
			||||||
 | 
					            'key' => PORTAL_KEY,
 | 
				
			||||||
 | 
					            'action' => "hastotp",
 | 
				
			||||||
 | 
					            'username' => $username
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($response->getStatusCode() > 299) {
 | 
				
			||||||
 | 
					        sendError("Login server error: " . $response->getBody());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $resp = json_decode($response->getBody(), TRUE);
 | 
				
			||||||
 | 
					    if ($resp['status'] == "OK") {
 | 
				
			||||||
 | 
					        return $resp['otp'];
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Generate a TOTP secret for the given user.
 | 
					 | 
				
			||||||
 * @param string $username
 | 
					 | 
				
			||||||
 * @return string OTP provisioning URI (for generating a QR code)
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
function newTOTP($username) {
 | 
					 | 
				
			||||||
    global $database;
 | 
					 | 
				
			||||||
    $secret = random_bytes(20);
 | 
					 | 
				
			||||||
    $encoded_secret = Base32::encode($secret);
 | 
					 | 
				
			||||||
    $userdata = $database->select('accounts', ['email', 'authsecret', 'realname'], ['username' => $username])[0];
 | 
					 | 
				
			||||||
    $totp = new TOTP((is_null($userdata['email']) ? $userdata['realname'] : $userdata['email']), $encoded_secret);
 | 
					 | 
				
			||||||
    $totp->setIssuer(SYSTEM_NAME);
 | 
					 | 
				
			||||||
    return $totp->getProvisioningUri();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Save a TOTP secret for the user.
 | 
					 | 
				
			||||||
 * @global $database $database
 | 
					 | 
				
			||||||
 * @param string $username
 | 
					 | 
				
			||||||
 * @param string $secret
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
function saveTOTP($username, $secret) {
 | 
					 | 
				
			||||||
    global $database;
 | 
					 | 
				
			||||||
    $database->update('accounts', ['authsecret' => $secret], ['username' => $username]);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -292,11 +202,26 @@ function saveTOTP($username, $secret) {
 | 
				
			|||||||
 * @return boolean true if it's legit, else false
 | 
					 * @return boolean true if it's legit, else false
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function verifyTOTP($username, $code) {
 | 
					function verifyTOTP($username, $code) {
 | 
				
			||||||
    global $database;
 | 
					    $client = new GuzzleHttp\Client();
 | 
				
			||||||
    $userdata = $database->select('accounts', ['email', 'authsecret'], ['username' => $username])[0];
 | 
					
 | 
				
			||||||
    if (is_empty($userdata['authsecret'])) {
 | 
					    $response = $client
 | 
				
			||||||
 | 
					            ->request('POST', PORTAL_API, [
 | 
				
			||||||
 | 
					        'form_params' => [
 | 
				
			||||||
 | 
					            'key' => PORTAL_KEY,
 | 
				
			||||||
 | 
					            'action' => "verifytotp",
 | 
				
			||||||
 | 
					            'username' => $username,
 | 
				
			||||||
 | 
					            'code' => $code
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($response->getStatusCode() > 299) {
 | 
				
			||||||
 | 
					        sendError("Login server error: " . $response->getBody());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $resp = json_decode($response->getBody(), TRUE);
 | 
				
			||||||
 | 
					    if ($resp['status'] == "OK") {
 | 
				
			||||||
 | 
					        return $resp['valid'];
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $totp = new TOTP(null, $userdata['authsecret']);
 | 
					 | 
				
			||||||
    return $totp->verify($code);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
    <type>org.netbeans.modules.php.project</type>
 | 
					    <type>org.netbeans.modules.php.project</type>
 | 
				
			||||||
    <configuration>
 | 
					    <configuration>
 | 
				
			||||||
        <data xmlns="http://www.netbeans.org/ns/php-project/1">
 | 
					        <data xmlns="http://www.netbeans.org/ns/php-project/1">
 | 
				
			||||||
            <name>WebAppTemplate</name>
 | 
					            <name>BusinessAppTemplate</name>
 | 
				
			||||||
        </data>
 | 
					        </data>
 | 
				
			||||||
    </configuration>
 | 
					    </configuration>
 | 
				
			||||||
</project>
 | 
					</project>
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,9 @@
 | 
				
			|||||||
// List of pages and metadata
 | 
					// List of pages and metadata
 | 
				
			||||||
define("PAGES", [
 | 
					define("PAGES", [
 | 
				
			||||||
    "home" => [
 | 
					    "home" => [
 | 
				
			||||||
        "title" => "home"
 | 
					        "title" => "home",
 | 
				
			||||||
 | 
					        "navbar" => true,
 | 
				
			||||||
 | 
					        "icon" => "home"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "404" => [
 | 
					    "404" => [
 | 
				
			||||||
        "title" => "404 error"
 | 
					        "title" => "404 error"
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,20 @@ define("SITE_TITLE", "Web App Template");
 | 
				
			|||||||
// Used to identify the system in OTP and other places
 | 
					// Used to identify the system in OTP and other places
 | 
				
			||||||
define("SYSTEM_NAME", "Web App Template");
 | 
					define("SYSTEM_NAME", "Web App Template");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Which pages to show the app icon on:
 | 
				
			||||||
 | 
					// index, app, both, none
 | 
				
			||||||
 | 
					define("SHOW_ICON", "both");
 | 
				
			||||||
 | 
					// Where to put the icon: top or menu
 | 
				
			||||||
 | 
					// Overridden to 'menu' if MENU_BAR_STYLE is 'fixed'.
 | 
				
			||||||
 | 
					define("ICON_POSITION", "menu");
 | 
				
			||||||
 | 
					// App menu bar style: fixed or static
 | 
				
			||||||
 | 
					define("MENU_BAR_STYLE", "fixed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// URL of the Business Portal API endpoint
 | 
				
			||||||
 | 
					define("PORTAL_API", "http://localhost/api.php");
 | 
				
			||||||
 | 
					// Business Portal API Key
 | 
				
			||||||
 | 
					define("PORTAL_KEY", "123");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// For supported values, see http://php.net/manual/en/timezones.php
 | 
					// For supported values, see http://php.net/manual/en/timezones.php
 | 
				
			||||||
define("TIMEZONE", "America/Denver");
 | 
					define("TIMEZONE", "America/Denver");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								static/img/logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/img/logo.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 12 KiB  | 
							
								
								
									
										78
									
								
								static/img/logo.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								static/img/logo.svg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   width="512"
 | 
				
			||||||
 | 
					   height="512"
 | 
				
			||||||
 | 
					   viewBox="0 0 512.00001 512.00001"
 | 
				
			||||||
 | 
					   id="svg2"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   inkscape:version="0.91 r13725"
 | 
				
			||||||
 | 
					   sodipodi:docname="logo.svg"
 | 
				
			||||||
 | 
					   inkscape:export-filename="/home/skylar/Documents/Projects/Sources/WebAppTemplate/static/img/logo.png"
 | 
				
			||||||
 | 
					   inkscape:export-xdpi="90"
 | 
				
			||||||
 | 
					   inkscape:export-ydpi="90">
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs4">
 | 
				
			||||||
 | 
					    <inkscape:perspective
 | 
				
			||||||
 | 
					       sodipodi:type="inkscape:persp3d"
 | 
				
			||||||
 | 
					       inkscape:vp_x="-493.3276 : 245.89848 : 1"
 | 
				
			||||||
 | 
					       inkscape:vp_y="0 : 1000 : 0"
 | 
				
			||||||
 | 
					       inkscape:vp_z="464.45088 : 245.89848 : 1"
 | 
				
			||||||
 | 
					       inkscape:persp3d-origin="-14.438371 : 160.56515 : 1"
 | 
				
			||||||
 | 
					       id="perspective4236" />
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     id="base"
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1.0"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0.0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:zoom="0.49497475"
 | 
				
			||||||
 | 
					     inkscape:cx="-135.9681"
 | 
				
			||||||
 | 
					     inkscape:cy="352.66131"
 | 
				
			||||||
 | 
					     inkscape:document-units="px"
 | 
				
			||||||
 | 
					     inkscape:current-layer="layer1"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     units="px" />
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata7">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					        <dc:title></dc:title>
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     inkscape:label="Layer 1"
 | 
				
			||||||
 | 
					     inkscape:groupmode="layer"
 | 
				
			||||||
 | 
					     id="layer1"
 | 
				
			||||||
 | 
					     transform="translate(0,-540.36216)">
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.74509804"
 | 
				
			||||||
 | 
					       id="rect4726"
 | 
				
			||||||
 | 
					       width="512"
 | 
				
			||||||
 | 
					       height="512"
 | 
				
			||||||
 | 
					       x="0"
 | 
				
			||||||
 | 
					       y="540.36218"
 | 
				
			||||||
 | 
					       rx="50"
 | 
				
			||||||
 | 
					       ry="50" />
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       id="path4348"
 | 
				
			||||||
 | 
					       style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:9.87128067;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
 | 
				
			||||||
 | 
					       d="m 132.93564,682.51771 213.96788,-43.14304 0,313.97496 -213.96788,-37.9643 z m 213.96788,-43.14304 0,313.97496 32.16084,-45.18373 0,-217.44396 z m -213.96788,43.14304 213.96788,-43.14304 32.16084,51.34727 -167.21823,22.47784 z m 78.91049,30.68207 167.21823,-22.47784 0,217.44396 -167.21823,-19.77968 z m -78.91049,-30.68207 0,232.86762 78.91049,-26.99911 0,-175.18644 z m 0,232.86762 213.96788,37.9643 32.16084,-45.18373 -167.21823,-19.77968 z"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 2.9 KiB  | 
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user