Plugin Directory

Changeset 2496270


Ignore:
Timestamp:
03/15/2021 07:24:48 PM (5 years ago)
Author:
unsproject
Message:

[2.0.0] Add support for SRP and inprove UI

Location:
unsproject
Files:
66 added
12 edited

Legend:

Unmodified
Added
Removed
  • unsproject/trunk/apiroutes.php

    r2412699 r2496270  
    342342    ]);
    343343
     344    //SRP routes
     345    register_rest_route(rtrim(UnsWordPressAPI::API_NAMESPACE, '/\\'), UnsWordPressAPI::SRP_REGISTER,
     346        [
     347            'methods' => 'POST',
     348            'callback' => function ($request) {
     349                try {
     350                    if (!isset($_REQUEST['JWT'])) {
     351                        throw  new Exception('Missing `JWT` parameter.');
     352                    }
     353
     354                    $siteOptions = new SiteOptions();
     355                    $jwt = $_REQUEST['JWT'];
     356                    $payload = (array)JWT::decode(
     357                        $jwt,
     358                        base64_decode($siteOptions->getValue('public_key')),
     359                        ['RS256']
     360                    );
     361
     362                    if ($payload === null) {
     363                        throw  new Exception('Something is wrong with your JWT payload.');
     364                    }
     365                    if(!isset($payload['user_id']) || !isset($payload['s']) || !isset($payload['v'])){
     366                        throw new Exception('JWT payload is malformed.');
     367                    }
     368                    $databaseService = new DatabaseService();
     369
     370                    $I = $payload['user_id'];
     371                    $srpUserCredentials = $databaseService->getSrpCredentials($I);
     372                    if (!empty($srpUserCredentials)) {
     373                        throw new Exception('User already is registered.');
     374                    }
     375                    $s = $payload["s"];
     376                    $v = $payload["v"];
     377
     378                    $databaseService->insertUserCredentials($I, $s, $v);
     379                    return json_encode([
     380                        "success" => true
     381                    ]);
     382                } catch (\Exception $e) {
     383                    @header('Content-Type: application/json; charset=UTF-8');
     384                    wp_send_json_error([
     385                        'status' => 'error',
     386                        'message' => $e->getMessage(),
     387                        'errorCode' => $e->getCode()
     388                    ],
     389                        400
     390                    );
     391                    return '';
     392                }
     393
     394            },
     395            'permission_callback' => '__return_true',
     396        ]
     397    );
     398
     399    register_rest_route(rtrim(UnsWordPressAPI::API_NAMESPACE, '/\\'), UnsWordPressAPI::SRP_LOGIN,
     400        [
     401            'methods' => 'POST',
     402            'callback' => function ($request) {
     403                try {
     404                    header('Content-type:application/json');
     405                    if (!isset($request['JWT'])) {
     406                        throw new Exception('Missing JWT.');
     407                    }
     408                    $siteOptions = new SiteOptions();
     409                    $payload = (array) JWT::decode(
     410                        $request['JWT'],
     411                        base64_decode($siteOptions->getValue('public_key')),
     412                        ['RS256']
     413                    );
     414                    if(!isset($payload['I'])){
     415                        throw new Exception('Wrong JWT. Missing I from payload.');
     416                    }
     417                    $srpHelper = new \UNSProjectApp\Helpers\SrpHelper($siteOptions);
     418                    $currentUser = $srpHelper->getUserByUsernameOrEmail($payload['I']);
     419                    if(empty($currentUser)){
     420                        throw new Exception('Wrong user provided or user does not exist.');
     421                    }
     422                    $databaseService = new DatabaseService();
     423                    $srpCredentials = $databaseService->getSrpCredentials($currentUser->ID);
     424                    if(empty($srpCredentials)){
     425                        throw new Exception('SRP credentials error');
     426                    }
     427
     428                    if(!isset($payload['phase'])){
     429                        throw new Exception('Invalid JWT provided. No phase parameter.');
     430                    }
     431                    $srp = new Srp\Srp();
     432                    switch ((int)$payload['phase']) {
     433                        case 1:
     434                            $session = [];
     435                            $session["v"] = $srpCredentials['v'];
     436                            $session["A"] = $payload['A'];
     437
     438                            $session["b"] = $srp->getRandomSeed();
     439                            $session["B"] = $srp->generateB($session["b"], $session["v"]);
     440
     441                            return wp_send_json(
     442                                [
     443                                    'success' => true,
     444                                    'JWT' => $srpHelper->createJwt($session)
     445                                ]
     446                            );
     447                            break;
     448                        case 2:
     449                            $session = [];
     450                            $session["S"] = $srp->generateS_Server(
     451                                $payload["A"],
     452                                $payload["B"],
     453                                $payload["b"],
     454                                $srpCredentials["v"]
     455                            );
     456                            $M1_check = $srp->generateM1($payload["A"], $payload["B"], $session["S"]);
     457
     458                            if($payload['M1'] !== $M1_check){
     459                                echo wp_send_json([
     460                                    "success" => false,
     461                                    'message' => 'M1 !== M1check'
     462                                ]);
     463                                exit;
     464                            }
     465
     466                            echo wp_send_json([
     467                                "success" => true,
     468                                'JWT' => $srpHelper->createJwt(
     469                                    $session
     470                                )
     471                            ]);
     472                            exit;
     473
     474                            break;
     475                    }
     476
     477                } catch (\Exception $e) {
     478                    @header('Content-Type: application/json; charset=UTF-8');
     479                    wp_send_json_error([
     480                        'status' => 'error',
     481                        'message' => $e->getMessage(),
     482                        'errorCode' => $e->getCode()
     483                    ],
     484                        400
     485                    );
     486                    return '';
     487                }
     488
     489            },
     490            'permission_callback' => '__return_true',
     491        ]
     492    );
    344493});
    345494
  • unsproject/trunk/autoload.php

    r2412699 r2496270  
    33function uns_autoloader($class)
    44{
     5    $namespaces = [
     6        [
     7            'class' => 'Srp\\',
     8            'namespace' => 'Srp\\',
     9            'directory' => __DIR__ . '/src/vendor/Srp/'
     10        ],
     11        [
     12            'class' => 'BrowserDetector\\',
     13            'namespace' => 'BrowserDetector\\',
     14            'directory' => __DIR__ . '/src/vendor/BrowserDetector/'
     15        ],
     16        [
     17            'class' => 'UNSProjectApp\\',
     18            'namespace' => 'UNSProjectApp\\',
     19            'directory' => __DIR__ . '/src/'
     20        ],
     21    ];
     22
    523    $namespace_map = null;
    6     if(strpos($class, 'BrowserDetector\\') !== false){
    7         $namespace_map = array('BrowserDetector\\' => __DIR__ . '/src/vendor/BrowserDetector/');
    8     } else if(strpos($class, 'UNSProjectApp\\') !== false){
    9         $namespace_map = array('UNSProjectApp\\' =>   __DIR__.'/src/');
     24    foreach ($namespaces as $oneNamespace) {
     25        if (strpos($class, $oneNamespace['class']) !== false) {
     26            $namespace_map = [
     27                $oneNamespace['namespace'] => $oneNamespace['directory']
     28            ];
     29        }
    1030    }
    1131
     
    2040}
    2141
    22 
    2342spl_autoload_register('uns_autoloader');
  • unsproject/trunk/css/backend.css

    r2412699 r2496270  
    3737
    3838.uns-button {
    39     padding: 10px;
    4039    display: inline-block;
    4140    color: #000;
     
    8079    box-sizing: border-box;
    8180}
    82 
     81.connection_status h2{
     82    font-size: 16px;
     83    margin-left: 0;
     84    font-weight: bold;
     85}
    8386.connection_status .row {
    8487    width: 100%;
     
    8992    width: 100%;
    9093    font-weight: bold;
    91     font-size: 14px;
     94
    9295    line-height: 14px;
    9396    margin-bottom: 12px;
     
    97100.connection_status .row input,
    98101.connection_status .row textarea {
    99     width: 100%;
    100102    border: 1px solid #ccc;
    101     padding: 5px;
    102103}
    103104
     
    156157    min-width: 85px;
    157158}
     159#unsproject-srp{
     160    margin-top:20px;
     161    width: 100%;
     162    font-size: 12px;
     163}
     164#unsproject-srp h1{
     165    font-size: 18px;
     166    font-weight: bold;
     167}
     168#unsproject-srp .learn_more{
     169    float: right;
     170    font-size: 10px;
     171    margin: 0 10px;
     172    background: #ccc;
     173    padding: 5px 10px;
     174    color: #000;
     175    text-decoration: none;
     176    text-transform: uppercase;
     177}
     178#unsproject-srp .srp-container{
     179    margin-top:20px;
     180}
     181
     182#unsproject-connection_status{
     183    font-size:12px;
     184    margin-top:10px;
     185}
     186#unsproject-connection_status .custom-container,
     187#unsproject-srp .custom-container{
     188    background:#FFF;
     189    padding: 20px;
     190    border: 1px solid #ccc;
     191}
     192#unsproject-connection_status .custom-container.top-round,
     193#unsproject-srp .custom-container.top-round{
     194    border-top-left-radius:0.3em;
     195    border-top-right-radius: 0.3em;
     196}
     197#unsproject-connection_status .custom-container.bottom-round,
     198#unsproject-srp .custom-container.bottom-round{
     199    border-bottom-left-radius:0.3em;
     200    border-bottom-right-radius: 0.3em;
     201}
     202#unsproject-connection_status .custom-container.no-top-border,
     203#unsproject-srp .custom-container.no-top-border{
     204    border-top: 0;
     205}
     206#unsproject-srp b.custom-title{
     207    line-height: 40px;
     208}
     209#unsproject-srp .custom-control-label{
     210    line-height: 24px;
     211    font-weight: bold
     212}
     213#unsproject-srp p.custom-info{
     214    word-break: break-word;
     215    text-align: justify;
     216    max-width: 74%;
     217}
     218
     219#unsproject-srp button.button{
     220    margin-top: 20px;
     221}
     222
     223.white-background-container{
     224    width: 100%;
     225    padding: 10px;
     226    border:1px solid #ccc;
     227    background:#fff;
     228    margin: 10px 0;
     229
     230}
  • unsproject/trunk/css/common.css

    r2412699 r2496270  
    3030    text-align: center;
    3131}
    32 
     32.login #unsproject_qr_code_conatainer h2{
     33   padding:25px 0;
     34}
    3335#unsproject_qr_code_conatainer a{
    3436    text-align: justify;
     
    165167    overflow: hidden;
    166168}
     169.login-form-uns-qr-code-container{
     170    margin: 0 auto;
     171    max-width: 320px;
     172    text-align: center;
     173}
  • unsproject/trunk/readme.md

    r2439247 r2496270  
    1 === UNS lets users securely login to WordPress with a smartphone app or browser ===
     1=== UNS Project WordPress Authentication ===
    22
    3 Contributors: nicu_m, unsproject
     3Contributors: unsproject, nicu_m
    44Tags: qrcode, qr code, jwt, login, secure login, uns, unsproject
    55Requires at least: 4.4.0
    6 Tested up to: 5.5
     6Tested up to: 5.7
    77Requires PHP: 5.3
    88Stable tag: trunk
     
    5555
    5656== Changelog ==
     57= 2.0.0 (15 Mar 2021)
     58* Add support for SRP
     59* Improve UI
     60
    5761= 1.1.0 (14 Dec 2020)
    5862* On plugin cleanup delete data from UNS servers
  • unsproject/trunk/src/DatabaseService.php

    r2412699 r2496270  
    1414    const TABLE_URLS = 'unsproject_urls';
    1515    const TABLE_TICKETS = 'unsproject_tickets';
     16    const TABLE_SRP = 'unsproject_srp';
    1617
    1718    /**
     
    317318        return false;
    318319    }
     320
     321
     322    /**
     323     * SRP
     324     */
     325    public function createSRPTable()
     326    {
     327        $query = "CREATE TABLE IF NOT EXISTS `" . $this->generateTableName(self::TABLE_SRP) . "` (
     328            `id` BIGINT(20) NOT NULL AUTO_INCREMENT ,
     329            `user_id` BIGINT(20) DEFAULT 0,
     330            `s` TEXT NOT NULL,
     331            `v` TEXT NOT NULL,
     332            `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
     333             PRIMARY KEY (`id`)
     334        ) ENGINE = InnoDB;";
     335        $this->database->query($query)->execute();
     336    }
     337
     338    /**
     339     * @param int $userId
     340     * @return array|null
     341     */
     342    public function getSrpCredentials($userId){
     343        $query = 'SELECT * FROM '.$this->generateTableName(self::TABLE_SRP)
     344            .' WHERE user_id = '. (int) $userId . ' LIMIT 1';
     345
     346        $row = $this->database->query($query)->getRow();
     347        if(!isset($row['s']) || !isset($row['v'])){
     348            return null;
     349        }
     350        return [
     351            's' => base64_decode($row['s']),
     352            'v' => base64_decode($row['v'])
     353        ];
     354    }
     355
     356    public function insertUserCredentials($userId, $s, $v){
     357        $s = base64_encode($s);
     358        $v = base64_encode($v);
     359        $query = 'INSERT INTO '.$this->generateTableName(self::TABLE_SRP)
     360            . " (user_id, s, v) VALUES ("
     361            . "'" . (int) $userId . "', "
     362            . "'" . $this->database->sanitize($s) . "', "
     363            . "'" . $this->database->sanitize($v) . "'"
     364            .");";
     365        $this->database->query($query)->execute();
     366    }
     367
     368    public function updateUserCredentials($userId, $s, $v){
     369        $s = base64_encode($s);
     370        $v = base64_encode($v);
     371        $query = 'UPDATE '.$this->generateTableName(self::TABLE_SRP)
     372            . " SET "
     373            . "s = '" . $this->database->sanitize($s) . "', "
     374            . "v = '" . $this->database->sanitize($v) . "'"
     375            ." WHERE user_id = ". (int) $userId . ' LIMIT 1';
     376
     377        $this->database->query($query)->execute();
     378    }
     379
    319380}
  • unsproject/trunk/src/ServerCall.php

    r2439247 r2496270  
    4141        $callResult = wp_remote_retrieve_body($response);
    4242
    43         return @json_decode($callResult, true);
     43        return json_decode($callResult, true);
    4444    }
    4545
  • unsproject/trunk/src/UnsWordPressAPI.php

    r2412699 r2496270  
    1616    const REGISTER_USER = '/verifyTicket/register';
    1717    const DISCONNECT_USER = '/disconnect';
     18    const SRP_REGISTER = '/srp/register';
     19    const SRP_LOGIN = '/srp/login';
    1820    const DEFAULT_JWT_EXPIRATION = 10; //minutes
    19     const DEFAULT_AUTHORIZATION_INTERVAL = 5000; //milliseconds
     21    const DEFAULT_AUTHORIZATION_INTERVAL = 1000; //milliseconds
    2022
    2123    /**
     
    3638     * @return string
    3739     */
    38     private static  function getApiPath(){
     40    public static  function getApiPath(){
    3941        return '/?rest_route=/' . self::API_NAMESPACE;
    4042    }
  • unsproject/trunk/src/Views/connection_status.php

    r2412699 r2496270  
    1010
    1111?>
    12 <button class="uns-button blue-button" id="save_attestation">Save</button>
     12<button class="btn btn-primary" id="save_attestation">Save</button>
    1313
    14 <div class="connection_status">
    15     <h2>Site Settings</h2>
    16     <div class="row">
    17         <label>Email</label>
    18         <input type="text" readonly="readonly"
    19                value="<?php echo(isset($siteOption['email']) ? esc_html($siteOption['email']) : ''); ?>"/>
     14<div id="unsproject-connection_status" class="connection_status">
     15    <div class="custom-container top-round">
     16        <h2>Site Settings</h2>
     17        <div class="row">
     18            <label>Email</label>
     19            <input type="text" readonly="readonly" class="form-control"
     20                   value="<?php echo(isset($siteOption['email']) ? esc_html($siteOption['email']) : ''); ?>"/>
     21        </div>
     22
     23        <div class="row">
     24            <label>Phone Number</label>
     25            <input type="text" readonly="readonly" class="form-control"
     26                   value="<?php echo(isset($siteOption['phoneNumber']) ? esc_html($siteOption['phoneNumber']) : ''); ?>"/>
     27        </div>
     28
     29        <div class="row">
     30            <label>Contact Name</label>
     31            <input type="text" readonly="readonly" class="form-control"
     32                   value="<?php echo(isset($siteOption['contactName']) ? esc_html($siteOption['contactName']) : ''); ?>"/>
     33        </div>
     34
     35        <div class="row">
     36            <label>Public Key</label>
     37            <textarea class="form-control"
     38                      readonly="readonly"><?php echo(isset($siteOption['public_key']) ? esc_html(base64_decode($siteOption['public_key'])) : ''); ?></textarea>
     39        </div>
     40
     41        <div class="row">
     42            <label>Private Key</label>
     43            <textarea class="form-control"
     44                      readonly="readonly"><?php echo(isset($siteOption['private_key']) ? esc_html(base64_decode($siteOption['private_key'])) : ''); ?></textarea>
     45        </div>
     46
     47        <div class="row">
     48            <label>Site URL</label>
     49            <input type="text" readonly="readonly" class="form-control"
     50                   value="<?php echo(isset($siteOption['site_url']) ? esc_html($siteOption['site_url']) : ''); ?>"/>
     51        </div>
     52
     53        <div class="row">
     54            <label>Unique ID</label>
     55            <input type="text" readonly="readonly" class="form-control"
     56                   value="<?php echo(isset($siteOption['uniqueId']) ? esc_html($siteOption['uniqueId']) : ''); ?>"/>
     57        </div>
     58    </div>
     59    <div class="custom-container no-top-border">
     60        <h2> UNSproject Credentials</h2>
     61        <div class="row">
     62            <label>Validation Code</label>
     63            <input type="text" readonly="readonly" class="form-control"
     64                   value="<?php echo(isset($siteOption['validationCode']) ? esc_html($siteOption['validationCode']) : ''); ?>"/>
     65        </div>
     66
     67        <div class="row">
     68            <label>Gatekeeper public key</label>
     69            <textarea class="form-control"
     70                      readonly="readonly"><?php echo(isset($siteOption['gatekeeperPublicKey']) ? esc_html($siteOption['gatekeeperPublicKey']) : ''); ?></textarea>
     71        </div>
    2072    </div>
    2173
    22     <div class="row">
    23         <label>Phone Number</label>
    24         <input type="text" readonly="readonly"
    25                value="<?php echo(isset($siteOption['phoneNumber']) ? esc_html($siteOption['phoneNumber']) : ''); ?>"/>
     74
     75    <div class="custom-container bottom-round no-top-border">
     76        <h2>Default Attestations</h2>
     77        <form method="POST" id="default_attestation">
     78            <input type="hidden" name="action" value="update_attestation"/>
     79            <?php
     80            foreach ($attestationTypes as $key => $label) {
     81                ?>
     82                <div class="uns-checkbox-container">
     83                    <input type="checkbox" name="default_attestation_type"
     84                           class="single-checkbox"
     85                           id="attestation_<?php echo $key; ?>"
     86                           value="<?php echo $key; ?>"
     87                        <?php
     88                        echo(
     89                        isset($siteOption['default_attestation_type']) && $siteOption['default_attestation_type'] === $key
     90                        || !isset($siteOption['default_attestation_type']) && $key === UnsApp::DEFAULT_ATTESTATION_TYPE
     91                            ? 'checked="checked"'
     92                            : ''
     93                        ) ?>
     94                    />
     95                    <label for="attestation_<?php echo $key; ?>">
     96                        <?php echo $label; ?>
     97                    </label>
     98                </div>
     99
     100                <?php
     101            }
     102            ?>
     103            <h2>Check authorization interval</h2>
     104            <input
     105                    type="text"
     106                    name="authorization_interval"
     107                    value="<?php echo isset($siteOption['authorization_interval']) ? (int)$siteOption['authorization_interval'] : UnsWordPressAPI::DEFAULT_AUTHORIZATION_INTERVAL ?>"
     108            /> milliseconds
     109            <br/>
     110            <br/>
     111            <button class="btn btn-primary">Save</button>
     112        </form>
    26113    </div>
    27 
    28     <div class="row">
    29         <label>Contact Name</label>
    30         <input type="text" readonly="readonly"
    31                value="<?php echo(isset($siteOption['contactName']) ? esc_html($siteOption['contactName']) : ''); ?>"/>
    32     </div>
    33 
    34     <div class="row">
    35         <label>Public Key</label>
    36         <textarea
    37                 readonly="readonly"><?php echo(isset($siteOption['public_key']) ? esc_html(base64_decode($siteOption['public_key'])) : ''); ?></textarea>
    38     </div>
    39 
    40     <div class="row">
    41         <label>Private Key</label>
    42         <textarea
    43                 readonly="readonly"><?php echo(isset($siteOption['private_key']) ? esc_html(base64_decode($siteOption['private_key'])) : ''); ?></textarea>
    44     </div>
    45 
    46     <div class="row">
    47         <label>Site URL</label>
    48         <input type="text" readonly="readonly"
    49                value="<?php echo(isset($siteOption['site_url']) ? esc_html($siteOption['site_url']) : ''); ?>"/>
    50     </div>
    51 
    52     <div class="row">
    53         <label>Unique ID</label>
    54         <input type="text" readonly="readonly"
    55                value="<?php echo(isset($siteOption['uniqueId']) ? esc_html($siteOption['uniqueId']) : ''); ?>"/>
    56     </div>
    57 
    58     <hr/>
    59 
    60     <h2> UNSproject Credentials</h2>
    61     <div class="row">
    62         <label>Validation Code</label>
    63         <input type="text" readonly="readonly"
    64                value="<?php echo(isset($siteOption['validationCode']) ? esc_html($siteOption['validationCode']) : ''); ?>"/>
    65     </div>
    66 
    67     <div class="row">
    68         <label>Gatekeeper public key</label>
    69         <textarea
    70                 readonly="readonly"><?php echo(isset($siteOption['gatekeeperPublicKey']) ? esc_html($siteOption['gatekeeperPublicKey']) : ''); ?></textarea>
    71     </div>
    72     <hr/>
    73 
    74     <h2>Default Attestations</h2>
    75     <form method="POST" id="default_attestation">
    76         <input type="hidden" name="action" value="update_attestation"/>
    77         <?php
    78         foreach ($attestationTypes as $key => $label) {
    79             ?>
    80             <div class="uns-checkbox-container">
    81                 <input type="checkbox" name="default_attestation_type"
    82                        class="single-checkbox"
    83                        id="attestation_<?php echo $key; ?>"
    84                        value="<?php echo $key; ?>"
    85                     <?php
    86                     echo(
    87                     isset($siteOption['default_attestation_type']) && $siteOption['default_attestation_type'] === $key
    88                     || !isset($siteOption['default_attestation_type']) && $key === UnsApp::DEFAULT_ATTESTATION_TYPE
    89                         ? 'checked="checked"'
    90                         : ''
    91                     ) ?>
    92                 />
    93                 <label for="attestation_<?php echo $key; ?>">
    94                     <?php echo $label; ?>
    95                 </label>
    96             </div>
    97 
    98             <?php
    99         }
    100         ?>
    101         <h2>Check authorization interval</h2>
    102         <input type="text" name="authorization_interval" value="<?php echo isset($siteOption['authorization_interval']) ? (int) $siteOption['authorization_interval'] : UnsWordPressAPI::DEFAULT_AUTHORIZATION_INTERVAL ?>" /> milliseconds
    103         <br/>
    104         <br/>
    105         <button class="uns-button blue-button">Save</button>
    106     </form>
    107114</div>
  • unsproject/trunk/src/Views/error.php

    r2412699 r2496270  
    33    exit;
    44} // Exit if accessed directly
     5/**
     6 * @var string $message;
     7 */
    58?>
    69<div class="error">
  • unsproject/trunk/src/Views/reset_plugin.php

    r2412699 r2496270  
    77    <form method="POST">
    88        <input type="hidden" name="clear" value="123"/>
    9         <input type="submit" value="Clear Plugin data" class="uns-button blue-button"/>
     9        <input type="submit" value="Clear Plugin data" class="btn btn-primary"/>
    1010    </form>
    1111</div>
  • unsproject/trunk/unsproject.php

    r2439247 r2496270  
    33    Plugin Name: UNSProject
    44    Plugin URI: https://www.unsproject.com/
    5     Description: Login to WordPress with UNS PROJECT
     5    Description: UNS Project offers secure private, passwordless, authentication for your WordPress site. The plugin also supports Secure Remote Password (SRP) Authentication. Protect passwords by not storing them on the server.
    66    Author: Nicu Micle
    77    Author URI: https://profiles.wordpress.org/nicu_m/
    88    Text Domain: uns-project
    99    Domain Path: /i18n
    10     Version: 1.1.0
     10    Version: 2.0.0
    1111*/
    1212
     
    1414use UNSProjectApp\FrontEnd;
    1515use UNSProjectApp\Helpers\View;
     16use UNSProjectApp\ServerCall;
    1617use UNSProjectApp\SiteOptions;
     18use UNSProjectApp\SrpService;
    1719use UNSProjectApp\UnsApp;
    1820use UNSProjectApp\UnsAppException;
     
    2830{
    2931
    30     $icon = plugins_url('/images/globe-16-16.png', __FILE__);
     32    $icon = plugins_url('/images/16x16.png', __FILE__);
    3133
    3234    // adding the main menu entry
    33     add_menu_page('UNS PROJECT', 'UNS Project', 'manage_options', 'main-page-unsproject',
    34         'unsproject_plugin_show_main_page', $icon);
     35    add_menu_page(
     36        'UNS PROJECT',
     37        'UNS Project',
     38        'manage_options',
     39        'main-page-unsproject',
     40       'unsproject_plugin_show_main_page',
     41        $icon
     42    );
     43
     44    add_submenu_page(
     45        'main-page-unsproject',
     46        'Secure Remote Password',
     47        'Secure Remote Password',
     48        'manage_options',
     49        'uns_project_srp',function(){
     50            include_once 'src/Views/Srp/home.php';
     51        $srp = new Srp\Srp();
     52        $pluginData = get_plugin_data(__FILE__);
     53        $pluginVersion = isset($pluginData['Version'])
     54            ? $pluginData['Version']
     55            : false;
     56        load_unsproject_backend_scripts_and_styles($pluginVersion);
     57        }
     58    );
    3559}
    3660add_action('admin_menu', 'unsproject_create_menu_entry');
     
    195219        'unsproject-backend-style',
    196220        plugin_dir_url(__FILE__) . 'css/backend.css',
     221        ['uns-project-bootstrap'],
     222        $pluginVersion
     223    );
     224    wp_enqueue_style(
     225        'uns-project-bootstrap',
     226        plugin_dir_url(__FILE__)  . 'css/bootstrap.min.css',
    197227        [],
    198228        $pluginVersion
     
    238268    $database->createTableTickets();
    239269    $database->createUrlTable();
     270    $database->createSRPTable();
    240271    ob_get_clean();
    241272}
     
    254285    $databaseService->deleteTable(DatabaseService::TABLE_URLS);
    255286    $databaseService->deleteTable(DatabaseService::TABLE_TICKETS);
     287    $databaseService->deleteTable(DatabaseService::TABLE_SRP);
    256288}
    257289
     
    262294    load_unsproject_common_scripts_and_styles();
    263295    $fe = new FrontEnd();
    264     return $fe->generateQRCodeViewWithTicketID(FrontEnd::PAGE_LOGIN, true);
    265 }
    266 
    267 add_action('login_message', 'unsproject_login_screen_hook');
     296    echo '<div class="login-form-uns-qr-code-container">';
     297    echo $fe->generateQRCodeViewWithTicketID(FrontEnd::PAGE_LOGIN, true);
     298    echo "</div>";
     299}
     300
     301add_action('login_footer', 'unsproject_login_screen_hook');
    268302
    269303/**
     
    323357
    324358include_once 'apiroutes.php';
     359include_once 'srpactions.php';
Note: See TracChangeset for help on using the changeset viewer.