CVE-2015-10102: URL Redirection to Untrusted Site ('Open Redirect') (CWE-601)
value: A vulnerability, which was classified as critical, has been found in Freshdesk Plugin 1.7 on WordPress. Affected by this issue is some unknown functionality. The manipulation leads to open redirect. The attack may be launched remotely. Upgrading to version 1.8 is able to address this issue. The patch is identified as 2aaecd4e0c7c6c1dc4e6a593163d5f7aa0fa5d5b. It is recommended to upgrade the affected component. VDB-226118 is the identifier assigned to this vulnerability.
CWE description: A web application accepts a user-controlled input that specifies a link to an external site, and uses that link in a Redirect. This simplifies phishing attacks.
CVSS v3 base score: 6.1
Published: 2023-04-17T18:15Z
Repository: https://github.com/wp-plugins/freshdesk-support
Language: PHP
Files changed: css/freshdesk_plugin.css, freshdesk-ext.php, freshdesk-plugin-api.php, js/freshdesk_plugin_js.js, readme.txt
Commit date: 2015-06-05 12:07:27 +0000
Commit message: Security fix for open redirect vulnerability

git-svn-id: https://plugins.svn.wordpress.org/freshdesk-support/trunk@1175214 b8457f37-d9ea-0310-8a92-e5e31aec5664

