Changeset 2103252
- Timestamp:
- 06/10/2019 11:47:56 AM (7 years ago)
- Location:
- clinked-client-portal/trunk
- Files:
-
- 4 edited
-
assets/js/clinked.js (modified) (3 diffs)
-
clinked-wordpress-plugin.php (modified) (2 diffs)
-
readme.txt (modified) (3 diffs)
-
views/login.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
clinked-client-portal/trunk/assets/js/clinked.js
r1929745 r2103252 7 7 $.each(options, function (key, value) { 8 8 params.push(key + '=' + value); 9 }) 9 }); 10 10 return root.data('ajax') + '?' + params.join('&'); 11 11 } … … 22 22 var root = element.parents('.clinked-container'); 23 23 var errorView = root.find('.clinked-error'); 24 24 25 25 errorView.hide(); 26 26 27 var redirect = function () {27 var redirect = function () { 28 28 // Pass event to default handler by resubmitting the form 29 29 container.unbind('submit'); 30 30 element.submit(); 31 31 }; 32 33 $.post(url(element), element.serializeArray() )32 33 $.post(url(element), element.serializeArray(), 'json') 34 34 .success(function () { 35 35 redirect(); … … 37 37 .error(function (request, textStatus, errorThrown) { 38 38 var json = JSON.parse(request.responseText); 39 switch (json.error) {39 switch (json.error) { 40 40 case 'missing_2fa': 41 41 // username and password are valid, a user will land to 2FA code input form page -
clinked-client-portal/trunk/clinked-wordpress-plugin.php
r2029374 r2103252 39 39 // Make sure we don't expose any info if called directly 40 40 if ( !function_exists( 'add_action' ) ) { 41 echo 'Hi there! I\'m just a plugin, not much I can do when called directly.';42 exit;41 echo 'Hi there! I\'m just a plugin, not much I can do when called directly.'; 42 exit; 43 43 } 44 44 … … 47 47 48 48 function _action($name, $handler) { 49 add_action("wp_ajax_" . $name, $handler);50 add_action("wp_ajax_nopriv_" . $name, $handler);49 add_action("wp_ajax_" . $name, $handler); 50 add_action("wp_ajax_nopriv_" . $name, $handler); 51 51 } 52 52 53 53 class ClinkedLogin_Widget extends WP_Widget { 54 protected $widget_slug = "clinked-login-widget"; 55 protected $widget_name = "Clinked Login Widget"; 56 57 protected static $shortcode = 'clinked-login'; 58 59 public static function get_widget($atts = [], $content = null, $tag = '') { 60 $atts = shortcode_atts([ 61 "portal_url" => "https://app.clinked.com", 62 "before_widget" => "", 63 "after_widget" => "", 64 "before_title" => "", 65 "after_title" => "", 66 "title" => "", 67 "text" => "", 68 "widget_id" => "", 69 ], $atts); 70 71 if (empty($atts['widget_id'])) { 72 global $_SESSION; 73 74 $widgetOptions = (object) $atts; 75 76 // store a random widget options in the sesssion 77 $widget_id = "clinked-" . spl_object_hash($widgetOptions); 78 79 $_SESSION[$widget_id] = $widgetOptions; 80 $atts['widget_id'] = $widget_id; 81 } 82 83 $model = [ 84 "portal_url" => $atts["portal_url"] 85 ]; 86 87 // Before widget hook. 88 $widget .= $atts["before_widget"]; 89 $widget .= ($atts["title"]) ? $atts["before_title"] . esc_html($atts["title"]) . $atts["after_title"] : ""; 90 $widget .= wpautop(wp_kses_post($atts["text"])); 91 92 $widget .= '<div class="clinked-container" data-ajax="' . admin_url("admin-ajax.php") . '" data-widget="' . $atts["widget_id"] . '">'; 93 94 $widget .= self::build_view($atts["widget_id"], 'login', $model); 95 $widget .= '</div>'; 96 97 // After widget hook. 98 $widget .= $atts["after_widget"]; 99 return $widget; 100 } 101 102 /** 103 * Render a view. 104 * 105 * @param unknown $widget widget 106 * @param unknown $view view 107 */ 108 public static function build_view($widget, $view, $model = []) { 109 if (empty($widget) || empty($view) || !preg_match("/^[a-zA-Z_]+$/", $view)) { 110 http_response_code(400); 54 protected $widget_slug = "clinked-login-widget"; 55 protected $widget_name = "Clinked Login Widget"; 56 57 protected static $shortcode = 'clinked-login'; 58 59 public static function get_widget($atts = [], $content = null, $tag = '') { 60 $atts = shortcode_atts([ 61 "portal_url" => "https://app.clinked.com", 62 "password_placeholder" => "Password", 63 "email_placeholder" => "E-mail address", 64 "username_label" => "", 65 "password_label" => "", 66 "container_class" => "", 67 "input_class" => "", 68 "button_class" => "", 69 "before_widget" => "", 70 "after_widget" => "", 71 "before_title" => "", 72 "after_title" => "", 73 "title" => "", 74 "text" => "", 75 "widget_id" => "", 76 ], $atts); 77 78 if (empty($atts['widget_id'])) { 79 global $_SESSION; 80 81 $widgetOptions = (object) $atts; 82 83 // store a random widget options in the sesssion 84 $widget_id = "clinked-" . spl_object_hash($widgetOptions); 85 86 $_SESSION[$widget_id] = $widgetOptions; 87 $atts['widget_id'] = $widget_id; 88 } 89 90 $containerClasses = Array('clinked-container'); 91 if (!empty($atts['container_class'])) { 92 array_push($containerClasses, $atts['container_class']); 93 } 94 $inputClasses = Array(); 95 if (!empty($atts['input_class'])) { 96 $inputClasses = array_merge($inputClasses, explode(',', $atts['input_class'])); 97 } 98 $atts['inputClasses'] = $inputClasses; 99 100 $buttonClasses = Array(); 101 if (!empty($atts['button_class'])) { 102 $buttonClasses = array_merge($buttonClasses, explode(',', $atts['button_class'])); 103 } 104 $atts['buttonClasses'] = $buttonClasses; 105 106 // Before widget hook. 107 $widget .= $atts["before_widget"]; 108 $widget .= ($atts["title"]) ? $atts["before_title"] . '<h2>' . esc_html($atts["title"]) . '</h2>'. $atts["after_title"] : ""; 109 $widget .= wpautop(wp_kses_post($atts["text"])); 110 111 $widget .= '<div class="' . join(' ', $containerClasses) . '" data-ajax="' . admin_url("admin-ajax.php") . '" data-widget="' . $atts["widget_id"] . '">'; 112 $widget .= self::build_view($atts["widget_id"], 'login', $atts); 113 $widget .= '</div>'; 114 115 // After widget hook. 116 $widget .= $atts["after_widget"]; 117 return $widget; 118 } 119 120 /** 121 * Render a view. 122 * 123 * @param unknown $widget widget 124 * @param unknown $view view 125 */ 126 public static function build_view($widget, $view, $model = []) { 127 if (empty($widget) || empty($view) || !preg_match("/^[a-zA-Z_]+$/", $view)) { 128 http_response_code(400); 129 } 130 // Attempt to call function that would build the model for view 131 $fn = [__CLASS__, "handle_" . $view . "_model"]; 132 if (is_callable($fn)) { 133 $model = array_merge($model, call_user_func($fn, $model)); 134 } 135 return self::render_view($view, $model); 136 } 137 138 public function __construct() { 139 $this->widget_name = esc_html__("Clinked Contact Area", "clinked"); 140 $this->default_widget_title = esc_html__("Clinked Contact Area", "clinked"); 141 142 parent::__construct($this->widget_slug, $this->widget_name, [ 143 "classname" => $this->widget_slug, 144 "description" => esc_html__("Please use your credentials to login", "clinked"), 145 ]); 146 147 add_action("switch_theme", [$this, "flush_widget_cache"]); 148 add_shortcode(self::$shortcode, [__CLASS__, "get_widget"]); 149 150 // ajax actions 151 _action("clinked_login", [$this, "handle_login_action"]); 152 } 153 154 public function handle_login_action() { 155 $username = $_POST["username"]; 156 $password = $_POST["password"]; 157 158 # Authenticate using username and password to check if credentials are valid 159 $curl = curl_init(); 160 curl_setopt_array($curl, array( 161 CURLOPT_URL => "https://api-p1.clinked.com/oauth/token?grant_type=password&client_id=clinked-mobile&username=$username&password=$password", 162 CURLOPT_RETURNTRANSFER => true, 163 CURLOPT_ENCODING => "", 164 CURLOPT_MAXREDIRS => 10, 165 CURLOPT_TIMEOUT => 30, 166 CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, 167 CURLOPT_CUSTOMREQUEST => "GET", 168 )); 169 $response = curl_exec($curl); 170 $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); 171 $err = curl_error($curl); 172 curl_close($curl); 173 174 if ($err || $httpcode < 200 || $httpcode > 299) { 175 http_response_code(400); 176 echo $response; 177 } else { 178 http_response_code(200); 179 } 180 die(); 181 } 182 183 /** 184 * Outputs the content of the widget 185 * 186 * @param array $args 187 * @param array $instance 188 */ 189 public function widget( $args, $instance ) { 190 echo self::get_widget(); 191 } 192 193 public static function render_view($name, $model) { 194 if (!preg_match("/^[\w_]+$/", $name)) { 195 return "Unknown template"; 196 } 197 $path = self::dir("views/" . $name . ".php"); 198 if (!file_exists($path)) { 199 return "Unknown template"; 200 } 201 if (is_string($model) && is_callable($model)) { 202 $model = call_user_func_array($model); 203 } 204 ob_start(); 205 if (is_array($model)) { 206 foreach ($model as $key => $value) { 207 ${$key} = $value; 111 208 } 112 113 // Attempt to call function that would build the model for view 114 $fn = [__CLASS__, "handle_" . $view . "_model"]; 115 if (is_callable($fn)) { 116 $model = array_merge($model, call_user_func($fn, $model)); 117 } 118 119 return self::render_view($view, $model); 120 } 121 122 public function __construct() { 123 $this->widget_name = esc_html__("Clinked Contact Area", "clinked"); 124 $this->default_widget_title = esc_html__("Clinked Contact Area", "clinked"); 125 126 parent::__construct( 127 $this->widget_slug, 128 $this->widget_name, 129 [ 130 "classname" => $this->widget_slug, 131 "description" => esc_html__("Please use your credentials to login", "clinked"), 132 ] 133 ); 134 135 add_action("switch_theme", [$this, "flush_widget_cache"]); 136 add_shortcode(self::$shortcode, [__CLASS__, "get_widget"]); 137 138 // ajax actions 139 _action("clinked_login", [$this, "handle_login_action"]); 140 } 141 142 public function handle_login_action() { 143 $username = $_POST["username"]; 144 $password = $_POST["password"]; 145 146 # Authenticate using username and password to check if credentials are valid 147 $curl = curl_init(); 148 curl_setopt_array($curl, array( 149 CURLOPT_URL => "https://api-p1.clinked.com/oauth/token?grant_type=password&client_id=clinked-mobile&username=$username&password=$password", 150 CURLOPT_RETURNTRANSFER => true, 151 CURLOPT_ENCODING => "", 152 CURLOPT_MAXREDIRS => 10, 153 CURLOPT_TIMEOUT => 30, 154 CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, 155 CURLOPT_CUSTOMREQUEST => "GET", 156 )); 157 $response = curl_exec($curl); 158 $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); 159 $err = curl_error($curl); 160 curl_close($curl); 161 162 if ($err || $httpcode < 200 || $httpcode > 299) { 163 echo $response; 164 die(http_response_code(400)); 165 } else { 166 die(http_response_code(200)); 167 } 168 } 169 170 /** 171 * Outputs the content of the widget 172 * 173 * @param array $args 174 * @param array $instance 175 */ 176 public function widget( $args, $instance ) { 177 echo self::get_widget(); 178 } 179 180 public static function render_view($name, $model) { 181 if (!preg_match("/^[\w_]+$/", $name)) { 182 return "Unknown template"; 183 } 184 $path = self::dir("views/" . $name . ".php"); 185 if (!file_exists($path)) { 186 return "Unknown template"; 187 } 188 if (is_string($model) && is_callable($model)) { 189 $model = call_user_func_array($model); 190 } 191 192 ob_start(); 193 if (is_array($model)) { 194 foreach ($model as $key => $value) { 195 ${$key} = $value; 196 } 197 } 198 include($path); 199 $result = ob_get_contents(); 200 ob_end_clean(); 201 202 return $result; 203 } 204 205 public static function dir($path = "") { 206 static $dir; 207 $dir = $dir ? $dir : trailingslashit(dirname(__FILE__)); 208 return $dir . $path; 209 } 210 211 public static function url($path = "") { 212 static $url; 213 $url = $url ? $url : trailingslashit(plugin_dir_url(__FILE__)); 214 return $url . $path; 215 } 209 } 210 include($path); 211 $result = ob_get_contents(); 212 ob_end_clean(); 213 return $result; 214 } 215 216 public static function dir($path = "") { 217 static $dir; 218 $dir = $dir ? $dir : trailingslashit(dirname(__FILE__)); 219 return $dir . $path; 220 } 221 222 public static function url($path = "") { 223 static $url; 224 $url = $url ? $url : trailingslashit(plugin_dir_url(__FILE__)); 225 return $url . $path; 226 } 216 227 } 217 228 218 229 function on_loaded() { 219 wp_enqueue_script("clinked-widget", ClinkedLogin_Widget::url("assets/js/clinked.js"), ["jquery"]);220 register_widget("ClinkedLogin_Widget");221 222 if (!session_id()) { 223 session_start(); 224 }225 } 230 wp_enqueue_script("clinked-widget", ClinkedLogin_Widget::url("assets/js/clinked.js"), ["jquery"]); 231 register_widget("ClinkedLogin_Widget"); 232 if (!session_id()) { 233 session_start(); 234 } 235 } 236 226 237 add_action("widgets_init", "on_loaded"); -
clinked-client-portal/trunk/readme.txt
r2029379 r2103252 4 4 Requires at least: 3.0 5 5 Tested up to: 5.0 6 Stable tag: 1. 26 Stable tag: 1.3 7 7 License: MIT 8 8 License URI: https://mit-license.org/ … … 101 101 * Updated a logo. 102 102 103 = 1.3 = 104 * Aditional attributes to customize the login form. 105 106 103 107 == Upgrade Notice == 104 108 … … 112 116 No upgrade notice necessary. 113 117 118 = 1.3 = 119 No upgrade notice necessary. 120 -
clinked-client-portal/trunk/views/login.php
r1929745 r2103252 1 <div class="clinked-error" >2 <?php esc_html_e('Invalid e-mail address or password.', 'clinked' ); ?>1 <div class="clinked-error" style="display: none"> 2 <?php esc_html_e('Invalid e-mail address or password.', 'clinked' ); ?> 3 3 </div> 4 <form method="post" class="clinked-login" action="<?php echo $portal_url."/login" ?>"> 5 <input type="hidden" name="login-url" value="<?php echo $portal_url."/login" ?>"> 6 <input type="hidden" name="action" value="clinked_login"> 4 7 5 <form method="post" class="clinked-login" action="<?php echo $portal_url."/login" ?>"> 6 <?php wp_nonce_field( 'clinked_login' ); ?> 7 <p> 8 <input id="clinked-login-form-username" type="text" name="username" autocomplete="off" placeholder="<?php _e('E-mail address', 'clinked'); ?>" value="<?php echo $_POST["username"] ?>"> 9 </p> 10 <p> 11 <input id="clinked-login-form-password" type="password" name="password" autocomplete="off" placeholder="<?php _e('Password', 'clinked'); ?>" value="<?php echo $_POST["password"] ?>"> 12 </p> 13 <p class="submit"> 14 <input type="submit" id="submit-button" value="<?php _e('Login', 'clinked'); ?>"> 15 <input type="hidden" name="login-url" value="<?php echo $portal_url."/login" ?>"> 16 <input type="hidden" name="action" value="clinked_login"> 17 </p> 8 <?php wp_nonce_field( 'clinked_login' ); ?> 9 <p class="clinked-form-group"> 10 <?php if (!empty($username_label)): ?> 11 <label for="clinked-login-form-username"><?php echo _e($username_label, 'clinked'); ?></label> 12 <?php endif; ?> 13 <input id="clinked-login-form-username" class="<?php echo join($inputClasses); ?>" type="text" name="username" autocomplete="off" placeholder="<?php _e($email_placeholder, 'clinked'); ?>" value="<?php echo $_POST["username"] ?>"> 14 </p> 15 <p class="clinked-form-group"> 16 <?php if (!empty($password_label)): ?> 17 <label for="clinked-login-form-password"><?php echo _e($password_label, 'clinked'); ?></label> 18 <?php endif; ?> 19 <input id="clinked-login-form-password" class="<?php echo join(' ', $inputClasses); ?>" type="password" name="password" autocomplete="off" placeholder="<?php _e($password_placeholder, 'clinked'); ?>" value="<?php echo $_POST["password"] ?>"> 20 </p> 21 <p class="clinked-form-group"> 22 <button type="submit" class="<?php echo join(' ', $buttonClasses); ?>" id="clinked-submit-button"><?php _e('Login', 'clinked'); ?></button> 23 </p> 18 24 </form>
Note: See TracChangeset
for help on using the changeset viewer.