/**
  * Add links to additional actions to the actions links in the plugins list
  *
  * @param $links
  *
  * @return array
  *
  * @since 1.0.0
  */
 public function add_action_links($links)
 {
     static $template = '<a href="%s">%s</a>';
     $links[] = sprintf($template, $this->get_settings_page(true), $this->wp_facade->__('Setup Wizard', $this->language_domain));
     $links[] = sprintf($template, $this->get_settings_page(), $this->wp_facade->__('Settings', $this->language_domain));
     return $links;
 }
 /**
  * @param array $input
  * @param array $errors
  * @param array $options
  */
 private function process_standard_options(&$input, &$errors, &$options)
 {
     if (empty($input[LaunchKey_WP_Options::OPTION_ROCKET_KEY])) {
         $errors[] = $this->wp_facade->__('Rocket Key is a required field', $this->language_domain);
     } else {
         $rocket_key = trim($input[LaunchKey_WP_Options::OPTION_ROCKET_KEY]);
         if (!is_numeric($rocket_key)) {
             $errors[] = $this->wp_facade->__('Rocket Key must be numeric', $this->language_domain);
         } elseif (strlen($rocket_key) !== 10) {
             $errors[] = $this->wp_facade->__('Rocket Key must be 10 digits', $this->language_domain);
         } else {
             $options[LaunchKey_WP_Options::OPTION_ROCKET_KEY] = $rocket_key;
         }
     }
     if (empty($input[LaunchKey_WP_Options::OPTION_SECRET_KEY]) && empty($options[LaunchKey_WP_Options::OPTION_SECRET_KEY])) {
         $errors[] = $this->wp_facade->__('Secret Key is a required field', $this->language_domain);
     } else {
         if (!empty($input[LaunchKey_WP_Options::OPTION_SECRET_KEY])) {
             $secret_key = trim($input[LaunchKey_WP_Options::OPTION_SECRET_KEY]);
             if (!ctype_alnum($secret_key)) {
                 $errors[] = $this->wp_facade->__('Secret Key must be alphanumeric', $this->language_domain);
             } elseif (strlen($secret_key) !== 32) {
                 $errors[] = $this->wp_facade->__('Secret Key must be 32 characters', $this->language_domain);
             } else {
                 $options[LaunchKey_WP_Options::OPTION_SECRET_KEY] = $secret_key;
             }
         }
     }
     $app_display_name = isset($input[LaunchKey_WP_Options::OPTION_APP_DISPLAY_NAME]) ? trim($input[LaunchKey_WP_Options::OPTION_APP_DISPLAY_NAME]) : null;
     if ('LaunchKey' !== $app_display_name && LaunchKey_WP_Implementation_Type::WHITE_LABEL !== $options[LaunchKey_WP_Options::OPTION_IMPLEMENTATION_TYPE]) {
         $errors[] = $this->wp_facade->__('App Display Name can only be modified for White Label implementations', $this->language_domain);
         $options[LaunchKey_WP_Options::OPTION_APP_DISPLAY_NAME] = 'LaunchKey';
     } else {
         $options[LaunchKey_WP_Options::OPTION_APP_DISPLAY_NAME] = $app_display_name ?: null;
     }
     if (empty($_FILES['private_key']['tmp_name']) && empty($options[LaunchKey_WP_Options::OPTION_PRIVATE_KEY]) && isset($options[LaunchKey_WP_Options::OPTION_IMPLEMENTATION_TYPE]) && LaunchKey_WP_Implementation_Type::requires_private_key($options[LaunchKey_WP_Options::OPTION_IMPLEMENTATION_TYPE])) {
         $errors[] = $this->wp_facade->__('Private Key is required', $this->language_domain);
     } else {
         if (!empty($_FILES['private_key']['tmp_name'])) {
             $private_key = @file_get_contents($_FILES['private_key']['tmp_name']);
             $rsa = new Crypt_RSA();
             if (@$rsa->loadKey($private_key)) {
                 if ($rsa->getPrivateKey($rsa->privateKeyFormat)) {
                     $options[LaunchKey_WP_Options::OPTION_PRIVATE_KEY] = $private_key;
                 } else {
                     $errors[] = $this->wp_facade->__('The Key file provided was a valid RSA key file but did not contain a private key.  Did you mistakenly supply the public key file?', $this->language_domain);
                 }
             } else {
                 $errors[] = $this->wp_facade->__('The Private Key provided was invalid', $this->language_domain);
             }
         }
     }
 }
 /**
  * Compile the data that will be used by the front end to generate a QR Code for WordPress auto-config.
  * @since 1.4.0
  */
 public function wizard_easy_setup_qr_code()
 {
     if (isset($_POST['nonce'])) {
         if ($this->wp_facade->wp_verify_nonce($_POST['nonce'], static::WIZARD_NONCE_KEY) && $this->wp_facade->current_user_can('manage_options')) {
             $lk_nonce = $this->launchkey_client->auth()->nonce();
             $this->update_option(static::EASY_SETUP_OPTION, array('nonce' => $lk_nonce, 'username' => $this->wp_facade->wp_get_current_user()->user_login));
             $payload = json_encode(array('nonce' => $lk_nonce->getNonce(), 'payload' => array('callback_url' => $this->admin->get_callback_url(), 'rocket_name' => $this->wp_facade->get_bloginfo('name'))));
             $qr_data = base64_encode($payload);
             $response['nonce'] = $this->wp_facade->wp_create_nonce(static::WIZARD_NONCE_KEY);
             $response['qr_code'] = $qr_data;
         } else {
             $response['errors'] = $this->wp_facade->__("An error occurred submitting the page.  Please refresh the page and submit again.");
         }
         $this->wp_facade->wp_send_json($response);
     }
 }
 /**
  * @param $user_id
  * @param $launchkey_username
  *
  * @return null|WP_Error
  */
 private function authenticate_user($user_id, $launchkey_username)
 {
     // reset user authentication
     $this->reset_auth($user_id);
     // Get the auth client from the SDK
     $auth = $this->launchkey_client->auth();
     try {
         // Authenticate and get the request ID
         $auth_request = $auth->authenticate($launchkey_username)->getAuthRequestId();
         // Set the auth request ID in the user metadata to be available to the server side event
         $this->wp_facade->update_user_meta($user_id, 'launchkey_auth', $auth_request);
         // Loop until a response has been recorded by the SSE callback
         do {
             // Sleep before checking for the response to not kill the server
             sleep(1);
             // See if the user has authorized
             $auth = $this->get_user_authorized($user_id);
         } while (null === $auth);
         // If the response is null, continue the loop
         if ($auth) {
             // If the user accepted, return true
             $response = true;
         } else {
             // Otherwise, return an error
             $response = new WP_Error('launchkey_authentication_denied', $this->wp_facade->__('Authentication denied!', $this->language_domain));
         }
     } catch (Exception $e) {
         // Process exceptions appropriately
         $response = new WP_Error();
         if ($e instanceof \LaunchKey\SDK\Service\Exception\NoPairedDevicesError) {
             $response->add('launchkey_authentication_denied', $this->wp_facade->__('No Paired Devices!', $this->language_domain));
         } elseif ($e instanceof \LaunchKey\SDK\Service\Exception\NoSuchUserError) {
             $response->add('launchkey_authentication_denied', $this->wp_facade->__('Authentication denied!', $this->language_domain));
         } elseif ($e instanceof \LaunchKey\SDK\Service\Exception\RateLimitExceededError) {
             $response->add('launchkey_authentication_denied', $this->wp_facade->__('Authentication denied!', $this->language_domain));
         } elseif ($e instanceof \LaunchKey\SDK\Service\Exception\ExpiredAuthRequestError) {
             $response->add('launchkey_authentication_timeout', $this->wp_facade->__('Authentication denied!', $this->language_domain));
         } else {
             if ($this->wp_facade->is_debug_log()) {
                 $this->wp_facade->error_log('Error authenticating user with Launchkey: ' . $e->getMessage());
             }
             $response->add('launchkey_authentication_error', $this->wp_facade->__('Authentication error!  Please try again later', $this->language_domain));
         }
     }
     return $response;
 }
 public function wizard_submit_ajax()
 {
     if (isset($_POST['nonce'])) {
         if ($this->wp_facade->wp_verify_nonce($_POST['nonce'], static::WIZARD_NONCE_KEY)) {
             list($options, $errors) = $this->admin->check_option($_POST);
             if ($errors) {
                 $response["errors"] = $errors;
             } else {
                 $this->wp_facade->update_option(LaunchKey_WP_Admin::OPTION_KEY, $options);
             }
             $response['nonce'] = $this->wp_facade->wp_create_nonce(static::WIZARD_NONCE_KEY);
         } else {
             $response["errors"] = $this->wp_facade->__("An error occurred submitting the page.  Please refresh the page and submit again.");
         }
         $this->wp_facade->wp_send_json($response);
     }
 }
 /**
  * Complete the pairing process based on the authentication attempt
  * Errors will displayed to the user by the pair_errors_callback
  * @since 1.0.0
  */
 public function pair_callback()
 {
     // launchkey_username in the post means it's a pairing attempt
     if (array_key_exists('launchkey_username', $_POST)) {
         $user = $this->wp_facade->wp_get_current_user();
         // If there is no valid nonce, set the pair error
         if (!$this->wp_facade->wp_verify_nonce($_POST['launchkey_nonce'], LaunchKey_WP_User_Profile::NONCE_KEY)) {
             $this->pair_error = new WP_Error('launchkey_pair_error', $this->wp_facade->__('Invalid nonce.  Please try again.', $this->language_domain));
         } elseif (!$user) {
             // If there is no user, set the pair error
             $this->pair_error = new WP_Error('launchkey_pair_error', $this->wp_facade->__('You must me logged in to pair', $this->language_domain));
         } elseif (!$_POST['launchkey_username']) {
             // If the launchkey_username is blank, set the pair error
             $this->pair_error = new WP_Error('launchkey_pair_error', $this->wp_facade->__('Username is required to pair', $this->language_domain));
         } else {
             // Otherwise, attempt to pair the LaunchKey userusing the supplied launchkey_username
             $response = $this->authenticate_user($user->ID, $_POST['launchkey_username']);
             // If there was an error during the authentication process, set the pair error
             if ($this->wp_facade->is_wp_error($response)) {
                 $this->pair_error = $response;
             }
         }
     }
 }