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>
This commit is contained in:
GitStart
2023-02-21 13:20:55 +01:00
committed by GitHub
parent e3d9a0441d
commit aff97bff26
8 changed files with 104 additions and 1 deletions

View File

@@ -2,3 +2,4 @@
//= link administrate/application.css
//= link administrate/application.js
//= link dashboardChart.js
//= link secretField.js

View File

@@ -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);
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -0,0 +1,4 @@
require 'administrate/field/base'
class SecretField < Administrate::Field::String
end

View File

@@ -0,0 +1,17 @@
<%#
# SecretField Index Partial
%>
<%= javascript_include_tag "secretField" %>
<div data-secret-text="<%= field.data %>" class="cell-data__secret-field">
<span data-secret-masked="true">••••••••••</span>
<button onclick="toggleSecretField(event)" data-secret-toggler>
<svg width="20" height="20">
<use xlink:href="#eye-show" />
</svg>
</button>
<button onclick="copySecretField(event)" data-secret-copier>
<svg width="20" height="20">
<use xlink:href="#icon-copy" />
</svg>
</button>
</div>

View File

@@ -0,0 +1,18 @@
<%#
# SecretField Show Partial
%>
<%= javascript_include_tag "secretField" %>
<div data-secret-text="<%= field.data %>" class="cell-data__secret-field">
<span data-secret-masked="true">••••••••••</span>
<button onclick="toggleSecretField(event)" data-secret-toggler>
<svg width="20" height="20">
<use xlink:href="#eye-show" />
</svg>
</button>
<button onclick="copySecretField(event)" data-secret-copier>
<svg width="20" height="20">
<use xlink:href="#icon-copy" />
</svg>
</button>
</div>

View File

@@ -10,4 +10,16 @@
<symbol id="icon-up-caret" viewBox="0 0 48 48">
<path d="M2.988 33.02c-1.66 0-1.943-.81-.618-1.824l20-15.28c.878-.672 2.31-.67 3.188 0l20.075 15.288c1.316 1.003 1.048 1.816-.62 1.816H2.987z" />
</symbol>
<symbol id="icon-copy" viewBox="0 0 24 24">
<path d="M5.503 4.627 5.5 6.75v10.504a3.25 3.25 0 0 0 3.25 3.25h8.616a2.251 2.251 0 0 1-2.122 1.5H8.75A4.75 4.75 0 0 1 4 17.254V6.75c0-.98.627-1.815 1.503-2.123ZM17.75 2A2.25 2.25 0 0 1 20 4.25v13a2.25 2.25 0 0 1-2.25 2.25h-9a2.25 2.25 0 0 1-2.25-2.25v-13A2.25 2.25 0 0 1 8.75 2h9Zm0 1.5h-9a.75.75 0 0 0-.75.75v13c0 .414.336.75.75.75h9a.75.75 0 0 0 .75-.75v-13a.75.75 0 0 0-.75-.75Z" />
</symbol>
<symbol id="eye-show" viewBox="0 0 24 24">
<path d="M12 9.005a4 4 0 1 1 0 8 4 4 0 0 1 0-8Zm0 1.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM12 5.5c4.613 0 8.596 3.15 9.701 7.564a.75.75 0 1 1-1.455.365 8.503 8.503 0 0 0-16.493.004.75.75 0 0 1-1.455-.363A10.003 10.003 0 0 1 12 5.5Z" />
</symbol>
<symbol id="eye-hide" viewBox="0 0 24 24">
<path d="M2.22 2.22a.75.75 0 0 0-.073.976l.073.084 4.034 4.035a9.986 9.986 0 0 0-3.955 5.75.75.75 0 0 0 1.455.364 8.49 8.49 0 0 1 3.58-5.034l1.81 1.81A4 4 0 0 0 14.8 15.86l5.919 5.92a.75.75 0 0 0 1.133-.977l-.073-.084-6.113-6.114.001-.002-1.2-1.198-2.87-2.87h.002L8.719 7.658l.001-.002-1.133-1.13L3.28 2.22a.75.75 0 0 0-1.06 0Zm7.984 9.045 3.535 3.536a2.5 2.5 0 0 1-3.535-3.535ZM12 5.5c-1 0-1.97.148-2.889.425l1.237 1.236a8.503 8.503 0 0 1 9.899 6.272.75.75 0 0 0 1.455-.363A10.003 10.003 0 0 0 12 5.5Zm.195 3.51 3.801 3.8a4.003 4.003 0 0 0-3.801-3.8Z" />
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB