From aff97bff26bd9d6ff14777fe8b04e2ed6d643fac Mon Sep 17 00:00:00 2001 From: GitStart <1501599+gitstart@users.noreply.github.com> Date: Tue, 21 Feb 2023 13:20:55 +0100 Subject: [PATCH] feat: Supports masking tokens in super admin (#6491) Supports masking/unmasking sensitive data such as API Tokens in the super admin dashboard. ref: #6322 Co-authored-by: raph941 <45232708+raph941@users.noreply.github.com> Co-authored-by: phunguyenmurcul <51897872+phunguyenmurcul@users.noreply.github.com> --- app/assets/config/manifest.js | 1 + app/assets/javascripts/secretField.js | 34 +++++++++++++++++++ .../administrate/components/_cells.scss | 17 ++++++++++ app/dashboards/access_token_dashboard.rb | 2 +- app/fields/secret_field.rb | 4 +++ app/views/fields/secret_field/_index.html.erb | 17 ++++++++++ app/views/fields/secret_field/_show.html.erb | 18 ++++++++++ .../super_admin/application/_icons.html.erb | 12 +++++++ 8 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/secretField.js create mode 100644 app/fields/secret_field.rb create mode 100644 app/views/fields/secret_field/_index.html.erb create mode 100644 app/views/fields/secret_field/_show.html.erb diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js index f5e0f5476..38da59e09 100644 --- a/app/assets/config/manifest.js +++ b/app/assets/config/manifest.js @@ -2,3 +2,4 @@ //= link administrate/application.css //= link administrate/application.js //= link dashboardChart.js +//= link secretField.js diff --git a/app/assets/javascripts/secretField.js b/app/assets/javascripts/secretField.js new file mode 100644 index 000000000..463109812 --- /dev/null +++ b/app/assets/javascripts/secretField.js @@ -0,0 +1,34 @@ +// eslint-disable-next-line +function toggleSecretField(e) { + e.preventDefault(); + e.stopPropagation(); + + const toggler = e.currentTarget; + const secretField = toggler.parentElement; + const textElement = secretField.querySelector('[data-secret-masked]'); + + if (!textElement) return; + + if (textElement.dataset.secretMasked === 'false') { + textElement.textContent = '•'.repeat(10); + textElement.dataset.secretMasked = 'true'; + toggler.querySelector('svg use').setAttribute('xlink:href', '#eye-show'); + + return; + } + + textElement.textContent = secretField.dataset.secretText; + textElement.dataset.secretMasked = 'false'; + toggler.querySelector('svg use').setAttribute('xlink:href', '#eye-hide'); +} + +// eslint-disable-next-line +function copySecretField(e) { + e.preventDefault(); + e.stopPropagation(); + + const toggler = e.currentTarget; + const secretField = toggler.parentElement; + + navigator.clipboard.writeText(secretField.dataset.secretText); +} diff --git a/app/assets/stylesheets/administrate/components/_cells.scss b/app/assets/stylesheets/administrate/components/_cells.scss index 2f7e27c4a..b5a079976 100644 --- a/app/assets/stylesheets/administrate/components/_cells.scss +++ b/app/assets/stylesheets/administrate/components/_cells.scss @@ -43,3 +43,20 @@ .cell-label--number { text-align: right; } + +.cell-data__secret-field { + align-items: center; + display: flex; + + span { + flex: 1; + } + + button { + margin-left: 5px; + + svg { + fill: currentColor; + } + } +} diff --git a/app/dashboards/access_token_dashboard.rb b/app/dashboards/access_token_dashboard.rb index 8d4f7840e..d3f05a799 100644 --- a/app/dashboards/access_token_dashboard.rb +++ b/app/dashboards/access_token_dashboard.rb @@ -10,7 +10,7 @@ class AccessTokenDashboard < Administrate::BaseDashboard ATTRIBUTE_TYPES = { owner: Field::Polymorphic, id: Field::Number, - token: Field::String, + token: SecretField, created_at: Field::DateTime, updated_at: Field::DateTime }.freeze diff --git a/app/fields/secret_field.rb b/app/fields/secret_field.rb new file mode 100644 index 000000000..6bc7c535a --- /dev/null +++ b/app/fields/secret_field.rb @@ -0,0 +1,4 @@ +require 'administrate/field/base' + +class SecretField < Administrate::Field::String +end diff --git a/app/views/fields/secret_field/_index.html.erb b/app/views/fields/secret_field/_index.html.erb new file mode 100644 index 000000000..d6518673f --- /dev/null +++ b/app/views/fields/secret_field/_index.html.erb @@ -0,0 +1,17 @@ +<%# +# SecretField Index Partial +%> +<%= javascript_include_tag "secretField" %> +
+ •••••••••• + + +
diff --git a/app/views/fields/secret_field/_show.html.erb b/app/views/fields/secret_field/_show.html.erb new file mode 100644 index 000000000..6b5d6059b --- /dev/null +++ b/app/views/fields/secret_field/_show.html.erb @@ -0,0 +1,18 @@ +<%# +# SecretField Show Partial +%> +<%= javascript_include_tag "secretField" %> + +
+ •••••••••• + + +
diff --git a/app/views/super_admin/application/_icons.html.erb b/app/views/super_admin/application/_icons.html.erb index 1add01cad..d4ea86470 100644 --- a/app/views/super_admin/application/_icons.html.erb +++ b/app/views/super_admin/application/_icons.html.erb @@ -10,4 +10,16 @@ + + + + + + + + + + + +