diff --git a/src/js/client.js b/src/js/client.js
index d5b17ee63..ac2595d8a 100644
--- a/src/js/client.js
+++ b/src/js/client.js
@@ -1882,6 +1882,19 @@ angular.module('Application').service('Client', ['$http', '$interval', '$timeout
});
};
+ Client.prototype.setGhost = function (userId, password, expiresAt, callback) {
+ var data = { password };
+
+ if (expiresAt) data.expiresAt = expiresAt;
+
+ post('/api/v1/users/' + userId + '/ghost', data, null, function (error, data, status) {
+ if (error) return callback(error);
+ if (status !== 204) return callback(new ClientError(status, data));
+
+ callback(null);
+ });
+ };
+
Client.prototype.startExternalLdapSync = function (callback) {
post('/api/v1/cloudron/sync_external_ldap', {}, null, function (error, data, status) {
if (error) return callback(error);
diff --git a/src/views/users.html b/src/views/users.html
index d50fcecdf..3decae8fa 100644
--- a/src/views/users.html
+++ b/src/views/users.html
@@ -379,6 +379,39 @@
+
+
+
@@ -553,6 +586,7 @@
+
diff --git a/src/views/users.js b/src/views/users.js
index 59cb5ccd7..2e767f39a 100644
--- a/src/views/users.js
+++ b/src/views/users.js
@@ -585,6 +585,46 @@ angular.module('Application').controller('UsersController', ['$scope', '$locatio
}
};
+ // https://stackoverflow.com/questions/1497481/javascript-password-generator
+ function generatePassword() {
+ var length = 12,
+ charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
+ retVal = "";
+ for (var i = 0, n = charset.length; i < length; ++i) {
+ retVal += charset.charAt(Math.floor(Math.random() * n));
+ }
+ return retVal;
+ }
+
+ $scope.setGhost = {
+ busy: false,
+ error: null,
+ user: null,
+ password: '',
+
+ show: function (user) {
+ $scope.setGhost.busy = false;
+ $scope.setGhost.error = null;
+ $scope.setGhost.user = user;
+ $scope.setGhost.password = generatePassword();
+
+ $('#setGhostModal').modal('show');
+ },
+
+ submit: function () {
+ $scope.setGhost.busy = true;
+
+ Client.setGhost($scope.setGhost.user.id, $scope.setGhost.password, null, function (error) {
+ $scope.setGhost.busy = false;
+
+ if (error) {
+ $scope.setGhost.error = error.message;
+ return console.error(error);
+ }
+ });
+ }
+ };
+
$scope.directoryConfig = {
editableUserProfiles: true,
mandatory2FA: false,
@@ -903,5 +943,27 @@ angular.module('Application').controller('UsersController', ['$scope', '$locatio
$timeout(function () { $('#setupLinkButton').tooltip('hide'); }, 2000);
});
+ var setGhostClipboardButton = new Clipboard('#setGhostClipboardButton');
+
+ setGhostClipboardButton.on('success', function(e) {
+ $('#setGhostClipboardButton').tooltip({
+ title: 'Copied!',
+ trigger: 'manual'
+ }).tooltip('show');
+
+ $timeout(function () { $('#setGhostClipboardButton').tooltip('hide'); }, 2000);
+
+ e.clearSelection();
+ });
+
+ setGhostClipboardButton.on('error', function(/*e*/) {
+ $('#setGhostClipboardButton').tooltip({
+ title: 'Press Ctrl+C to copy',
+ trigger: 'manual'
+ }).tooltip('show');
+
+ $timeout(function () { $('#setGhostClipboardButton').tooltip('hide'); }, 2000);
+ });
+
$('.modal-backdrop').remove();
}]);