Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add license key to auth button #85

Merged
merged 17 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/Uplink/Admin/Ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace StellarWP\Uplink\Admin;

use StellarWP\ContainerContract\ContainerInterface;
use StellarWP\Uplink\Auth\Auth_Url_Builder;
use StellarWP\Uplink\Config;
use StellarWP\Uplink\Resources\Collection;
use StellarWP\Uplink\Utils;
Expand Down Expand Up @@ -55,12 +56,17 @@ public function validate_license(): void {
] );
}

$results = $plugin->validate_license( $submission['key'] );
$message = is_plugin_active_for_network( $plugin->get_path() ) ? $results->get_network_message()->get() : $results->get_message()->get();
$results = $plugin->validate_license( $submission['key'] );
$message = is_plugin_active_for_network( $plugin->get_path() ) ? $results->get_network_message()->get() : $results->get_message()->get();
$auth_url = Config::get_container()
->get( Auth_Url_Builder::class )
->set_license( $submission['key'] )
->build( $submission['slug'], get_site_url() );

wp_send_json( [
'status' => absint( $results->is_valid() ),
'message' => $message,
'auth_url' => $auth_url,
] );
}

Expand Down
15 changes: 2 additions & 13 deletions src/Uplink/Admin/Fields/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,22 +237,11 @@ public function get_render_html(): string {

$args = [
'field' => $this,
'resource' => $this->resource,
'group' => $this->group->get_name( $this->get_slug() ),
];

if ( $this->resource->is_using_oauth() ) {
ob_start();

if ( $this->resource->oauth_requires_license_key() ) {
echo $this->view->render( self::VIEW, $args );
}

UplinkNamespace\render_authorize_button( $this->get_slug() );

$html = (string) ob_get_clean();
} else {
$html = $this->view->render( self::VIEW, $args );
}
$html = $this->view->render( self::VIEW, $args );

/**
* Filters the field HTML.
Expand Down
9 changes: 8 additions & 1 deletion src/Uplink/Auth/Auth_Url_Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ public function build( string $slug, string $domain = '' ): string {
return '';
}

$callback_url = admin_url( $pagenow );

// If building the URL in an ajax context, use the referring URL.
if ( wp_parse_url( $pagenow, PHP_URL_PATH ) === 'admin-ajax.php' ) {
$callback_url = wp_get_referer();
}

$auth_url = $this->auth_url_manager->get( $slug );

if ( ! $auth_url ) {
Expand All @@ -69,7 +76,7 @@ public function build( string $slug, string $domain = '' ): string {

$url = add_query_arg(
array_filter( array_merge( $_GET, $args ) ),
admin_url( $pagenow )
$callback_url
);

return sprintf( '%s?%s',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ public function render( array $args = [] ): void {
'target' => $target,
'tag' => $tag,
'classes' => $this->classes( $classes ),
'slug' => $slug,
] );
}

Expand Down
6 changes: 4 additions & 2 deletions src/Uplink/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,15 @@ function is_user_authorized(): bool {
*
* @param string $slug The Product slug to render the button for.
* @param string $domain An optional domain associated with a license key to pass along.
* @param string $license An optional license key to pass along.
*
* @return string
*/
function build_auth_url( string $slug, string $domain = '' ): string {
function build_auth_url( string $slug, string $domain = '', string $license = ''): string {
try {
return Config::get_container()->get( Auth_Url_Builder::class )
->build( $slug, $domain );
->set_license( $license )
->build( $slug, $domain, $license );
} catch ( Throwable $e ) {
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( "Error building auth URL: {$e->getMessage()} {$e->getFile()}:{$e->getLine()} {$e->getTraceAsString()}" );
Expand Down
17 changes: 12 additions & 5 deletions src/assets/css/main.css
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
.license-test-results {
margin-top: 10px;
margin-top: 10px;
}

.key-validity {
display: inline-block;
display: inline-block;
}

.valid-key {
color: green;
color: green;
}

.invalid-key {
color: red;
color: red;
}

.uplink-authorize-container {
display: inline-block;
}

.uplink-authorize {
margin-bottom: 16px !important;
transition: border-color 300ms ease-in-out;
}

.uplink-authorize.button {
vertical-align: initial;
}

.uplink-authorize.not-authorized {
background: #b8e6bf;
border-color: #00a32a;
Expand Down
32 changes: 32 additions & 0 deletions src/assets/js/key-admin.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
( function( $, obj ) {
obj.init = function() {

$('a.uplink-authorize').on( 'click', function (e) {
if ( $( this ).attr('disabled') === 'disabled' ) {
e.preventDefault();
}
} );

$( '.stellarwp-uplink-license-key-field' ).each( function() {
var $el = $( this );
var slug = $el.data( 'plugin-slug' );
var $field = $el.find( 'input[type="text"]' );
var $oauth = $el.find( `a[data-plugin-slug="${slug}"]`);

if ( '' === $field.val().trim() ) {
$el.find( '.license-test-results' ).hide();
obj.disableAuthorizeButton( $oauth );
}

obj.validateKey( $el );
Expand All @@ -17,13 +27,25 @@
} );
};

obj.disableAuthorizeButton = function( $button ) {
$button.attr( 'aria-disabled', 'true' );
$button.attr( 'disabled', 'disabled' );
}

obj.enableAuthorizeButton = function( $button ) {
$button.removeAttr( 'aria-disabled' );
$button.removeAttr( 'disabled' );
}

obj.validateKey = function( $el ) {
const field = $el.find( 'input[type="text"]' )
const action = $el.data( 'action' );
const slug = $el.data( 'plugin-slug' );
const $oauth = $el.find( `a[data-plugin-slug="${slug}"]`);
let $validityMessage = $el.find( '.key-validity' );

if ( '' === field.val().trim() ) {
obj.disableAuthorizeButton( $oauth );
return;
}

Expand Down Expand Up @@ -53,17 +75,27 @@
switch (response.status) {
case 1:
$validityMessage.addClass('valid-key').removeClass('invalid-key');
obj.enableAuthorizeButton( $oauth );
if ( $oauth.hasClass( 'not-authorized' ) ) {
$oauth.attr( 'href', response.auth_url );
}
break;
case 2:
$validityMessage.addClass('valid-key service-msg');
obj.enableAuthorizeButton( $oauth );
if ( $oauth.hasClass( 'not-authorized' ) ) {
$oauth.attr( 'href', response.auth_url );
}
break;
default:
$validityMessage.addClass('invalid-key').removeClass('valid-key');
obj.disableAuthorizeButton( $oauth );
break;
}
}).fail(function(error) {
$validityMessage.show();
$validityMessage.html(error.message);
obj.disableAuthorizeButton( $oauth );
}).always(function() {
$($el).find('.ajax-loading-license').hide();
});
Expand Down
2 changes: 2 additions & 0 deletions src/views/admin/authorize-button.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* @var string $target The link target.
* @var string $tag The HTML tag to use for the wrapper.
* @var string $classes The CSS classes for the hyperlink.
* @var string $slug The slug of the product the authorize button is for.
*/

defined( 'ABSPATH' ) || exit;
Expand All @@ -19,6 +20,7 @@
<a href="<?php echo esc_url( $url ) ?>"
target="<?php echo $target ? esc_attr( $target ) : '' ?>"
<?php echo $classes ? sprintf( 'class="%s"', esc_attr( $classes ) ) : '' ?>
data-plugin-slug="<?php echo esc_attr( $slug ); ?>"
>
<?php echo esc_html( $link_text ) ?>
</a>
Expand Down
98 changes: 58 additions & 40 deletions src/views/admin/fields/field.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<?php declare( strict_types=1 );
/**
* @var Field $field The Field object.
* @var Resource $resource The Field resource.
* @var string $group The group name.
*/

use StellarWP\Uplink\Config;
use StellarWP\Uplink\Admin\Fields\Field;
use StellarWP\Uplink\Resources\Resource;
use StellarWP\Uplink\Components\Admin\Authorize_Button_Controller;
?>

<?php
Expand All @@ -20,50 +23,65 @@
?>
<?php if ( $field->should_show_label() ) : ?>
<table class="form-table" role="presentation">
<tr class="stellarwp-uplink-license-key-field">
<th scope="row">
<label for="<?php echo esc_attr( $field->get_field_id() ); ?>"><?php echo esc_html( $field->get_label() ); ?></label>
</th>
<td>
<tr class="stellarwp-uplink-license-key-field">
<th scope="row">
<label for="<?php echo esc_attr( $field->get_field_id() ); ?>"><?php echo esc_html( $field->get_label() ); ?></label>
</th>
<td>
<?php endif; ?>
<div class="stellarwp-uplink__license-field">
<div
class="<?php echo esc_attr( $field->get_classes() ); ?>"
id="<?php echo esc_attr( $field->get_product() ); ?>"
data-slug="<?php echo esc_attr( $field->get_product() ); ?>"
data-plugin="<?php echo esc_attr( $field->get_product() ); ?>"
data-plugin-slug="<?php echo esc_attr( $field->get_product_slug() ); ?>"
data-action="<?php echo esc_attr( $field->get_nonce_action() ); ?>"
>
<fieldset class="stellarwp-uplink__settings-group">
<?php settings_fields( $group ); ?>
<div class="stellarwp-uplink__license-field">
<div
class="<?php echo esc_attr( $field->get_classes() ); ?>"
id="<?php echo esc_attr( $field->get_product() ); ?>"
data-slug="<?php echo esc_attr( $field->get_product() ); ?>"
data-plugin="<?php echo esc_attr( $field->get_product() ); ?>"
data-plugin-slug="<?php echo esc_attr( $field->get_product_slug() ); ?>"
data-action="<?php echo esc_attr( $field->get_nonce_action() ); ?>"
>
<fieldset class="stellarwp-uplink__settings-group">
<?php settings_fields( $group ); ?>

<?php
/**
* Fires before the license key input is printed on the page.
*
* @since TBD
*
* @param string $slug The slug of the field.
*/
do_action( 'stellarwp/uplink/' . Config::get_hook_prefix() . '/license_field_before_input', $field->get_slug() );
?>
<?php
/**
* Fires before the license key input is printed on the page.
*
* @since TBD
*
* @param string $slug The slug of the field.
*/
do_action( 'stellarwp/uplink/' . Config::get_hook_prefix() . '/license_field_before_input', $field->get_slug() );
?>

<input
type="text"
name="<?php echo esc_attr( $field->get_field_name() ); ?>"
value="<?php echo esc_attr( $field->get_field_value() ); ?>"
placeholder="<?php echo esc_attr( $field->get_placeholder() ); ?>"
class="regular-text stellarwp-uplink__settings-field"
/>
<?php echo $field->get_key_status_html(); ?>
</fieldset>
<?php echo $field->get_nonce_field(); ?>
</div>
</div>
<input
type="text"
name="<?php echo esc_attr( $field->get_field_name() ); ?>"
value="<?php echo esc_attr( $field->get_field_value() ); ?>"
placeholder="<?php echo esc_attr( $field->get_placeholder() ); ?>"
class="regular-text stellarwp-uplink__settings-field"
/>
<?php if ( $resource->is_using_oauth() ) : ?>
<?php
try {
Config::get_container()->get( Authorize_Button_Controller::class )->render( [
'slug' => $field->get_slug(),
'domain' => get_site_url(),
'license' => $resource->license_key ?? '',
] );
} catch ( Throwable $e ) {
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( "Unable to render authorize button: {$e->getMessage()} {$e->getFile()}:{$e->getLine()} {$e->getTraceAsString()}" );
}
}
?>
<?php endif; ?>
<?php echo $field->get_key_status_html(); ?>
</fieldset>
<?php echo $field->get_nonce_field(); ?>
</div>
</div>
<?php if ( $field->should_show_label() ) : ?>
</td>
</tr>
</td>
</tr>
</table>
<?php endif; ?>
<?php
Expand Down
2 changes: 1 addition & 1 deletion tests/wpunit/Admin/Fields/FieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public function it_should_render_correct_html_for_oauth_resource_with_license_ke
update_option( 'test_storage', [
'stellarwp_auth_url_service_oauth_with_license_key_field_1' => [
'expiration' => 0,
'value' => 'https://licensing.stellarwp.com/account-auth?uplink_domain=&uplink_slug=service-oauth-with-license-key-field-1&_uplink_nonce=535281edcd',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why this is being removed? Was the test passing before? Did something change to actually not require those query args? Were they useless before and this is cleanup?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, they were unnecessary when the test was first added. Those values are combined and encoded for the uplink_callback parameter here in Auth_Url_Builder::build():

// Query arguments to combine with $_GET and add to the authorization URL.
$args = [
'uplink_domain' => $domain,
'uplink_slug' => $slug,
];
// Optionally include a license key if set.
if ( ! empty( $this->license_key ) ) {
$args['uplink_license'] = $this->license_key;
}
$url = add_query_arg(
array_filter( array_merge( $_GET, $args ) ),
admin_url( $pagenow )
);
return sprintf( '%s?%s',
$auth_url,
http_build_query( [
'uplink_callback' => base64_encode( $this->nonce->create_url( $url ) ),
] )
);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to update this because of the new data attribute, so I made some changes there too.

'value' => 'https://licensing.stellarwp.com/account-auth',
]
] );
$collection = $this->container->get( Collection::class );
Expand Down
Loading
Loading