From bbfd04e1e3ed05f2d42b0af178a794ea30939364 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 3 Nov 2020 04:25:43 -0800 Subject: [PATCH] oauth-client - Add basic UI to inspect/debug JWT-based tokens --- .../ang/oauthClientTokens.aff.html | 6 ++++ ext/oauth-client/ang/oauthJwtDebug.aff.html | 34 +++++++++++++++++++ ext/oauth-client/ang/oauthJwtDebug.aff.json | 6 ++++ .../ang/unvalidatedJwtDecode.ang.php | 10 ++++++ ext/oauth-client/ang/unvalidatedJwtDecode.js | 32 +++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 ext/oauth-client/ang/oauthJwtDebug.aff.html create mode 100644 ext/oauth-client/ang/oauthJwtDebug.aff.json create mode 100644 ext/oauth-client/ang/unvalidatedJwtDecode.ang.php create mode 100644 ext/oauth-client/ang/unvalidatedJwtDecode.js diff --git a/ext/oauth-client/ang/oauthClientTokens.aff.html b/ext/oauth-client/ang/oauthClientTokens.aff.html index 5d463e4ce0..7dc9f031e1 100644 --- a/ext/oauth-client/ang/oauthClientTokens.aff.html +++ b/ext/oauth-client/ang/oauthClientTokens.aff.html @@ -21,6 +21,12 @@ {{token.created_date}}
+ {{ts('Inspect')}} + +
+ +

This is a temporary debug page. It requires super user permissions or manage oauth client secrets.

+ +

Some (but not all) OAuth2 tokens are based on JWT. If a token is based on JWT, then we can examine its content to learn more about what the token signifies. This may help with debugging token-access issues.

+ +

Token ID

+ + + + + + +
+ +

Access Token: Raw

+ +
{{data.token[0].access_token}}
+ +

Access Token: JWT Payload

+ +
{{data.token[0].access_token|unvalidatedJwtDecode|json}}
+ +
+ +
\ No newline at end of file diff --git a/ext/oauth-client/ang/oauthJwtDebug.aff.json b/ext/oauth-client/ang/oauthJwtDebug.aff.json new file mode 100644 index 0000000000..a0ab1a2891 --- /dev/null +++ b/ext/oauth-client/ang/oauthJwtDebug.aff.json @@ -0,0 +1,6 @@ +{ + "title": "OAuth2 JWT Debug", + "requires": ["unvalidatedJwtDecode", "afCore"], + "server_route": "civicrm/admin/oauth-jwt-debug", + "permission": "manage OAuth client secrets" +} \ No newline at end of file diff --git a/ext/oauth-client/ang/unvalidatedJwtDecode.ang.php b/ext/oauth-client/ang/unvalidatedJwtDecode.ang.php new file mode 100644 index 0000000000..3db419d899 --- /dev/null +++ b/ext/oauth-client/ang/unvalidatedJwtDecode.ang.php @@ -0,0 +1,10 @@ + [ + 'ang/unvalidatedJwtDecode.js', + ], + 'requires' => [ + 'crmUi', + 'crmUtil', + ], +]; diff --git a/ext/oauth-client/ang/unvalidatedJwtDecode.js b/ext/oauth-client/ang/unvalidatedJwtDecode.js new file mode 100644 index 0000000000..dfb7d53442 --- /dev/null +++ b/ext/oauth-client/ang/unvalidatedJwtDecode.js @@ -0,0 +1,32 @@ +(function(angular, $, _) { + angular.module('unvalidatedJwtDecode', CRM.angRequires('unvalidatedJwtDecode')); + angular.module('unvalidatedJwtDecode').filter('unvalidatedJwtDecode', function() { + return function(token) { + if (!token) return null; + var payload = token.split('.')[1]; + var tokenData = url_base64_decode(payload); + try { + return JSON.parse(tokenData); + } catch (e) { + return tokenData; + } + }; + }); + + function url_base64_decode(str) { + var output = str.replace(/-/g, '+').replace(/_/g, '/'); + switch (output.length % 4) { + case 0: + break; + case 2: + output += '=='; + break; + case 3: + output += '='; + break; + default: + throw 'Illegal base64url string!'; + } + return decodeURIComponent(window.escape(atob(output))); + } +})(angular, CRM.$, CRM._); -- 2.25.1