From 6c3bb82368b3413e2e170d4c4a31458da1ea6c13 Mon Sep 17 00:00:00 2001 From: ozhozh Date: Sat, 9 Oct 2010 11:41:41 +0000 Subject: [PATCH] Massive commit - renamed index_ajax.php to admin-ajax.php: name more accurate, no underscore to avoid error with htaccess RewriteCond (wtf?) - renamed all parameters "mode" to "action" - added nonces to Add, Edit, Save, Delete buttons. Fixes issue 425. - changed behavior & args of yourls_verify_nonce() - cosmetic tweak in CSS (edit row bg color) - new function: yourls_site_url() to return YOURLS_SITE with http(s) preference - comply to SSL pref when loading ressources. Fixes issue 512. - Ajax URL now echoed in head, complying to SSL pref git-svn-id: http://yourls.googlecode.com/svn/trunk@511 12232710-3e20-11de-b438-597f59cd7555 --- admin/{index_ajax.php => admin-ajax.php} | 15 ++++++-- admin/plugins.php | 2 +- css/style.css | 2 +- includes/functions-auth.php | 2 +- includes/functions-html.php | 48 +++++++++++++----------- includes/functions.php | 47 ++++++++++++++++++----- js/common.js | 29 +++++++++++++- js/insert.js | 40 +++++++++++++++----- 8 files changed, 137 insertions(+), 48 deletions(-) rename admin/{index_ajax.php => admin-ajax.php} (62%) diff --git a/admin/index_ajax.php b/admin/admin-ajax.php similarity index 62% rename from admin/index_ajax.php rename to admin/admin-ajax.php index 69975e6..372bfe4 100644 --- a/admin/index_ajax.php +++ b/admin/admin-ajax.php @@ -7,25 +7,33 @@ // This file will output a JSON string header('Content-type: application/json'); +if( !isset( $_REQUEST['action'] ) ) + die(); + // Pick action -switch( stripslashes($_REQUEST['mode']) ) { +$action = $_REQUEST['action']; +switch( $action ) { case 'add': + yourls_verify_nonce( 'add_url', $_REQUEST['nonce'], false, 'omg error' ); $return = yourls_add_new_link( $_REQUEST['url'], $_REQUEST['keyword'] ); echo json_encode($return); break; case 'edit_display': + yourls_verify_nonce( 'edit-link_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' ); $row = yourls_table_edit_row ( $_REQUEST['keyword'] ); echo json_encode( array('html' => $row) ); break; case 'edit_save': + yourls_verify_nonce( 'edit-save_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' ); $return = yourls_edit_link( $_REQUEST['url'], $_REQUEST['keyword'], $_REQUEST['newkeyword'], $_REQUEST['title'] ); echo json_encode($return); break; case 'delete': + yourls_verify_nonce( 'delete-link_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' ); $query = yourls_delete_link_by_keyword( $_REQUEST['keyword'] ); echo json_encode(array('success'=>$query)); break; @@ -36,7 +44,8 @@ break; default: - die('Not implemented'); + yourls_do_action( 'yourls_ajax_'.$action ); } -?> \ No newline at end of file + +die(); diff --git a/admin/plugins.php b/admin/plugins.php index f75793a..b498b58 100644 --- a/admin/plugins.php +++ b/admin/plugins.php @@ -12,7 +12,7 @@ if( isset( $_GET['action'] ) ) { // Check nonce - yourls_verify_nonce( 'manage_plugins' ); + yourls_verify_nonce( 'manage_plugins', $_REQUEST['nonce'] ); // Check plugin file is valid if( isset( $_GET['plugin'] ) && yourls_validate_plugin_file( YOURLS_PLUGINDIR.'/'.$_GET['plugin'].'/plugin.php') ) { diff --git a/css/style.css b/css/style.css index 711b475..2be4ff4 100644 --- a/css/style.css +++ b/css/style.css @@ -94,7 +94,7 @@ input.text:focus, textarea:focus { margin:0px; } tr.edit-row td { - background:#a9f6ff !important; + background:#e3f3ff !important; } #new_url { text-align:center; diff --git a/includes/functions-auth.php b/includes/functions-auth.php index 07131e1..7518101 100644 --- a/includes/functions-auth.php +++ b/includes/functions-auth.php @@ -7,7 +7,7 @@ function yourls_is_valid_user() { return true; // Logout request - if( isset( $_GET['mode'] ) && $_GET['mode'] == 'logout') { + if( isset( $_GET['action'] ) && $_GET['action'] == 'logout') { yourls_store_cookie( null ); return 'Logged out successfully'; } diff --git a/includes/functions-html.php b/includes/functions-html.php index 8cc81d4..2ca3b64 100644 --- a/includes/functions-html.php +++ b/includes/functions-html.php @@ -6,7 +6,7 @@ function yourls_html_logo() { ?>

