diff --git a/functions.inc/auth/modules/Scim.php b/functions.inc/auth/modules/Scim.php
index bcf12ef9..6ecd84ce 100644
--- a/functions.inc/auth/modules/Scim.php
+++ b/functions.inc/auth/modules/Scim.php
@@ -90,15 +90,20 @@ public static function getConfig($userman, $freepbx, $config) {
'title' => _("SCIM Token"),
'type' => 'raw',
'value' => sprintf(
- '
+ '
+
+
',
$typeauth,
- _("Refresh Token")
+ _("Refresh Token"),
+ _("Copy Token"),
+ _("Show Token"),
+ _("Hide Token")
),
- 'help' => _("Use this token for SCIM provisioning"),
+ 'help' => _("Use this token for SCIM provisioning. The value is masked by default; use the Show/Hide and Copy buttons to view or copy it."),
),
array('type' => 'fieldset_init', 'legend' => _("Operational Settings")),
array(
diff --git a/views/directories.php b/views/directories.php
index 3d559aed..26be62a2 100644
--- a/views/directories.php
+++ b/views/directories.php
@@ -464,6 +464,78 @@ function rotateScimToken() {
rotateScimToken();
});
+ function copyScimTokenFallback(token) {
+ var $field = $("#scim-token");
+ if (!$field.length) {
+ return false;
+ }
+ var originalType = $field.attr("type");
+ $field.attr("type", "text");
+ var node = $field[0];
+ try {
+ node.focus();
+ node.select();
+ if (typeof node.setSelectionRange === "function") {
+ node.setSelectionRange(0, token.length);
+ }
+ } catch (e) {}
+ var copied = false;
+ try {
+ copied = document.execCommand("copy");
+ } catch (e) {
+ copied = false;
+ }
+ $field.attr("type", originalType);
+ try { node.blur(); } catch (e) {}
+ return copied;
+ }
+
+ $(document).on("click", "#scim-copy-token", function() {
+ var token = ($("#scim-token").val() || "").toString();
+ if (!token) {
+ showScimMessage("", "danger");
+ return;
+ }
+ if (navigator.clipboard && typeof navigator.clipboard.writeText === "function") {
+ navigator.clipboard.writeText(token).then(function() {
+ showScimMessage("", "success");
+ }).catch(function() {
+ if (copyScimTokenFallback(token)) {
+ showScimMessage("", "success");
+ } else {
+ showScimMessage("", "danger");
+ }
+ });
+ return;
+ }
+ if (copyScimTokenFallback(token)) {
+ showScimMessage("", "success");
+ } else {
+ showScimMessage("", "danger");
+ }
+ });
+
+ $(document).on("click", "#scim-toggle-token", function() {
+ var $btn = $(this);
+ var $field = $("#scim-token");
+ if (!$field.length) {
+ return;
+ }
+ var $label = $btn.find(".scim-toggle-label");
+ var $icon = $btn.find("i");
+ var showLabel = $btn.data("show-label");
+ var hideLabel = $btn.data("hide-label");
+ if ($field.attr("type") === "password") {
+ $field.attr("type", "text");
+ $label.text(hideLabel);
+ $icon.removeClass("fa-eye").addClass("fa-eye-slash");
+ } else {
+ $field.attr("type", "password");
+ $label.text(showLabel);
+ $icon.removeClass("fa-eye-slash").addClass("fa-eye");
+ }
+ });
+
function generateScimToken() {
var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var token = "";