Plugin Directory

Changeset 3379010


Ignore:
Timestamp:
10/15/2025 03:37:26 PM (3 months ago)
Author:
Hakik
Message:

v1.0.8: * Fix: Security Vulnerability. * Update: Disallow profile.php for temporary users. * Tweak: Loads the scripts only on the plugin settings page. * Removed: load_plugin_textdomain() as this plugin is hosted on WordPress.org, so, it is no longer need to manually include this function call for translations under the plugin slug. WordPress will automatically load the translations as needed.

Location:
create-temporary-login/trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • create-temporary-login/trunk/admin/js/admin.js

    r3083509 r3379010  
    88            url: ctl_admin_ajax_object.ajaxurl,
    99
    10             data: { action: 'ctl_create_link', create_user: "yes", ctl_security: ctl_admin_ajax_object.ctl_nonce_field },
     10            data: {
     11                action: 'ctl_create_link',
     12                create_user: "yes",
     13                ctl_security: ctl_admin_ajax_object.ctl_nonce_field
     14            },
    1115
    1216            beforeSend: function(response) {
  • create-temporary-login/trunk/create-temporary-login.php

    r3295769 r3379010  
    11<?php
    2 /*
    3 Plugin Name:        WPBifröst - Instant Passwordless Temporary Login Links
    4 Plugin URI:         https://github.com/hakikz/create-temporary-login
    5 Description:        Create passwordless temporary login links to easily give access to your site's dashboard.
    6 Version:            1.0.7
    7 Author:             Hakik Zaman
    8 Author URI:         https://profiles.wordpress.org/users/hakik 
    9 License:            GPL v2 or later
    10 License URI:        https://www.gnu.org/licenses/gpl-2.0.html
    11 Text Domain:        create-temporary-login
    12 Domain Path:        /languages
    13 Requires at least:  6.2
    14 Tested up to:       6.8
    15 */
     2/**
     3 * Plugin Name:        WPBifröst - Instant Passwordless Temporary Login Links
     4 * Plugin URI:         https://github.com/hakikz/create-temporary-login
     5 * Description:        Create passwordless temporary login links to easily give access to your site's dashboard.
     6 * Version:            1.0.8
     7 * Author:             Hakik Zaman
     8 * Author URI:         https://profiles.wordpress.org/users/hakik   
     9 * License:            GPL v2 or later
     10 * License URI:        https://www.gnu.org/licenses/gpl-2.0.html
     11 * Text Domain:        create-temporary-login
     12 * Domain Path:        /languages
     13 * Requires at least:  6.2
     14 * Tested up to:       6.8
     15 */
    1616
    17 defined( 'ABSPATH' ) || exit;
     17defined( 'ABSPATH' ) || exit; // Prevent direct access.
    1818
    1919/**
    20  * Defining the constants
     20 * Plugin version constant.
    2121 */
    2222if ( ! defined( 'CTLAZ_TEMP_LOGIN_VERSION' ) ) {
    23     define( 'CTLAZ_TEMP_LOGIN_VERSION', '1.0.7' );
     23    define( 'CTLAZ_TEMP_LOGIN_VERSION', '1.0.8' );
    2424}
    2525
     26/**
     27 * Main plugin file path constant.
     28 */
    2629if ( ! defined( 'CTLAZ_TEMP_LOGIN_FILE' ) ) {
    2730    define( 'CTLAZ_TEMP_LOGIN_FILE', __FILE__ );
     
    2932
    3033/**
    31  * Include the main class.
     34 * Load the core plugin class.
    3235 */
    3336if ( ! class_exists( 'CTLAZ_Create_Temporary_Login', false ) ) {
     
    3538}
    3639
    37 
    3840/**
    39  * Creates a temporary login.
     41 * Initializes the core plugin class.
    4042 *
    41  * @return     <instance>  ( the core class )
     43 * @return CTLAZ_Create_Temporary_Login The singleton instance of the core plugin class.
    4244 */
    4345function ctlaz_create_temporary_login() {
    44 
    4546    return CTLAZ_Create_Temporary_Login::instance();
    4647}
    4748
     49// Boot the plugin after all plugins are loaded.
    4850add_action( 'plugins_loaded', 'ctlaz_create_temporary_login' );
  • create-temporary-login/trunk/includes/class-admin.php

    r3295769 r3379010  
    88class CTLHZ_Admin{
    99
     10    /**
     11     * Holds the singleton instance of the class.
     12     *
     13     * @var CTLHZ_Admin|null
     14     */
    1015    protected static $_instance = null;
    1116
    12 
    13     public static function instance() {
    14         if ( is_null( self::$_instance ) ) {
    15             self::$_instance = new self();
    16         }
    17 
    18         return self::$_instance;
    19     }
    20    
    21     // Construtct [Initial Function]
     17    /**
     18     * Returns the singleton instance of the class.
     19     *
     20     * Ensures only one instance is created throughout the lifecycle of the request.
     21     *
     22     * @return CTLHZ_Admin
     23     */
     24    public static function instance() {
     25        if ( is_null( self::$_instance ) ) {
     26            self::$_instance = new self();
     27        }
     28
     29        return self::$_instance;
     30    }
     31   
     32    /**
     33     * CTLHZ_Admin constructor.
     34     *
     35     * Initializes the plugin by registering necessary hooks.
     36     */
    2237    public function __construct(){
    2338        // Firing Hooks
     
    2641
    2742    /**
    28      * Hooks of the plugin
     43     * Registers all WordPress hooks used by the plugin in the admin area.
     44     *
     45     * This includes:
     46     * - Admin menu setup
     47     * - Script enqueueing
     48     * - AJAX handler for link creation
     49     * - Dashboard redirect
     50     * - Plugin action link
     51     * - Password reset restriction
     52     * - Authentication filtering
     53     * - Admin init redirect logic
    2954     */
    3055    public function hooks(){
     
    4873
    4974    /**
    50      * Settings page
     75     * Adds a submenu page under the "Users" menu in the WordPress admin.
     76     *
     77     * This page allows admins to manage and generate temporary login links.
    5178     */
    5279    public function setting_page(){
     
    6289
    6390    /**
    64      * Enqueue Scripts
     91     * Enqueues admin scripts and styles for the plugin settings page.
     92     *
     93     * Only loads assets on the "Create Temporary Login" admin page.
    6594     */
    6695    public function enqueue_srcipts(){
    67         wp_enqueue_style( 'ctl-admin', plugins_url( '/admin/css/admin.css', CTLAZ_TEMP_LOGIN_FILE ), array(), CTLAZ_TEMP_LOGIN_VERSION, 'all' );
    68         wp_enqueue_script( 'ctl-admin',  plugins_url( '/admin/js/admin.js', CTLAZ_TEMP_LOGIN_FILE ), array('jquery'), CTLAZ_TEMP_LOGIN_VERSION, true );
    69         wp_localize_script( 'ctl-admin', 'ctl_admin_ajax_object', array(
    70             'ajaxurl' => admin_url( 'admin-ajax.php' ),
    71             'ctl_nonce_field' => wp_create_nonce( 'ctl-create-link' )
    72         ) );
    73     }
    74 
    75    
    76     /**
    77      * Sets the header redirect.
     96        $screen = get_current_screen();
     97        if ( $screen && $screen->id === 'users_page_create-temporary-login' ) {
     98            wp_enqueue_style( 'ctl-admin', plugins_url( '/admin/css/admin.css', CTLAZ_TEMP_LOGIN_FILE ), array(), CTLAZ_TEMP_LOGIN_VERSION, 'all' );
     99            wp_enqueue_script( 'ctl-admin',  plugins_url( '/admin/js/admin.js', CTLAZ_TEMP_LOGIN_FILE ), array('jquery'), CTLAZ_TEMP_LOGIN_VERSION, true );
     100            wp_localize_script( 'ctl-admin', 'ctl_admin_ajax_object', array(
     101                'ajaxurl' => admin_url( 'admin-ajax.php' ),
     102                'ctl_nonce_field' => wp_create_nonce( 'ctl-create-link' )
     103            ) );   
     104        }
     105    }
     106
     107   
     108    /**
     109     * Handles redirection based on query string actions.
     110     *
     111     * - Deletes a temporary user if `ctl_delete_link_nonce` and `user_id` are set and valid.
     112     * - Extends a user's temporary login duration if `ctl_extend_link_nonce` is set.
     113     * - Disallow temporary user to access the profile.php
     114     *
     115     * @return void
    78116     */
    79117    public function set_header_redirect(){
     118
    80119        // If found a user_id as a get delete the user
    81         if ( isset($_GET['ctl_delete_link_nonce']) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['ctl_delete_link_nonce'] ) ), 'ctl_delete_link') ){
     120        if (
     121            isset($_GET['ctl_delete_link_nonce']) &&
     122            wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['ctl_delete_link_nonce'] ) ), 'ctl_delete_link') &&
     123            current_user_can( 'manage_options' )
     124        ){
    82125            $delete_user = isset( $_GET['user_id'] ) ? wp_delete_user( sanitize_text_field( wp_unslash( $_GET['user_id'] ) ) ) : false;
    83126            if( $delete_user ){
     
    86129        }
    87130
    88         // If found a user_id as a extend link for the user
    89         if ( isset($_GET['ctl_extend_link_nonce']) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['ctl_extend_link_nonce'] ) ), 'ctl_extend_link') ){
     131        // If found a user_id as an extend link for the user
     132        if (
     133            isset($_GET['ctl_extend_link_nonce']) &&
     134            wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['ctl_extend_link_nonce'] ) ), 'ctl_extend_link') &&
     135            current_user_can( 'manage_options' )
     136        ){
    90137            $extend_link = isset( $_GET['user_id'] ) ? ctlaz_create_temporary_login()->get_option()->extend_expiration( sanitize_text_field( wp_unslash( $_GET['user_id'] ) ) ) : false;
    91138            if( $extend_link ){
     
    93140            }
    94141        }
    95     }
    96 
    97     /**
    98      * Create Temporary Login Interface
     142
     143        // Disallow profile.php for temporary user
     144        global $pagenow;
     145
     146        // Disallow access to profile.php
     147        if ( $pagenow === 'profile.php' ) {
     148            $user_id = get_current_user_id();
     149
     150            // Check for temporary user flag
     151            if ( get_user_meta( $user_id, 'ctl_user', true ) === 'yes' ) {
     152                wp_redirect( admin_url() ); // or use a custom page
     153                exit;
     154            }
     155        }
     156    }
     157
     158    /**
     159     * Renders the plugin's admin page UI for generating and managing temporary login links.
     160     *
     161     * - Only accessible by non-temporary users.
     162     * - Displays a list of all temporary users with options to copy, extend, or delete links.
     163     *
     164     * @return void
    99165     */
    100166    public function create_temporary_login(){
     
    185251   
    186252    /**
    187      * Creates a link.
     253     * Handles AJAX request to create a new temporary user login.
     254     *
     255     * - Generates a unique user with an expiration timestamp.
     256     * - Returns the new user ID if successful.
     257     *
     258     * @return void Outputs user ID or nothing. Dies immediately after output.
    188259     */
    189260    public function create_link(){
    190261
    191         if ( isset( $_POST['create_user'] )
     262        check_ajax_referer( 'ctl-create-link', 'ctl_security' );
     263
     264        if ( !current_user_can( 'manage_options' ) ) {
     265            wp_send_json_error( 'Permission denied.' );
     266            wp_die();
     267        }
     268
     269
     270        if (
     271            isset( $_POST['create_user'] )
    192272            && $_POST['create_user'] === "yes"
    193273        ) {
    194 
    195             check_ajax_referer( 'ctl-create-link', 'ctl_security' );
    196274
    197275            // Getting the site url and passing it to `wp_parse_url` function to get the host name later.
    198276            $url_parse = wp_parse_url( site_url() );
    199277       
     278            $random_str = wp_generate_password( 16, false );
     279
    200280            $uniqid = bin2hex( random_bytes(16) );
     281
    201282            $data = array(
    202                 'user_login'           => sanitize_text_field( 'ctl_user_'.$uniqid ), // the user's login username.
     283                'user_login'           => sanitize_text_field( 'ctl_user_'.$random_str ), // the user's login username. We used a random string for the username. Removed the token from the username.
    203284                'user_pass'            => sanitize_text_field( 'ctl_password_'.$uniqid ), // not necessary to hash password ( The plain-text user password ).
    204285                'user_email'           => sanitize_email( 'ctl_email_' . $uniqid . '@' . $url_parse['host'] ),
     
    211292                )
    212293            );
     294
    213295            $user_id = wp_insert_user( $data );
     296
    214297            if ( ! is_wp_error( $user_id ) ) {
    215298       
     
    225308
    226309    /**
    227      * Redirect to dashboard
     310     * Authenticates a user via a token and redirects to the admin dashboard.
     311     *
     312     * - Matches the `ctl_token` in the URL to a temporary user.
     313     * - Verifies the user has not expired.
     314     * - Sets login cookies and redirects to admin dashboard or home page.
     315     *
     316     * @return void
    228317     */
    229318    public function redirect_to_dashboard(){
     
    233322        if( wp_verify_nonce( $nonce, 'ctl_login_user_nonce' ) && isset($_GET['ctl_token']) ) {
    234323
    235             $user = get_user_by( 'login', sanitize_text_field( "ctl_user_".sanitize_key( $_GET['ctl_token'] ) ) );
     324            // Getting the site url and passing it to `wp_parse_url` function to get the host name later.
     325            $url_parse = wp_parse_url( site_url() );
     326
     327            $user = get_user_by( 'email', sanitize_email( 'ctl_email_' . sanitize_key( $_GET['ctl_token'] ) . '@' . $url_parse['host'] ) );
    236328
    237329            if (
     
    255347   
    256348    /**
    257      * Adding settings menu to the plugin list page
    258      *
    259      * @param      array  $links  The links
    260      *
    261      * @return     array  ( Array of the link to display in plugin list page under the plugin name )
     349     * Adds a "Create Temporary Login" link to the plugin's action links on the plugin list page.
     350     *
     351     * @param array $links Existing plugin action links.
     352     *
     353     * @return array Modified list of plugin action links with the settings link prepended.
    262354     */
    263355    public function login_settings_link($links) {
     
    296388   
    297389    /**
    298      * Disallow Temporary Users to direct login to the site
    299      *
    300      * @param      object   The user
    301      *
    302      * @return     void     ( Sending an error to display for direct login attempt by temporary user )
     390     * Prevents temporary users from resetting their password.
     391     *
     392     * @param bool $allow Whether to allow password reset.
     393     * @param int  $user_ID The ID of the user attempting to reset the password.
     394     *
     395     * @return bool False if the user is a temporary user, unchanged otherwise.
    303396     */
    304397    public function disallow_temporary_user_login( $user ) {
  • create-temporary-login/trunk/includes/class-create-temporary-login.php

    r3089036 r3379010  
    44
    55/**
    6  *
     6 * Main class responsible for bootstrapping the Temporary Login plugin.
     7 *
     8 * Loads dependencies, initializes options and admin classes,
     9 * and hooks into WordPress as needed.
    710 */
    8 class CTLAZ_Create_Temporary_Login{
     11class CTLAZ_Create_Temporary_Login {
    912
    10     protected static $_instance = null;
     13    /**
     14     * The single instance of the class.
     15     *
     16     * @var CTLAZ_Create_Temporary_Login|null
     17     */
     18    protected static $_instance = null;
    1119
    12 
     20    /**
     21     * Main instance method (Singleton pattern).
     22     *
     23     * Ensures only one instance of the class is loaded or can be loaded.
     24     *
     25     * @return CTLAZ_Create_Temporary_Login
     26     */
    1327    public static function instance() {
    1428        if ( is_null( self::$_instance ) ) {
     
    1933    }
    2034
    21     /*
    22      * Construct of the Class.
     35    /**
     36     * Class constructor.
    2337     *
     38     * Includes required files and initializes plugin components.
    2439     */
    25 
    26     public function __construct(){
    27 
     40    public function __construct() {
    2841        $this->includes();
    2942        $this->init();
    30 
    3143    }
    3244
    33     /*
    34      * Includes files.
     45    /**
     46     * Includes required class files for the plugin.
    3547     *
     48     * @return void
    3649     */
    37 
    3850    public function includes() {
    3951        require_once dirname( __FILE__ ) . '/class-option.php';
     
    4153    }
    4254
    43     /*
    44      * Bootstraps the class and hooks required actions & filters.
     55    /**
     56     * Initializes plugin functionality.
    4557     *
     58     * Loads option and admin instances and sets up hooks.
     59     *
     60     * @return void
    4661     */
    4762    public function init() {
    48 
    4963        $this->get_option();
    5064        $this->get_admin();
    5165        $this->set_hooks();
    52     }
    53 
    54     /**
    55      * Sets the hooks.
    56      */
    57     public function set_hooks(){
    58         add_action( 'plugins_loaded', array( $this, 'load_textdomain' ), 10 );
    5966    }
    6067
    6168    /**
    62      * Loads a textdomain.
     69     * Sets up WordPress hooks used by the plugin.
     70     *
     71     * @return void
    6372     */
    64     public function load_textdomain() {
    65         load_plugin_textdomain( 'create-temporary-login', false, basename( dirname( CTLAZ_TEMP_LOGIN_FILE ) )."/languages" );
     73    public function set_hooks() {
     74       
    6675    }
    6776
    6877    /**
     78     * Gets the instance of the plugin option handler.
    6979     *
    70      * Option
    71      *
     80     * @return CTLHZ_Option
    7281     */
    73 
    74     public function get_option(){
     82    public function get_option() {
    7583        return CTLHZ_Option::instance();
    7684    }
    7785
    7886    /**
     87     * Gets the instance of the plugin admin handler.
    7988     *
    80      * Admin
    81      *
     89     * @return CTLHZ_Admin
    8290     */
    83 
    84     public function get_admin(){
     91    public function get_admin() {
    8592        return CTLHZ_Admin::instance();
    8693    }
    87 
    8894}
  • create-temporary-login/trunk/includes/class-option.php

    r3095291 r3379010  
    44
    55/**
    6  *
     6 * Class CTLHZ_Option
     7 *
     8 * Handles temporary user logic such as expiration, identification, and capability control.
    79 */
    8 class CTLHZ_Option{
     10class CTLHZ_Option {
    911
    10     protected static $_instance = null;
     12    /**
     13     * The single instance of the class (Singleton pattern).
     14     *
     15     * @var CTLHZ_Option|null
     16     */
     17    protected static $_instance = null;
    1118
    12 
     19    /**
     20     * Returns the single instance of the class.
     21     *
     22     * @return CTLHZ_Option
     23     */
    1324    public static function instance() {
    1425        if ( is_null( self::$_instance ) ) {
     
    1829        return self::$_instance;
    1930    }
    20    
    21     // Construtct [Initial Function]
    22     public function __construct(){
    23         // Firing Hooks
    24         $this->set_hooks();
    25     }
    2631
    27     /**
    28      * Sets the hooks.
    29      */
    30     public function set_hooks(){
    31         add_action( 'wp_dashboard_setup', array( $this, 'set_temporary_logged_in_user_permission' ), 10 );
    32     }
     32    /**
     33     * Class constructor.
     34     *
     35     * Sets necessary WordPress hooks.
     36     */
     37    public function __construct() {
     38        $this->set_hooks();
     39    }
    3340
    34     /**
    35      * Determines whether the specified user id is temporary user.
    36      *
    37      * @param      int  $user_ID  The user id
    38      *
    39      * @return     bool    True if the specified user id is temporary user, False otherwise.
    40      */
    41     public function is_temporary_user( $user_ID ) : bool {
    42         return (bool) get_user_meta( $user_ID, 'ctl_user', true );
    43     }
     41    /**
     42     * Sets the necessary WordPress hooks.
     43     *
     44     * @return void
     45     */
     46    public function set_hooks() {
     47        add_action( 'wp_dashboard_setup', array( $this, 'set_temporary_logged_in_user_permission' ), 10 );
     48    }
    4449
    45     /**
    46      * Gets the maximum expired time.
    47      *
    48      * @return     int   The maximum expired time.
    49      */
    50     public function get_max_expired_time(): int {
    51         return current_time( 'timestamp' ) + WEEK_IN_SECONDS;
    52     }
     50    /**
     51     * Checks if a user is a temporary user.
     52     *
     53     * @param int $user_ID The user ID.
     54     * @return bool True if the user is temporary, false otherwise.
     55     */
     56    public function is_temporary_user( $user_ID ) : bool {
     57        return (bool) get_user_meta( $user_ID, 'ctl_user', true );
     58    }
    5359
    54     /**
    55      * Determines whether the specified user id is user expired.
    56      *
    57      * @param      int  $user_ID  The user id
    58      *
    59      * @return     bool    True if the specified user id is user expired, False otherwise.
    60      */
    61     public function is_user_expired( $user_ID ): bool {
    62         $expiration = $this->get_expiration( $user_ID );
     60    /**
     61     * Gets the maximum expiration timestamp (7 days from now).
     62     *
     63     * @return int The expiration timestamp.
     64     */
     65    public function get_max_expired_time() : int {
     66        return current_time( 'timestamp' ) + WEEK_IN_SECONDS;
     67    }
    6368
    64         if ( empty( $expiration ) ) {
    65             return true;
    66         }
     69    /**
     70     * Checks if a user's temporary access has expired.
     71     *
     72     * @param int $user_ID The user ID.
     73     * @return bool True if expired, false otherwise.
     74     */
     75    public function is_user_expired( $user_ID ) : bool {
     76        $expiration = $this->get_expiration( $user_ID );
    6777
    68         return current_time( 'timestamp' ) > $expiration;
    69     }
     78        if ( empty( $expiration ) ) {
     79            return true;
     80        }
    7081
    71     /**
    72      * Gets the expiration.
    73      *
    74      * @param      int  $user_ID  The user id
    75      *
    76      * @return     int | bool  Meta ID if the key didn’t exist, true on successful update, false on failure or if the value passed to the function is the same as the one that is already in the database.
    77      */
    78     public function get_expiration( $user_ID ) {
    79         return get_user_meta( $user_ID, 'ctl_expiration', true );
    80     }
     82        return current_time( 'timestamp' ) > $expiration;
     83    }
    8184
    82    
    83    
    84     /**
    85      * Gets the human readable link duration.
    86      *
    87      * @param      int  $user_ID  The user id
    88      *
    89      * @return     mixed  The human readable link duration.
    90      */
    91     public function get_human_readable_link_duration( $user_ID ){
    92         if( $this->is_user_expired( $user_ID ) ){
    93             return esc_html__( 'Expired', 'create-temporary-login' );
    94         }
    95         return sprintf(
    96             /* translators: %s: How many days remaining */
    97              esc_html__( 'Will be expired after:&nbsp;%s', 'create-temporary-login' ),
    98              wp_kses_post( human_time_diff( $this->get_expiration( $user_ID ), current_time('U') ) )
    99          );
    100     }
     85    /**
     86     * Gets the expiration timestamp for a user.
     87     *
     88     * @param int $user_ID The user ID.
     89     * @return int|bool The expiration timestamp or false if not found.
     90     */
     91    public function get_expiration( $user_ID ) {
     92        return get_user_meta( $user_ID, 'ctl_expiration', true );
     93    }
    10194
    102     /**
    103      * Extends the expiration.
    104      *
    105      * @param      <int>  $user_ID  The user id
    106      *
    107      * @return     int | bool    Meta ID if the key didn’t exist, true on successful update, false on failure or if the value passed to the function is the same as the one that is already in the database.
    108      */
    109     public function extend_expiration( $user_ID ) {
    110         $expiration = $this->get_expiration( $user_ID );
     95    /**
     96     * Gets a human-readable expiration message.
     97     *
     98     * @param int $user_ID The user ID.
     99     * @return string Human-readable string showing time until expiration or 'Expired'.
     100     */
     101    public function get_human_readable_link_duration( $user_ID ) {
     102        if ( $this->is_user_expired( $user_ID ) ) {
     103            return esc_html__( 'Expired', 'create-temporary-login' );
     104        }
    111105
    112         if ( empty( $expiration ) ) {
    113             return false;
    114         }
     106        return sprintf(
     107            /* translators: %s: How many days remaining */
     108            esc_html__( 'Will be expired after:&nbsp;%s', 'create-temporary-login' ),
     109            wp_kses_post( human_time_diff( $this->get_expiration( $user_ID ), current_time( 'U' ) ) )
     110        );
     111    }
    115112
    116         if ( $this->is_user_expired( $user_ID ) ) {
    117             $expiration = current_time( 'timestamp' );
    118         }
     113    /**
     114     * Extends a temporary user's expiration by 3 days (up to 7 days max).
     115     *
     116     * @param int $user_ID The user ID.
     117     * @return int|bool Meta ID on success, false on failure.
     118     */
     119    public function extend_expiration( $user_ID ) {
     120        $expiration = $this->get_expiration( $user_ID );
    119121
    120         $expiration += 3 * DAY_IN_SECONDS;
     122        if ( empty( $expiration ) ) {
     123            return false;
     124        }
    121125
    122         $expiration = min( $expiration, $this->get_max_expired_time() );
     126        if ( $this->is_user_expired( $user_ID ) ) {
     127            $expiration = current_time( 'timestamp' );
     128        }
    123129
    124         return update_user_meta( $user_ID, 'ctl_expiration', $expiration );
    125     }
     130        $expiration += 3 * DAY_IN_SECONDS;
    126131
    127    
    128     /**
    129      * Sets the temporary logged in user permission.
    130      */
    131     public function set_temporary_logged_in_user_permission(){
     132        // Cap the expiration to not exceed the max expiration limit (7 days).
     133        $expiration = min( $expiration, $this->get_max_expired_time() );
    132134
    133         if( $this->is_temporary_user( get_current_user_id() ) ){
     135        return update_user_meta( $user_ID, 'ctl_expiration', $expiration );
     136    }
    134137
    135             // Remove a capability from a specific user.
    136             $user = new WP_User( get_current_user_id() );
    137             /**
    138              * @note `list_users` to revoke entire access of the user menus
    139              *
    140              * To print the available capabilities for this current user- `print_r($user->get_role_caps());`
    141              */
    142             $user->add_cap( 'create_users', false );
    143             $user->add_cap( 'list_users', false );
    144             $user->add_cap( 'delete_users', false );
    145             /**
     138    /**
     139     * Restricts permissions and UI for logged-in temporary users.
     140     *
     141     * Removes capabilities and menu pages for better control.
     142     *
     143     * @return void
     144     */
     145    public function set_temporary_logged_in_user_permission() {
     146        if ( $this->is_temporary_user( get_current_user_id() ) ) {
     147            $user = new WP_User( get_current_user_id() );
     148
     149            // Revoke key user management capabilities.
     150            $user->add_cap( 'create_users', false );
     151            $user->add_cap( 'list_users', false );
     152            $user->add_cap( 'delete_users', false );
     153
     154            // Optionally remove menus for temporary users.
     155
     156            /**
    146157             * @note for future use
    147158             * Remove the User menu for temporary users
    148159             * remove_menu_page( 'users.php' );
    149160             */
    150             remove_menu_page( 'users.php' );
    151             remove_menu_page( 'profile.php' );
    152         }
    153        
    154        
    155 
    156     }
     161            remove_menu_page( 'users.php' );
     162            remove_menu_page( 'profile.php' );
     163        }
     164    }
    157165
    158166}
  • create-temporary-login/trunk/index.php

    r3083509 r3379010  
    11<?php
     2/**
     3 * Silence is golden.
     4 *
     5 * Prevents direct access to plugin directory by displaying a simple message.
     6 *
     7 * @package WPBifrost
     8 */
    29
    310echo "Keep silent! You silly Human";
  • create-temporary-login/trunk/languages/create-temporary-login.pot

    r3295769 r3379010  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: WPBifröst - Instant Passwordless Temporary Login Links 1.0.7\n"
     5"Project-Id-Version: WPBifröst - Instant Passwordless Temporary Login Links 1.0.8\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/create-temporary-login\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2025-05-18T08:17:13+00:00\n"
     12"POT-Creation-Date: 2025-10-15T08:22:19+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.11.0\n"
     
    4040msgstr ""
    4141
    42 #: includes/class-admin.php:119
     42#: includes/class-admin.php:185
    4343msgid "WPBifröst - Settings (Instant Passwordless Temporary Login Links)"
    4444msgstr ""
    4545
    46 #: includes/class-admin.php:121
     46#: includes/class-admin.php:187
    4747msgid "Generate a link"
    4848msgstr ""
    4949
    50 #: includes/class-admin.php:160
     50#: includes/class-admin.php:226
    5151msgid "Delete"
    5252msgstr ""
    5353
    54 #: includes/class-admin.php:162
     54#: includes/class-admin.php:228
    5555msgid "Copied"
    5656msgstr ""
    5757
    58 #: includes/class-admin.php:166
     58#: includes/class-admin.php:232
    5959msgid "Extend 3 days"
    6060msgstr ""
    6161
    62 #: includes/class-admin.php:175
     62#: includes/class-admin.php:241
    6363msgid "Click to Copy!"
    6464msgstr ""
    6565
    66 #: includes/class-admin.php:271
     66#: includes/class-admin.php:363
    6767msgid "Create Temporary Login"
    6868msgstr ""
    6969
    70 #: includes/class-admin.php:308
     70#: includes/class-admin.php:401
    7171msgid "<strong>Error:</strong> The username is not registered on this site. If you are unsure of your username, try your email address instead."
    7272msgstr ""
    7373
    74 #: includes/class-option.php:93
     74#: includes/class-option.php:103
    7575msgid "Expired"
    7676msgstr ""
    7777
    7878#. translators: %s: How many days remaining
    79 #: includes/class-option.php:97
     79#: includes/class-option.php:108
    8080msgid "Will be expired after:&nbsp;%s"
    8181msgstr ""
  • create-temporary-login/trunk/readme.txt

    r3295769 r3379010  
    55Requires at least: 6.2
    66Tested up to: 6.8
    7 Stable tag: 1.0.7
     7Stable tag: 1.0.8
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    8989== Changelog ==
    9090
     91= 1.0.8 =
     92* Fix: Security Vulnerability.
     93* Update: Disallow profile.php for temporary users.
     94* Tweak: Loads the scripts only on the plugin settings page.
     95* Removed: `load_plugin_textdomain()` as this plugin is hosted on WordPress.org, so, it is no longer need to manually include this function call for translations under the plugin slug. WordPress will automatically load the translations as needed.
     96
    9197= 1.0.7 =
    9298* Fix: Show Toolbar when viewing site.
  • create-temporary-login/trunk/uninstall.php

    r3095291 r3379010  
    11<?php
     2/**
     3 * Uninstall script for WPBifröst - Instant Passwordless Temporary Login Links plugin.
     4 *
     5 * This script deletes all temporary users created by the plugin when it is uninstalled.
     6 *
     7 * @package    WPBifrost
     8 * @subpackage Uninstall
     9 */
    210
    3 // if uninstall.php is not called by WordPress, die
    4 if (!defined('WP_UNINSTALL_PLUGIN')) {
    5     die;
     11// If uninstall.php is not called by WordPress, exit.
     12if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
     13    exit;
    614}
    715
    8 // Get all users
     16// Get all users.
    917$ctl_users = get_users();
    1018
    11 foreach ($ctl_users as $key => $user) {
    12     //Getting only ctl users
    13     if( get_user_meta( $user->ID, 'ctl_user', true ) ){
    14         wp_delete_user( sanitize_text_field( $user->ID ) );
    15     }
     19foreach ( $ctl_users as $user ) {
     20    // Check if user is a temporary login user created by the plugin.
     21    if ( get_user_meta( $user->ID, 'ctl_user', true ) ) {
     22        wp_delete_user( intval( $user->ID ) );
     23    }
    1624}
    17  
Note: See TracChangeset for help on using the changeset viewer.