TB-71: Ability to activate users without sending email.
This commit is contained in:
		
							parent
							
								
									3019bf7570
								
							
						
					
					
						commit
						86515896dd
					
				@ -173,7 +173,12 @@ public class AuthController extends BaseController {
 | 
			
		||||
            String baseUrl = constructBaseUrl(request);
 | 
			
		||||
            String loginUrl = String.format("%s/login", baseUrl);
 | 
			
		||||
            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 refreshToken = refreshTokenRepository.requestRefreshToken(securityUser);
 | 
			
		||||
 | 
			
		||||
@ -63,6 +63,7 @@ public class UserController extends BaseController {
 | 
			
		||||
    @RequestMapping(value = "/user", method = RequestMethod.POST)
 | 
			
		||||
    @ResponseBody 
 | 
			
		||||
    public User saveUser(@RequestBody User user,
 | 
			
		||||
                         @RequestParam(required = false, defaultValue = "true") boolean sendActivationMail,
 | 
			
		||||
            HttpServletRequest request) throws ThingsboardException {
 | 
			
		||||
        try {
 | 
			
		||||
            SecurityUser authUser = getCurrentUser();
 | 
			
		||||
@ -70,7 +71,7 @@ public class UserController extends BaseController {
 | 
			
		||||
                throw new ThingsboardException("You don't have permission to perform this operation!",
 | 
			
		||||
                        ThingsboardErrorCode.PERMISSION_DENIED);
 | 
			
		||||
            }
 | 
			
		||||
            boolean sendEmail = user.getId() == null;
 | 
			
		||||
            boolean sendEmail = user.getId() == null && sendActivationMail;
 | 
			
		||||
            if (getCurrentUser().getAuthority() == Authority.TENANT_ADMIN) {
 | 
			
		||||
                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')")
 | 
			
		||||
    @RequestMapping(value = "/user/{userId}", method = RequestMethod.DELETE)
 | 
			
		||||
    @ResponseStatus(value = HttpStatus.OK)
 | 
			
		||||
 | 
			
		||||
@ -45,6 +45,7 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi
 | 
			
		||||
        isUserLoaded: isUserLoaded,
 | 
			
		||||
        saveUser: saveUser,
 | 
			
		||||
        sendActivationEmail: sendActivationEmail,
 | 
			
		||||
        getActivationLink: getActivationLink,
 | 
			
		||||
        setUserFromJwtToken: setUserFromJwtToken,
 | 
			
		||||
        getJwtToken: getJwtToken,
 | 
			
		||||
        clearJwtToken: clearJwtToken,
 | 
			
		||||
@ -397,9 +398,12 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi
 | 
			
		||||
        return deferred.promise;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function saveUser(user) {
 | 
			
		||||
    function saveUser(user, sendActivationMail) {
 | 
			
		||||
        var deferred = $q.defer();
 | 
			
		||||
        var url = '/api/user';
 | 
			
		||||
        if (angular.isDefined(sendActivationMail)) {
 | 
			
		||||
            url += '?sendActivationMail=' + sendActivationMail;
 | 
			
		||||
        }
 | 
			
		||||
        $http.post(url, user).then(function success(response) {
 | 
			
		||||
            deferred.resolve(response.data);
 | 
			
		||||
        }, function fail(response) {
 | 
			
		||||
@ -441,6 +445,17 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi
 | 
			
		||||
        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) {
 | 
			
		||||
        if (currentUser && isAuthenticated()) {
 | 
			
		||||
            if (currentUser.authority === 'TENANT_ADMIN' || currentUser.authority === 'CUSTOMER_USER') {
 | 
			
		||||
 | 
			
		||||
@ -74,6 +74,11 @@ export default function AppRun($rootScope, $window, $injector, $location, $log,
 | 
			
		||||
 | 
			
		||||
            var locationSearch = $location.search();
 | 
			
		||||
            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.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) {
 | 
			
		||||
            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)) {
 | 
			
		||||
                $translate(to.data.pageTitle).then(function (translation) {
 | 
			
		||||
                    $rootScope.pageTitle = 'Thingsboard | ' + translation;
 | 
			
		||||
                    $rootScope.pageTitle = 'ThingsBoard | ' + translation;
 | 
			
		||||
                }, function (translationId) {
 | 
			
		||||
                    $rootScope.pageTitle = 'Thingsboard | ' + translationId;
 | 
			
		||||
                    $rootScope.pageTitle = 'ThingsBoard | ' + translationId;
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ import gridTemplate from './grid.tpl.html';
 | 
			
		||||
 | 
			
		||||
export default angular.module('thingsboard.directives.grid', [thingsboardScopeElement, thingsboardDetailsSidenav])
 | 
			
		||||
    .directive('tbGrid', Grid)
 | 
			
		||||
    .controller('AddItemController', AddItemController)
 | 
			
		||||
    .controller('ItemCardController', ItemCardController)
 | 
			
		||||
    .directive('tbGridCardContent', GridCardContent)
 | 
			
		||||
    .filter('range', RangeFilter)
 | 
			
		||||
@ -342,6 +343,11 @@ function GridController($scope, $state, $mdDialog, $document, $q, $timeout, $tra
 | 
			
		||||
        } else {
 | 
			
		||||
            vm.itemCardController = 'ItemCardController';
 | 
			
		||||
        }
 | 
			
		||||
        if (vm.config.addItemController) {
 | 
			
		||||
            vm.addItemController =  vm.config.addItemController;
 | 
			
		||||
        } else {
 | 
			
		||||
            vm.addItemController = 'AddItemController';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        vm.parentCtl = vm.config.parentCtl || vm;
 | 
			
		||||
 | 
			
		||||
@ -468,7 +474,7 @@ function GridController($scope, $state, $mdDialog, $document, $q, $timeout, $tra
 | 
			
		||||
 | 
			
		||||
    function addItem($event) {
 | 
			
		||||
        $mdDialog.show({
 | 
			
		||||
            controller: AddItemController,
 | 
			
		||||
            controller: vm.addItemController,
 | 
			
		||||
            controllerAs: 'vm',
 | 
			
		||||
            templateUrl: vm.addItemTemplateUrl,
 | 
			
		||||
            parent: angular.element($document[0].body),
 | 
			
		||||
 | 
			
		||||
@ -1037,6 +1037,7 @@ export default angular.module('thingsboard.locale', [])
 | 
			
		||||
                    "resend-activation": "Resend activation",
 | 
			
		||||
                    "email": "Email",
 | 
			
		||||
                    "email-required": "Email is required.",
 | 
			
		||||
                    "invalid-email-format": "Invalid email format.",
 | 
			
		||||
                    "first-name": "First Name",
 | 
			
		||||
                    "last-name": "Last Name",
 | 
			
		||||
                    "description": "Description",
 | 
			
		||||
@ -1044,7 +1045,14 @@ export default angular.module('thingsboard.locale', [])
 | 
			
		||||
                    "always-fullscreen": "Always fullscreen",
 | 
			
		||||
                    "select-user": "Select user",
 | 
			
		||||
                    "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": {
 | 
			
		||||
                    "type": "Value type",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								ui/src/app/user/activation-link.controller.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ui/src/app/user/activation-link.controller.js
									
									
									
									
									
										Normal file
									
								
							@ -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
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								ui/src/app/user/activation-link.dialog.tpl.html
									
									
									
									
									
										Normal file
									
								
							@ -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
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								ui/src/app/user/add-user.controller.js
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -15,8 +15,8 @@
 | 
			
		||||
    limitations under the License.
 | 
			
		||||
 | 
			
		||||
-->
 | 
			
		||||
<md-dialog aria-label="{{ 'user.add' | translate }}" tb-help="'users'" help-container-id="help-container">
 | 
			
		||||
	<form name="theForm" ng-submit="vm.add()">
 | 
			
		||||
<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($event)">
 | 
			
		||||
	    <md-toolbar>
 | 
			
		||||
	      <div class="md-toolbar-tools">
 | 
			
		||||
	        <h2 translate>user.add</h2>
 | 
			
		||||
@ -32,6 +32,15 @@
 | 
			
		||||
	    <md-dialog-content>
 | 
			
		||||
	      <div class="md-dialog-content">
 | 
			
		||||
  	        	<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>
 | 
			
		||||
	    </md-dialog-content>
 | 
			
		||||
	    <md-dialog-actions layout="row">
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,8 @@ import thingsboardToast from '../services/toast';
 | 
			
		||||
 | 
			
		||||
import UserRoutes from './user.routes';
 | 
			
		||||
import UserController from './user.controller';
 | 
			
		||||
import AddUserController from './add-user.controller';
 | 
			
		||||
import ActivationLinkDialogController from './activation-link.controller';
 | 
			
		||||
import UserDirective from './user.directive';
 | 
			
		||||
 | 
			
		||||
export default angular.module('thingsboard.user', [
 | 
			
		||||
@ -30,5 +32,7 @@ export default angular.module('thingsboard.user', [
 | 
			
		||||
])
 | 
			
		||||
    .config(UserRoutes)
 | 
			
		||||
    .controller('UserController', UserController)
 | 
			
		||||
    .controller('AddUserController', AddUserController)
 | 
			
		||||
    .controller('ActivationLinkDialogController', ActivationLinkDialogController)
 | 
			
		||||
    .directive('tbUser', UserDirective)
 | 
			
		||||
    .name;
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,9 @@
 | 
			
		||||
    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">{{
 | 
			
		||||
    'user.resend-activation' | translate }}
 | 
			
		||||
</md-button>
 | 
			
		||||
@ -26,9 +29,12 @@
 | 
			
		||||
    <fieldset ng-disabled="loading || !isEdit">
 | 
			
		||||
        <md-input-container class="md-block">
 | 
			
		||||
            <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 translate ng-message="required">user.email-required</div>
 | 
			
		||||
                <div translate ng-message="pattern">user.invalid-email-format</div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </md-input-container>
 | 
			
		||||
        <md-input-container class="md-block">
 | 
			
		||||
@ -43,7 +49,7 @@
 | 
			
		||||
            <label translate>user.description</label>
 | 
			
		||||
            <textarea ng-model="user.additionalInfo.description" rows="2"></textarea>
 | 
			
		||||
        </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>
 | 
			
		||||
            <section flex layout="column" layout-gt-sm="row">
 | 
			
		||||
                <tb-dashboard-autocomplete ng-if="isTenantAdmin()"
 | 
			
		||||
 | 
			
		||||
@ -17,12 +17,13 @@
 | 
			
		||||
 | 
			
		||||
import addUserTemplate from './add-user.tpl.html';
 | 
			
		||||
import userCard from './user-card.tpl.html';
 | 
			
		||||
import activationLinkDialogTemplate from './activation-link.dialog.tpl.html';
 | 
			
		||||
 | 
			
		||||
/* eslint-enable import/no-unresolved, import/default */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*@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 customerId = $stateParams.customerId;
 | 
			
		||||
@ -58,6 +59,7 @@ export default function UserController(userService, toast, $scope, $controller,
 | 
			
		||||
        onGridInited: gridInited,
 | 
			
		||||
 | 
			
		||||
        addItemTemplateUrl: addUserTemplate,
 | 
			
		||||
        addItemController: 'AddUserController',
 | 
			
		||||
 | 
			
		||||
        addItemText: function() { return $translate.instant('user.add-user-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.displayActivationLink = displayActivationLink;
 | 
			
		||||
    vm.resendActivation = resendActivation;
 | 
			
		||||
 | 
			
		||||
    initController();
 | 
			
		||||
@ -151,6 +154,29 @@ export default function UserController(userService, toast, $scope, $controller,
 | 
			
		||||
        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) {
 | 
			
		||||
        userService.sendActivationEmail(user.email).then(function success() {
 | 
			
		||||
            toast.showSuccess($translate.instant('user.activation-email-sent-message'));
 | 
			
		||||
 | 
			
		||||
@ -45,6 +45,7 @@ export default function UserDirective($compile, $templateCache/*, dashboardServi
 | 
			
		||||
            user: '=',
 | 
			
		||||
            isEdit: '=',
 | 
			
		||||
            theForm: '=',
 | 
			
		||||
            onDisplayActivationLink: '&',
 | 
			
		||||
            onResendActivation: '&',
 | 
			
		||||
            onDeleteUser: '&'
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@
 | 
			
		||||
	<tb-user user="vm.grid.operatingItem()"
 | 
			
		||||
			 is-edit="vm.grid.detailsConfig.isDetailsEditMode"
 | 
			
		||||
			 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-delete-user="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-user>
 | 
			
		||||
</tb-grid>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user