Browse Source

TB-71: Ability to activate users without sending email.

pull/214/head
Igor Kulikov 9 years ago
parent
commit
86515896dd
  1. 7
      application/src/main/java/org/thingsboard/server/controller/AuthController.java
  2. 32
      application/src/main/java/org/thingsboard/server/controller/UserController.java
  3. 17
      ui/src/app/api/user.service.js
  4. 11
      ui/src/app/app.run.js
  5. 8
      ui/src/app/components/grid.directive.js
  6. 10
      ui/src/app/locale/locale.constant.js
  7. 35
      ui/src/app/user/activation-link.controller.js
  8. 55
      ui/src/app/user/activation-link.dialog.tpl.html
  9. 112
      ui/src/app/user/add-user.controller.js
  10. 13
      ui/src/app/user/add-user.tpl.html
  11. 4
      ui/src/app/user/index.js
  12. 10
      ui/src/app/user/user-fieldset.tpl.html
  13. 28
      ui/src/app/user/user.controller.js
  14. 1
      ui/src/app/user/user.directive.js
  15. 1
      ui/src/app/user/users.tpl.html

7
application/src/main/java/org/thingsboard/server/controller/AuthController.java

@ -173,7 +173,12 @@ public class AuthController extends BaseController {
String baseUrl = constructBaseUrl(request); String baseUrl = constructBaseUrl(request);
String loginUrl = String.format("%s/login", baseUrl); String loginUrl = String.format("%s/login", baseUrl);
String email = user.getEmail(); String email = user.getEmail();
mailService.sendAccountActivatedEmail(loginUrl, email);
try {
mailService.sendAccountActivatedEmail(loginUrl, email);
} catch (Exception e) {
log.info("Unable to send account activation email [{}]", e.getMessage());
}
JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser); JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser);
JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser); JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser);

32
application/src/main/java/org/thingsboard/server/controller/UserController.java

