IGNITE-10914 Web Console: Fixed missing unique index on Accounts.
diff --git a/backend/app/schemas.js b/backend/app/schemas.js
index 2f6498f..fe3c637 100644
--- a/backend/app/schemas.js
+++ b/backend/app/schemas.js
@@ -37,7 +37,7 @@
     const Account = new Schema({
         firstName: String,
         lastName: String,
-        email: String,
+        email: {type: String, unique: true},
         phone: String,
         company: String,
         country: String,
diff --git a/backend/migrations/1547440382485-account-make-email-unique.js b/backend/migrations/1547440382485-account-make-email-unique.js
new file mode 100644
index 0000000..787c767
--- /dev/null
+++ b/backend/migrations/1547440382485-account-make-email-unique.js
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+const _ = require('lodash');
+
+const log = require('./migration-utils').log;
+
+function deduplicateAccounts(model) {
+    const accountsModel = model('Account');
+    const spaceModel = model('Space');
+
+    return accountsModel.aggregate([
+        {$group: {_id: '$email', count: {$sum: 1}}},
+        {$match: {count: {$gt: 1}}}
+    ]).exec()
+        .then((accounts) => _.map(accounts, '_id'))
+        .then((emails) => Promise.all(
+            _.map(emails, (email) => accountsModel.find({email}, {_id: 1, email: 1, lastActivity: 1, lastLogin: 1}).lean().exec())
+        ))
+        .then((promises) => {
+            const duplicates = _.flatMap(promises, (accounts) => _.sortBy(accounts, [(a) => a.lastActivity || '', 'lastLogin']).slice(0, -1));
+
+            if (_.isEmpty(duplicates))
+                log('Duplicates not found!');
+            else {
+                log(`Duplicates found: ${_.size(duplicates)}`);
+
+                _.forEach(duplicates, (dup) => log(`  ID: ${dup._id}, e-mail: ${dup.email}`));
+            }
+
+            return _.map(duplicates, '_id');
+        })
+        .then((accountIds) => {
+            if (_.isEmpty(accountIds))
+                return Promise.resolve();
+
+            return spaceModel.find({owner: {$in: accountIds}}, {_id: 1}).lean().exec()
+                .then((spaces) => _.map(spaces, '_id'))
+                .then((spaceIds) =>
+                    Promise.all([
+                        model('Cluster').remove({space: {$in: spaceIds}}).exec(),
+                        model('Cache').remove({space: {$in: spaceIds}}).exec(),
+                        model('DomainModel').remove({space: {$in: spaceIds}}).exec(),
+                        model('Igfs').remove({space: {$in: spaceIds}}).exec(),
+                        model('Notebook').remove({space: {$in: spaceIds}}).exec(),
+                        model('Activities').remove({owner: accountIds}).exec(),
+                        model('Notifications').remove({owner: accountIds}).exec(),
+                        spaceModel.remove({owner: accountIds}).exec(),
+                        accountsModel.remove({_id: accountIds}).exec()
+                    ])
+                )
+                .then(() => {
+                    const conditions = _.map(accountIds, (accountId) => ({session: {$regex: `"${accountId}"`}}));
+
+                    return accountsModel.db.collection('sessions').deleteMany({$or: conditions});
+                });
+        });
+}
+
+exports.up = function up(done) {
+    deduplicateAccounts((name) => this(name))
+        .then(() => this('Account').collection.createIndex({email: 1}, {unique: true, background: false}))
+        .then(() => done())
+        .catch(done);
+};
+
+exports.down = function down(done) {
+    log('Account migration can not be reverted');
+
+    done();
+};
diff --git a/frontend/app/components/list-editable/controller.ts b/frontend/app/components/list-editable/controller.ts
index e870e82..d4d9da6 100644
--- a/frontend/app/components/list-editable/controller.ts
+++ b/frontend/app/components/list-editable/controller.ts
@@ -43,8 +43,8 @@
     }
 
     ngModel: ListEditableNgModel<T>;
-    hasItemView: boolean
-    private _cache: Map<ID, T>
+    hasItemView: boolean;
+    private _cache: Map<ID, T>;
 
     id(item: T | undefined, index: number): ID {
         if (item && item._id)
@@ -61,6 +61,7 @@
         this.ngModel.$isEmpty = (value) => {
             return !Array.isArray(value) || !value.length;
         };
+
         this.ngModel.editListItem = (item) => {
             this.$timeout(() => {
                 this.startEditView(this.id(item, this.ngModel.$viewValue.indexOf(item)));
@@ -69,6 +70,7 @@
                 this.ngModel.$validate();
             });
         };
+
         this.ngModel.editListIndex = (index) => {
             this.$timeout(() => {
                 this.startEditView(this.id(this.ngModel.$viewValue[index], index));
diff --git a/frontend/app/components/permanent-notifications/controller.ts b/frontend/app/components/permanent-notifications/controller.ts
index d672304..ff0b182 100644
--- a/frontend/app/components/permanent-notifications/controller.ts
+++ b/frontend/app/components/permanent-notifications/controller.ts
@@ -16,12 +16,14 @@
  */
 
 export default class PermanentNotifications {
-    static $inject = ['UserNotifications', '$rootScope', '$window']
+    static $inject = ['UserNotifications', '$rootScope', '$window'];
+
     constructor(
         private UserNotifications: unknown,
         private $rootScope: ng.IRootScopeService,
         private $window: ng.IWindowService
     ) {}
+
     closeDemo() {
         this.$window.close();
     }
diff --git a/frontend/app/components/web-console-footer/controller.ts b/frontend/app/components/web-console-footer/controller.ts
index 0811748..0ca604c 100644
--- a/frontend/app/components/web-console-footer/controller.ts
+++ b/frontend/app/components/web-console-footer/controller.ts
@@ -18,9 +18,12 @@
 import {default as Version} from '../../services/Version.service';
 
 export default class WebConsoleFooter {
-    static $inject = ['IgniteVersion', '$rootScope']
+    static $inject = ['IgniteVersion', '$rootScope'];
+
     constructor(private Version: Version, private $root: ng.IRootScopeService) {}
-    year = new Date().getFullYear()
+
+    year = new Date().getFullYear();
+
     get userIsAuthorized() {
         return !!this.$root.user;
     }
diff --git a/frontend/app/components/web-console-header/components/user-menu/controller.ts b/frontend/app/components/web-console-header/components/user-menu/controller.ts
index 812d3b5..dc5768a 100644
--- a/frontend/app/components/web-console-header/components/user-menu/controller.ts
+++ b/frontend/app/components/web-console-header/components/user-menu/controller.ts
@@ -16,7 +16,8 @@
  */
 
 export default class UserMenu {
-    static $inject = ['$rootScope', 'IgniteUserbar', 'AclService', '$state', 'gettingStarted']
+    static $inject = ['$rootScope', 'IgniteUserbar', 'AclService', '$state', 'gettingStarted'];
+
     constructor(
         private $root: ng.IRootScopeService,
         private IgniteUserbar: any,
@@ -24,6 +25,7 @@
         private $state: any,
         private gettingStarted: any
     ) {}
+
     $onInit() {
         this.items = [
             {text: 'Profile', sref: 'base.settings.profile'},
@@ -47,6 +49,7 @@
 
         this.$root.$on('user', _rebuildSettings);
     }
+
     get user() {
         return this.$root.user;
     }
diff --git a/frontend/app/components/web-console-header/components/web-console-header-content/controller.ts b/frontend/app/components/web-console-header/components/web-console-header-content/controller.ts
index 4345553..2ae9000 100644
--- a/frontend/app/components/web-console-header/components/web-console-header-content/controller.ts
+++ b/frontend/app/components/web-console-header/components/web-console-header-content/controller.ts
@@ -18,7 +18,8 @@
 import {StateService} from '@uirouter/angularjs';
 
 export default class WebConsoleHeaderContent {
-    static $inject = ['$rootScope', '$state']
+    static $inject = ['$rootScope', '$state'];
+
     constructor(
         private $rootScope: ng.IRootScopeService,
         private $state: StateService
diff --git a/frontend/app/components/web-console-sidebar/controller.ts b/frontend/app/components/web-console-sidebar/controller.ts
index bdf606b..02b21a1 100644
--- a/frontend/app/components/web-console-sidebar/controller.ts
+++ b/frontend/app/components/web-console-sidebar/controller.ts
@@ -18,12 +18,15 @@
 import {AppStore, selectSidebarOpened} from '../../store';
 
 export default class WebConsoleSidebar {
-    static $inject = ['$rootScope', 'Store']
+    static $inject = ['$rootScope', 'Store'];
+
     constructor(
         private $rootScope: ng.IRootScopeService,
         private store: AppStore
     ) {}
-    sidebarOpened$ = this.store.state$.pipe(selectSidebarOpened())
+
+    sidebarOpened$ = this.store.state$.pipe(selectSidebarOpened());
+
     get showNavigation(): boolean {
         return !!this.$rootScope.user;
     }
diff --git a/frontend/app/components/web-console-sidebar/web-console-sidebar-navigation/controller.ts b/frontend/app/components/web-console-sidebar/web-console-sidebar-navigation/controller.ts
index 8b5355a..3daafe8 100644
--- a/frontend/app/components/web-console-sidebar/web-console-sidebar-navigation/controller.ts
+++ b/frontend/app/components/web-console-sidebar/web-console-sidebar-navigation/controller.ts
@@ -18,7 +18,9 @@
 import {AppStore, selectNavigationMenu} from '../../../store';
 
 export default class WebConsoleSidebarNavigation {
-    static $inject = ['Store']
+    static $inject = ['Store'];
+
     constructor(private store: AppStore) {}
-    menu$ = this.store.state$.pipe(selectNavigationMenu())
+
+    menu$ = this.store.state$.pipe(selectNavigationMenu());
 }
diff --git a/frontend/app/components/web-console-sidebar/web-console-sidebar-overflow/controller.ts b/frontend/app/components/web-console-sidebar/web-console-sidebar-overflow/controller.ts
index d5403f4..6c2ebb9 100644
--- a/frontend/app/components/web-console-sidebar/web-console-sidebar-overflow/controller.ts
+++ b/frontend/app/components/web-console-sidebar/web-console-sidebar-overflow/controller.ts
@@ -18,13 +18,18 @@
 import ResizeObserver from 'resize-observer-polyfill';
 
 export default class WebCOnsoleSidebarOverflow {
-    static $inject = ['$element', 'gridUtil', '$window']
+    static $inject = ['$element', 'gridUtil', '$window'];
+
     constructor(private el: JQLite, private gridUtil: {getScrollbarWidth(): number}, private $win: ng.IWindowService) {}
-    scrollEl!: JQLite
-    resizeObserver: ResizeObserver
+
+    scrollEl!: JQLite;
+
+    resizeObserver: ResizeObserver;
+
     $onInit() {
         this.el.css('--scrollbar-width', this.gridUtil.getScrollbarWidth());
     }
+
     $postLink() {
         this.scrollEl[0].addEventListener('scroll', this.onScroll, {passive: true});
         this.resizeObserver = new ResizeObserver(() => this.applyStyles(this.scrollEl[0]));
diff --git a/frontend/app/configuration/components/page-configure-advanced/controller.ts b/frontend/app/configuration/components/page-configure-advanced/controller.ts
index 2efab10..cbeb57b 100644
--- a/frontend/app/configuration/components/page-configure-advanced/controller.ts
+++ b/frontend/app/configuration/components/page-configure-advanced/controller.ts
@@ -23,7 +23,7 @@
         { text: 'IGFS', sref: 'base.configuration.edit.advanced.igfs' }
     ];
 
-    menuItems: Array<{text: string, sref: string}>
+    menuItems: Array<{text: string, sref: string}>;
 
     $onInit() {
         this.menuItems = this.constructor.menuItems;
diff --git a/frontend/app/configuration/services/ConfigChangesGuard.ts b/frontend/app/configuration/services/ConfigChangesGuard.ts
index a6735fb..70467f4 100644
--- a/frontend/app/configuration/services/ConfigChangesGuard.ts
+++ b/frontend/app/configuration/services/ConfigChangesGuard.ts
@@ -23,7 +23,7 @@
 import 'jsondiffpatch/public/formatters-styles/html.css';
 
 export class IgniteObjectDiffer<T> {
-    diffPatcher: DiffPatcher
+    diffPatcher: DiffPatcher;
 
     constructor() {
         this.diffPatcher = new DiffPatcher({
diff --git a/frontend/app/configuration/services/ConfigureState.ts b/frontend/app/configuration/services/ConfigureState.ts
index db631b1..b2e10f7 100644
--- a/frontend/app/configuration/services/ConfigureState.ts
+++ b/frontend/app/configuration/services/ConfigureState.ts
@@ -19,7 +19,7 @@
 import {tap, scan} from 'rxjs/operators';
 
 export default class ConfigureState {
-    actions$: Subject<{type: string}>
+    actions$: Subject<{type: string}>;
 
     constructor() {
         this.actions$ = new Subject();
diff --git a/frontend/app/store/effects/ui.ts b/frontend/app/store/effects/ui.ts
index 2a635d6..01f52ab 100644
--- a/frontend/app/store/effects/ui.ts
+++ b/frontend/app/store/effects/ui.ts
@@ -19,7 +19,7 @@
 import {map} from 'rxjs/operators';
 
 export class UIEffects {
-    static $inject = ['Store']
+    static $inject = ['Store'];
     constructor(private store: AppStore) {}
 
     toggleQueriesNavItemEffect$ = this.store.actions$.pipe(