YOURLS: Your Own URL Shortener
- YOURLS
+ YOURLS

<?php echo $title ?> - + - - - - - + + + + + - - + + - - + + - + - - - - + + + + - - + + + @@ -126,6 +131,7 @@ function yourls_html_addnew( $url = '', $keyword = '' ) {
Enter the URL: Optional: Custom short URL: +
@@ -308,7 +314,7 @@ function yourls_html_link( $href, $title = '', $element = '' ) { function yourls_login_screen( $error_msg = '' ) { yourls_html_head( 'login' ); - $action = ( isset($_GET['mode']) && $_GET['mode'] == 'logout' ? '?' : '' ); + $action = ( isset($_GET['action']) && $_GET['action'] == 'logout' ? '?' : '' ); yourls_html_logo(); ?> @@ -343,14 +349,14 @@ function yourls_html_menu() { ?> diff --git a/includes/functions.php b/includes/functions.php index 468d614..cb3cf86 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -229,9 +229,15 @@ function yourls_table_edit_row( $keyword ) { $safe_title = stripslashes( $title ); $www = YOURLS_SITE; + $save_link = yourls_nonce_url( 'save-link_'.$id, + yourls_add_query_arg( array( 'id' => $id, 'action' => 'edit_save', 'keyword' => $keyword ), yourls_admin_url( 'admin-ajax.php' ) ) + ); + + $nonce = yourls_create_nonce( 'edit-save_'.$id ); + if( $url ) { $return = <<Original URL: Short URL: $www/
Title:   +Original URL: Short URL: $www/
Title:   RETURN; } else { $return = 'Error, URL not found'; @@ -268,8 +274,18 @@ function yourls_table_add_row( $keyword, $url, $title = '', $ip, $clicks, $times $display_link = "$display_url"; } + $delete_link = yourls_nonce_url( 'delete-link_'.$id, + yourls_add_query_arg( array( 'id' => $id, 'action' => 'delete', 'keyword' => $keyword ), yourls_admin_url( 'admin-ajax.php' ) ) + ); + + $edit_link = yourls_nonce_url( 'edit-link_'.$id, + yourls_add_query_arg( array( 'id' => $id, 'action' => 'edit', 'keyword' => $keyword ), yourls_admin_url( 'admin-ajax.php' ) ) + ); + + + $actions = <<StatsShareEditDelete +StatsShareEditDelete ACTION; $actions = yourls_apply_filter( 'action_links', $actions, $keyword, $url, $ip, $clicks, $timestamp ); @@ -1518,22 +1534,21 @@ function yourls_nonce_url( $action, $url = false, $name = 'nonce', $user = false return yourls_add_query_arg( $name, $nonce, $url ); } -// Check validity of a nonce (ie time span, user and action match). Returns true or dies. -// $nonce is the name of the GET or POST parameter -function yourls_verify_nonce( $action, $nonce = 'nonce', $user = false ) { +// Check validity of a nonce (ie time span, user and action match). +// Returns true if valid, dies otherwise (yourls_die() or die($return) if defined) +function yourls_verify_nonce( $action, $nonce, $user = false, $return = '' ) { // get user if( false == $user ) $user = defined('YOURLS_USER') ? YOURLS_USER : '-1'; // what nonce should be - $valid = yourls_create_nonce( $action, $user ); - - // what nonce is - $nonce = isset($_REQUEST[$nonce]) ? $_REQUEST[$nonce] : false; + $valid = yourls_create_nonce( $action, $user ); if( $nonce == $valid ) { return true; } else { + if( $return ) + die( $return ); yourls_die( 'Unauthorized action or expired link', 'Error', 403 ); } } @@ -1578,7 +1593,7 @@ function yourls_is_infos() { // Check if we'll need interface display function (ie not API or redirection) function yourls_has_interface() { - if( yourls_is_API() or yourls_is_GO() or yourls_is_Ajax() ) + if( yourls_is_API() or yourls_is_GO() ) return false; return true; } @@ -1610,6 +1625,18 @@ function yourls_admin_url( $page = '' ) { return yourls_apply_filter( 'admin_url', $admin, $page ); } +// Return YOURLS_SITE, with SSL preference +function yourls_site_url( $echo = true ) { + $site = YOURLS_SITE; + // Do not enforce (checking yourls_need_ssl() ) but check current usage so it won't force SSL on non-admin pages + if( yourls_is_ssl() ) + $site = str_replace( 'http://', 'https://', $site ); + $site = yourls_apply_filter( 'site_url', $site ); + if( $echo ) + echo $site; + return $site; +} + // Check if SSL is used, returns bool. Stolen from WP. function yourls_is_ssl() { $is_ssl = false; diff --git a/js/common.js b/js/common.js index 9a7c19f..8021354 100644 --- a/js/common.js +++ b/js/common.js @@ -39,8 +39,8 @@ function feedback(msg, type, delay) { function logout() { $.ajax({ type: "POST", - url: "index_ajax.php", - data: {mode:'logout'}, + url: ajaxurl, + data: {action:'logout'}, success: function() { window.parent.location.href = window.parent.location.href; } @@ -72,6 +72,31 @@ function trim_long_string( string, length) { return newstring; } +// Get the var=xxx from a query string +function get_var_from_query( url, varname, default_val ) { + if( varname == undefined ) { + varname = 'nonce'; + } + if( default_val == undefined ) { + default_val = ''; + } + + try{ + url = url.split('?')[1].split('&').reverse().filter(function(e){ + var pair = e.split('='); + return( pair[0] == varname ); + })[0].split('=')[1]; + // weeeeeeee + // split the query string on '&', reverse to check last pairs first so that ?ozh=1&ozh=2 matches ozh=2 first + // then filter on each pair to find the matching 'varname=something', + // which is then returned in a one element array that we split on '=' and take second part. woot! + } catch(err) { + return default_val; + } + + return url; +} + /** * Jquery Cookie plugin * Copyright (c) 2006 Klaus Hartl (stilbuero.de) diff --git a/js/insert.js b/js/insert.js index ae2da49..eb8346b 100644 --- a/js/insert.js +++ b/js/insert.js @@ -8,21 +8,31 @@ $(document).ready(function(){ $('input.text').focus(function(){ $(this).select(); - }); + }); + // this one actually has little impact, the .hasClass('disabled') in each edit(), remove() etc... fires faster + $('a.button').live('click', function() { + if( $(this).hasClass('disabled') ) { + return false; + } + }); }); // Create new link and add to table function add() { + if( $('#add-button').hasClass('disabled') ) { + return false; + } var newurl = $("#add-url").val(); + var nonce = $("#nonce-add").val(); if ( !newurl || newurl == 'http://' || newurl == 'https://' ) { return; } var keyword = $("#add-keyword").val(); add_loading("#add-button"); $.getJSON( - "index_ajax.php", - {mode:'add', url: newurl, keyword: keyword}, + ajaxurl, + {action:'add', url: newurl, keyword: keyword, nonce: nonce}, function(data){ if(data.status == 'success') { $('#main_table tbody').prepend( data.html ).trigger("update"); @@ -56,11 +66,15 @@ function toggle_share_fill_boxes( url, shorturl, title ) { // Display the edition interface function edit(id) { + if( $('#edit-button-'+id).hasClass('disabled') ) { + return false; + } add_loading('#actions-'+id+' .button'); var keyword = $('#keyword_'+id).val(); + var nonce = get_var_from_query( $('#edit-button-'+id).attr('href'), 'nonce' ); $.getJSON( - "index_ajax.php", - { mode: "edit_display", keyword: keyword }, + ajaxurl, + { action: "edit_display", keyword: keyword, nonce: nonce, id: id }, function(data){ $("#id-" + id).after( data.html ); $("#edit-url-"+ id).focus(); @@ -71,13 +85,17 @@ function edit(id) { // Delete a link function remove(id) { + if( $('#delete-button-'+id).hasClass('disabled') ) { + return false; + } if (!confirm('Really delete?')) { return; } var keyword = $('#keyword_'+id).val(); + var nonce = get_var_from_query( $('#delete-button-'+id).attr('href'), 'nonce' ); $.getJSON( - "index_ajax.php", - { mode: "delete", keyword: keyword }, + ajaxurl, + { action: "delete", keyword: keyword, nonce: nonce, id: id }, function(data){ if (data.success == 1) { $("#id-" + id).fadeOut(function(){ @@ -115,10 +133,11 @@ function edit_save(id) { var newkeyword = $("#edit-keyword-" + id).val(); var title = $("#edit-title-" + id).val(); var keyword = $('#old_keyword_'+id).val(); + var nonce = $('#nonce_'+id).val(); var www = $('#yourls-site').val(); $.getJSON( - "index_ajax.php", - {mode:'edit_save', url: newurl, keyword: keyword, newkeyword: newkeyword, title: title }, + ajaxurl, + {action:'edit_save', url: newurl, id: id, keyword: keyword, newkeyword: newkeyword, title: title, nonce: nonce }, function(data){ if(data.status == 'success') { @@ -173,6 +192,9 @@ function decrement() { // Toggle Share box function toggle_share(id) { + if( $('#share-button-'+id).hasClass('disabled') ) { + return false; + } var link = $('#url-'+id+' a:first'); var longurl = link.attr('href'); var title = link.attr('title'); -- 2.45.0