Commit 822c69cf authored by raphael.peim's avatar raphael.peim

Add sign up feature

parent 291108e5
No preview for this file type
<?php
// define __ROOT_DIR constant which contains the absolute path on disk
// of the directory that contains this file (index.php)
// e.g. http://eden.imt-lille-douai.fr/~luc.fabresse/index.php => __ROOT_DIR = /home/luc.fabresse/public_html
$rootDirectoryPath = realpath(dirname(__FILE__));
define ('__ROOT_DIR', $rootDirectoryPath );
// Load all application config
require_once(__ROOT_DIR . "/config/config.php");
// Load the Loader class to automatically load classes when needed
require_once(__ROOT_DIR . '/classes/AutoLoader.class.php');
// Reify the current request
$request = Request::getCurrentRequest();
Response::interceptEchos();
try {
$controller = Dispatcher::dispatch($request);
$response = $controller->execute();
} catch (Exception $e) {
$log = Response::getEchos();
$log .= " " . $e->getMessage();
$response = Response::errorResponse($log);
}
$response->send();
?>
\ No newline at end of file
<?php
class AutoLoader {
public function __construct() {
spl_autoload_register( array($this, 'load') );
// spl_autoload_register(array($this, 'loadComplete'));
}
// This method will be automatically executed by PHP whenever it encounters an unknown class name in the source code
private function load($className) {
$paths = array('/classes/', '/controller/', '/model/', '/sql/');
$fileToLoad = null;
$i = 0;
do {
$fileToLoad = __ROOT_DIR . $paths[$i] . ucfirst($className) . '.class.php';
$i++;
} while(!is_readable($fileToLoad) && $i < count($paths));
if (!is_readable($fileToLoad))
throw new Exception('Unknown class ' . $className);
require_once($fileToLoad);
if (strlen(strstr($fileToLoad, '/model/')) > 0) {
$fileToLoadSql = __ROOT_DIR . '/sql/' . ucfirst($className) . '.sql.php';
if (is_readable($fileToLoadSql)) {
require_once($fileToLoadSql);
}
}
}
}
$__LOADER = new AutoLoader();
?>
\ No newline at end of file
<?php
class DatabasePDO extends PDO {
protected static $singleton = NULL;
public static function singleton(){
if(is_null(static::$singleton))
static::$singleton = new static();
return static::$singleton;
}
public function __construct() {
$connectionString = "mysql:host=". DB_HOST;
if(defined('DB_PORT'))
$connectionString .= ";port=". DB_PORT;
$connectionString .= ";dbname=" . DB_DATABASE;
$connectionString .= ";charset=utf8";
parent::__construct($connectionString, DB_USERNAME, DB_PASSWORD);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
}
?>
\ No newline at end of file
<?php
/*
* Analyses a request, created the right Controller passing it the request
*/
class Dispatcher {
public static function dispatch($request) {
return static::dispatchToController($request->getControllerName(), $request);
}
public static function dispatchToController($controllerName, $request) {
$controllerClassName = ucfirst($controllerName) . 'Controller';
if (!class_exists($controllerName))
throw new Exception("$controllerName does not exist");
return new $controllerClassName($controllerName, $request);
}
}
?>
\ No newline at end of file
<?php
class Request {
protected $controllerName;
protected $uriParameters;
protected static $singleton = NULL;
public function __construct() {
$this->jsonReceived = null;
$this->initBaseURI();
$this->initControllerAndParametersFromURI();
}
public static function getCurrentRequest() {
if (is_null(static::$singleton))
static::$singleton = new static();
return static::$singleton;
}
public function jsonContent() {
if(is_null($this->jsonReceived))
$this->jsonReceived = json_decode(file_get_contents("php://input"));
return $this->jsonReceived;
}
protected function initBaseURI() {
$this->baseURI = explode('/api.php', $_SERVER['SCRIPT_NAME'])[0];
}
protected function initControllerAndParametersFromURI(){
$url = trim($_SERVER['PATH_INFO'], '/');
$urlSegments = explode('/', $url);
$scheme = ['controller', 'params'];
$route = [];
foreach ($urlSegments as $index => $segment){
if ($scheme[$index] == 'params'){
$route['params'] = array_slice($urlSegments, $index);
break;
} else {
$route[$scheme[$index]] = $segment;
}
}
$this->controllerName = $route['controller'] != "" ? $route['controller'] : "default";
$this->uriParameters = isset($route['params']) ? $route['params'] : [];
}
// ==============
// Public API
// ==============
public function getControllerName() {
return $this->controllerName;
}
public function getHttpMethod() {
return $_SERVER["REQUEST_METHOD"];
}
public function getUriParameters() {
return $this->uriParameters;
}
public function getJwtToken() {
$headers = getallheaders();
$autorization = $headers['Authorization'];
$arr = explode(" ", $autorization);
if (count($arr) < 2)
throw new Exception("Missing JWT token");
$jwt_token = $arr[1];
return $jwt_token;
}
}
?>
\ No newline at end of file
<?php
class Response {
protected $code;
protected $body;
public function __construct($code = 404, $msg = "") {
$this->code = $code;
$this->body = $msg;
}
public static function okResponse($message = "")
{
return new Response(200, $message);
}
public static function errorResponse($message = "") {
return new Response(400, $message);
}
public static function errorInParametersResponse($message = "")
{
return new Response(400, $message);
}
public static function unauthorizedResponse($message = "")
{
return new Response(401, $message);
}
public static function notFoundResponse($message = "")
{
return new Response(404, $message);
}
public static function serverErrorResponse($message = "")
{
return new Response(500, $message);
}
public static function interceptEchos() {
ob_start();
}
public static function getEchos() {
return ob_get_clean();
}
public function send() {
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
header("Access-Control-Allow-Methods: GET,POST,PUT,DELETE");
header("Access-Control-Max-Age: 3600"); // Maximum number of seconds the results can be cached.
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
http_response_code($this->code);
echo $this->body;
exit; // do we keep that?
}
}
?>
\ No newline at end of file
<?php
// DB
define('DB_HOST', 'localhost');
define('DB_PORT', 8888);
define('DB_DATABASE', 'dbtest');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', 'root');
// JWT
define( 'JWT_BACKEND_KEY', '6d8HbcZndVGNAbo4Ih1TGaKcuA1y2BKs-I5CmP' );
define( 'JWT_ISSUER', $_SERVER['HTTP_HOST'] . $_SERVER['CONTEXT_PREFIX']);
// define('__DEBUG', false);
define('__DEBUG', true);
// ================================================================================
// Debug utilities
// ================================================================================
if(__DEBUG) {
error_reporting(E_ALL);
ini_set("display_errors", E_ALL);
} else {
error_reporting(0);
ini_set("display_errors", 0);
}
function myLog($msg) {
if(__DEBUG) {
echo $msg;
}
}
function myDump($var) {
if(__DEBUG) {
var_dump($var);
}
}
?>
\ No newline at end of file
<?php
/*
* A Controller is dedicated to process a request
* its responsabilities are:
* - analyses the action to be done
* - analyses the parameters
* - act on the model objects to perform the action
* - process the data
* - call the view and passes it the data
* - return the response
*/
abstract class Controller {
protected $name;
protected $request;
public function __construct($name, $request) {
$this->name = $name;
$this->request = $request;
}
public abstract function processRequest();
public function execute() {
$response = $this->processRequest();
if(empty($response)) {
// $response = Response::serverErrorResponse("error processing request in ". self::class); // Oh my PHP!
$response = Response::serverErrorResponse("error processing request in ". static::class);
}
return $response;
}
}
?>
\ No newline at end of file
<?php
class DefaultController extends Controller {
public function __construct($name, $request) {
parent::__construct($name, $request);
}
// ==============
// Actions
// ==============
public function processRequest() {
return Response::errorResponse('{ "message" : "Unsupported endpoint"}' );
}
}
?>
\ No newline at end of file
<?php
include_once __ROOT_DIR . '/libs/php-jwt/src/BeforeValidException.php';
include_once __ROOT_DIR . '/libs/php-jwt/src/ExpiredException.php';
include_once __ROOT_DIR . '/libs/php-jwt/src/SignatureInvalidException.php';
include_once __ROOT_DIR . '/libs/php-jwt/src/JWT.php';
use \Firebase\JWT\JWT;
class LoginController extends Controller {
public function __construct($name, $request) {
parent::__construct($name, $request);
}
public function processRequest() {
if($this->request->getHttpMethod() !== 'POST')
return Response::errorResponse('{ "message" : "Unsupported endpoint" }' );
$json = $this->request->jsonContent();
if(!isset($json->login) || !isset($json->pwd)) {
$r = new Response(422,"login and pwd fields are mandatory");
$r->send();
}
$user = User::getWithLogin($json->login);
// var_dump($user);
if(empty($user) || !hash_equals($json->pwd, $user->password)) {
$r = new Response(422,"wrong credentials");
$r->sendWithLog();
}
// generate json web token
$issued_at = time();
$expiration_time = $issued_at + (60 * 60); // valid for 1 hour
$token = array(
"iat" => $issued_at,
"exp" => $expiration_time,
"iss" => JWT_ISSUER,
"data" => array(
"id" => $user->id,
"firstname" => $user->firstname,
"lastname" => $user->lastname,
"email" => $user->email
)
);
$jwt = JWT::encode( $token, JWT_BACKEND_KEY );
$jsonResult = json_encode(array("jwt_token" => $jwt));
return Response::okResponse($jsonResult);
}
}
?>
\ No newline at end of file
<?php
include_once __ROOT_DIR . '/libs/php-jwt/src/BeforeValidException.php';
include_once __ROOT_DIR . '/libs/php-jwt/src/ExpiredException.php';
include_once __ROOT_DIR . '/libs/php-jwt/src/SignatureInvalidException.php';
include_once __ROOT_DIR . '/libs/php-jwt/src/JWT.php';
use \Firebase\JWT\JWT;
class UserController extends Controller {
public function __construct($name, $request) {
parent::__construct($name, $request);
}
// ==============
// Actions
// ==============
public function processRequest() {
switch ($this->request->getHttpMethod()) {
case 'POST':
$post = json_decode(file_get_contents("php://input"));
return $this->createUser($post);
break;
case 'GET':
if (empty($this->request->getUriParameters()))
return $this->getAllUsers();
else
return $this->getUserById($this->request->getUriParameters()[0]);
break;
case 'PUT':
$put = json_decode(file_get_contents("php://input"));
$id = $this->request->getUriParameters()[0];
return $this->updateUser($put, $id);
break;
case 'DELETE':
$id = $this->request->getUriParameters()[0];
return $this->deleteUser($id);
break;
}
return Response::errorResponse("unsupported parameters or method in users");
}
protected function createUser($post) {
if (isset($post->firstname)
&& isset($post->lastname)
&& isset($post->login)
&& isset($post->email)
&& isset($post->password)
&& isset($post->role)) {
User::create($post);
$response = Response::okResponse("Utilisateur ajouté");
}
else {
// $response = Response::notFoundResponse("Aucun utilisateur ajouté");
$response = Response::notFoundResponse(var_dump($post));
}
return $response;
}
protected function getAllUsers() {
$users = User::getList();
if (!empty($users))
$response = Response::okResponse(json_encode($users));
else
$response = Response::notFoundResponse("Aucune réponse");
return $response;
}
protected function getUserById($id) {
$user = User::getWithId($id);
if (!empty($user))
$response = Response::okResponse(json_encode($user));
else
$response = Response::notFoundResponse("Aucune réponse");
return $response;
}
protected function updateUser($put, $id) {
$user = User::getWithId($id);
if (!empty($put) && !empty($user)) {
$jwt_token = $this->request->getJwtToken();
$jwt = JWT::decode($jwt_token, JWT_BACKEND_KEY, array('HS256'));
if ($jwt->data->id == $id) {
User::update($put, $id);
$response = Response::okResponse("Utilisateur modifié");
return $response;
}
else {
return Response::unauthorizedResponse("Modification non autorisée");
}
}
else {
return Response::notFoundResponse("Aucun utilisateur modifié");
}
}
protected function deleteUser($id) {
$user = User::getWithId($id);
if (!empty($user)) {
User::delete($id);
$response = Response::okResponse("Utilisateur supprimé");
}
else {
$response = Response::notFoundResponse("Aucun utilisateur supprimé");
}
return $response;
}
}
?>
\ No newline at end of file
<?php
include_once __ROOT_DIR . '/libs/php-jwt/src/BeforeValidException.php';
include_once __ROOT_DIR . '/libs/php-jwt/src/ExpiredException.php';
include_once __ROOT_DIR . '/libs/php-jwt/src/SignatureInvalidException.php';
include_once __ROOT_DIR . '/libs/php-jwt/src/JWT.php';
use \Firebase\JWT\JWT;
class ValidatetokenController extends Controller {
public function __construct($name, $request) {
parent::__construct($name, $request);
}
public function processRequest() {
try {
$jwt_token = $this->request->getJwtToken();
// echo "jwt = $jwt_token";
$decodedJWT = JWT::decode($jwt_token, JWT_BACKEND_KEY, array('HS256'));
$jsonResult = json_encode(array(
"message" => "Access granted.",
"data" => $decodedJWT
));
}
catch (Exception $e){
header('WWW-Authenticate: Bearer realm="' . JWT_ISSUER . '"');
$jsonResult = json_encode(array(
"message" => "Access denied.",
"error" => $e->getMessage()
));
return Response::unauthorizedResponse($jsonResult);
}
$response = Response::okResponse($jsonResult);
return $response;
}
}
?>
\ No newline at end of file
<?php
phpinfo();
?>
\ No newline at end of file
Copyright (c) 2011, Neuman Vong
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Neuman Vong nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[![Build Status](https://travis-ci.org/firebase/php-jwt.png?branch=master)](https://travis-ci.org/firebase/php-jwt)
[![Latest Stable Version](https://poser.pugx.org/firebase/php-jwt/v/stable)](https://packagist.org/packages/firebase/php-jwt)
[![Total Downloads](https://poser.pugx.org/firebase/php-jwt/downloads)](https://packagist.org/packages/firebase/php-jwt)
[![License](https://poser.pugx.org/firebase/php-jwt/license)](https://packagist.org/packages/firebase/php-jwt)
PHP-JWT
=======
A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to [RFC 7519](https://tools.ietf.org/html/rfc7519).
Installation
------------
Use composer to manage your dependencies and download PHP-JWT:
```bash
composer require firebase/php-jwt
```
Example
-------
```php
<?php
use \Firebase\JWT\JWT;
$key = "example_key";
$payload = array(
"iss" => "http://example.org",
"aud" => "http://example.com",
"iat" => 1356999524,
"nbf" => 1357000000
);
/**
* IMPORTANT:
* You must specify supported algorithms for your application. See
* https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40
* for a list of spec-compliant algorithms.
*/
$jwt = JWT::encode($payload, $key);
$decoded = JWT::decode($jwt, $key, array('HS256'));
print_r($decoded);
/*
NOTE: This will now be an object instead of an associative array. To get
an associative array, you will need to cast it as such:
*/
$decoded_array = (array) $decoded;
/**
* You can add a leeway to account for when there is a clock skew times between
* the signing and verifying servers. It is recommended that this leeway should
* not be bigger than a few minutes.
*
* Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef
*/
JWT::$leeway = 60; // $leeway in seconds
$decoded = JWT::decode($jwt, $key, array('HS256'));
?>
```
Example with RS256 (openssl)
----------------------------
```php
<?php
use \Firebase\JWT\JWT;
$privateKey = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC8kGa1pSjbSYZVebtTRBLxBz5H4i2p/llLCrEeQhta5kaQu/Rn
vuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t0tyazyZ8JXw+KgXTxldMPEL9
5+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4ehde/zUxo6UvS7UrBQIDAQAB
AoGAb/MXV46XxCFRxNuB8LyAtmLDgi/xRnTAlMHjSACddwkyKem8//8eZtw9fzxz
bWZ/1/doQOuHBGYZU8aDzzj59FZ78dyzNFoF91hbvZKkg+6wGyd/LrGVEB+Xre0J
Nil0GReM2AHDNZUYRv+HYJPIOrB0CRczLQsgFJ8K6aAD6F0CQQDzbpjYdx10qgK1
cP59UHiHjPZYC0loEsk7s+hUmT3QHerAQJMZWC11Qrn2N+ybwwNblDKv+s5qgMQ5
5tNoQ9IfAkEAxkyffU6ythpg/H0Ixe1I2rd0GbF05biIzO/i77Det3n4YsJVlDck
ZkcvY3SK2iRIL4c9yY6hlIhs+K9wXTtGWwJBAO9Dskl48mO7woPR9uD22jDpNSwe
k90OMepTjzSvlhjbfuPN1IdhqvSJTDychRwn1kIJ7LQZgQ8fVz9OCFZ/6qMCQGOb
qaGwHmUK6xzpUbbacnYrIM6nLSkXgOAwv7XXCojvY614ILTK3iXiLBOxPu5Eu13k
eUz9sHyD6vkgZzjtxXECQAkp4Xerf5TGfQXGXhxIX52yH+N2LtujCdkQZjXAsGdm
B2zNzvrlgRmgBrklMTrMYgm1NPcW+bRLGcwgW2PTvNM=
-----END RSA PRIVATE KEY-----
EOD;
$publicKey = <<<EOD
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kGa1pSjbSYZVebtTRBLxBz5H
4i2p/llLCrEeQhta5kaQu/RnvuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t
0tyazyZ8JXw+KgXTxldMPEL95+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4
ehde/zUxo6UvS7UrBQIDAQAB
-----END PUBLIC KEY-----
EOD;
$payload = array(
"iss" => "example.org",
"aud" => "example.com",
"iat" => 1356999524,
"nbf" => 1357000000
);
$jwt = JWT::encode($payload, $privateKey, 'RS256');
echo "Encode:\n" . print_r($jwt, true) . "\n";
$decoded = JWT::decode($jwt, $publicKey, array('RS256'));
/*
NOTE: This will now be an object instead of an associative array. To get
an associative array, you will need to cast it as such:
*/
$decoded_array = (array) $decoded;
echo "Decode:\n" . print_r($decoded_array, true) . "\n";
?>
```
Using JWKs
----------
```php
// Set of keys. The "keys" key is required. For example, the JSON response to
// this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk
$jwks = ['keys' => []];
// JWK::parseKeySet($jwks) returns an associative array of **kid** to private
// key. Pass this as the second parameter to JWT::decode.
JWT::decode($payload, JWK::parseKeySet($jwks), $supportedAlgorithm);
```
Changelog
---------
#### 5.0.0 / 2017-06-26
- Support RS384 and RS512.
See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)!
- Add an example for RS256 openssl.
See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)!
- Detect invalid Base64 encoding in signature.
See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)!
- Update `JWT::verify` to handle OpenSSL errors.
See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)!
- Add `array` type hinting to `decode` method
See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)!
- Add all JSON error types.
See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)!
- Bugfix 'kid' not in given key list.
See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)!
- Miscellaneous cleanup, documentation and test fixes.
See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115),
[#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and
[#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman),
[@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)!
#### 4.0.0 / 2016-07-17
- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)!
- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)!
- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)!
- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)!
#### 3.0.0 / 2015-07-22
- Minimum PHP version updated from `5.2.0` to `5.3.0`.
- Add `\Firebase\JWT` namespace. See
[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to
[@Dashron](https://github.com/Dashron)!
- Require a non-empty key to decode and verify a JWT. See
[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to
[@sjones608](https://github.com/sjones608)!
- Cleaner documentation blocks in the code. See
[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to
[@johanderuijter](https://github.com/johanderuijter)!
#### 2.2.0 / 2015-06-22
- Add support for adding custom, optional JWT headers to `JWT::encode()`. See
[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to
[@mcocaro](https://github.com/mcocaro)!
#### 2.1.0 / 2015-05-20
- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew
between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)!
- Add support for passing an object implementing the `ArrayAccess` interface for
`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)!
#### 2.0.0 / 2015-04-01
- **Note**: It is strongly recommended that you update to > v2.0.0 to address
known security vulnerabilities in prior versions when both symmetric and
asymmetric keys are used together.
- Update signature for `JWT::decode(...)` to require an array of supported
algorithms to use when verifying token signatures.
Tests
-----
Run the tests using phpunit:
```bash
$ pear install PHPUnit
$ phpunit --configuration phpunit.xml.dist
PHPUnit 3.7.10 by Sebastian Bergmann.
.....
Time: 0 seconds, Memory: 2.50Mb
OK (5 tests, 5 assertions)
```
New Lines in private keys
-----
If your private key contains `\n` characters, be sure to wrap it in double quotes `""`
and not single quotes `''` in order to properly interpret the escaped characters.
License
-------
[3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause).
{
"name": "firebase/php-jwt",
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
"homepage": "https://github.com/firebase/php-jwt",
"keywords": [
"php",
"jwt"
],
"authors": [
{
"name": "Neuman Vong",
"email": "neuman+pear@twilio.com",
"role": "Developer"
},
{
"name": "Anant Narayanan",
"email": "anant@php.net",
"role": "Developer"
}
],
"license": "BSD-3-Clause",
"require": {
"php": ">=5.3.0"
},
"autoload": {
"psr-4": {
"Firebase\\JWT\\": "src"
}
},
"require-dev": {
"phpunit/phpunit": ">=4.8 <=9"
}
}
<?php
namespace Firebase\JWT;
class BeforeValidException extends \UnexpectedValueException
{
}
<?php
namespace Firebase\JWT;
class ExpiredException extends \UnexpectedValueException
{
}
<?php
namespace Firebase\JWT;
use DomainException;
use UnexpectedValueException;
/**
* JSON Web Key implementation, based on this spec:
* https://tools.ietf.org/html/draft-ietf-jose-json-web-key-41
*
* PHP version 5
*
* @category Authentication
* @package Authentication_JWT
* @author Bui Sy Nguyen <nguyenbs@gmail.com>
* @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
* @link https://github.com/firebase/php-jwt
*/
class JWK
{
/**
* Parse a set of JWK keys
*
* @param array $jwks The JSON Web Key Set as an associative array
*
* @return array An associative array that represents the set of keys
*
* @throws InvalidArgumentException Provided JWK Set is empty
* @throws UnexpectedValueException Provided JWK Set was invalid
* @throws DomainException OpenSSL failure
*
* @uses parseKey
*/
public static function parseKeySet(array $jwks)
{
$keys = array();
if (!isset($jwks['keys'])) {
throw new UnexpectedValueException('"keys" member must exist in the JWK Set');
}
if (empty($jwks['keys'])) {
throw new InvalidArgumentException('JWK Set did not contain any keys');
}
foreach ($jwks['keys'] as $k => $v) {
$kid = isset($v['kid']) ? $v['kid'] : $k;
if ($key = self::parseKey($v)) {
$keys[$kid] = $key;
}
}
if (0 === \count($keys)) {
throw new UnexpectedValueException('No supported algorithms found in JWK Set');
}
return $keys;
}
/**
* Parse a JWK key
*
* @param array $jwk An individual JWK
*
* @return resource|array An associative array that represents the key
*
* @throws InvalidArgumentException Provided JWK is empty
* @throws UnexpectedValueException Provided JWK was invalid
* @throws DomainException OpenSSL failure
*
* @uses createPemFromModulusAndExponent
*/
private static function parseKey(array $jwk)
{
if (empty($jwk)) {
throw new InvalidArgumentException('JWK must not be empty');
}
if (!isset($jwk['kty'])) {
throw new UnexpectedValueException('JWK must contain a "kty" parameter');
}
switch ($jwk['kty']) {
case 'RSA':
if (\array_key_exists('d', $jwk)) {
throw new UnexpectedValueException('RSA private keys are not supported');
}
if (!isset($jwk['n']) || !isset($jwk['e'])) {
throw new UnexpectedValueException('RSA keys must contain values for both "n" and "e"');
}
$pem = self::createPemFromModulusAndExponent($jwk['n'], $jwk['e']);
$publicKey = \openssl_pkey_get_public($pem);
if (false === $publicKey) {
throw new DomainException(
'OpenSSL error: ' . \openssl_error_string()
);
}
return $publicKey;
default:
// Currently only RSA is supported
break;
}
}
/**
* Create a public key represented in PEM format from RSA modulus and exponent information
*
* @param string $n The RSA modulus encoded in Base64
* @param string $e The RSA exponent encoded in Base64
*
* @return string The RSA public key represented in PEM format
*
* @uses encodeLength
*/
private static function createPemFromModulusAndExponent($n, $e)
{
$modulus = JWT::urlsafeB64Decode($n);
$publicExponent = JWT::urlsafeB64Decode($e);
$components = array(
'modulus' => \pack('Ca*a*', 2, self::encodeLength(\strlen($modulus)), $modulus),
'publicExponent' => \pack('Ca*a*', 2, self::encodeLength(\strlen($publicExponent)), $publicExponent)
);
$rsaPublicKey = \pack(
'Ca*a*a*',
48,
self::encodeLength(\strlen($components['modulus']) + \strlen($components['publicExponent'])),
$components['modulus'],
$components['publicExponent']
);
// sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
$rsaOID = \pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
$rsaPublicKey = \chr(0) . $rsaPublicKey;
$rsaPublicKey = \chr(3) . self::encodeLength(\strlen($rsaPublicKey)) . $rsaPublicKey;
$rsaPublicKey = \pack(
'Ca*a*',
48,
self::encodeLength(\strlen($rsaOID . $rsaPublicKey)),
$rsaOID . $rsaPublicKey
);
$rsaPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
\chunk_split(\base64_encode($rsaPublicKey), 64) .
'-----END PUBLIC KEY-----';
return $rsaPublicKey;
}
/**
* DER-encode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @param int $length
* @return string
*/
private static function encodeLength($length)
{
if ($length <= 0x7F) {
return \chr($length);
}
$temp = \ltrim(\pack('N', $length), \chr(0));
return \pack('Ca*', 0x80 | \strlen($temp), $temp);
}
}
This diff is collapsed.
<?php
namespace Firebase\JWT;
class SignatureInvalidException extends \UnexpectedValueException
{
}
<?php
class Login extends Model {
}
?>
\ No newline at end of file
<?php
class Model {
protected static function db(){
return DatabasePDO::singleton();
}
// *** Queries in sql/model.sql.php ****
protected static $requests = array();
public static function addSqlQuery($key, $sql){
static::$requests[$key] = $sql;
}
public static function sqlQueryNamed($key){
return static::$requests[$key];
}
protected static function query($sql){
$st = static::db()->query($sql) or die("sql query error ! request : " . $sql);
$st->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, get_called_class());
return $st;
}
protected static function exec($sqlKey, $values=array()){
$sth = static::db()->prepare(static::sqlQueryNamed($sqlKey));
$sth->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, get_called_class());
$sth->execute($values);
return $sth;
}
}
?>
\ No newline at end of file
<?php
class User extends Model {
// ===========
// = Statics =
// ===========
public static function tryLogin($login) {
return new static();
}
protected static $table_name = 'USER';
public static function create($post) {
parent::exec('USER_CREATE', [':firstname' => $post->firstname,
':lastname' => $post->lastname,
':login' => $post->login,
':email' => $post->email,
':password' => password_hash($post->password, PASSWORD_BCRYPT),
':role' => $post->role]);
}
public static function getList() {
$stm = parent::exec('USER_GET_LIST');
return $stm->fetchAll();
}
public static function getWithId($id) {
$stm = parent::exec('USER_GET_WITH_ID', [':id' => $id]);
return $stm->fetch();
}
public static function getWithLogin($login) {
$stm = parent::exec('USER_GET_WITH_LOGIN', [':login' => $login]);
return $stm->fetch();
}
public static function update($put, $id) {
parent::exec('USER_UPDATE', [':email' => $put->email, ':id' => $id]);
}
public static function delete($id) {
parent::exec('USER_DELETE', [':id' => $id]);
}
}
?>
\ No newline at end of file
<?php
class Validatetoken extends Model {
}
?>
\ No newline at end of file
<?php
User::addSqlQuery('USER_CREATE',
'INSERT INTO `users` VALUES (NULL, :firstname, :lastname, :login, :email, :password, :role)');
User::addSqlQuery('USER_GET_LIST',
'SELECT * FROM `users` ORDER BY `id` ');
User::addSqlQuery('USER_GET_WITH_ID',
'SELECT * FROM `users` WHERE `id` = :id');
User::addSqlQuery('USER_GET_WITH_LOGIN',
'SELECT * FROM `users` WHERE `login` = :login');
User::addSqlQuery('USER_UPDATE',
'UPDATE `users` SET `email` = :email WHERE `id` = :id');
User::addSqlQuery('USER_DELETE',
'DELETE FROM `users` WHERE `id` = :id');
?>
\ No newline at end of file
const href = window.location.href;
const url = href.substring(0, href.lastIndexOf('/')) + "/api/api.php/user";
const form = document.forms[0];
form.addEventListener('submit', function(e) {
e.preventDefault();
fetch(url, {
method: 'GET'
})
.then(response => {
if (response.status === 200) {
return response.json();
} else {
throw new Error('Something went wrong on api server!');
}
})
.then(data => {
const index = data.findIndex((e) => e.login == form.elements.login.value);
}).catch(error => {
console.error(error);
});
});
\ No newline at end of file
console.log("Hey !"); const href = window.location.href;
\ No newline at end of file const url = href.substring(0, href.lastIndexOf('/')) + "/api/api.php/user";
const form = document.forms[0];
let body = { 'role': 0 };
form.addEventListener('submit', function(e) {
e.preventDefault();
Object.entries(form.elements).forEach((key) => {
if (key[1].id != "repeatPassword")
body[key[1].id] = key[1].value;
})
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
})
.then(response => {
if (response.status === 200) {
window.location.href = href.substring(0, href.lastIndexOf('/')) + "/login.php";
} else {
throw new Error('Something went wrong on api server!');
}
}).catch(error => {
console.error(error);
});
});
...@@ -15,20 +15,18 @@ ...@@ -15,20 +15,18 @@
<div class="col-lg-6"> <div class="col-lg-6">
<div class="p-5"> <div class="p-5">
<div class="text-center"> <div class="text-center">
<h1 class="h4 text-gray-900 mb-4">Bienvenue !</h1> <h1 class="h4 text-gray-900 mb-4">Connectez-vous !</h1>
</div> </div>
<form class="user" method="post"> <form class="user">
<div class="form-group"> <div class="form-group">
<input type="text" class="form-control form-control-user" id="pseudo" placeholder="Pseudo"> <input type="text" class="form-control form-control-user" id="login" placeholder="Login">
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control form-control-user" id="password" placeholder="Password"> <input type="password" class="form-control form-control-user" id="password" placeholder="Mot de passe">
</div> </div>
<a href="gameCreate.php" class="btn btn-primary btn-user btn-block"> <button type="submit" class="btn btn-primary btn-user btn-block">Connexion</button>
Connexion
</a>
<hr>
</form> </form>
<hr>
<div class="text-center"> <div class="text-center">
<a class="small" href="signup.php">Créer un compte</a> <a class="small" href="signup.php">Créer un compte</a>
</div> </div>
......
This diff is collapsed.
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
}, },
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "5.15.1", "@fortawesome/fontawesome-free": "5.15.1",
"bcrypt": "^5.0.0",
"bootstrap": "4.5.3", "bootstrap": "4.5.3",
"chart.js": "2.9.4", "chart.js": "2.9.4",
"datatables.net-bs4": "1.10.22", "datatables.net-bs4": "1.10.22",
......
...@@ -18,14 +18,14 @@ ...@@ -18,14 +18,14 @@
<form class="user"> <form class="user">
<div class="form-group row"> <div class="form-group row">
<div class="col-sm-6 mb-3 mb-sm-0"> <div class="col-sm-6 mb-3 mb-sm-0">
<input type="text" class="form-control form-control-user" id="firstName" placeholder="Prénom"> <input type="text" class="form-control form-control-user" id="firstname" placeholder="Prénom">
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<input type="text" class="form-control form-control-user" id="lastName" placeholder="Nom"> <input type="text" class="form-control form-control-user" id="lastname" placeholder="Nom">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="text" class="form-control form-control-user" id="pseudo" placeholder="Pseudo"> <input type="text" class="form-control form-control-user" id="login" placeholder="Login">
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="email" class="form-control form-control-user" id="email" placeholder="Email"> <input type="email" class="form-control form-control-user" id="email" placeholder="Email">
...@@ -38,9 +38,7 @@ ...@@ -38,9 +38,7 @@
<input type="password" class="form-control form-control-user" id="repeatPassword" placeholder="Confirmation"> <input type="password" class="form-control form-control-user" id="repeatPassword" placeholder="Confirmation">
</div> </div>
</div> </div>
<a href="login.php" class="btn btn-primary btn-user btn-block"> <button type="submit" class="btn btn-primary btn-user btn-block">Inscription</button>
Inscription
</a>
</form> </form>
<hr> <hr>
<div class="text-center"> <div class="text-center">
......
The MIT License (MIT)
Copyright (c) 2011-2020 Twitter, Inc.
Copyright (c) 2011-2020 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*!
* Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus:not(:focus-visible) {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([class]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
-ms-overflow-style: scrollbar;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
[role="button"] {
cursor: pointer;
}
select {
word-wrap: normal;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button:not(:disabled),
[type="button"]:not(:disabled),
[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */
\ No newline at end of file
/*!
* Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
\ No newline at end of file
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
/*!
* Bootstrap alert.js v4.5.3 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) :
typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Alert = factory(global.jQuery, global.Util));
}(this, (function ($, Util) { 'use strict';
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var $__default = /*#__PURE__*/_interopDefaultLegacy($);
var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util);
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
var NAME = 'alert';
var VERSION = '4.5.3';
var DATA_KEY = 'bs.alert';
var EVENT_KEY = "." + DATA_KEY;
var DATA_API_KEY = '.data-api';
var JQUERY_NO_CONFLICT = $__default['default'].fn[NAME];
var SELECTOR_DISMISS = '[data-dismiss="alert"]';
var EVENT_CLOSE = "close" + EVENT_KEY;
var EVENT_CLOSED = "closed" + EVENT_KEY;
var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY;
var CLASS_NAME_ALERT = 'alert';
var CLASS_NAME_FADE = 'fade';
var CLASS_NAME_SHOW = 'show';
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
var Alert = /*#__PURE__*/function () {
function Alert(element) {
this._element = element;
} // Getters
var _proto = Alert.prototype;
// Public
_proto.close = function close(element) {
var rootElement = this._element;
if (element) {
rootElement = this._getRootElement(element);
}
var customEvent = this._triggerCloseEvent(rootElement);
if (customEvent.isDefaultPrevented()) {
return;
}
this._removeElement(rootElement);
};
_proto.dispose = function dispose() {
$__default['default'].removeData(this._element, DATA_KEY);
this._element = null;
} // Private
;
_proto._getRootElement = function _getRootElement(element) {
var selector = Util__default['default'].getSelectorFromElement(element);
var parent = false;
if (selector) {
parent = document.querySelector(selector);
}
if (!parent) {
parent = $__default['default'](element).closest("." + CLASS_NAME_ALERT)[0];
}
return parent;
};
_proto._triggerCloseEvent = function _triggerCloseEvent(element) {
var closeEvent = $__default['default'].Event(EVENT_CLOSE);
$__default['default'](element).trigger(closeEvent);
return closeEvent;
};
_proto._removeElement = function _removeElement(element) {
var _this = this;
$__default['default'](element).removeClass(CLASS_NAME_SHOW);
if (!$__default['default'](element).hasClass(CLASS_NAME_FADE)) {
this._destroyElement(element);
return;
}
var transitionDuration = Util__default['default'].getTransitionDurationFromElement(element);
$__default['default'](element).one(Util__default['default'].TRANSITION_END, function (event) {
return _this._destroyElement(element, event);
}).emulateTransitionEnd(transitionDuration);
};
_proto._destroyElement = function _destroyElement(element) {
$__default['default'](element).detach().trigger(EVENT_CLOSED).remove();
} // Static
;
Alert._jQueryInterface = function _jQueryInterface(config) {
return this.each(function () {
var $element = $__default['default'](this);
var data = $element.data(DATA_KEY);
if (!data) {
data = new Alert(this);
$element.data(DATA_KEY, data);
}
if (config === 'close') {
data[config](this);
}
});
};
Alert._handleDismiss = function _handleDismiss(alertInstance) {
return function (event) {
if (event) {
event.preventDefault();
}
alertInstance.close(this);
};
};
_createClass(Alert, null, [{
key: "VERSION",
get: function get() {
return VERSION;
}
}]);
return Alert;
}();
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$__default['default'](document).on(EVENT_CLICK_DATA_API, SELECTOR_DISMISS, Alert._handleDismiss(new Alert()));
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$__default['default'].fn[NAME] = Alert._jQueryInterface;
$__default['default'].fn[NAME].Constructor = Alert;
$__default['default'].fn[NAME].noConflict = function () {
$__default['default'].fn[NAME] = JQUERY_NO_CONFLICT;
return Alert._jQueryInterface;
};
return Alert;
})));
//# sourceMappingURL=alert.js.map
{"version":3,"file":"alert.js","sources":["../src/alert.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst SELECTOR_DISMISS = '[data-dismiss=\"alert\"]'\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_ALERT = 'alert'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(EVENT_CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(CLASS_NAME_SHOW)\n\n if (!$(element).hasClass(CLASS_NAME_FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, event => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(EVENT_CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n EVENT_CLICK_DATA_API,\n SELECTOR_DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","SELECTOR_DISMISS","EVENT_CLOSE","EVENT_CLOSED","EVENT_CLICK_DATA_API","CLASS_NAME_ALERT","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","element","_element","close","rootElement","_getRootElement","customEvent","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","selector","Util","getSelectorFromElement","parent","document","querySelector","closest","closeEvent","Event","trigger","removeClass","hasClass","_destroyElement","transitionDuration","getTransitionDurationFromElement","one","TRANSITION_END","event","emulateTransitionEnd","detach","remove","_jQueryInterface","config","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict"],"mappings":"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"}
\ No newline at end of file
/*!
* Bootstrap button.js v4.5.3 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) :
typeof define === 'function' && define.amd ? define(['jquery'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Button = factory(global.jQuery));
}(this, (function ($) { 'use strict';
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var $__default = /*#__PURE__*/_interopDefaultLegacy($);
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
var NAME = 'button';
var VERSION = '4.5.3';
var DATA_KEY = 'bs.button';
var EVENT_KEY = "." + DATA_KEY;
var DATA_API_KEY = '.data-api';
var JQUERY_NO_CONFLICT = $__default['default'].fn[NAME];
var CLASS_NAME_ACTIVE = 'active';
var CLASS_NAME_BUTTON = 'btn';
var CLASS_NAME_FOCUS = 'focus';
var SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]';
var SELECTOR_DATA_TOGGLES = '[data-toggle="buttons"]';
var SELECTOR_DATA_TOGGLE = '[data-toggle="button"]';
var SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle="buttons"] .btn';
var SELECTOR_INPUT = 'input:not([type="hidden"])';
var SELECTOR_ACTIVE = '.active';
var SELECTOR_BUTTON = '.btn';
var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY;
var EVENT_FOCUS_BLUR_DATA_API = "focus" + EVENT_KEY + DATA_API_KEY + " " + ("blur" + EVENT_KEY + DATA_API_KEY);
var EVENT_LOAD_DATA_API = "load" + EVENT_KEY + DATA_API_KEY;
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
var Button = /*#__PURE__*/function () {
function Button(element) {
this._element = element;
this.shouldAvoidTriggerChange = false;
} // Getters
var _proto = Button.prototype;
// Public
_proto.toggle = function toggle() {
var triggerChangeEvent = true;
var addAriaPressed = true;
var rootElement = $__default['default'](this._element).closest(SELECTOR_DATA_TOGGLES)[0];
if (rootElement) {
var input = this._element.querySelector(SELECTOR_INPUT);
if (input) {
if (input.type === 'radio') {
if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {
triggerChangeEvent = false;
} else {
var activeElement = rootElement.querySelector(SELECTOR_ACTIVE);
if (activeElement) {
$__default['default'](activeElement).removeClass(CLASS_NAME_ACTIVE);
}
}
}
if (triggerChangeEvent) {
// if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input
if (input.type === 'checkbox' || input.type === 'radio') {
input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE);
}
if (!this.shouldAvoidTriggerChange) {
$__default['default'](input).trigger('change');
}
}
input.focus();
addAriaPressed = false;
}
}
if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {
if (addAriaPressed) {
this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE));
}
if (triggerChangeEvent) {
$__default['default'](this._element).toggleClass(CLASS_NAME_ACTIVE);
}
}
};
_proto.dispose = function dispose() {
$__default['default'].removeData(this._element, DATA_KEY);
this._element = null;
} // Static
;
Button._jQueryInterface = function _jQueryInterface(config, avoidTriggerChange) {
return this.each(function () {
var $element = $__default['default'](this);
var data = $element.data(DATA_KEY);
if (!data) {
data = new Button(this);
$element.data(DATA_KEY, data);
}
data.shouldAvoidTriggerChange = avoidTriggerChange;
if (config === 'toggle') {
data[config]();
}
});
};
_createClass(Button, null, [{
key: "VERSION",
get: function get() {
return VERSION;
}
}]);
return Button;
}();
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$__default['default'](document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
var button = event.target;
var initialButton = button;
if (!$__default['default'](button).hasClass(CLASS_NAME_BUTTON)) {
button = $__default['default'](button).closest(SELECTOR_BUTTON)[0];
}
if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {
event.preventDefault(); // work around Firefox bug #1540995
} else {
var inputBtn = button.querySelector(SELECTOR_INPUT);
if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {
event.preventDefault(); // work around Firefox bug #1540995
return;
}
if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {
Button._jQueryInterface.call($__default['default'](button), 'toggle', initialButton.tagName === 'INPUT');
}
}
}).on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
var button = $__default['default'](event.target).closest(SELECTOR_BUTTON)[0];
$__default['default'](button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type));
});
$__default['default'](window).on(EVENT_LOAD_DATA_API, function () {
// ensure correct active class is set to match the controls' actual values/states
// find all checkboxes/readio buttons inside data-toggle groups
var buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS));
for (var i = 0, len = buttons.length; i < len; i++) {
var button = buttons[i];
var input = button.querySelector(SELECTOR_INPUT);
if (input.checked || input.hasAttribute('checked')) {
button.classList.add(CLASS_NAME_ACTIVE);
} else {
button.classList.remove(CLASS_NAME_ACTIVE);
}
} // find all button toggles
buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE));
for (var _i = 0, _len = buttons.length; _i < _len; _i++) {
var _button = buttons[_i];
if (_button.getAttribute('aria-pressed') === 'true') {
_button.classList.add(CLASS_NAME_ACTIVE);
} else {
_button.classList.remove(CLASS_NAME_ACTIVE);
}
}
});
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$__default['default'].fn[NAME] = Button._jQueryInterface;
$__default['default'].fn[NAME].Constructor = Button;
$__default['default'].fn[NAME].noConflict = function () {
$__default['default'].fn[NAME] = JQUERY_NO_CONFLICT;
return Button._jQueryInterface;
};
return Button;
})));
//# sourceMappingURL=button.js.map
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment