├── uninstall.php ├── README.md ├── LICENSE └── plugin.php /uninstall.php: -------------------------------------------------------------------------------- 1 | = 1.7.3`. 5 | 6 | Description 7 | ----------- 8 | The *Password Protection* plugin will give you the ability to password protect any short URL you want (*passwords are set individually*)! The plugin will prompt the user for a password before redircting them! 9 | 10 | Installation 11 | ------------ 12 | 1. In `/user/plugins`, create a new folder named `password-protection`. 13 | 2. Drop these files in that directory. 14 | 3. Go to the plugins administration page ( *eg* `http://sho.rt/admin/plugins.php` ) and activate the plugin. 15 | 3. Configure the plugin ( *eg* `http://sho.rt/admin/plugins.php?page=matthew_pwp` )! 16 | 4. Have fun! 17 | 18 | Example 19 | ------- 20 | ![Password Manager Example](https://mateoc.net/b_plugin/yourls_PasswordProtection/yourlsPasswordManager-1.1.gif "Password Manager Example") 21 | 22 | License 23 | ------- 24 | [MIT](LICENSE) 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Matthew Ghost 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /plugin.php: -------------------------------------------------------------------------------- 1 | alertify.error(\"Incorrect Password, try again\")" : ""); 44 | $matthew_ppu = yourls__( "Password Protected URL", "matthew_pwp" ); // Translate Password Title 45 | $matthew_ph = yourls__( "Password" , "matthew_pwp" ); // Translate the word Password 46 | $matthew_sm = yourls__( "Please enter the password below to continue.", "matthew_pwp" ); // Translate the main message 47 | $matthew_submit = yourls__( "Send!" , "matthew_pwp" ); // Translate the Submit button 48 | // Displays main "Insert Password" area 49 | echo << 51 | 52 | Redirection Notice 53 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 |
179 |
180 |
181 |
182 |

183 |

184 |
185 |
186 |
187 |
188 | $error 189 | 190 | 191 | PWP; 192 | die(); 193 | } 194 | } 195 | } 196 | 197 | // Register plugin page in admin page 198 | yourls_add_action( 'plugins_loaded', 'matthew_pwprotection_display_panel' ); 199 | function matthew_pwprotection_display_panel() { 200 | yourls_register_plugin_page( 'matthew_pwp', 'Password Protection', 'matthew_pwprotection_display_page' ); 201 | } 202 | 203 | // Function which will draw the admin page 204 | function matthew_pwprotection_display_page() { 205 | if( isset( $_POST[ 'checked' ] ) && isset( $_POST[ 'password' ] ) || isset( $_POST[ 'unchecked' ] ) ) { 206 | matthew_pwprotection_process_new(); 207 | matthew_pwprotection_process_display(); 208 | } else { 209 | if(yourls_get_option('matthew_pwprotection') !== false){ 210 | yourls_add_option( 'matthew_pwprotection', 'null' ); 211 | } 212 | matthew_pwprotection_process_display(); 213 | } 214 | } 215 | 216 | // Set/Delete password from DB 217 | function matthew_pwprotection_process_new() { 218 | // Verify nonce token. 219 | yourls_verify_nonce( "matthew_pwprotection_update" ); 220 | 221 | $matthew_pwprotection_array = json_decode(yourls_get_option('matthew_pwprotection'), true); 222 | 223 | foreach( $_POST[ 'password' ] as $url => $url_password) { 224 | if($url_password != "DONOTCHANGE_8fggwrFrRXvqndzw") { 225 | $_POST[ 'password' ][ $url ] = password_hash($url_password, PASSWORD_BCRYPT); 226 | } else { 227 | $_POST[ 'password' ][ $url ] = $matthew_pwprotection_array[ $url ]; 228 | } 229 | } 230 | 231 | // Update database 232 | yourls_update_option( 'matthew_pwprotection', json_encode( $_POST[ 'password' ] ) ); 233 | 234 | echo "

Success!

"; 235 | } 236 | 237 | // Display Form 238 | function matthew_pwprotection_process_display() { 239 | $ydb = yourls_get_db(); 240 | 241 | // get limit and offset for pagination 242 | $limit = 50; 243 | $offset = @$_GET['p']; 244 | if ($offset == NULL){ 245 | $offset = 0; 246 | }else{ 247 | if ((int)$offset < 0){ 248 | $offset = 1; 249 | } 250 | $offset = ((int)$offset - 1) * $limit; 251 | } 252 | 253 | $where = '1=1'; 254 | $binds = array( 255 | 'limit'=> $limit, 256 | 'offset'=> $offset, 257 | ); 258 | 259 | $short_url_to_filter = @$_GET['q']; 260 | if ($short_url_to_filter != NULL && strlen($short_url_to_filter)>0){ 261 | $where = 'keyword LIKE :keyword'; 262 | $binds['keyword'] = '%'.$short_url_to_filter.'%'; 263 | } 264 | 265 | $table = YOURLS_DB_TABLE_URL; 266 | $sql = "SELECT * FROM `$table` WHERE $where LIMIT :limit OFFSET :offset"; 267 | 268 | $query = $ydb->fetchAll($sql, $binds); 269 | 270 | $matthew_su = yourls__( "Short URL" , "matthew_pwp" ); // Translate "Short URL" 271 | $matthew_ou = yourls__( "Original URL", "matthew_pwp" ); // Translate "Original URL" 272 | $matthew_pw = yourls__( "Password" , "matthew_pwp" ); // Translate "Password" 273 | 274 | // Protect action with nonce 275 | $matthew_pwprotection_noncefield = yourls_nonce_field( "matthew_pwprotection_update" ); 276 | 277 | echo << 279 | table { 280 | border-collapse: collapse; 281 | width: 100%; 282 | } 283 | 284 | th, td { 285 | text-align: left; 286 | padding: 8px; 287 | } 288 | 289 | tr:nth-child(even){background-color: #f2f2f2} 290 | tr:nth-child(odd){background-color: #fff} 291 | 292 |
293 |
294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | TB; 304 | 305 | foreach( $query as $link ) { // Displays all shorturls in the YOURLS DB 306 | $short = $link["keyword"]; 307 | $url = $link["url"]; 308 | $matthew_pwprotection_array = json_decode(yourls_get_option('matthew_pwprotection'), true); // Get array of currently active Password Protected URLs 309 | if( strlen( $url ) > 51 ) { // If URL is too long, shorten it with '...' 310 | $sURL = substr( $url, 0, 30 ). "..."; 311 | } else { 312 | $sURL = $url; 313 | } 314 | if( array_key_exists( $short, (array)$matthew_pwprotection_array ) ){ // Check if URL is currently password protected or not 315 | $text = yourls__( "Enable?" ); 316 | $password = "DONOTCHANGE_8fggwrFrRXvqndzw"; 317 | $checked = " checked"; 318 | $unchecked = ''; 319 | $style = ''; 320 | $disabled = ''; 321 | } else { 322 | $text = yourls__( "Enable?" ); 323 | $password = ''; 324 | $checked = ''; 325 | $unchecked = ' disabled'; 326 | $style = 'display: none'; 327 | $disabled = ' disabled'; 328 | } 329 | 330 | echo <<
$matthew_su$matthew_ou$matthew_pw
332 | 333 | 334 | 339 | 340 | TABLE; 341 | } 342 | 343 | $current_page = $offset/$limit+1; 344 | $previous_page = $current_page-1; 345 | $next_page = $current_page+1; 346 | $total_data = count($query); 347 | 348 | echo << 350 | $matthew_pwprotection_noncefield 351 | 352 | 353 |

354 | 355 | 356 | 440 | END; 441 | } 442 | ?> 443 | --------------------------------------------------------------------------------
$short$sURL 335 | $text 336 | 337 |
338 |