From 9f4e3eed21d1438f32a5ac2d307d669de787fe97 Mon Sep 17 00:00:00 2001 From: Patrick Kelly Date: Thu, 28 May 2020 15:29:28 -0400 Subject: [PATCH 1/2] Create a method to create a JWT when sending the connection request. --- plugins/jsconnect/class.jsconnect.plugin.php | 44 +++++++++++++------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/plugins/jsconnect/class.jsconnect.plugin.php b/plugins/jsconnect/class.jsconnect.plugin.php index bb2e18d84..524b31054 100644 --- a/plugins/jsconnect/class.jsconnect.plugin.php +++ b/plugins/jsconnect/class.jsconnect.plugin.php @@ -47,6 +47,26 @@ public function __construct(\Garden\Web\Cookie $cookie, UserModel $userModel) { $this->userModel = $userModel; } + /** + * @param array $provider + * @return string + */ + private static function getV3SignInURL(array $provider): string { + $target = Gdn::request()->get('target', Gdn::request()->get('target')); + if (!$target) { + $target = '/' . ltrim(Gdn::request()->path()); + } + if (stringBeginsWith($target, '/entry/signin')) { + $target = '/'; + } + + $baseURL = url('/entry/jsconnect-redirect'); + return $baseURL . '?' . http_build_query([ + 'client_id' => $provider[self::FIELD_PROVIDER_CLIENT_ID], + 'target' => $target + ]); + } + /** * Get the AuthenticationSchemeAlias value. * @@ -173,18 +193,7 @@ public static function connectButton($provider, $options = []) { * @return string */ private static function connectButtonV3(array $provider): string { - $target = Gdn::request()->get('target', Gdn::request()->get('target')); - if (!$target) { - $target = '/'.ltrim(Gdn::request()->path()); - } - if (stringBeginsWith($target, '/entry/signin')) { - $target = '/'; - } - - $url = url('/entry/jsconnect-redirect').'?'.http_build_query([ - 'client_id' => $provider[self::FIELD_PROVIDER_CLIENT_ID], - 'target' => $target - ]); + $url = self::getV3SignInURL($provider); $result = '
'. anchor( @@ -355,7 +364,12 @@ public static function getSignInUrl($provider, $target = null) { $provider = static::getProvider($provider); } - $signInUrl = val('SignInUrl', $provider); + if ($provider['Protocol'] === 'v3') { + $signInUrl = url('/entry/jsconnect-redirect'); + } else { + $signInUrl = $provider['SignInUrl']; + } + if (!$signInUrl) { return ''; } @@ -420,7 +434,9 @@ public function authenticationProviderModel_calculateJsConnect_handler($sender, $provider['SignInUrlFinal'] = static::getSignInUrl($provider, $target); $provider['RegisterUrlFinal'] = static::getRegisterUrl($provider, $target); } - + public function entryController_overrideSignIn_handler($sender, $args) { + $args['DefaultProvider']['SignInUrl'] = static::getV3SignInURL($args['DefaultProvider']); + } /** * Add jsConnect buttons to the page. * From 4c666508532974ba78556be13bfb10bed34f2345 Mon Sep 17 00:00:00 2001 From: Patrick Kelly Date: Thu, 28 May 2020 17:24:25 -0400 Subject: [PATCH 2/2] Add a method to redirect all v3 sign ins to go to the jsconnect-redirect endpoint to have the JWT created. --- plugins/jsconnect/class.jsconnect.plugin.php | 31 ++++++++++++-------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/plugins/jsconnect/class.jsconnect.plugin.php b/plugins/jsconnect/class.jsconnect.plugin.php index 524b31054..e738b4dbd 100644 --- a/plugins/jsconnect/class.jsconnect.plugin.php +++ b/plugins/jsconnect/class.jsconnect.plugin.php @@ -48,11 +48,13 @@ public function __construct(\Garden\Web\Cookie $cookie, UserModel $userModel) { } /** - * @param array $provider - * @return string + * Create a URL that directs the browser to the V3 redirect to create the JWT. + * + * @param array $provider JSConnect settings. + * @return string URL with the target. */ - private static function getV3SignInURL(array $provider): string { - $target = Gdn::request()->get('target', Gdn::request()->get('target')); + private static function entryRedirectURL(array $provider): string { + $target = Gdn::request()->get('Target', Gdn::request()->get('Target')); if (!$target) { $target = '/' . ltrim(Gdn::request()->path()); } @@ -193,7 +195,7 @@ public static function connectButton($provider, $options = []) { * @return string */ private static function connectButtonV3(array $provider): string { - $url = self::getV3SignInURL($provider); + $url = self::entryRedirectURL($provider); $result = '
'. anchor( @@ -364,12 +366,7 @@ public static function getSignInUrl($provider, $target = null) { $provider = static::getProvider($provider); } - if ($provider['Protocol'] === 'v3') { - $signInUrl = url('/entry/jsconnect-redirect'); - } else { - $signInUrl = $provider['SignInUrl']; - } - + $signInUrl = val('SignInUrl', $provider); if (!$signInUrl) { return ''; } @@ -434,8 +431,18 @@ public function authenticationProviderModel_calculateJsConnect_handler($sender, $provider['SignInUrlFinal'] = static::getSignInUrl($provider, $target); $provider['RegisterUrlFinal'] = static::getRegisterUrl($provider, $target); } + + /** + * If this is the default provider and V3, make sure it goes through the redirect URL. + * + * @param EntryController $sender + * @param array $args + */ public function entryController_overrideSignIn_handler($sender, $args) { - $args['DefaultProvider']['SignInUrl'] = static::getV3SignInURL($args['DefaultProvider']); + $protocol = $args['DefaultProvider']['Protocol'] ?? null; + if ($protocol === self::PROTOCOL_V3) { + $args['DefaultProvider']['SignInUrl'] = static::entryRedirectURL($args['DefaultProvider']); + } } /** * Add jsConnect buttons to the page.