Diff: diff --git a/css/freshdesk_plugin.css b/css/freshdesk_plugin.css
new file mode 100644
index 0000000..f589c6f
--- /dev/null
+++ b/css/freshdesk_plugin.css
@@ -0,0 +1,87 @@
+.info-data{
+	color: #888; 
+	font-size: 13px;
+	width:50%;
+	padding-top: 3px;
+}
+.fd_lmargin{
+	margin-left: 25px;
+}
+.fd_button{
+	float: left;
+}
+.fd_ui_element{
+		padding: 5px 5px;
+		border-radius: 4px;
+		font-size: 13px;
+		font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+}
+.fd-code {
+	padding: 6px 11px;
+	background: none repeat scroll 0 0 #EEEEEE;
+  border: 1px solid #DDDDDD;
+  border-radius: 4px;
+  font-weight: 13px;
+}
+.wrap{
+		font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+}
+.fd-form-table{
+	padding:0px;
+	margin:0px;
+}
+.fd-form-table li{
+	margin:0px;
+}
+.form-table th{
+	width:120px;
+	padding-bottom: 5px;
+	padding-top: 10px;
+}
+.form-table td{
+	padding-bottom: 5px;
+	padding-top: 5px;
+}
+.form-table tr{
+	padding:5px;
+	font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+}
+.fd_text{
+	width:60%;
+}
+.form-table li{
+	list-style: none;
+	padding-top: 5px;
+	padding-bottom: 5px;
+}
+.info-title{
+	margin-bottom: 5px;
+	font-weight: 500;
+	font-size: 90%;
+}
+.fd-content{
+	margin-top: 0px;
+}
+.fd-bold{
+	font-weight: bold;
+}
+input[type='checkbox']{
+	margin: 2px 5px 0px 0px;
+}
+
+#adminmenu .menu-icon-generic.toplevel_page_freshdesk-menu-handle div.wp-menu-image{
+	left: 10px;
+  position: relative;
+  top: 8px;
+ 	background: transparent url('../images/fd-menulogog.png') no-repeat !important;
+}
+#adminmenu .menu-icon-generic.toplevel_page_freshdesk-menu-handle a:hover div.wp-menu-image{
+	background: transparent url('../images/fd-menulogob.png') no-repeat !important;
+}
+#adminmenu .menu-icon-generic.toplevel_page_freshdesk-menu-handle a.current div.wp-menu-image{
+	background: transparent url('../images/fd-menulogow.png') no-repeat !important;
+}
+
+#adminmenu .menu-icon-generic.toplevel_page_freshdesk-menu-handle div.wp-menu-image:before{
+	content : "";
+}
\ No newline at end of file
diff --git a/freshdesk-ext.php b/freshdesk-ext.php
new file mode 100644
index 0000000..fce426f
--- /dev/null
+++ b/freshdesk-ext.php
@@ -0,0 +1,410 @@
+<?php
+/*
+  @package Freshdesk Official
+  @version 1.8
+*/
+/*
+  Plugin Name: Freshdesk Official
+  Plugin URI: 
+  Description: Freshdesk Official is a seamless way to add your helpdesk account to your website. Supports various useful functions.
+  Author: hjohnpaul,sathishfreshdesk,balakumars,shreyasns
+  Version: 1.8
+  Author URI: http://freshdesk.com/
+*/
+
+
+if ( ! defined( 'ABSPATH' ) ) {
+	die(); //Die if accessed directly.
+}
+
+#include freshdesk api class.
+define( 'FD_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
+define( 'FD_PAGE_BASENAME', 'freshdesk-menu-handle' );
+define( 'DOMAIN_REGEX', '/\bhttps?:\/\/([-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|])/i' );
+require_once( plugin_dir_path( __FILE__ ) . 'freshdesk-plugin-api.php' );
+
+add_action( 'init', 'fd_login' ); //Sso handler and comment action handler
+add_action( 'admin_menu', 'freshdesk_plugin_menu' ); //Plugin Menu
+add_filter( 'comment_row_actions', 'freshdesk_comment_action', 10, 2 ); // This adds the comment action menu.
+add_action( 'wp_ajax_fd_ticket_action', 'fd_action_callback' ); // This is the ajax action handler
+add_filter( 'login_redirect', 'fd_login_redirect', 10, 3 ); // This is used to redirect to Freshdesk on SSO.
+add_filter( 'login_message', "show_login_message" );
+// admin messages hook!
+add_action( 'admin_notices', 'freshdesk_admin_msgs' );
+?>
+<?php
+function show_login_message() {
+	$freshdesk_options= get_option('freshdesk_options');
+	if ( $freshdesk_options['freshdesk_enable_sso'] != 'checked' && $_GET['action'] == 'freshdesk-login' ){
+		//ToDO change the login message
+		return "<div style='padding:12px;border-left:4px solid #feba11; background:#fff; margin-bottom:4px'>We are not able to log you in, please contact your Wordpress administrator to enable SSO in your account.</div>";
+	}
+}
+function fd_login_redirect( $url, $request, $user ) {
+	parse_str( $request, $params );
+	$fd_redirect_to = $params['fd_redirect_to'];
+	if ( ! $fd_redirect_to ) {
+		return $url;
+	}
+	$redirect_url = get_redirect_url( $fd_redirect_to );
+
+	// For handling Redirect to Freshdesk on login.
+	if ( $_REQUEST['wp-submit'] == "Log In" && is_a( $user, 'WP_User' ) && $redirect_url ) {
+		$freshdesk_options = get_option( 'freshdesk_options' );		
+		
+		$user_name = $user->data->display_name;
+		$secret = $freshdesk_options['freshdesk_sso_key'];
+		$data = $user_name.$user->data->user_email.time();
+		$hash_key = hash_hmac("md5", $data, $secret);
+		$ssl_url = $redirect_url."/login/sso?name=".urlencode($user->data->display_name)."&email=".urlencode($user->data->user_email)."&timestamp=".time()."&hash=".urlencode($hash_key);
+		sleep(1); // holding a bit so that it falls within FD 30 mins bar.
+		header("Location: ".$ssl_url);
+		die();
+	}
+	return  $request;
+}
+
+function get_redirect_url($host_url) {
+	$freshdesk_options = get_option( 'freshdesk_options' );
+
+	//Stripping protocols from urls to match the host url correctly.
+	$host_url = preg_replace( DOMAIN_REGEX, "$1", trim($host_url) );
+	$domains = split( ",", $freshdesk_options['freshdesk_cname'] );
+	array_push( $domains, $freshdesk_options['freshdesk_domain_url'] );
+
+	//Checking the host url against the provided helpdesk/portal url to avoid Open-redirect vulnerability
+	foreach ( $domains as $domain ) {
+		$domain = trim($domain);
+		$url = preg_replace( DOMAIN_REGEX, "$1", $domain);
+		if ( $url == $host_url ) {
+			return $domain;
+		}
+	}
+}
+function freshdesk_plugin_menu() {
+	add_menu_page( 'Freshdesk Settings', 'Freshdesk', 'manage_options', 'freshdesk-menu-handle', 'freshdesk_settings_page');
+	add_action( 'admin_init', 'freshdesk_settings_init' );
+}
+
+function freshdesk_settings_page() {
+?>
+	<div class="wrap">
+		<h2><?php echo __("Freshdesk Settings") ?></h2>
+		<form class="form-table" method="post" action="options.php"> 
+			<?php settings_fields('freshdesk_options_group'); //setting fields group?>
+			<?php do_settings_sections('freshdesk-menu-handle'); ?>
+			<p class="submit"><input class="wp-core-ui button-primary" name="Submit" type="submit" value="<?php esc_attr_e('Save Changes'); ?>" /></p>
+		</form>
+	</div>
+<?php
+} //Function End
+
+function freshdesk_settings_init() {
+	register_setting( 'freshdesk_options_group', 'freshdesk_options', 'validate_freshdesk_settings' );
+	add_settings_section( 'freshdesk_settings_section', '', '', 'freshdesk-menu-handle' );
+	//Domain url.
+	add_settings_field( 'freshdesk_domain_url', __('Helpdesk URL'), 'freshdesk_domain_callback' ,'freshdesk-menu-handle', 'freshdesk_settings_section' );
+	//Host url
+	add_settings_field( 'freshdesk_cname', __('Portal URLs'), 'freshdesk_cname_callback' ,'freshdesk-menu-handle', 'freshdesk_settings_section' );
+	
+	//Freshdesk Api Key.
+	add_settings_field( 'freshdesk_api_key', 'API Key', 'freshdesk_api_callback' , 'freshdesk-menu-handle', 'freshdesk_settings_section' );
+	
+	//Enable SSO
+	add_settings_field( 'freshdesk_enable_sso', '', 'freshdesk_enable_sso_callback' , 'freshdesk-menu-handle', 'freshdesk_settings_section' );
+	
+	//Enable/disable freshdesk widget code.
+	register_setting( 'freshdesk_options_group','freshdesk_feedback_options','validate_freshdesk_fb_settings' );
+	add_settings_field( 'freshdesk_enable_feedback', '', 'freshdesk_enable_fb_callback' , 'freshdesk-menu-handle', 'freshdesk_settings_section' );
+}
+
+// Callback Functions that constructs the UI.
+function freshdesk_domain_callback() {
+	$options = get_option( 'freshdesk_options' );
+	echo "<input class='fd_ui_element' id='freshdesk_domain_url' name='freshdesk_options[freshdesk_domain_url]' size='72' type='text' value='{$options['freshdesk_domain_url']}' />";
+	echo '<div class="info-data fd_ui_element">Eg: https://yourcompany.freshdesk.com</div>';
+}
+
+function freshdesk_cname_callback() {
+	$options = get_option( 'freshdesk_options' );
+	echo "<input class='fd_ui_element' id='freshdesk_cname' name='freshdesk_options[freshdesk_cname]' size='72' type='text' value='{$options['freshdesk_cname']}' />";
+	echo '<div class="info-data fd_ui_element">Eg: https://support.yourdomain.com,https://support2.yourdomain.com</div>';
+}
+
+function freshdesk_enable_sso_callback() {
+	$options = get_option( 'freshdesk_options' );
+	echo '<tr><td colspan="2"><ul class="fd-form-table"><li><div><label><input class="fd_button" type="checkbox" name="freshdesk_options[freshdesk_enable_sso]" id="freshdesk_enable_sso" '.$options['freshdesk_enable_sso'].' /><span class="fd_ui_element fd-bold">Enable SSO Login </span></label><div><div class="info-data fd_lmargin">Enabling this will let your users to login using their wordpress credentials</div></li>';
+	
+	//SSO Secret
+	echo '<div id="freshdesk_sso_options" style="display: none;padding-left:45px">';
+	freshdesk_sso_callback();
+	
+	//Remote login and Logout Urls
+	freshdesk_sso_urls_callback();
+	echo '</div>';
+	
+}
+
+function freshdesk_sso_callback() {
+	$options = get_option( 'freshdesk_options' );
+	echo "<div class='freshdesk_sso_settings' style='display: none;' ><div class='info-title'>".__("SSO Shared Secret")."</div><input class='fd_ui_element' id='freshdesk_sso_key' name='freshdesk_options[freshdesk_sso_key]' size='72' type='text' value='{$options['freshdesk_sso_key']}' />";
+	echo '<div class="info-data fd_ui_element freshdesk_helpdesk_url">Enable SSO on your Helpdesk account and copy the <a href="'.$options['freshdesk_domain_url'].'/admin/security" target="_blank" >SSO shared secret</a> above.</div></div>';
+}
+
+function freshdesk_sso_urls_callback() {
+	$options = get_option( 'freshdesk_options' );
+	echo '<ul class="fd-content freshdesk_sso_settings" style="display: none;"><li><div class="info-title">'.__('Remote Login URL').'</div>';
+	echo '<input class="fd-code" value="' . wp_login_url() . '?action=freshdesk-login" type="button"/>';
+	echo '<div class="info-data freshdesk_helpdesk_url">'.__("Copy the above <i>Remote Login Url</i> to your").' <a href="'.$options['freshdesk_domain_url'].'/admin/security" target="_blank" >Single Sign On settings.</a></div></li>';
+	echo '<li><div class="info-title">'.__('Remote Logout URL').'</div>';
+	echo '<input class="fd-code" value="' . wp_login_url() . '?action=freshdesk-logout" type="button"/>';
+	echo '<div class="info-data freshdesk_helpdesk_url" id="freshdesk_redirect_url">'.__("Copy the above <i>Remote Logout Url</i> to your").' <a href="'.$options['freshdesk_domain_url'].'/admin/security" target="_blank" >Single Sign On settings.</a></div></li></ul>';
+}
+
+function freshdesk_api_callback() {
+	$options = get_option( 'freshdesk_options' );
+	echo "<input class='fd_ui_element' type='text' name='freshdesk_options[freshdesk_api_key]' size='72' value='{$options['freshdesk_api_key']}' />";
+	echo '<div class="info-data fd_ui_element">'.__("Your Helpdesk's Apikey will be available under Agent profile settings.").'</div>';
+}
+
+function freshdesk_enable_fb_callback() {
+	$options = get_option( 'freshdesk_feedback_options' );
+	echo '<tr><td colspan="2"><ul class="fd-form-table"><li><div><label><input class="fd_button" type="checkbox" name="freshdesk_feedback_options[freshdesk_enable_feedback]" id="freshdesk_enable_feedback" '.$options['freshdesk_enable_feedback'].' /><span class="fd_ui_element fd-bold">Show FeedBack Widget </span></label><div><div class="info-data fd_lmargin">This widget will be shown on your wordpress site for Visitors to post feedback</div></li>';
+	freshdesk_fb_widget_callback();
+}
+
+function freshdesk_fb_widget_callback() {
+	$options = get_option( 'freshdesk_feedback_options' );
+	$fd_options = get_option( 'freshdesk_options' );
+	
+	echo '<li><div id="freshdesk_feedback_widget_id" style="display: none;"><div class="info-data  fd_text fd_ui_element freshdesk_widget_url"><a href="'.$fd_options['freshdesk_domain_url'].'/admin/widget_config" target="_blank">Copy feedback widget code</a> from your helpdesk and paste it below.</div>';
+	echo '<textarea class="fd_ui_element fd_text" name="freshdesk_feedback_options[freshdesk_fb_widget_code]" id="freshdesk_fb_widget_code" rows="7">'.$options['freshdesk_fb_widget_code'].'</textarea></div></li></ul></td></tr>';
+}
+
+/* This is the validation(db before_save) callback */
+function validate_freshdesk_settings( $input ) {
+	$freshdesk_options = get_option( 'freshdesk_options' );
+	$error = 0;
+	$url=trim($input['freshdesk_domain_url']);
+	if ( $url && ! preg_match( DOMAIN_REGEX, $url )  ) {
+		add_settings_error(
+			'freshdesk_domain_url', // setting title
+			'fd_invalid_domain', // error ID
+			"$url is an invalid  Helpdesk url", // error message
+			'error' // type of message
+		);
+		$error=1;
+	}
+	$cnames = split( ",", trim($input['freshdesk_cname'] ) );
+	foreach ( $cnames as $cname ) {
+		$cname = trim($cname);
+		if ( ! preg_match( DOMAIN_REGEX, $cname ) && $cname ) {
+			add_settings_error(
+				'freshdesk_cname', // setting title
+				'fd_cname_invalid_domain', // error ID
+				"$cname is an invalid  domain url", // error message
+				'error' // type of message
+			);
+			$error=1;
+			break;
+		}
+	}
+	$cname = trim($input['freshdesk_cname'] );
+	
+	$sso_secret = $input['freshdesk_sso_key'];
+	$api_key = $input['freshdesk_api_key'];
+	$enable_feedback = validate_checkbox( $input['freshdesk_enable_feedback'] );
+	$enable_sso = validate_checkbox( $input['freshdesk_enable_sso'] );
+	
+	if ( ! $url ) {
+		add_settings_error(
+			'freshdesk_domain_url', // setting title
+			'fd_domain_url_not_present', // error ID
+			'Helpdesk url cannot be blank', // error message
+			'error' // type of message
+		);
+		$error=1;
+	}
+	
+	if ( ! $api_key ) {
+		add_settings_error(
+			'freshdesk_api_key', // setting title
+			'fd_api_key_not_present', // error ID
+			'API key cannot be blank', // error message
+			'error' // type of message
+		);
+		$error=1;
+	}
+	
+	if ( $enable_sso == 'checked' && ! $sso_secret ) {
+		add_settings_error(
+			'freshdesk_sso_key', // setting title
+			'fd_sso_key_not_present', // error ID
+			'Please enter the sso secret to enable sso', // error message
+			'error' // type of message
+		);
+		$error=1;
+	}
+	
+	if ( $error ) {
+		return $freshdesk_options;
+	}
+	$settings = array( 'freshdesk_domain_url' => $url, 'freshdesk_cname' => $cname, 'freshdesk_enable_sso' => $enable_sso, 'freshdesk_sso_key' => $sso_secret, 'freshdesk_api_key' => $api_key, 'freshdesk_enable_feedback' => $enable_feedback );
+	
+	return $settings;	
+}
+
+function validate_freshdesk_fb_settings( $input ) {
+	$enable_feedback = validate_checkbox( $input['freshdesk_enable_feedback'] );
+	$fb_widget_code = $input['freshdesk_fb_widget_code'];
+	$settings = array( 'freshdesk_fb_widget_code' => $fb_widget_code, 'freshdesk_enable_feedback' => $enable_feedback );
+	return $settings;
+}
+
+function validate_checkbox( $input ){
+	if($input == 'on'){
+		$input = 'checked';
+	}
+	return $input;
+}
+/* Validation callback End. */
+
+/* Adding 'Create Ticket' Action for the Comments*/
+function freshdesk_comment_action( $actions, $comment ) {
+	$options = get_option( 'freshdesk_options' );
+	if (current_user_can( 'administrator') ) {
+		if( (trim( get_comment_meta( $comment->comment_ID, "fd_ticket_id", true) ) == false ) ){
+			$actions['freshdesk'] = '<a class="fd_convert_ticket" href="#" domain_url='.$options['freshdesk_domain_url'].' id="' . $comment->comment_ID . '">' . __( 'Convert to Ticket', 'fd_ticket' ) . '</a>';
+		}
+		else {
+			$actions['freshdesk'] = '<a class="fd_convert_ticket" href="#" title="hello" ticket_id="'.get_comment_meta($comment->comment_ID,"fd_ticket_id", true).'"domain_url='.$options['freshdesk_domain_url'].' id="' . $comment->comment_ID . '">' . __( 'View Ticket', 'fd_ticket_link' ) . '</a>';
+		}
+	}
+	return $actions;
+}
+
+
+//freshdesk login sso handler/feedback widget handler.
+//and css/js loader for settings and comments page.
+function fd_login() {
+	global $pagenow, $display_name , $user_email;
+	if ( 'wp-login.php' == $pagenow ){
+		$freshdesk_options = get_option( 'freshdesk_options' );
+		$domain = get_redirect_url($_REQUEST['host_url']);
+		error_log("Domain : $domain ");
+		if( ! $domain ) {
+			return;
+		}
+		if ( $_GET['action'] == 'freshdesk-login' ) {
+			// NOTE: is_user_logged_in dont't work during  [wp-submit] => Log In
+			if( $freshdesk_options['freshdesk_enable_sso'] != 'checked' ){
+				return;
+			}
+			if ( is_user_logged_in() ) {
+				// For the case when user has already logged into Wordpress and then in another tab opens Freshdesk and click on login then he should be logged into FD with out entering credentials.
+				$current_user = wp_get_current_user();
+				$secret = $freshdesk_options['freshdesk_sso_key'];
+				$user_name= $current_user->data->display_name;
+				$user_email = $current_user->user_email;
+				$data = $user_name.$user_email.time();
+				$hash_key = hash_hmac( "md5", $data, $secret );
+				$url = freshdesk_sso_login_url( $domain, $user_name, $user_email ,$hash_key );
+				header( 'Location: '.$url ) ;	
+				die();
+			}
+			else{ // if wordpress is not logged in.
+				
+				if (isset($domain)){
+					header( "Location: " .wp_login_url()."?redirect_to=fd_redirect_to=".$domain );
+					die();
+				}
+		 	}
+		}
+		if ( $_GET['action'] == 'freshdesk-logout' ) {
+			wp_logout();
+			header( 'Location: '.$domain );
+			die();
+		}
+	}
+	if ( 'edit-comments.php' == $pagenow ||  ( $_GET['page'] == 'freshdesk-menu-handle' ) ){
+		if ( current_user_can( 'manage_options' ) ) {
+			wp_enqueue_script( 'fd_plugin_js',FD_PLUGIN_URL . 'js/freshdesk_plugin_js.js', array( 'jquery' ) );
+			wp_localize_script( 'fd_plugin_js', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
+		}
+	}
+	wp_enqueue_style( 'fd_plugin_css',FD_PLUGIN_URL . 'css/freshdesk_plugin.css' );
+	$feedback_options=get_option( 'freshdesk_feedback_options' );
+	if ( $feedback_options['freshdesk_enable_feedback'] == "checked" ) {
+		add_action( 'wp_footer', 'freshdesk_widget_code' );
+	}
+}
+
+//Feedback widget code snippet include.
+function freshdesk_widget_code() {
+	$options = get_option( 'freshdesk_feedback_options' );
+	echo $options['freshdesk_fb_widget_code'];
+}
+
+function freshdesk_handshake_secret() {
+	
+}
+
+function freshdesk_sso_login_url($domain, $user_name, $email, $hash_key){
+	return $domain."/login/sso?name=".urlencode($user_name)."&email=".urlencode($email)."&timestamp=".time()."&hash=".urlencode($hash_key);
+}
+
+//Ajax Action handler. Freshdesk Ticket creation handled here.
+function fd_action_callback() {
+	$id = $_POST['commentId'];	
+	$comment = get_comment($id);
+	$comment_link = get_comment_link( $comment, 'all' );
+	$email = $comment->comment_author_email;
+	$description = $comment->comment_content;
+	$description = $description . "<br/><br/><a href=" . htmlentities($comment_link) . ">Go to comment</a>";
+	$type = $comment->comment_type;
+	$comment_meta = $comment->comment_agent;
+	$comment_date = $comment->comment_date;
+	$comment_post = $comment->comment_post_ID;
+	$comment_author_name = $comment->comment_author;
+	$subject = "comment id :".$id;
+	$options = get_option( 'freshdesk_options' );
+	$fd_api_handle = new Freshdesk_Plugin_Api( $options['freshdesk_api_key'], $options['freshdesk_domain_url'] );
+	$result = $fd_api_handle->create_ticket( $email, $subject, $description );
+	$response = array(
+		'what'=>'helpdesk_ticket',
+		'action'=>'create',
+		'id'=>'1',
+		'data'=>$result
+	);
+	
+	$resp = add_comment_meta( $id, 'fd_ticket_id', $result, false );
+	$xmlResponse = new WP_Ajax_Response( $response );
+	$xmlResponse->send();
+}
+
+
+function freshdesk_show_msg( $message, $msgclass = 'info' ) {
+	echo "<div id='message' class='$msgclass'>$message</div>";
+}
+
+function freshdesk_admin_msgs() {
+	// check for our settings page - need this in conditional further down
+	$wptuts_settings_pg = strpos( $_GET['page'], FD_PAGE_BASENAME );
+	// collect setting errors/notices: //http://codex.wordpress.org/Function_Reference/get_settings_errors
+	$set_errors = get_settings_errors();
+
+	//display admin message only for the admin to see, only on our settings page and only when setting errors/notices are returned!
+	if ( current_user_can ('manage_options') && $wptuts_settings_pg !== FALSE && ! empty( $set_errors ) ){
+		// have our settings succesfully been updated?
+		if ( $set_errors[0]['code'] == 'settings_updated' && isset( $_GET['settings-updated'] ) ) {
+			freshdesk_show_msg("<p>" . $set_errors[0]['message'] . "</p>", 'updated');
+		} else {
+			// there maybe more than one so run a foreach loop.
+			foreach ( $set_errors as $set_error ) {
+				// set the title attribute to match the error "setting title" - need this in js file
+				freshdesk_show_msg("<p class='setting-error-message' title='" . $set_error['setting'] . "'>" . $set_error['message'] . "</p>", 'error');
+			}
+		}
+	}
+}
+?>
diff --git a/freshdesk-plugin-api.php b/freshdesk-plugin-api.php
new file mode 100644
index 0000000..2343640
--- /dev/null
+++ b/freshdesk-plugin-api.php
@@ -0,0 +1,65 @@
+<?php
+
+/* Fresdesk Api class
+* Adding functionality to create ticket.
+*/
+class Freshdesk_Plugin_Api{
+
+private $apikey, $domain_url, $response, $response_status;
+
+	public function __construct($apikey, $domain_url){
+		$this->apikey = $apikey;
+		$this->domain_url = $domain_url;
+	}	
+
+	function create_ticket($email,$subject,$description){
+		$datafields =  array (
+     									"helpdesk_ticket" =>array("subject"=>$subject,"description_html"=>$description,"email"=>$email)
+     								);
+ 		$jsondata= json_encode($datafields);
+ 		$this->make_request($this->domain_url."/helpdesk/tickets.json",$jsondata,$header);
+ 		if($this->response_status!= 200){
+ 			return -1;
+ 		}
+ 		return $this->response;
+	}
+
+	private function make_request($requestUri,$payload){
+		$ch = curl_init ($requestUri);
+ 		$header[] = "Content-type: application/json";
+		curl_setopt($ch, CURLOPT_POST, true);
+		curl_setopt($ch, CURLOPT_POSTFIELDS,$payload);
+		$user_pwd = $this->auth_method();
+		// echo "value:".$user_pwd."##";
+		curl_setopt($ch, CURLOPT_USERPWD,$user_pwd);
+		curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+		curl_setopt($ch, CURLOPT_HEADER, false);
+		// receive server response ...
+		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+		curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
+		$server_output = curl_exec ($ch);
+
+		$fd_response = json_decode($server_output);
+		// echo "RESPONSE:<br/>".var_dump($this->response);
+		$this->response_status = curl_getinfo($ch,CURLINFO_HTTP_CODE);
+		$this->response = $fd_response->{'helpdesk_ticket'}->{'display_id'};
+		curl_close ($ch);
+	}
+
+	function get_response(){
+		return $this->response;
+	}
+
+	function get_response_status(){
+		return $this->response_status;
+	}
+
+	private function auth_method(){
+		return $this->apikey.":X";
+	}
+
+
+}
+?>
\ No newline at end of file
diff --git a/images/fd-menulogob.png b/images/fd-menulogob.png
new file mode 100644
index 0000000..47b244d
Binary files /dev/null and b/images/fd-menulogob.png differ
diff --git a/images/fd-menulogog.png b/images/fd-menulogog.png
new file mode 100644
index 0000000..b12f142
Binary files /dev/null and b/images/fd-menulogog.png differ
diff --git a/images/fd-menulogow.png b/images/fd-menulogow.png
new file mode 100644
index 0000000..2c98f72
Binary files /dev/null and b/images/fd-menulogow.png differ
diff --git a/js/freshdesk_plugin_js.js b/js/freshdesk_plugin_js.js
new file mode 100644
index 0000000..4303dff
--- /dev/null
+++ b/js/freshdesk_plugin_js.js
@@ -0,0 +1,89 @@
+jQuery(document).ready(function($){
+
+	toggle_url();	
+
+	$('.fd_convert_ticket').on('click',function(evt){
+		evt.preventDefault();
+		var comment_link = this;
+		// var ticket_link= $(this).find('fd_ticket_link').first();
+		var commentId= $(this).attr('id');
+		var ticketId= $(this).attr('ticket_id');
+		var href= $(this).attr('domain_url');
+
+		if(ticketId == undefined){
+			var data = {
+				action: 'fd_ticket_action',
+				commentId: commentId
+			};
+
+				// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
+			$.post(ajaxurl, data, function(response) {
+				resp = jQuery(response).find('response_data').text();
+				$(comment_link).text('View Ticket');
+				if(resp == -1){
+					alert('Got this from the server: ' + resp);
+				}
+				else{
+				$(comment_link).attr('ticket_id',resp);
+					confirm('Ticket #'+resp+' created Successfully.');
+				}
+
+			});
+		}
+		else{
+			window.open(href+"/helpdesk/tickets/"+ticketId, '_blank');
+		}
+	});
+
+	if($('#freshdesk_enable_feedback')[0].checked){
+		toggle_feedback_widget();
+	}
+
+	$('#freshdesk_enable_feedback').on('click',function(){
+		toggle_feedback_widget();
+	});
+
+	if($('#freshdesk_enable_sso')[0].checked){
+	 	toggle_sso();
+	}
+	$('#freshdesk_enable_sso').on('click',function(){
+		toggle_sso();
+	});
+	$('#freshdesk_domain_url').on('blur',function(){
+		toggle_url();
+	});
+
+	function toggle_url(){
+		if($('#freshdesk_domain_url').val() != ''){
+			$('.freshdesk_sso_settings').slideDown();
+			url = $('#freshdesk_domain_url').val();
+			$('.freshdesk_helpdesk_url').find('a').each(function(){
+				$(this).attr('href',url+'/admin/security');
+			});
+			$('.freshdesk_widget_url').find('a').first().attr('href',url+'/admin/widget_config');
+			return;
+		}
+		$('.freshdesk_sso_settings').slideUp();
+	}
+
+	function toggle_feedback_widget(){
+		if($('#freshdesk_enable_feedback')[0].checked){
+			$('#freshdesk_feedback_widget_id').slideDown();
+			$('#freshdesk_fb_widget_code').prop('disabled',false);
+			return;
+		}
+		$('#freshdesk_fb_widget_code').prop('disabled',true);
+		$('#freshdesk_feedback_widget_id').slideUp();
+	}
+
+	function toggle_sso(){
+		if($('#freshdesk_enable_sso')[0].checked){
+			$('#freshdesk_sso_options').slideDown();
+			//$('#freshdesk_fb_widget_code').prop('disabled',false);
+			return;
+		}
+		//$('#freshdesk_fb_widget_code').prop('disabled',true);
+		$('#freshdesk_sso_options').slideUp();
+	}
+
+});
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..57ad90b
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,119 @@
+=== Freshdesk Official===
+Contributors: hjohnpaul, sathishfreshdesk, balakumars, shreyasns
+Donate link: 
+Tags: freshdesk, helpdesk, support tool
+Requires at least: 3.4
+Tested up to: 4.1.5
+Stable tag: 1.8
+License: GPLv2 or later
+License URI: http://www.gnu.org/licenses/gpl-2.0.html
+
+
+Freshdesk Official plugin is a seamless way to add your helpdesk account to your website. Supports various useful functions.
+
+==Description==
+
+Freshdesk Official plugin enables users to achieve three important functions:
+
+- Avoid additional login to helpdesk if the user has already logged in to WP(Single Sign On).
+- Effortlessly integrate the helpdesk' s feedback widget along with solutions search to his wordpress site.
+- Allows the site admin to convert comments into helpdesk tickets.
+- Adding the comment link to ticket description.
+
+1. Single Sign On:
+Users can now login to their helpdesk(freshdesk) support portal using Wordpress authentication. The single sign on feature ensures that users who have already logged into their Wordpress site can start working in their Freshdesk support portal as well without having to log in separately. 
+
+2. Feedback Pop-up Widget:
+The plugin allows Wordpress users to have a Freshdesk feedback widget embedded in their wordpress site. The widget allows people visiting the site to provide feedback and search for answers.
+
+3. Convert Comments to Tickets on helpdesk:
+Users with admin access to their Wordpress sites can convert comments into “Tickets”. The marked comments are sent to the user’s support portal that can be solved or responded to later.
+
+4. Adding the comment link-back in the ticket added:
+   Comments converted to tickets in freshdesk will now have the link-back url to the actual comment in the wordpress site appended in its description.
+
+== Installation ==
+* For an automatic installation through WordPress
+1. Go to the 'Add New' plugins screen in your WordPress admin area.
+2. Search for 'Freshdesk Official' plugin.
+3. Click 'Install Now' and activate the plugin.
+
+
+Manual Installation:
+
+1. Download the latest version of 'Freshdesk Official'  plugin from the WordPress Plugin Directory.
+2. Extract the zip and Upload the freshdesk_support directory to your /wp-content/plugins directory
+3. Go to the plugins management page and activate the plugin
+4. You now have a new admin menu 'Freshdesk Official' in your WordPress admin menu bar. Click on it and Configure your settings as mentioned in the info comments in the screen.
+
+== Frequently Asked Questions ==
+1. Where do i find sso shared secret ?
+
+  SSO shared secret will be available in your helpdesk account's admin -> security -> sso section.
+
+2. How can login to my helpdesk using normal login screen after enabling sso ?
+
+  You can always access your help desk's normal login screen using http://yourcompany.freshdesk.com/login/normal link.
+
+3. Where can I find the feedback widget code snippet ?
+
+  Feedback widget code has to be copied from the admin -> feedback section. You can configure the alignment and kbase search hide and much more here and copy the generate code snippet.
+
+== Screenshots ==
+1. This screen shot shows the Settings Screen.
+2. This shows the comments page where a new action('Convert to ticket') added to make the comment as a ticket.
+3. This shows the comments page with 'View Ticket' option showing if the comment is already converted to ticket.
+4. This shows the comment link in the ticket description.
+
+== Changelog ==
+= 1.8 =
+  Security fix for open redirect vulnerablity. Now users are required to configure all the portal urls in the settings page.
+= 1.7 =
+  Added option to enable/disable sso.
+  Logging out of wordpress no longer logs out the Freshdesk session.
+  Added validations for the settings page.
+  Fixed the error showing up on the plugin settings page.
+= 1.6 =
+  Fix the SSO login redirect to Freshdesk and on wordpress logout, logout of Freshdesk as well.
+= 1.5 =
+  Includes fix for SSO and Vanity URL redirect.
+= 1.4 =
+  Bug fix for SSO and Vanity URL redirect.
+= 1.3 =
+ Added comment link to ticket description
+= 1.2 =
+ Fix for the error message("The plugin does not have a valid header.") on enabling plugin 
+= 1.1 =
+Previous revision. 
+Bug Fix:
+ - Freshdesk remote log-in failing for new users.
+ - Sign-out from freshdesk does not logout wordpress session. 
+= 1.0 =
+First Release Version.
+
+== Upgrade Notice ==
+  Security fix for open redirect vulnerablity. Now users are required to configure all the portal urls in the settings page.
+= 1.8 =
+  Security fix for open redirect vulnerablity. Now users are required to configure all the portal urls in the settings page.  
+== 1.7 ==
+  Added option to enable/disable sso.
+  Logging out of wordpress will no longer logout the Freshdesk session.
+  Added validations for the settings page.
+  Fixed the error showing up on the plugin settings page.
+== 1.6 ==
+  Fix for SSO login redirect back to Freshdesk.
+  Change logout url to Freshdesk logout url so that Freshdesk is also logged out.
+== 1.5 ==
+  Fixing problem with 1.4 getting listed as development version.
+  Includes bug fix for SSO and Vanity URL redirect.
+== 1.4 ==
+  Bug fix for SSO and Vanity URL redirect.
+  Now works with SSO and Vanity URL.
+== 1.3 ==
+ Added comment link to ticket description.
+== 1.2 ==
+ Fix for the error message on enabling the plugin.
+== 1.1 ==
+  Revision with bugs addressed.
+== 1.0 ==
+This is the First release version.

Fixed code: .info-data{
	color: #888; 
	font-size: 13px;
	width:50%;
	padding-top: 3px;
}
.fd_lmargin{
	margin-left: 25px;
}
.fd_button{
	float: left;
}
.fd_ui_element{
		padding: 5px 5px;
		border-radius: 4px;
		font-size: 13px;
		font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.fd-code {
	padding: 6px 11px;
	background: none repeat scroll 0 0 #EEEEEE;
  border: 1px solid #DDDDDD;
  border-radius: 4px;
  font-weight: 13px;
}
.wrap{
		font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.fd-form-table{
	padding:0px;
	margin:0px;
}
.fd-form-table li{
	margin:0px;
}
.form-table th{
	width:120px;
	padding-bottom: 5px;
	padding-top: 10px;
}
.form-table td{
	padding-bottom: 5px;
	padding-top: 5px;
}
.form-table tr{
	padding:5px;
	font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.fd_text{
	width:60%;
}
.form-table li{
	list-style: none;
	padding-top: 5px;
	padding-bottom: 5px;
}
.info-title{
	margin-bottom: 5px;
	font-weight: 500;
	font-size: 90%;
}
.fd-content{
	margin-top: 0px;
}
.fd-bold{
	font-weight: bold;
}
input[type='checkbox']{
	margin: 2px 5px 0px 0px;
}

#adminmenu .menu-icon-generic.toplevel_page_freshdesk-menu-handle div.wp-menu-image{
	left: 10px;
  position: relative;
  top: 8px;
 	background: transparent url('../images/fd-menulogog.png') no-repeat !important;
}
#adminmenu .menu-icon-generic.toplevel_page_freshdesk-menu-handle a:hover div.wp-menu-image{
	background: transparent url('../images/fd-menulogob.png') no-repeat !important;
}
#adminmenu .menu-icon-generic.toplevel_page_freshdesk-menu-handle a.current div.wp-menu-image{
	background: transparent url('../images/fd-menulogow.png') no-repeat !important;
}

#adminmenu .menu-icon-generic.toplevel_page_freshdesk-menu-handle div.wp-menu-image:before{
	content : "";
}
<?php
/*
  @package Freshdesk Official
  @version 1.8
*/
/*
  Plugin Name: Freshdesk Official
  Plugin URI: 
  Description: Freshdesk Official is a seamless way to add your helpdesk account to your website. Supports various useful functions.
  Author: hjohnpaul,sathishfreshdesk,balakumars,shreyasns
  Version: 1.8
  Author URI: http://freshdesk.com/
*/


if ( ! defined( 'ABSPATH' ) ) {
	die(); //Die if accessed directly.
}

#include freshdesk api class.
define( 'FD_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'FD_PAGE_BASENAME', 'freshdesk-menu-handle' );
define( 'DOMAIN_REGEX', '/\bhttps?:\/\/([-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|])/i' );
require_once( plugin_dir_path( __FILE__ ) . 'freshdesk-plugin-api.php' );

add_action( 'init', 'fd_login' ); //Sso handler and comment action handler
add_action( 'admin_menu', 'freshdesk_plugin_menu' ); //Plugin Menu
add_filter( 'comment_row_actions', 'freshdesk_comment_action', 10, 2 ); // This adds the comment action menu.
add_action( 'wp_ajax_fd_ticket_action', 'fd_action_callback' ); // This is the ajax action handler
add_filter( 'login_redirect', 'fd_login_redirect', 10, 3 ); // This is used to redirect to Freshdesk on SSO.
add_filter( 'login_message', "show_login_message" );
// admin messages hook!
add_action( 'admin_notices', 'freshdesk_admin_msgs' );
?>
<?php
function show_login_message() {
	$freshdesk_options= get_option('freshdesk_options');
	if ( $freshdesk_options['freshdesk_enable_sso'] != 'checked' && $_GET['action'] == 'freshdesk-login' ){
		//ToDO change the login message
		return "<div style='padding:12px;border-left:4px solid #feba11; background:#fff; margin-bottom:4px'>We are not able to log you in, please contact your Wordpress administrator to enable SSO in your account.</div>";
	}
}
function fd_login_redirect( $url, $request, $user ) {
	parse_str( $request, $params );
	$fd_redirect_to = $params['fd_redirect_to'];
	if ( ! $fd_redirect_to ) {
		return $url;
	}
	$redirect_url = get_redirect_url( $fd_redirect_to );

	// For handling Redirect to Freshdesk on login.
	if ( $_REQUEST['wp-submit'] == "Log In" && is_a( $user, 'WP_User' ) && $redirect_url ) {
		$freshdesk_options = get_option( 'freshdesk_options' );		
		
		$user_name = $user->data->display_name;
		$secret = $freshdesk_options['freshdesk_sso_key'];
		$data = $user_name.$user->data->user_email.time();
		$hash_key = hash_hmac("md5", $data, $secret);
		$ssl_url = $redirect_url."/login/sso?name=".urlencode($user->data->display_name)."&email=".urlencode($user->data->user_email)."&timestamp=".time()."&hash=".urlencode($hash_key);
		sleep(1); // holding a bit so that it falls within FD 30 mins bar.
		header("Location: ".$ssl_url);
		die();
	}
	return  $request;
}

function get_redirect_url($host_url) {
	$freshdesk_options = get_option( 'freshdesk_options' );

	//Stripping protocols from urls to match the host url correctly.
	$host_url = preg_replace( DOMAIN_REGEX, "$1", trim($host_url) );
	$domains = split( ",", $freshdesk_options['freshdesk_cname'] );
	array_push( $domains, $freshdesk_options['freshdesk_domain_url'] );

	//Checking the host url against the provided helpdesk/portal url to avoid Open-redirect vulnerability
	foreach ( $domains as $domain ) {
		$domain = trim($domain);
		$url = preg_replace( DOMAIN_REGEX, "$1", $domain);
		if ( $url == $host_url ) {
			return $domain;
		}
	}
}
function freshdesk_plugin_menu() {
	add_menu_page( 'Freshdesk Settings', 'Freshdesk', 'manage_options', 'freshdesk-menu-handle', 'freshdesk_settings_page');
	add_action( 'admin_init', 'freshdesk_settings_init' );
}

function freshdesk_settings_page() {
?>
	<div class="wrap">
		<h2><?php echo __("Freshdesk Settings") ?></h2>
		<form class="form-table" method="post" action="options.php"> 
			<?php settings_fields('freshdesk_options_group'); //setting fields group?>
			<?php do_settings_sections('freshdesk-menu-handle'); ?>
			<p class="submit"><input class="wp-core-ui button-primary" name="Submit" type="submit" value="<?php esc_attr_e('Save Changes'); ?>" /></p>
		</form>
	</div>
<?php
} //Function End

function freshdesk_settings_init() {
	register_setting( 'freshdesk_options_group', 'freshdesk_options', 'validate_freshdesk_settings' );
	add_settings_section( 'freshdesk_settings_section', '', '', 'freshdesk-menu-handle' );
	//Domain url.
	add_settings_field( 'freshdesk_domain_url', __('Helpdesk URL'), 'freshdesk_domain_callback' ,'freshdesk-menu-handle', 'freshdesk_settings_section' );
	//Host url
	add_settings_field( 'freshdesk_cname', __('Portal URLs'), 'freshdesk_cname_callback' ,'freshdesk-menu-handle', 'freshdesk_settings_section' );
	
	//Freshdesk Api Key.
	add_settings_field( 'freshdesk_api_key', 'API Key', 'freshdesk_api_callback' , 'freshdesk-menu-handle', 'freshdesk_settings_section' );
	
	//Enable SSO
	add_settings_field( 'freshdesk_enable_sso', '', 'freshdesk_enable_sso_callback' , 'freshdesk-menu-handle', 'freshdesk_settings_section' );
	
	//Enable/disable freshdesk widget code.
	register_setting( 'freshdesk_options_group','freshdesk_feedback_options','validate_freshdesk_fb_settings' );
	add_settings_field( 'freshdesk_enable_feedback', '', 'freshdesk_enable_fb_callback' , 'freshdesk-menu-handle', 'freshdesk_settings_section' );
}

// Callback Functions that constructs the UI.
function freshdesk_domain_callback() {
	$options = get_option( 'freshdesk_options' );
	echo "<input class='fd_ui_element' id='freshdesk_domain_url' name='freshdesk_options[freshdesk_domain_url]' size='72' type='text' value='{$options['freshdesk_domain_url']}' />";
	echo '<div class="info-data fd_ui_element">Eg: https://yourcompany.freshdesk.com</div>';
}

function freshdesk_cname_callback() {
	$options = get_option( 'freshdesk_options' );
	echo "<input class='fd_ui_element' id='freshdesk_cname' name='freshdesk_options[freshdesk_cname]' size='72' type='text' value='{$options['freshdesk_cname']}' />";
	echo '<div class="info-data fd_ui_element">Eg: https://support.yourdomain.com,https://support2.yourdomain.com</div>';
}

function freshdesk_enable_sso_callback() {
	$options = get_option( 'freshdesk_options' );
	echo '<tr><td colspan="2"><ul class="fd-form-table"><li><div><label><input class="fd_button" type="checkbox" name="freshdesk_options[freshdesk_enable_sso]" id="freshdesk_enable_sso" '.$options['freshdesk_enable_sso'].' /><span class="fd_ui_element fd-bold">Enable SSO Login </span></label><div><div class="info-data fd_lmargin">Enabling this will let your users to login using their wordpress credentials</div></li>';
	
	//SSO Secret
	echo '<div id="freshdesk_sso_options" style="display: none;padding-left:45px">';
	freshdesk_sso_callback();
	
	//Remote login and Logout Urls
	freshdesk_sso_urls_callback();
	echo '</div>';
	
}

function freshdesk_sso_callback() {
	$options = get_option( 'freshdesk_options' );
	echo "<div class='freshdesk_sso_settings' style='display: none;' ><div class='info-title'>".__("SSO Shared Secret")."</div><input class='fd_ui_element' id='freshdesk_sso_key' name='freshdesk_options[freshdesk_sso_key]' size='72' type='text' value='{$options['freshdesk_sso_key']}' />";
	echo '<div class="info-data fd_ui_element freshdesk_helpdesk_url">Enable SSO on your Helpdesk account and copy the <a href="'.$options['freshdesk_domain_url'].'/admin/security" target="_blank" >SSO shared secret</a> above.</div></div>';
}

function freshdesk_sso_urls_callback() {
	$options = get_option( 'freshdesk_options' );
	echo '<ul class="fd-content freshdesk_sso_settings" style="display: none;"><li><div class="info-title">'.__('Remote Login URL').'</div>';
	echo '<input class="fd-code" value="' . wp_login_url() . '?action=freshdesk-login" type="button"/>';
	echo '<div class="info-data freshdesk_helpdesk_url">'.__("Copy the above <i>Remote Login Url</i> to your").' <a href="'.$options['freshdesk_domain_url'].'/admin/security" target="_blank" >Single Sign On settings.</a></div></li>';
	echo '<li><div class="info-title">'.__('Remote Logout URL').'</div>';
	echo '<input class="fd-code" value="' . wp_login_url() . '?action=freshdesk-logout" type="button"/>';
	echo '<div class="info-data freshdesk_helpdesk_url" id="freshdesk_redirect_url">'.__("Copy the above <i>Remote Logout Url</i> to your").' <a href="'.$options['freshdesk_domain_url'].'/admin/security" target="_blank" >Single Sign On settings.</a></div></li></ul>';
}

function freshdesk_api_callback() {
	$options = get_option( 'freshdesk_options' );
	echo "<input class='fd_ui_element' type='text' name='freshdesk_options[freshdesk_api_key]' size='72' value='{$options['freshdesk_api_key']}' />";
	echo '<div class="info-data fd_ui_element">'.__("Your Helpdesk's Apikey will be available under Agent profile settings.").'</div>';
}

function freshdesk_enable_fb_callback() {
	$options = get_option( 'freshdesk_feedback_options' );
	echo '<tr><td colspan="2"><ul class="fd-form-table"><li><div><label><input class="fd_button" type="checkbox" name="freshdesk_feedback_options[freshdesk_enable_feedback]" id="freshdesk_enable_feedback" '.$options['freshdesk_enable_feedback'].' /><span class="fd_ui_element fd-bold">Show FeedBack Widget </span></label><div><div class="info-data fd_lmargin">This widget will be shown on your wordpress site for Visitors to post feedback</div></li>';
	freshdesk_fb_widget_callback();
}

function freshdesk_fb_widget_callback() {
	$options = get_option( 'freshdesk_feedback_options' );
	$fd_options = get_option( 'freshdesk_options' );
	
	echo '<li><div id="freshdesk_feedback_widget_id" style="display: none;"><div class="info-data  fd_text fd_ui_element freshdesk_widget_url"><a href="'.$fd_options['freshdesk_domain_url'].'/admin/widget_config" target="_blank">Copy feedback widget code</a> from your helpdesk and paste it below.</div>';
	echo '<textarea class="fd_ui_element fd_text" name="freshdesk_feedback_options[freshdesk_fb_widget_code]" id="freshdesk_fb_widget_code" rows="7">'.$options['freshdesk_fb_widget_code'].'</textarea></div></li></ul></td></tr>';
}

/* This is the validation(db before_save) callback */
function validate_freshdesk_settings( $input ) {
	$freshdesk_options = get_option( 'freshdesk_options' );
	$error = 0;
	$url=trim($input['freshdesk_domain_url']);
	if ( $url && ! preg_match( DOMAIN_REGEX, $url )  ) {
		add_settings_error(
			'freshdesk_domain_url', // setting title
			'fd_invalid_domain', // error ID
			"$url is an invalid  Helpdesk url", // error message
			'error' // type of message
		);
		$error=1;
	}
	$cnames = split( ",", trim($input['freshdesk_cname'] ) );
	foreach ( $cnames as $cname ) {
		$cname = trim($cname);
		if ( ! preg_match( DOMAIN_REGEX, $cname ) && $cname ) {
			add_settings_error(
				'freshdesk_cname', // setting title
				'fd_cname_invalid_domain', // error ID
				"$cname is an invalid  domain url", // error message
				'error' // type of message
			);
			$error=1;
			break;
		}
	}
	$cname = trim($input['freshdesk_cname'] );
	
	$sso_secret = $input['freshdesk_sso_key'];
	$api_key = $input['freshdesk_api_key'];
	$enable_feedback = validate_checkbox( $input['freshdesk_enable_feedback'] );
	$enable_sso = validate_checkbox( $input['freshdesk_enable_sso'] );
	
	if ( ! $url ) {
		add_settings_error(
			'freshdesk_domain_url', // setting title
			'fd_domain_url_not_present', // error ID
			'Helpdesk url cannot be blank', // error message
			'error' // type of message
		);
		$error=1;
	}
	
	if ( ! $api_key ) {
		add_settings_error(
			'freshdesk_api_key', // setting title
			'fd_api_key_not_present', // error ID
			'API key cannot be blank', // error message
			'error' // type of message
		);
		$error=1;
	}
	
	if ( $enable_sso == 'checked' && ! $sso_secret ) {
		add_settings_error(
			'freshdesk_sso_key', // setting title
			'fd_sso_key_not_present', // error ID
			'Please enter the sso secret to enable sso', // error message
			'error' // type of message
		);
		$error=1;
	}
	
	if ( $error ) {
		return $freshdesk_options;
	}
	$settings = array( 'freshdesk_domain_url' => $url, 'freshdesk_cname' => $cname, 'freshdesk_enable_sso' => $enable_sso, 'freshdesk_sso_key' => $sso_secret, 'freshdesk_api_key' => $api_key, 'freshdesk_enable_feedback' => $enable_feedback );
	
	return $settings;	
}

function validate_freshdesk_fb_settings( $input ) {
	$enable_feedback = validate_checkbox( $input['freshdesk_enable_feedback'] );
	$fb_widget_code = $input['freshdesk_fb_widget_code'];
	$settings = array( 'freshdesk_fb_widget_code' => $fb_widget_code, 'freshdesk_enable_feedback' => $enable_feedback );
	return $settings;
}

function validate_checkbox( $input ){
	if($input == 'on'){
		$input = 'checked';
	}
	return $input;
}
/* Validation callback End. */

/* Adding 'Create Ticket' Action for the Comments*/
function freshdesk_comment_action( $actions, $comment ) {
	$options = get_option( 'freshdesk_options' );
	if (current_user_can( 'administrator') ) {
		if( (trim( get_comment_meta( $comment->comment_ID, "fd_ticket_id", true) ) == false ) ){
			$actions['freshdesk'] = '<a class="fd_convert_ticket" href="#" domain_url='.$options['freshdesk_domain_url'].' id="' . $comment->comment_ID . '">' . __( 'Convert to Ticket', 'fd_ticket' ) . '</a>';
		}
		else {
			$actions['freshdesk'] = '<a class="fd_convert_ticket" href="#" title="hello" ticket_id="'.get_comment_meta($comment->comment_ID,"fd_ticket_id", true).'"domain_url='.$options['freshdesk_domain_url'].' id="' . $comment->comment_ID . '">' . __( 'View Ticket', 'fd_ticket_link' ) . '</a>';
		}
	}
	return $actions;
}


//freshdesk login sso handler/feedback widget handler.
//and css/js loader for settings and comments page.
function fd_login() {
	global $pagenow, $display_name , $user_email;
	if ( 'wp-login.php' == $pagenow ){
		$freshdesk_options = get_option( 'freshdesk_options' );
		$domain = get_redirect_url($_REQUEST['host_url']);
		error_log("Domain : $domain ");
		if( ! $domain ) {
			return;
		}
		if ( $_GET['action'] == 'freshdesk-login' ) {
			// NOTE: is_user_logged_in dont't work during  [wp-submit] => Log In
			if( $freshdesk_options['freshdesk_enable_sso'] != 'checked' ){
				return;
			}
			if ( is_user_logged_in() ) {
				// For the case when user has already logged into Wordpress and then in another tab opens Freshdesk and click on login then he should be logged into FD with out entering credentials.
				$current_user = wp_get_current_user();
				$secret = $freshdesk_options['freshdesk_sso_key'];
				$user_name= $current_user->data->display_name;
				$user_email = $current_user->user_email;
				$data = $user_name.$user_email.time();
				$hash_key = hash_hmac( "md5", $data, $secret );
				$url = freshdesk_sso_login_url( $domain, $user_name, $user_email ,$hash_key );
				header( 'Location: '.$url ) ;	
				die();
			}
			else{ // if wordpress is not logged in.
				
				if (isset($domain)){
					header( "Location: " .wp_login_url()."?redirect_to=fd_redirect_to=".$domain );
					die();
				}
		 	}
		}
		if ( $_GET['action'] == 'freshdesk-logout' ) {
			wp_logout();
			header( 'Location: '.$domain );
			die();
		}
	}
	if ( 'edit-comments.php' == $pagenow ||  ( $_GET['page'] == 'freshdesk-menu-handle' ) ){
		if ( current_user_can( 'manage_options' ) ) {
			wp_enqueue_script( 'fd_plugin_js',FD_PLUGIN_URL . 'js/freshdesk_plugin_js.js', array( 'jquery' ) );
			wp_localize_script( 'fd_plugin_js', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
		}
	}
	wp_enqueue_style( 'fd_plugin_css',FD_PLUGIN_URL . 'css/freshdesk_plugin.css' );
	$feedback_options=get_option( 'freshdesk_feedback_options' );
	if ( $feedback_options['freshdesk_enable_feedback'] == "checked" ) {
		add_action( 'wp_footer', 'freshdesk_widget_code' );
	}
}

//Feedback widget code snippet include.
function freshdesk_widget_code() {
	$options = get_option( 'freshdesk_feedback_options' );
	echo $options['freshdesk_fb_widget_code'];
}

function freshdesk_handshake_secret() {
	
}

function freshdesk_sso_login_url($domain, $user_name, $email, $hash_key){
	return $domain."/login/sso?name=".urlencode($user_name)."&email=".urlencode($email)."&timestamp=".time()."&hash=".urlencode($hash_key);
}

//Ajax Action handler. Freshdesk Ticket creation handled here.
function fd_action_callback() {
	$id = $_POST['commentId'];	
	$comment = get_comment($id);
	$comment_link = get_comment_link( $comment, 'all' );
	$email = $comment->comment_author_email;
	$description = $comment->comment_content;
	$description = $description . "<br/><br/><a href=" . htmlentities($comment_link) . ">Go to comment</a>";
	$type = $comment->comment_type;
	$comment_meta = $comment->comment_agent;
	$comment_date = $comment->comment_date;
	$comment_post = $comment->comment_post_ID;
	$comment_author_name = $comment->comment_author;
	$subject = "comment id :".$id;
	$options = get_option( 'freshdesk_options' );
	$fd_api_handle = new Freshdesk_Plugin_Api( $options['freshdesk_api_key'], $options['freshdesk_domain_url'] );
	$result = $fd_api_handle->create_ticket( $email, $subject, $description );
	$response = array(
		'what'=>'helpdesk_ticket',
		'action'=>'create',
		'id'=>'1',
		'data'=>$result
	);
	
	$resp = add_comment_meta( $id, 'fd_ticket_id', $result, false );
	$xmlResponse = new WP_Ajax_Response( $response );
	$xmlResponse->send();
}


function freshdesk_show_msg( $message, $msgclass = 'info' ) {
	echo "<div id='message' class='$msgclass'>$message</div>";
}

function freshdesk_admin_msgs() {
	// check for our settings page - need this in conditional further down
	$wptuts_settings_pg = strpos( $_GET['page'], FD_PAGE_BASENAME );
	// collect setting errors/notices: //http://codex.wordpress.org/Function_Reference/get_settings_errors
	$set_errors = get_settings_errors();

	//display admin message only for the admin to see, only on our settings page and only when setting errors/notices are returned!
	if ( current_user_can ('manage_options') && $wptuts_settings_pg !== FALSE && ! empty( $set_errors ) ){
		// have our settings succesfully been updated?
		if ( $set_errors[0]['code'] == 'settings_updated' && isset( $_GET['settings-updated'] ) ) {
			freshdesk_show_msg("<p>" . $set_errors[0]['message'] . "</p>", 'updated');
		} else {
			// there maybe more than one so run a foreach loop.
			foreach ( $set_errors as $set_error ) {
				// set the title attribute to match the error "setting title" - need this in js file
				freshdesk_show_msg("<p class='setting-error-message' title='" . $set_error['setting'] . "'>" . $set_error['message'] . "</p>", 'error');
			}
		}
	}
}
?>
<?php

/* Fresdesk Api class
* Adding functionality to create ticket.
*/
class Freshdesk_Plugin_Api{

private $apikey, $domain_url, $response, $response_status;

	public function __construct($apikey, $domain_url){
		$this->apikey = $apikey;
		$this->domain_url = $domain_url;
	}	

	function create_ticket($email,$subject,$description){
		$datafields =  array (
     									"helpdesk_ticket" =>array("subject"=>$subject,"description_html"=>$description,"email"=>$email)
     								);
 		$jsondata= json_encode($datafields);
 		$this->make_request($this->domain_url."/helpdesk/tickets.json",$jsondata,$header);
 		if($this->response_status!= 200){
 			return -1;
 		}
 		return $this->response;
	}

	private function make_request($requestUri,$payload){
		$ch = curl_init ($requestUri);
 		$header[] = "Content-type: application/json";
		curl_setopt($ch, CURLOPT_POST, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS,$payload);
		$user_pwd = $this->auth_method();
		// echo "value:".$user_pwd."##";
		curl_setopt($ch, CURLOPT_USERPWD,$user_pwd);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
		curl_setopt($ch, CURLOPT_HEADER, false);
		// receive server response ...
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
		$server_output = curl_exec ($ch);

		$fd_response = json_decode($server_output);
		// echo "RESPONSE:<br/>".var_dump($this->response);
		$this->response_status = curl_getinfo($ch,CURLINFO_HTTP_CODE);
		$this->response = $fd_response->{'helpdesk_ticket'}->{'display_id'};
		curl_close ($ch);
	}

	function get_response(){
		return $this->response;
	}

	function get_response_status(){
		return $this->response_status;
	}

	private function auth_method(){
		return $this->apikey.":X";
	}


}
?>
jQuery(document).ready(function($){

	toggle_url();	

	$('.fd_convert_ticket').on('click',function(evt){
		evt.preventDefault();
		var comment_link = this;
		// var ticket_link= $(this).find('fd_ticket_link').first();
		var commentId= $(this).attr('id');
		var ticketId= $(this).attr('ticket_id');
		var href= $(this).attr('domain_url');

		if(ticketId == undefined){
			var data = {
				action: 'fd_ticket_action',
				commentId: commentId
			};

				// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
			$.post(ajaxurl, data, function(response) {
				resp = jQuery(response).find('response_data').text();
				$(comment_link).text('View Ticket');
				if(resp == -1){
					alert('Got this from the server: ' + resp);
				}
				else{
				$(comment_link).attr('ticket_id',resp);
					confirm('Ticket #'+resp+' created Successfully.');
				}

			});
		}
		else{
			window.open(href+"/helpdesk/tickets/"+ticketId, '_blank');
		}
	});

	if($('#freshdesk_enable_feedback')[0].checked){
		toggle_feedback_widget();
	}

	$('#freshdesk_enable_feedback').on('click',function(){
		toggle_feedback_widget();
	});

	if($('#freshdesk_enable_sso')[0].checked){
	 	toggle_sso();
	}
	$('#freshdesk_enable_sso').on('click',function(){
		toggle_sso();
	});
	$('#freshdesk_domain_url').on('blur',function(){
		toggle_url();
	});

	function toggle_url(){
		if($('#freshdesk_domain_url').val() != ''){
			$('.freshdesk_sso_settings').slideDown();
			url = $('#freshdesk_domain_url').val();
			$('.freshdesk_helpdesk_url').find('a').each(function(){
				$(this).attr('href',url+'/admin/security');
			});
			$('.freshdesk_widget_url').find('a').first().attr('href',url+'/admin/widget_config');
			return;
		}
		$('.freshdesk_sso_settings').slideUp();
	}

	function toggle_feedback_widget(){
		if($('#freshdesk_enable_feedback')[0].checked){
			$('#freshdesk_feedback_widget_id').slideDown();
			$('#freshdesk_fb_widget_code').prop('disabled',false);
			return;
		}
		$('#freshdesk_fb_widget_code').prop('disabled',true);
		$('#freshdesk_feedback_widget_id').slideUp();
	}

	function toggle_sso(){
		if($('#freshdesk_enable_sso')[0].checked){
			$('#freshdesk_sso_options').slideDown();
			//$('#freshdesk_fb_widget_code').prop('disabled',false);
			return;
		}
		//$('#freshdesk_fb_widget_code').prop('disabled',true);
		$('#freshdesk_sso_options').slideUp();
	}

});
=== Freshdesk Official===
Contributors: hjohnpaul, sathishfreshdesk, balakumars, shreyasns
Donate link: 
Tags: freshdesk, helpdesk, support tool
Requires at least: 3.4
Tested up to: 4.1.5
Stable tag: 1.8
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html


Freshdesk Official plugin is a seamless way to add your helpdesk account to your website. Supports various useful functions.

==Description==

Freshdesk Official plugin enables users to achieve three important functions:

- Avoid additional login to helpdesk if the user has already logged in to WP(Single Sign On).
- Effortlessly integrate the helpdesk' s feedback widget along with solutions search to his wordpress site.
- Allows the site admin to convert comments into helpdesk tickets.
- Adding the comment link to ticket description.

1. Single Sign On:
Users can now login to their helpdesk(freshdesk) support portal using Wordpress authentication. The single sign on feature ensures that users who have already logged into their Wordpress site can start working in their Freshdesk support portal as well without having to log in separately. 

2. Feedback Pop-up Widget:
The plugin allows Wordpress users to have a Freshdesk feedback widget embedded in their wordpress site. The widget allows people visiting the site to provide feedback and search for answers.

3. Convert Comments to Tickets on helpdesk:
Users with admin access to their Wordpress sites can convert comments into “Tickets”. The marked comments are sent to the user’s support portal that can be solved or responded to later.

4. Adding the comment link-back in the ticket added:
   Comments converted to tickets in freshdesk will now have the link-back url to the actual comment in the wordpress site appended in its description.

== Installation ==
* For an automatic installation through WordPress
1. Go to the 'Add New' plugins screen in your WordPress admin area.
2. Search for 'Freshdesk Official' plugin.
3. Click 'Install Now' and activate the plugin.


Manual Installation:

1. Download the latest version of 'Freshdesk Official'  plugin from the WordPress Plugin Directory.
2. Extract the zip and Upload the freshdesk_support directory to your /wp-content/plugins directory
3. Go to the plugins management page and activate the plugin
4. You now have a new admin menu 'Freshdesk Official' in your WordPress admin menu bar. Click on it and Configure your settings as mentioned in the info comments in the screen.

== Frequently Asked Questions ==
1. Where do i find sso shared secret ?

  SSO shared secret will be available in your helpdesk account's admin -> security -> sso section.

2. How can login to my helpdesk using normal login screen after enabling sso ?

  You can always access your help desk's normal login screen using http://yourcompany.freshdesk.com/login/normal link.

3. Where can I find the feedback widget code snippet ?

  Feedback widget code has to be copied from the admin -> feedback section. You can configure the alignment and kbase search hide and much more here and copy the generate code snippet.

== Screenshots ==
1. This screen shot shows the Settings Screen.
2. This shows the comments page where a new action('Convert to ticket') added to make the comment as a ticket.
3. This shows the comments page with 'View Ticket' option showing if the comment is already converted to ticket.
4. This shows the comment link in the ticket description.

== Changelog ==
= 1.8 =
  Security fix for open redirect vulnerablity. Now users are required to configure all the portal urls in the settings page.
= 1.7 =
  Added option to enable/disable sso.
  Logging out of wordpress no longer logs out the Freshdesk session.
  Added validations for the settings page.
  Fixed the error showing up on the plugin settings page.
= 1.6 =
  Fix the SSO login redirect to Freshdesk and on wordpress logout, logout of Freshdesk as well.
= 1.5 =
  Includes fix for SSO and Vanity URL redirect.
= 1.4 =
  Bug fix for SSO and Vanity URL redirect.
= 1.3 =
 Added comment link to ticket description
= 1.2 =
 Fix for the error message("The plugin does not have a valid header.") on enabling plugin 
= 1.1 =
Previous revision. 
Bug Fix:
 - Freshdesk remote log-in failing for new users.
 - Sign-out from freshdesk does not logout wordpress session. 
= 1.0 =
First Release Version.

== Upgrade Notice ==
  Security fix for open redirect vulnerablity. Now users are required to configure all the portal urls in the settings page.
= 1.8 =
  Security fix for open redirect vulnerablity. Now users are required to configure all the portal urls in the settings page.  
== 1.7 ==
  Added option to enable/disable sso.
  Logging out of wordpress will no longer logout the Freshdesk session.
  Added validations for the settings page.
  Fixed the error showing up on the plugin settings page.
== 1.6 ==
  Fix for SSO login redirect back to Freshdesk.
  Change logout url to Freshdesk logout url so that Freshdesk is also logged out.
== 1.5 ==
  Fixing problem with 1.4 getting listed as development version.
  Includes bug fix for SSO and Vanity URL redirect.
== 1.4 ==
  Bug fix for SSO and Vanity URL redirect.
  Now works with SSO and Vanity URL.
== 1.3 ==
 Added comment link to ticket description.
== 1.2 ==
 Fix for the error message on enabling the plugin.
== 1.1 ==
  Revision with bugs addressed.
== 1.0 ==
This is the First release version.