@ -63,6 +63,7 @@ public class UserController extends BaseController {
@RequestMapping(value = "/user", method = RequestMethod.POST) @RequestMapping(value = "/user", method = RequestMethod.POST)
@ResponseBody @ResponseBody
public User saveUser(@RequestBody User user, public User saveUser(@RequestBody User user,
@RequestParam(required = false, defaultValue = "true") boolean sendActivationMail,
HttpServletRequest request) throws ThingsboardException { HttpServletRequest request) throws ThingsboardException {
try { try {
SecurityUser authUser = getCurrentUser(); SecurityUser authUser = getCurrentUser();
@ -70,7 +71,7 @@ public class UserController extends BaseController {
throw new ThingsboardException("You don't have permission to perform this operation!", throw new ThingsboardException("You don't have permission to perform this operation!",
ThingsboardErrorCode.PERMISSION_DENIED); ThingsboardErrorCode.PERMISSION_DENIED);
} }
boolean sendEmail = user.getId() == null; boolean sendEmail = user.getId() == null && sendActivationMail;
if (getCurrentUser().getAuthority() == Authority.TENANT_ADMIN) { if (getCurrentUser().getAuthority() == Authority.TENANT_ADMIN) {
user.setTenantId(getCurrentUser().getTenantId()); user.setTenantId(getCurrentUser().getTenantId());
} }
@ -116,6 +117,35 @@ public class UserController extends BaseController {
} }
} }
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/user/{userId}/activationLink", method = RequestMethod.GET, produces = "text/plain")
@ResponseBody
public String getActivationLink(
@PathVariable("userId") String strUserId,
HttpServletRequest request) throws ThingsboardException {
checkParameter("userId", strUserId);
try {
UserId userId = new UserId(toUUID(strUserId));
SecurityUser authUser = getCurrentUser();
if (authUser.getAuthority() == Authority.CUSTOMER_USER && !authUser.getId().equals(userId)) {
throw new ThingsboardException("You don't have permission to perform this operation!",
ThingsboardErrorCode.PERMISSION_DENIED);
}
User user = checkUserId(userId);
UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getId());
if (!userCredentials.isEnabled()) {
String baseUrl = constructBaseUrl(request);
String activateUrl = String.format("%s/api/noauth/activate?activateToken=%s", baseUrl,
userCredentials.getActivateToken());
return activateUrl;
} else {
throw new ThingsboardException("User is already active!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
}
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/user/{userId}", method = RequestMethod.DELETE) @RequestMapping(value = "/user/{userId}", method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)

17
ui/src/app/api/user.service.js

@ -45,6 +45,7 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi
isUserLoaded: isUserLoaded, isUserLoaded: isUserLoaded,
saveUser: saveUser, saveUser: saveUser,
sendActivationEmail: sendActivationEmail, sendActivationEmail: sendActivationEmail,
getActivationLink: getActivationLink,
setUserFromJwtToken: setUserFromJwtToken, setUserFromJwtToken: setUserFromJwtToken,
getJwtToken: getJwtToken, getJwtToken: getJwtToken,
clearJwtToken: clearJwtToken, clearJwtToken: clearJwtToken,
@ -397,9 +398,12 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi
return deferred.promise; return deferred.promise;
} }
function saveUser(user) { function saveUser(user, sendActivationMail) {
var deferred = $q.defer(); var deferred = $q.defer();
var url = '/api/user'; var url = '/api/user';
if (angular.isDefined(sendActivationMail)) {
url += '?sendActivationMail=' + sendActivationMail;
}
$http.post(url, user).then(function success(response) { $http.post(url, user).then(function success(response) {
deferred.resolve(response.data); deferred.resolve(response.data);
}, function fail(response) { }, function fail(response) {
@ -441,6 +445,17 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi
return deferred.promise; return deferred.promise;
} }
function getActivationLink(userId) {
var deferred = $q.defer();
var url = `/api/user/${userId}/activationLink`
$http.get(url).then(function success(response) {
deferred.resolve(response.data);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
function forceDefaultPlace(to, params) { function forceDefaultPlace(to, params) {
if (currentUser && isAuthenticated()) { if (currentUser && isAuthenticated()) {
if (currentUser.authority === 'TENANT_ADMIN' || currentUser.authority === 'CUSTOMER_USER') { if (currentUser.authority === 'TENANT_ADMIN' || currentUser.authority === 'CUSTOMER_USER') {

11
ui/src/app/app.run.js

@ -74,6 +74,11 @@ export default function AppRun($rootScope, $window, $injector, $location, $log,
var locationSearch = $location.search(); var locationSearch = $location.search();
var publicId = locationSearch.publicId; var publicId = locationSearch.publicId;
var activateToken = locationSearch.activateToken;
if (to.url === '/createPassword?activateToken' && activateToken && activateToken.length) {
userService.setUserFromJwtToken(null, null, false);
}
if (userService.isUserLoaded() === true) { if (userService.isUserLoaded() === true) {
if (userService.isAuthenticated()) { if (userService.isAuthenticated()) {
@ -124,7 +129,7 @@ export default function AppRun($rootScope, $window, $injector, $location, $log,
} }
}) })
$rootScope.pageTitle = 'Thingsboard'; $rootScope.pageTitle = 'ThingsBoard';
$rootScope.stateChangeSuccessHandle = $rootScope.$on('$stateChangeSuccess', function (evt, to, params) { $rootScope.stateChangeSuccessHandle = $rootScope.$on('$stateChangeSuccess', function (evt, to, params) {
if (userService.isPublic() && to.name === 'home.dashboards.dashboard') { if (userService.isPublic() && to.name === 'home.dashboards.dashboard') {
@ -133,9 +138,9 @@ export default function AppRun($rootScope, $window, $injector, $location, $log,
} }
if (angular.isDefined(to.data.pageTitle)) { if (angular.isDefined(to.data.pageTitle)) {
$translate(to.data.pageTitle).then(function (translation) { $translate(to.data.pageTitle).then(function (translation) {
$rootScope.pageTitle = 'Thingsboard | ' + translation; $rootScope.pageTitle = 'ThingsBoard | ' + translation;
}, function (translationId) { }, function (translationId) {
$rootScope.pageTitle = 'Thingsboard | ' + translationId; $rootScope.pageTitle = 'ThingsBoard | ' + translationId;
}); });
} }
}) })

8
ui/src/app/components/grid.directive.js

@ -26,6 +26,7 @@ import gridTemplate from './grid.tpl.html';
export default angular.module('thingsboard.directives.grid', [thingsboardScopeElement, thingsboardDetailsSidenav]) export default angular.module('thingsboard.directives.grid', [thingsboardScopeElement, thingsboardDetailsSidenav])
.directive('tbGrid', Grid) .directive('tbGrid', Grid)
.controller('AddItemController', AddItemController)
.controller('ItemCardController', ItemCardController) .controller('ItemCardController', ItemCardController)
.directive('tbGridCardContent', GridCardContent) .directive('tbGridCardContent', GridCardContent)
.filter('range', RangeFilter) .filter('range', RangeFilter)
@ -342,6 +343,11 @@ function GridController($scope, $state, $mdDialog, $document, $q, $timeout, $tra
} else { } else {
vm.itemCardController = 'ItemCardController'; vm.itemCardController = 'ItemCardController';
} }
if (vm.config.addItemController) {
vm.addItemController = vm.config.addItemController;
} else {
vm.addItemController = 'AddItemController';
}
vm.parentCtl = vm.config.parentCtl || vm; vm.parentCtl = vm.config.parentCtl || vm;
@ -468,7 +474,7 @@ function GridController($scope, $state, $mdDialog, $document, $q, $timeout, $tra
function addItem($event) { function addItem($event) {
$mdDialog.show({ $mdDialog.show({
controller: AddItemController, controller: vm.addItemController,
controllerAs: 'vm', controllerAs: 'vm',
templateUrl: vm.addItemTemplateUrl, templateUrl: vm.addItemTemplateUrl,
parent: angular.element($document[0].body), parent: angular.element($document[0].body),

10
ui/src/app/locale/locale.constant.js

@ -1037,6 +1037,7 @@ export default angular.module('thingsboard.locale', [])
"resend-activation": "Resend activation", "resend-activation": "Resend activation",
"email": "Email", "email": "Email",
"email-required": "Email is required.", "email-required": "Email is required.",
"invalid-email-format": "Invalid email format.",
"first-name": "First Name", "first-name": "First Name",
"last-name": "Last Name", "last-name": "Last Name",
"description": "Description", "description": "Description",
@ -1044,7 +1045,14 @@ export default angular.module('thingsboard.locale', [])
"always-fullscreen": "Always fullscreen", "always-fullscreen": "Always fullscreen",
"select-user": "Select user", "select-user": "Select user",
"no-users-matching": "No users matching '{{entity}}' were found.", "no-users-matching": "No users matching '{{entity}}' were found.",
"user-required": "User is required" "user-required": "User is required",
"activation-method": "Activation method",
"display-activation-link": "Display activation link",
"send-activation-mail": "Send activation mail",
"activation-link": "User activation link",
"activation-link-text": "In order to activate user use the following <a href='{{activationLink}}' target='_blank'>activation link</a> :",
"copy-activation-link": "Copy activation link",
"activation-link-copied-message": "User activation link has been copied to clipboard"
}, },
"value": { "value": {
"type": "Value type", "type": "Value type",

35
ui/src/app/user/activation-link.controller.js

@ -0,0 +1,35 @@
/*
* Copyright © 2016-2017 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*@ngInject*/
export default function ActivationLinkDialogController($mdDialog, $translate, toast, activationLink) {
var vm = this;
vm.activationLink = activationLink;
vm.onActivationLinkCopied = onActivationLinkCopied;
vm.close = close;
function onActivationLinkCopied(){
toast.showSuccess($translate.instant('user.activation-link-copied-message'), 750, angular.element('#activation-link-dialog-content'), 'bottom left');
}
function close() {
$mdDialog.hide();
}
}

55
ui/src/app/user/activation-link.dialog.tpl.html

@ -0,0 +1,55 @@
<!--
Copyright © 2016-2017 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<md-dialog aria-label="{{ 'user.activation-link' | translate }}" style="min-width: 400px;">
<form>
<md-toolbar>
<div class="md-toolbar-tools">
<h2 translate="user.activation-link"></h2>
<span flex></span>
<md-button class="md-icon-button" ng-click="vm.close()">
<ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<div id="activation-link-dialog-content" class="md-dialog-content">
<md-content class="md-padding" layout="column">
<span translate="user.activation-link-text" translate-values="{activationLink: vm.activationLink}"></span>
<div layout="row" layout-align="start center">
<pre class="tb-highlight" flex><code>{{ vm.activationLink }}</code></pre>
<md-button class="md-icon-button"
ngclipboard
data-clipboard-text="{{ vm.activationLink }}"
ngclipboard-success="vm.onActivationLinkCopied(e)">
<md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon>
<md-tooltip md-direction="top">
{{ 'user.copy-activation-link' | translate }}
</md-tooltip>
</md-button>
</div>
</md-content>
</div>
</md-dialog-content>
<md-dialog-actions layout="row">
<span flex></span>
<md-button ng-click="vm.close()">{{ 'action.ok' |
translate }}
</md-button>
</md-dialog-actions>
</form>
</md-dialog>

112
ui/src/app/user/add-user.controller.js

@ -0,0 +1,112 @@
/*
* Copyright © 2016-2017 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable import/no-unresolved, import/default */
import activationLinkDialogTemplate from './activation-link.dialog.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/
export default function AddUserController($scope, $mdDialog, $state, $stateParams, $document, $q, types, userService, saveItemFunction, helpLinks) {
var vm = this;
var tenantId = $stateParams.tenantId;
var customerId = $stateParams.customerId;
var usersType = $state.$current.data.usersType;
vm.helpLinks = helpLinks;
vm.item = {};
vm.activationMethods = [
{
value: 'displayActivationLink',
name: 'user.display-activation-link'
},
{
value: 'sendActivationMail',
name: 'user.send-activation-mail'
}
];
vm.userActivationMethod = 'displayActivationLink';
vm.add = add;
vm.cancel = cancel;
function cancel() {
$mdDialog.cancel();
}
function add($event) {
var sendActivationMail = false;
if (vm.userActivationMethod == 'sendActivationMail') {
sendActivationMail = true;
}
if (usersType === 'tenant') {
vm.item.authority = "TENANT_ADMIN";
vm.item.tenantId = {
entityType: types.entityType.tenant,
id: tenantId
};
} else if (usersType === 'customer') {
vm.item.authority = "CUSTOMER_USER";
vm.item.customerId = {
entityType: types.entityType.customer,
id: customerId
};
}
userService.saveUser(vm.item, sendActivationMail).then(function success(item) {
vm.item = item;
$scope.theForm.$setPristine();
if (vm.userActivationMethod == 'displayActivationLink') {
userService.getActivationLink(vm.item.id.id).then(
function success(activationLink) {
displayActivationLink($event, activationLink).then(
function() {
$mdDialog.hide();
}
);
}
);
} else {
$mdDialog.hide();
}
});
}
function displayActivationLink($event, activationLink) {
var deferred = $q.defer();
$mdDialog.show({
controller: 'ActivationLinkDialogController',
controllerAs: 'vm',
templateUrl: activationLinkDialogTemplate,
locals: {
activationLink: activationLink
},
parent: angular.element($document[0].body),
fullscreen: true,
skipHide: true,
targetEvent: $event
}).then(function () {
deferred.resolve();
});
return deferred.promise;
}
}

13
ui/src/app/user/add-user.tpl.html

@ -15,8 +15,8 @@
limitations under the License. limitations under the License.
--> -->
<md-dialog aria-label="{{ 'user.add' | translate }}" tb-help="'users'" help-container-id="help-container"> <md-dialog style="width: 600px;" aria-label="{{ 'user.add' | translate }}" tb-help="'users'" help-container-id="help-container">
<form name="theForm" ng-submit="vm.add()"> <form name="theForm" ng-submit="vm.add($event)">
<md-toolbar> <md-toolbar>
<div class="md-toolbar-tools"> <div class="md-toolbar-tools">
<h2 translate>user.add</h2> <h2 translate>user.add</h2>
@ -32,6 +32,15 @@
<md-dialog-content> <md-dialog-content>
<div class="md-dialog-content"> <div class="md-dialog-content">
<tb-user user="vm.item" is-edit="true" the-form="theForm"></tb-user> <tb-user user="vm.item" is-edit="true" the-form="theForm"></tb-user>
<md-input-container class="md-block">
<label translate>user.activation-method</label>
<md-select aria-label="{{ 'user.activation-method' | translate }}"
ng-model="vm.userActivationMethod">
<md-option ng-repeat="activationMethod in vm.activationMethods" ng-value="activationMethod.value">
{{activationMethod.name | translate}}
</md-option>
</md-select>
</md-input-container>
</div> </div>
</md-dialog-content> </md-dialog-content>
<md-dialog-actions layout="row"> <md-dialog-actions layout="row">

4
ui/src/app/user/index.js

@ -20,6 +20,8 @@ import thingsboardToast from '../services/toast';
import UserRoutes from './user.routes'; import UserRoutes from './user.routes';
import UserController from './user.controller'; import UserController from './user.controller';
import AddUserController from './add-user.controller';
import ActivationLinkDialogController from './activation-link.controller';
import UserDirective from './user.directive'; import UserDirective from './user.directive';
export default angular.module('thingsboard.user', [ export default angular.module('thingsboard.user', [
@ -30,5 +32,7 @@ export default angular.module('thingsboard.user', [
]) ])
.config(UserRoutes) .config(UserRoutes)
.controller('UserController', UserController) .controller('UserController', UserController)
.controller('AddUserController', AddUserController)
.controller('ActivationLinkDialogController', ActivationLinkDialogController)
.directive('tbUser', UserDirective) .directive('tbUser', UserDirective)
.name; .name;

10
ui/src/app/user/user-fieldset.tpl.html

@ -15,6 +15,9 @@
limitations under the License. limitations under the License.
--> -->
<md-button ng-click="onDisplayActivationLink({event: $event})" ng-show="!isEdit" class="md-raised md-primary">{{
'user.display-activation-link' | translate }}
</md-button>
<md-button ng-click="onResendActivation({event: $event})" ng-show="!isEdit" class="md-raised md-primary">{{ <md-button ng-click="onResendActivation({event: $event})" ng-show="!isEdit" class="md-raised md-primary">{{
'user.resend-activation' | translate }} 'user.resend-activation' | translate }}
</md-button> </md-button>
@ -26,9 +29,12 @@
<fieldset ng-disabled="loading || !isEdit"> <fieldset ng-disabled="loading || !isEdit">
<md-input-container class="md-block"> <md-input-container class="md-block">
<label translate>user.email</label> <label translate>user.email</label>
<input required name="email" type="email" ng-model="user.email"> <input required name="email"
ng-pattern="/^[_a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/"
ng-model="user.email">
<div ng-messages="theForm.email.$error"> <div ng-messages="theForm.email.$error">
<div translate ng-message="required">user.email-required</div> <div translate ng-message="required">user.email-required</div>
<div translate ng-message="pattern">user.invalid-email-format</div>
</div> </div>
</md-input-container> </md-input-container>
<md-input-container class="md-block"> <md-input-container class="md-block">
@ -43,7 +49,7 @@
<label translate>user.description</label> <label translate>user.description</label>
<textarea ng-model="user.additionalInfo.description" rows="2"></textarea> <textarea ng-model="user.additionalInfo.description" rows="2"></textarea>
</md-input-container> </md-input-container>
<section class="tb-default-dashboard" flex layout="column"> <section class="tb-default-dashboard" flex layout="column" ng-if="user.id">
<span class="tb-default-dashboard-label" ng-class="{'tb-disabled-label': loading || !isEdit}" translate>user.default-dashboard</span> <span class="tb-default-dashboard-label" ng-class="{'tb-disabled-label': loading || !isEdit}" translate>user.default-dashboard</span>
<section flex layout="column" layout-gt-sm="row"> <section flex layout="column" layout-gt-sm="row">
<tb-dashboard-autocomplete ng-if="isTenantAdmin()" <tb-dashboard-autocomplete ng-if="isTenantAdmin()"

28
ui/src/app/user/user.controller.js

@ -17,12 +17,13 @@
import addUserTemplate from './add-user.tpl.html'; import addUserTemplate from './add-user.tpl.html';
import userCard from './user-card.tpl.html'; import userCard from './user-card.tpl.html';
import activationLinkDialogTemplate from './activation-link.dialog.tpl.html';
/* eslint-enable import/no-unresolved, import/default */ /* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/ /*@ngInject*/
export default function UserController(userService, toast, $scope, $controller, $state, $stateParams, $translate, types) { export default function UserController(userService, toast, $scope, $mdDialog, $document, $controller, $state, $stateParams, $translate, types) {
var tenantId = $stateParams.tenantId; var tenantId = $stateParams.tenantId;
var customerId = $stateParams.customerId; var customerId = $stateParams.customerId;
@ -58,6 +59,7 @@ export default function UserController(userService, toast, $scope, $controller,
onGridInited: gridInited, onGridInited: gridInited,
addItemTemplateUrl: addUserTemplate, addItemTemplateUrl: addUserTemplate,
addItemController: 'AddUserController',
addItemText: function() { return $translate.instant('user.add-user-text') }, addItemText: function() { return $translate.instant('user.add-user-text') },
noItemsText: function() { return $translate.instant('user.no-users-text') }, noItemsText: function() { return $translate.instant('user.no-users-text') },
@ -72,6 +74,7 @@ export default function UserController(userService, toast, $scope, $controller,
vm.userGridConfig.topIndex = $stateParams.topIndex; vm.userGridConfig.topIndex = $stateParams.topIndex;
} }
vm.displayActivationLink = displayActivationLink;
vm.resendActivation = resendActivation; vm.resendActivation = resendActivation;
initController(); initController();
@ -151,6 +154,29 @@ export default function UserController(userService, toast, $scope, $controller,
return userService.deleteUser(userId); return userService.deleteUser(userId);
} }
function displayActivationLink(event, user) {
userService.getActivationLink(user.id.id).then(
function success(activationLink) {
openActivationLinkDialog(event, activationLink);
}
);
}
function openActivationLinkDialog(event, activationLink) {
$mdDialog.show({
controller: 'ActivationLinkDialogController',
controllerAs: 'vm',
templateUrl: activationLinkDialogTemplate,
locals: {
activationLink: activationLink
},
parent: angular.element($document[0].body),
fullscreen: true,
skipHide: true,
targetEvent: event
});
}
function resendActivation(user) { function resendActivation(user) {
userService.sendActivationEmail(user.email).then(function success() { userService.sendActivationEmail(user.email).then(function success() {
toast.showSuccess($translate.instant('user.activation-email-sent-message')); toast.showSuccess($translate.instant('user.activation-email-sent-message'));

1
ui/src/app/user/user.directive.js

@ -45,6 +45,7 @@ export default function UserDirective($compile, $templateCache/*, dashboardServi
user: '=', user: '=',
isEdit: '=', isEdit: '=',
theForm: '=', theForm: '=',
onDisplayActivationLink: '&',
onResendActivation: '&', onResendActivation: '&',
onDeleteUser: '&' onDeleteUser: '&'
} }

1
ui/src/app/user/users.tpl.html

@ -22,6 +22,7 @@
<tb-user user="vm.grid.operatingItem()" <tb-user user="vm.grid.operatingItem()"
is-edit="vm.grid.detailsConfig.isDetailsEditMode" is-edit="vm.grid.detailsConfig.isDetailsEditMode"
the-form="vm.grid.detailsForm" the-form="vm.grid.detailsForm"
on-display-activation-link="vm.displayActivationLink(event, vm.grid.detailsConfig.currentItem)"
on-resend-activation="vm.resendActivation(vm.grid.detailsConfig.currentItem)" on-resend-activation="vm.resendActivation(vm.grid.detailsConfig.currentItem)"
on-delete-user="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-user> on-delete-user="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-user>
</tb-grid> </tb-grid>

Loading…
Cancel
Save