+
+
+
+
+
+
+
+
+
-
-
-
- {{'updateMasterPasswordWarning' | i18n}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/src/popup/accounts/update-temp-password.component.ts b/src/popup/accounts/update-temp-password.component.ts
index b473be0aae..5496c6940e 100644
--- a/src/popup/accounts/update-temp-password.component.ts
+++ b/src/popup/accounts/update-temp-password.component.ts
@@ -1,65 +1,82 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
-import { ApiService } from 'jslib-common/abstractions/api.service';
-import { CryptoService } from 'jslib-common/abstractions/crypto.service';
-import { I18nService } from 'jslib-common/abstractions/i18n.service';
-import { LogService } from 'jslib-common/abstractions/log.service';
-import { MessagingService } from 'jslib-common/abstractions/messaging.service';
-import { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';
-import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
-import { PolicyService } from 'jslib-common/abstractions/policy.service';
-import { SyncService } from 'jslib-common/abstractions/sync.service';
-import { UserService } from 'jslib-common/abstractions/user.service';
+import { ApiService } from "jslib-common/abstractions/api.service";
+import { CryptoService } from "jslib-common/abstractions/crypto.service";
+import { I18nService } from "jslib-common/abstractions/i18n.service";
+import { LogService } from "jslib-common/abstractions/log.service";
+import { MessagingService } from "jslib-common/abstractions/messaging.service";
+import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service";
+import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
+import { PolicyService } from "jslib-common/abstractions/policy.service";
+import { SyncService } from "jslib-common/abstractions/sync.service";
+import { UserService } from "jslib-common/abstractions/user.service";
-import { UpdateTempPasswordComponent as BaseUpdateTempPasswordComponent } from 'jslib-angular/components/update-temp-password.component';
+import { UpdateTempPasswordComponent as BaseUpdateTempPasswordComponent } from "jslib-angular/components/update-temp-password.component";
interface MasterPasswordScore {
- Color: string;
- Text: string;
- Width: number;
+ Color: string;
+ Text: string;
+ Width: number;
}
@Component({
- selector: 'app-update-temp-password',
- templateUrl: 'update-temp-password.component.html',
+ selector: "app-update-temp-password",
+ templateUrl: "update-temp-password.component.html",
})
export class UpdateTempPasswordComponent extends BaseUpdateTempPasswordComponent {
- get masterPasswordScoreStyle(): MasterPasswordScore {
- const scoreWidth = this.masterPasswordScore == null ? 0 : (this.masterPasswordScore + 1) * 20;
- switch (this.masterPasswordScore) {
- case 4:
- return {
- Color: 'bg-success',
- Text: 'strong',
- Width: scoreWidth,
- };
- case 3:
- return {
- Color: 'bg-primary',
- Text: 'good',
- Width: scoreWidth,
- };
- case 2:
- return {
- Color: 'bg-warning',
- Text: 'weak',
- Width: scoreWidth,
- };
- default:
- return {
- Color: 'bg-danger',
- Text: 'weak',
- Width: scoreWidth,
- };
- }
+ get masterPasswordScoreStyle(): MasterPasswordScore {
+ const scoreWidth = this.masterPasswordScore == null ? 0 : (this.masterPasswordScore + 1) * 20;
+ switch (this.masterPasswordScore) {
+ case 4:
+ return {
+ Color: "bg-success",
+ Text: "strong",
+ Width: scoreWidth,
+ };
+ case 3:
+ return {
+ Color: "bg-primary",
+ Text: "good",
+ Width: scoreWidth,
+ };
+ case 2:
+ return {
+ Color: "bg-warning",
+ Text: "weak",
+ Width: scoreWidth,
+ };
+ default:
+ return {
+ Color: "bg-danger",
+ Text: "weak",
+ Width: scoreWidth,
+ };
}
+ }
- constructor(i18nService: I18nService, platformUtilsService: PlatformUtilsService,
- passwordGenerationService: PasswordGenerationService, policyService: PolicyService,
- cryptoService: CryptoService, userService: UserService,
- messagingService: MessagingService, apiService: ApiService,
- syncService: SyncService, logService: LogService) {
- super(i18nService, platformUtilsService, passwordGenerationService, policyService, cryptoService,
- userService, messagingService, apiService, syncService, logService);
- }
+ constructor(
+ i18nService: I18nService,
+ platformUtilsService: PlatformUtilsService,
+ passwordGenerationService: PasswordGenerationService,
+ policyService: PolicyService,
+ cryptoService: CryptoService,
+ userService: UserService,
+ messagingService: MessagingService,
+ apiService: ApiService,
+ syncService: SyncService,
+ logService: LogService
+ ) {
+ super(
+ i18nService,
+ platformUtilsService,
+ passwordGenerationService,
+ policyService,
+ cryptoService,
+ userService,
+ messagingService,
+ apiService,
+ syncService,
+ logService
+ );
+ }
}
diff --git a/src/popup/app-routing.animations.ts b/src/popup/app-routing.animations.ts
index e2362bec02..0d358f4c0a 100644
--- a/src/popup/app-routing.animations.ts
+++ b/src/popup/app-routing.animations.ts
@@ -1,199 +1,213 @@
-import {
- animate,
- group,
- query,
- style,
- transition,
- trigger,
-} from '@angular/animations';
+import { animate, group, query, style, transition, trigger } from "@angular/animations";
-import { BrowserApi } from '../browser/browserApi';
+import { BrowserApi } from "../browser/browserApi";
-const queryShown = query(':enter, :leave', [
- style({ position: 'fixed', width: '100%', height: '100%' }),
-], { optional: true });
+const queryShown = query(
+ ":enter, :leave",
+ [style({ position: "fixed", width: "100%", height: "100%" })],
+ {
+ optional: true,
+ }
+);
// ref: https://github.com/angular/angular/issues/15477
-const queryChildRoute = query('router-outlet ~ *', [
- style({}),
- animate(1, style({})),
-], { optional: true });
+const queryChildRoute = query("router-outlet ~ *", [style({}), animate(1, style({}))], {
+ optional: true,
+});
-const speed = '0.4s';
+const speed = "0.4s";
-export function queryTranslate(direction: string, axis: string, from: number, to: number, zIndex: number = 1000) {
- return query(':' + direction, [
- style({ transform: 'translate' + axis + '(' + from + '%)', zIndex: zIndex, boxShadow: '0 3px 2px -2px gray' }),
- animate(speed + ' ease-in-out', style({ transform: 'translate' + axis + '(' + to + '%)' })),
- ], { optional: true });
+export function queryTranslate(
+ direction: string,
+ axis: string,
+ from: number,
+ to: number,
+ zIndex: number = 1000
+) {
+ return query(
+ ":" + direction,
+ [
+ style({
+ transform: "translate" + axis + "(" + from + "%)",
+ zIndex: zIndex,
+ boxShadow: "0 3px 2px -2px gray",
+ }),
+ animate(speed + " ease-in-out", style({ transform: "translate" + axis + "(" + to + "%)" })),
+ ],
+ { optional: true }
+ );
}
-export function queryTranslateX(direction: string, from: number, to: number, zIndex: number = 1000) {
- return queryTranslate(direction, 'X', from, to, zIndex);
+export function queryTranslateX(
+ direction: string,
+ from: number,
+ to: number,
+ zIndex: number = 1000
+) {
+ return queryTranslate(direction, "X", from, to, zIndex);
}
-export function queryTranslateY(direction: string, from: number, to: number, zIndex: number = 1000) {
- return queryTranslate(direction, 'Y', from, to, zIndex);
+export function queryTranslateY(
+ direction: string,
+ from: number,
+ to: number,
+ zIndex: number = 1000
+) {
+ return queryTranslate(direction, "Y", from, to, zIndex);
}
const inSlideLeft = [
- queryShown,
- group([
- queryTranslateX('enter', 100, 0),
- queryTranslateX('leave', 0, -100),
- queryChildRoute,
- ]),
+ queryShown,
+ group([queryTranslateX("enter", 100, 0), queryTranslateX("leave", 0, -100), queryChildRoute]),
];
const outSlideRight = [
- queryShown,
- group([
- queryTranslateX('enter', -100, 0),
- queryTranslateX('leave', 0, 100),
- ]),
+ queryShown,
+ group([queryTranslateX("enter", -100, 0), queryTranslateX("leave", 0, 100)]),
];
const inSlideUp = [
- queryShown,
- group([
- queryTranslateY('enter', 100, 0, 1010),
- queryTranslateY('leave', 0, 0),
- queryChildRoute,
- ]),
+ queryShown,
+ group([queryTranslateY("enter", 100, 0, 1010), queryTranslateY("leave", 0, 0), queryChildRoute]),
];
const outSlideDown = [
- queryShown,
- group([
- queryTranslateY('enter', 0, 0),
- queryTranslateY('leave', 0, 100, 1010),
- ]),
+ queryShown,
+ group([queryTranslateY("enter", 0, 0), queryTranslateY("leave", 0, 100, 1010)]),
];
const inSlideDown = [
- queryShown,
- group([
- queryTranslateY('enter', -100, 0, 1010),
- queryTranslateY('leave', 0, 0),
- queryChildRoute,
- ]),
+ queryShown,
+ group([queryTranslateY("enter", -100, 0, 1010), queryTranslateY("leave", 0, 0), queryChildRoute]),
];
const outSlideUp = [
- queryShown,
- group([
- queryTranslateY('enter', 0, 0),
- queryTranslateY('leave', 0, -100, 1010),
- ]),
+ queryShown,
+ group([queryTranslateY("enter", 0, 0), queryTranslateY("leave", 0, -100, 1010)]),
];
export function tabsToCiphers(fromState: string, toState: string) {
- if (fromState == null || toState === null || toState.indexOf('ciphers_') === -1) {
- return false;
- }
- return (fromState.indexOf('ciphers_') === 0 && fromState.indexOf('ciphers_direction=b') === -1) ||
- fromState === 'tabs';
+ if (fromState == null || toState === null || toState.indexOf("ciphers_") === -1) {
+ return false;
+ }
+ return (
+ (fromState.indexOf("ciphers_") === 0 && fromState.indexOf("ciphers_direction=b") === -1) ||
+ fromState === "tabs"
+ );
}
export function ciphersToTabs(fromState: string, toState: string) {
- if (fromState == null || toState === null || fromState.indexOf('ciphers_') === -1) {
- return false;
- }
- return toState.indexOf('ciphers_direction=b') === 0 || toState === 'tabs';
+ if (fromState == null || toState === null || fromState.indexOf("ciphers_") === -1) {
+ return false;
+ }
+ return toState.indexOf("ciphers_direction=b") === 0 || toState === "tabs";
}
export function ciphersToView(fromState: string, toState: string) {
- if (fromState == null || toState === null) {
- return false;
- }
- return fromState.indexOf('ciphers_') === 0 &&
- (toState === 'view-cipher' || toState === 'add-cipher' || toState === 'clone-cipher');
+ if (fromState == null || toState === null) {
+ return false;
+ }
+ return (
+ fromState.indexOf("ciphers_") === 0 &&
+ (toState === "view-cipher" || toState === "add-cipher" || toState === "clone-cipher")
+ );
}
export function viewToCiphers(fromState: string, toState: string) {
- if (fromState == null || toState === null) {
- return false;
- }
- return (fromState === 'view-cipher' || fromState === 'add-cipher' || fromState === 'clone-cipher') &&
- toState.indexOf('ciphers_') === 0;
+ if (fromState == null || toState === null) {
+ return false;
+ }
+ return (
+ (fromState === "view-cipher" || fromState === "add-cipher" || fromState === "clone-cipher") &&
+ toState.indexOf("ciphers_") === 0
+ );
}
-export const routerTransition = trigger('routerTransition', [
- transition('void => home', inSlideLeft),
- transition('void => tabs', inSlideLeft),
+export const routerTransition = trigger("routerTransition", [
+ transition("void => home", inSlideLeft),
+ transition("void => tabs", inSlideLeft),
- transition('home => environment, home => login, home => register', inSlideUp),
+ transition("home => environment, home => login, home => register", inSlideUp),
- transition('login => home', outSlideDown),
- transition('login => hint', inSlideUp),
- transition('login => tabs, login => 2fa', inSlideLeft),
+ transition("login => home", outSlideDown),
+ transition("login => hint", inSlideUp),
+ transition("login => tabs, login => 2fa", inSlideLeft),
- transition('hint => login, register => home, environment => home', outSlideDown),
+ transition("hint => login, register => home, environment => home", outSlideDown),
- transition('2fa => login', outSlideRight),
- transition('2fa => 2fa-options', inSlideUp),
- transition('2fa-options => 2fa', outSlideDown),
- transition('2fa => tabs', inSlideLeft),
+ transition("2fa => login", outSlideRight),
+ transition("2fa => 2fa-options", inSlideUp),
+ transition("2fa-options => 2fa", outSlideDown),
+ transition("2fa => tabs", inSlideLeft),
- transition(tabsToCiphers, inSlideLeft),
- transition(ciphersToTabs, outSlideRight),
+ transition(tabsToCiphers, inSlideLeft),
+ transition(ciphersToTabs, outSlideRight),
- transition(ciphersToView, inSlideUp),
- transition(viewToCiphers, outSlideDown),
+ transition(ciphersToView, inSlideUp),
+ transition(viewToCiphers, outSlideDown),
- transition('tabs => view-cipher', inSlideUp),
- transition('view-cipher => tabs', outSlideDown),
+ transition("tabs => view-cipher", inSlideUp),
+ transition("view-cipher => tabs", outSlideDown),
- transition('view-cipher => edit-cipher, view-cipher => cipher-password-history', inSlideUp),
- transition('edit-cipher => view-cipher, cipher-password-history => view-cipher, edit-cipher => tabs', outSlideDown),
+ transition("view-cipher => edit-cipher, view-cipher => cipher-password-history", inSlideUp),
+ transition(
+ "edit-cipher => view-cipher, cipher-password-history => view-cipher, edit-cipher => tabs",
+ outSlideDown
+ ),
- transition('view-cipher => clone-cipher', inSlideUp),
- transition('clone-cipher => view-cipher, clone-cipher => tabs', outSlideDown),
+ transition("view-cipher => clone-cipher", inSlideUp),
+ transition("clone-cipher => view-cipher, clone-cipher => tabs", outSlideDown),
- transition('view-cipher => share-cipher', inSlideUp),
- transition('share-cipher => view-cipher', outSlideDown),
+ transition("view-cipher => share-cipher", inSlideUp),
+ transition("share-cipher => view-cipher", outSlideDown),
- transition('tabs => add-cipher', inSlideUp),
- transition('add-cipher => tabs', outSlideDown),
+ transition("tabs => add-cipher", inSlideUp),
+ transition("add-cipher => tabs", outSlideDown),
- transition('generator => generator-history, tabs => generator-history', inSlideLeft),
- transition('generator-history => generator, generator-history => tabs', outSlideRight),
+ transition("generator => generator-history, tabs => generator-history", inSlideLeft),
+ transition("generator-history => generator, generator-history => tabs", outSlideRight),
- transition('add-cipher => generator, edit-cipher => generator, clone-cipher => generator', inSlideUp),
- transition('generator => add-cipher, generator => edit-cipher, generator => clone-cipher', outSlideDown),
+ transition(
+ "add-cipher => generator, edit-cipher => generator, clone-cipher => generator",
+ inSlideUp
+ ),
+ transition(
+ "generator => add-cipher, generator => edit-cipher, generator => clone-cipher",
+ outSlideDown
+ ),
- transition('edit-cipher => attachments, edit-cipher => collections', inSlideLeft),
- transition('attachments => edit-cipher, collections => edit-cipher', outSlideRight),
+ transition("edit-cipher => attachments, edit-cipher => collections", inSlideLeft),
+ transition("attachments => edit-cipher, collections => edit-cipher", outSlideRight),
- transition('clone-cipher => attachments, clone-cipher => collections', inSlideLeft),
- transition('attachments => clone-cipher, collections => clone-cipher', outSlideRight),
+ transition("clone-cipher => attachments, clone-cipher => collections", inSlideLeft),
+ transition("attachments => clone-cipher, collections => clone-cipher", outSlideRight),
- transition('tabs => export', inSlideLeft),
- transition('export => tabs', outSlideRight),
+ transition("tabs => export", inSlideLeft),
+ transition("export => tabs", outSlideRight),
- transition('tabs => folders', inSlideLeft),
- transition('folders => tabs', outSlideRight),
+ transition("tabs => folders", inSlideLeft),
+ transition("folders => tabs", outSlideRight),
- transition('folders => edit-folder, folders => add-folder', inSlideUp),
- transition('edit-folder => folders, add-folder => folders', outSlideDown),
+ transition("folders => edit-folder, folders => add-folder", inSlideUp),
+ transition("edit-folder => folders, add-folder => folders", outSlideDown),
- transition('tabs => sync', inSlideLeft),
- transition('sync => tabs', outSlideRight),
+ transition("tabs => sync", inSlideLeft),
+ transition("sync => tabs", outSlideRight),
- transition('tabs => options', inSlideLeft),
- transition('options => tabs', outSlideRight),
+ transition("tabs => options", inSlideLeft),
+ transition("options => tabs", outSlideRight),
- transition('tabs => premium', inSlideLeft),
- transition('premium => tabs', outSlideRight),
+ transition("tabs => premium", inSlideLeft),
+ transition("premium => tabs", outSlideRight),
- transition('tabs => lock', inSlideDown),
+ transition("tabs => lock", inSlideDown),
- transition('tabs => send-type', inSlideLeft),
- transition('send-type => tabs', outSlideRight),
+ transition("tabs => send-type", inSlideLeft),
+ transition("send-type => tabs", outSlideRight),
- transition('tabs => add-send, send-type => add-send', inSlideUp),
- transition('add-send => tabs, add-send => send-type', outSlideDown),
+ transition("tabs => add-send, send-type => add-send", inSlideUp),
+ transition("add-send => tabs, add-send => send-type", outSlideDown),
- transition('tabs => edit-send, send-type => edit-send', inSlideUp),
- transition('edit-send => tabs, edit-send => send-type', outSlideDown),
+ transition("tabs => edit-send, send-type => edit-send", inSlideUp),
+ transition("edit-send => tabs, edit-send => send-type", outSlideDown),
]);
diff --git a/src/popup/app-routing.module.ts b/src/popup/app-routing.module.ts
index e9b8c797f9..9c7acd60ed 100644
--- a/src/popup/app-routing.module.ts
+++ b/src/popup/app-routing.module.ts
@@ -1,355 +1,352 @@
-import { Injectable, NgModule } from '@angular/core';
-import {
- ActivatedRouteSnapshot,
- RouteReuseStrategy,
- RouterModule,
- Routes,
-} from '@angular/router';
+import { Injectable, NgModule } from "@angular/core";
+import { ActivatedRouteSnapshot, RouteReuseStrategy, RouterModule, Routes } from "@angular/router";
-import { AuthGuardService } from 'jslib-angular/services/auth-guard.service';
-import { LockGuardService } from 'jslib-angular/services/lock-guard.service';
+import { AuthGuardService } from "jslib-angular/services/auth-guard.service";
+import { LockGuardService } from "jslib-angular/services/lock-guard.service";
-import { DebounceNavigationService } from './services/debounceNavigationService';
-import { LaunchGuardService } from './services/launch-guard.service';
+import { DebounceNavigationService } from "./services/debounceNavigationService";
+import { LaunchGuardService } from "./services/launch-guard.service";
-import { EnvironmentComponent } from './accounts/environment.component';
-import { HintComponent } from './accounts/hint.component';
-import { HomeComponent } from './accounts/home.component';
-import { LockComponent } from './accounts/lock.component';
-import { LoginComponent } from './accounts/login.component';
-import { RegisterComponent } from './accounts/register.component';
-import { RemovePasswordComponent } from './accounts/remove-password.component';
-import { SetPasswordComponent } from './accounts/set-password.component';
-import { SsoComponent } from './accounts/sso.component';
-import { TwoFactorOptionsComponent } from './accounts/two-factor-options.component';
-import { TwoFactorComponent } from './accounts/two-factor.component';
-import { UpdateTempPasswordComponent } from './accounts/update-temp-password.component';
+import { EnvironmentComponent } from "./accounts/environment.component";
+import { HintComponent } from "./accounts/hint.component";
+import { HomeComponent } from "./accounts/home.component";
+import { LockComponent } from "./accounts/lock.component";
+import { LoginComponent } from "./accounts/login.component";
+import { RegisterComponent } from "./accounts/register.component";
+import { RemovePasswordComponent } from "./accounts/remove-password.component";
+import { SetPasswordComponent } from "./accounts/set-password.component";
+import { SsoComponent } from "./accounts/sso.component";
+import { TwoFactorOptionsComponent } from "./accounts/two-factor-options.component";
+import { TwoFactorComponent } from "./accounts/two-factor.component";
+import { UpdateTempPasswordComponent } from "./accounts/update-temp-password.component";
-import { PasswordGeneratorHistoryComponent } from './generator/password-generator-history.component';
-import { PasswordGeneratorComponent } from './generator/password-generator.component';
+import { PasswordGeneratorHistoryComponent } from "./generator/password-generator-history.component";
+import { PasswordGeneratorComponent } from "./generator/password-generator.component";
-import { PrivateModeComponent } from './private-mode.component';
-import { TabsComponent } from './tabs.component';
+import { PrivateModeComponent } from "./private-mode.component";
+import { TabsComponent } from "./tabs.component";
-import { ExcludedDomainsComponent } from './settings/excluded-domains.component';
-import { ExportComponent } from './settings/export.component';
-import { FolderAddEditComponent } from './settings/folder-add-edit.component';
-import { FoldersComponent } from './settings/folders.component';
-import { OptionsComponent } from './settings/options.component';
-import { PremiumComponent } from './settings/premium.component';
-import { SettingsComponent } from './settings/settings.component';
-import { SyncComponent } from './settings/sync.component';
+import { ExcludedDomainsComponent } from "./settings/excluded-domains.component";
+import { ExportComponent } from "./settings/export.component";
+import { FolderAddEditComponent } from "./settings/folder-add-edit.component";
+import { FoldersComponent } from "./settings/folders.component";
+import { OptionsComponent } from "./settings/options.component";
+import { PremiumComponent } from "./settings/premium.component";
+import { SettingsComponent } from "./settings/settings.component";
+import { SyncComponent } from "./settings/sync.component";
-import { AddEditComponent } from './vault/add-edit.component';
-import { AttachmentsComponent } from './vault/attachments.component';
-import { CiphersComponent } from './vault/ciphers.component';
-import { CollectionsComponent } from './vault/collections.component';
-import { CurrentTabComponent } from './vault/current-tab.component';
-import { GroupingsComponent } from './vault/groupings.component';
-import { PasswordHistoryComponent } from './vault/password-history.component';
-import { ShareComponent } from './vault/share.component';
-import { ViewComponent } from './vault/view.component';
+import { AddEditComponent } from "./vault/add-edit.component";
+import { AttachmentsComponent } from "./vault/attachments.component";
+import { CiphersComponent } from "./vault/ciphers.component";
+import { CollectionsComponent } from "./vault/collections.component";
+import { CurrentTabComponent } from "./vault/current-tab.component";
+import { GroupingsComponent } from "./vault/groupings.component";
+import { PasswordHistoryComponent } from "./vault/password-history.component";
+import { ShareComponent } from "./vault/share.component";
+import { ViewComponent } from "./vault/view.component";
-import { SendAddEditComponent } from './send/send-add-edit.component';
-import { SendGroupingsComponent } from './send/send-groupings.component';
-import { SendTypeComponent } from './send/send-type.component';
+import { SendAddEditComponent } from "./send/send-add-edit.component";
+import { SendGroupingsComponent } from "./send/send-groupings.component";
+import { SendTypeComponent } from "./send/send-type.component";
const routes: Routes = [
- {
- path: '',
- redirectTo: 'home',
- pathMatch: 'full',
- },
- {
- path: 'vault',
- redirectTo: '/tabs/vault',
- pathMatch: 'full',
- },
- {
- path: 'home',
- component: HomeComponent,
- canActivate: [LaunchGuardService],
- data: { state: 'home' },
- },
- {
- path: 'login',
- component: LoginComponent,
- canActivate: [LaunchGuardService],
- data: { state: 'login' },
- },
- {
- path: 'lock',
- component: LockComponent,
- canActivate: [LockGuardService],
- data: { state: 'lock' },
- },
- {
- path: '2fa',
- component: TwoFactorComponent,
- canActivate: [LaunchGuardService],
- data: { state: '2fa' },
- },
- {
- path: '2fa-options',
- component: TwoFactorOptionsComponent,
- canActivate: [LaunchGuardService],
- data: { state: '2fa-options' },
- },
- {
- path: 'sso',
- component: SsoComponent,
- canActivate: [LaunchGuardService],
- data: { state: 'sso' },
- },
- {
- path: 'set-password',
- component: SetPasswordComponent,
- data: { state: 'set-password' },
- },
- {
- path: 'remove-password',
- component: RemovePasswordComponent,
+ {
+ path: "",
+ redirectTo: "home",
+ pathMatch: "full",
+ },
+ {
+ path: "vault",
+ redirectTo: "/tabs/vault",
+ pathMatch: "full",
+ },
+ {
+ path: "home",
+ component: HomeComponent,
+ canActivate: [LaunchGuardService],
+ data: { state: "home" },
+ },
+ {
+ path: "login",
+ component: LoginComponent,
+ canActivate: [LaunchGuardService],
+ data: { state: "login" },
+ },
+ {
+ path: "lock",
+ component: LockComponent,
+ canActivate: [LockGuardService],
+ data: { state: "lock" },
+ },
+ {
+ path: "2fa",
+ component: TwoFactorComponent,
+ canActivate: [LaunchGuardService],
+ data: { state: "2fa" },
+ },
+ {
+ path: "2fa-options",
+ component: TwoFactorOptionsComponent,
+ canActivate: [LaunchGuardService],
+ data: { state: "2fa-options" },
+ },
+ {
+ path: "sso",
+ component: SsoComponent,
+ canActivate: [LaunchGuardService],
+ data: { state: "sso" },
+ },
+ {
+ path: "set-password",
+ component: SetPasswordComponent,
+ data: { state: "set-password" },
+ },
+ {
+ path: "remove-password",
+ component: RemovePasswordComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "remove-password" },
+ },
+ {
+ path: "register",
+ component: RegisterComponent,
+ canActivate: [LaunchGuardService],
+ data: { state: "register" },
+ },
+ {
+ path: "hint",
+ component: HintComponent,
+ canActivate: [LaunchGuardService],
+ data: { state: "hint" },
+ },
+ {
+ path: "environment",
+ component: EnvironmentComponent,
+ canActivate: [LaunchGuardService],
+ data: { state: "environment" },
+ },
+ {
+ path: "ciphers",
+ component: CiphersComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "ciphers" },
+ },
+ {
+ path: "view-cipher",
+ component: ViewComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "view-cipher" },
+ },
+ {
+ path: "cipher-password-history",
+ component: PasswordHistoryComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "cipher-password-history" },
+ },
+ {
+ path: "add-cipher",
+ component: AddEditComponent,
+ canActivate: [AuthGuardService, DebounceNavigationService],
+ data: { state: "add-cipher" },
+ runGuardsAndResolvers: "always",
+ },
+ {
+ path: "edit-cipher",
+ component: AddEditComponent,
+ canActivate: [AuthGuardService, DebounceNavigationService],
+ data: { state: "edit-cipher" },
+ runGuardsAndResolvers: "always",
+ },
+ {
+ path: "share-cipher",
+ component: ShareComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "share-cipher" },
+ },
+ {
+ path: "collections",
+ component: CollectionsComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "collections" },
+ },
+ {
+ path: "attachments",
+ component: AttachmentsComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "attachments" },
+ },
+ {
+ path: "generator",
+ component: PasswordGeneratorComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "generator" },
+ },
+ {
+ path: "generator-history",
+ component: PasswordGeneratorHistoryComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "generator-history" },
+ },
+ {
+ path: "export",
+ component: ExportComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "export" },
+ },
+ {
+ path: "folders",
+ component: FoldersComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "folders" },
+ },
+ {
+ path: "add-folder",
+ component: FolderAddEditComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "add-folder" },
+ },
+ {
+ path: "edit-folder",
+ component: FolderAddEditComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "edit-folder" },
+ },
+ {
+ path: "sync",
+ component: SyncComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "sync" },
+ },
+ {
+ path: "excluded-domains",
+ component: ExcludedDomainsComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "excluded-domains" },
+ },
+ {
+ path: "premium",
+ component: PremiumComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "premium" },
+ },
+ {
+ path: "options",
+ component: OptionsComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "options" },
+ },
+ {
+ path: "private-mode",
+ component: PrivateModeComponent,
+ data: { state: "private-mode" },
+ },
+ {
+ path: "clone-cipher",
+ component: AddEditComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "clone-cipher" },
+ },
+ {
+ path: "send-type",
+ component: SendTypeComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "send-type" },
+ },
+ {
+ path: "add-send",
+ component: SendAddEditComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "add-send" },
+ },
+ {
+ path: "edit-send",
+ component: SendAddEditComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "edit-send" },
+ },
+ {
+ path: "update-temp-password",
+ component: UpdateTempPasswordComponent,
+ canActivate: [AuthGuardService],
+ data: { state: "update-temp-password" },
+ },
+ {
+ path: "tabs",
+ component: TabsComponent,
+ data: { state: "tabs" },
+ children: [
+ {
+ path: "",
+ redirectTo: "/tabs/vault",
+ pathMatch: "full",
+ },
+ {
+ path: "current",
+ component: CurrentTabComponent,
canActivate: [AuthGuardService],
- data: { state: 'remove-password' },
- },
- {
- path: 'register',
- component: RegisterComponent,
- canActivate: [LaunchGuardService],
- data: { state: 'register' },
- },
- {
- path: 'hint',
- component: HintComponent,
- canActivate: [LaunchGuardService],
- data: { state: 'hint' },
- },
- {
- path: 'environment',
- component: EnvironmentComponent,
- canActivate: [LaunchGuardService],
- data: { state: 'environment' },
- },
- {
- path: 'ciphers',
- component: CiphersComponent,
+ data: { state: "tabs_current" },
+ runGuardsAndResolvers: "always",
+ },
+ {
+ path: "vault",
+ component: GroupingsComponent,
canActivate: [AuthGuardService],
- data: { state: 'ciphers' },
- },
- {
- path: 'view-cipher',
- component: ViewComponent,
- canActivate: [AuthGuardService],
- data: { state: 'view-cipher' },
- },
- {
- path: 'cipher-password-history',
- component: PasswordHistoryComponent,
- canActivate: [AuthGuardService],
- data: { state: 'cipher-password-history' },
- },
- {
- path: 'add-cipher',
- component: AddEditComponent,
- canActivate: [AuthGuardService, DebounceNavigationService],
- data: { state: 'add-cipher' },
- runGuardsAndResolvers: 'always',
- },
- {
- path: 'edit-cipher',
- component: AddEditComponent,
- canActivate: [AuthGuardService, DebounceNavigationService],
- data: { state: 'edit-cipher' },
- runGuardsAndResolvers: 'always',
- },
- {
- path: 'share-cipher',
- component: ShareComponent,
- canActivate: [AuthGuardService],
- data: { state: 'share-cipher' },
- },
- {
- path: 'collections',
- component: CollectionsComponent,
- canActivate: [AuthGuardService],
- data: { state: 'collections' },
- },
- {
- path: 'attachments',
- component: AttachmentsComponent,
- canActivate: [AuthGuardService],
- data: { state: 'attachments' },
- },
- {
- path: 'generator',
+ data: { state: "tabs_vault" },
+ },
+ {
+ path: "generator",
component: PasswordGeneratorComponent,
canActivate: [AuthGuardService],
- data: { state: 'generator' },
- },
- {
- path: 'generator-history',
- component: PasswordGeneratorHistoryComponent,
+ data: { state: "tabs_generator" },
+ },
+ {
+ path: "settings",
+ component: SettingsComponent,
canActivate: [AuthGuardService],
- data: { state: 'generator-history' },
- },
- {
- path: 'export',
- component: ExportComponent,
+ data: { state: "tabs_settings" },
+ },
+ {
+ path: "send",
+ component: SendGroupingsComponent,
canActivate: [AuthGuardService],
- data: { state: 'export' },
- },
- {
- path: 'folders',
- component: FoldersComponent,
- canActivate: [AuthGuardService],
- data: { state: 'folders' },
- },
- {
- path: 'add-folder',
- component: FolderAddEditComponent,
- canActivate: [AuthGuardService],
- data: { state: 'add-folder' },
- },
- {
- path: 'edit-folder',
- component: FolderAddEditComponent,
- canActivate: [AuthGuardService],
- data: { state: 'edit-folder' },
- },
- {
- path: 'sync',
- component: SyncComponent,
- canActivate: [AuthGuardService],
- data: { state: 'sync' },
- },
- {
- path: 'excluded-domains',
- component: ExcludedDomainsComponent,
- canActivate: [AuthGuardService],
- data: { state: 'excluded-domains' },
- },
- {
- path: 'premium',
- component: PremiumComponent,
- canActivate: [AuthGuardService],
- data: { state: 'premium' },
- },
- {
- path: 'options',
- component: OptionsComponent,
- canActivate: [AuthGuardService],
- data: { state: 'options' },
- },
- {
- path: 'private-mode',
- component: PrivateModeComponent,
- data: { state: 'private-mode' },
- },
- {
- path: 'clone-cipher',
- component: AddEditComponent,
- canActivate: [AuthGuardService],
- data: { state: 'clone-cipher' },
- },
- {
- path: 'send-type',
- component: SendTypeComponent,
- canActivate: [AuthGuardService],
- data: { state: 'send-type' },
- },
- {
- path: 'add-send',
- component: SendAddEditComponent,
- canActivate: [AuthGuardService],
- data: { state: 'add-send' },
- },
- {
- path: 'edit-send',
- component: SendAddEditComponent,
- canActivate: [AuthGuardService],
- data: { state: 'edit-send' },
- },
- {
- path: 'update-temp-password',
- component: UpdateTempPasswordComponent,
- canActivate: [AuthGuardService],
- data: { state: 'update-temp-password' },
- },
- {
- path: 'tabs',
- component: TabsComponent,
- data: { state: 'tabs' },
- children: [
- {
- path: '',
- redirectTo: '/tabs/vault',
- pathMatch: 'full',
- },
- {
- path: 'current',
- component: CurrentTabComponent,
- canActivate: [AuthGuardService],
- data: { state: 'tabs_current' },
- runGuardsAndResolvers: 'always',
- },
- {
- path: 'vault',
- component: GroupingsComponent,
- canActivate: [AuthGuardService],
- data: { state: 'tabs_vault' },
- },
- {
- path: 'generator',
- component: PasswordGeneratorComponent,
- canActivate: [AuthGuardService],
- data: { state: 'tabs_generator' },
- },
- {
- path: 'settings',
- component: SettingsComponent,
- canActivate: [AuthGuardService],
- data: { state: 'tabs_settings' },
- },
- {
- path: 'send',
- component: SendGroupingsComponent,
- canActivate: [AuthGuardService],
- data: { state: 'tabs_send' },
- },
- ],
- },
+ data: { state: "tabs_send" },
+ },
+ ],
+ },
];
@Injectable()
export class NoRouteReuseStrategy implements RouteReuseStrategy {
- shouldDetach(route: ActivatedRouteSnapshot) {
- return false;
- }
+ shouldDetach(route: ActivatedRouteSnapshot) {
+ return false;
+ }
- store(route: ActivatedRouteSnapshot, handle: {}) { /* Nothing */ }
+ store(route: ActivatedRouteSnapshot, handle: {}) {
+ /* Nothing */
+ }
- shouldAttach(route: ActivatedRouteSnapshot) {
- return false;
- }
+ shouldAttach(route: ActivatedRouteSnapshot) {
+ return false;
+ }
- retrieve(route: ActivatedRouteSnapshot): any {
- return null;
- }
+ retrieve(route: ActivatedRouteSnapshot): any {
+ return null;
+ }
- shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot) {
- return false;
- }
+ shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot) {
+ return false;
+ }
}
@NgModule({
- imports: [RouterModule.forRoot(routes, {
- useHash: true,
- onSameUrlNavigation: 'reload',
- /*enableTracing: true,*/
- })],
- exports: [RouterModule],
- providers: [
- { provide: RouteReuseStrategy, useClass: NoRouteReuseStrategy },
- ],
+ imports: [
+ RouterModule.forRoot(routes, {
+ useHash: true,
+ onSameUrlNavigation: "reload",
+ /*enableTracing: true,*/
+ }),
+ ],
+ exports: [RouterModule],
+ providers: [{ provide: RouteReuseStrategy, useClass: NoRouteReuseStrategy }],
})
-export class AppRoutingModule { }
+export class AppRoutingModule {}
diff --git a/src/popup/app.component.ts b/src/popup/app.component.ts
index bd3bb1fda2..635b88504a 100644
--- a/src/popup/app.component.ts
+++ b/src/popup/app.component.ts
@@ -1,243 +1,254 @@
-import {
- ChangeDetectorRef,
- Component,
- NgZone,
- OnInit,
- SecurityContext,
-} from '@angular/core';
-import { DomSanitizer } from '@angular/platform-browser';
-import {
- NavigationEnd,
- Router,
- RouterOutlet,
-} from '@angular/router';
-import {
- IndividualConfig,
- ToastrService,
-} from 'ngx-toastr';
-import Swal, { SweetAlertIcon } from 'sweetalert2/src/sweetalert2.js';
-import { BrowserApi } from '../browser/browserApi';
+import { ChangeDetectorRef, Component, NgZone, OnInit, SecurityContext } from "@angular/core";
+import { DomSanitizer } from "@angular/platform-browser";
+import { NavigationEnd, Router, RouterOutlet } from "@angular/router";
+import { IndividualConfig, ToastrService } from "ngx-toastr";
+import Swal, { SweetAlertIcon } from "sweetalert2/src/sweetalert2.js";
+import { BrowserApi } from "../browser/browserApi";
-import { AuthService } from 'jslib-common/abstractions/auth.service';
-import { BroadcasterService } from 'jslib-common/abstractions/broadcaster.service';
-import { I18nService } from 'jslib-common/abstractions/i18n.service';
-import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
-import { MessagingService } from 'jslib-common/abstractions/messaging.service';
-import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
-import { StateService } from 'jslib-common/abstractions/state.service';
-import { StorageService } from 'jslib-common/abstractions/storage.service';
+import { AuthService } from "jslib-common/abstractions/auth.service";
+import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
+import { I18nService } from "jslib-common/abstractions/i18n.service";
+import { KeyConnectorService } from "jslib-common/abstractions/keyConnector.service";
+import { MessagingService } from "jslib-common/abstractions/messaging.service";
+import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
+import { StateService } from "jslib-common/abstractions/state.service";
+import { StorageService } from "jslib-common/abstractions/storage.service";
-import { ConstantsService } from 'jslib-common/services/constants.service';
+import { ConstantsService } from "jslib-common/services/constants.service";
-import { routerTransition } from './app-routing.animations';
+import { routerTransition } from "./app-routing.animations";
@Component({
- selector: 'app-root',
- styles: [],
- animations: [routerTransition],
- template: `
-
-
- `,
+ selector: "app-root",
+ styles: [],
+ animations: [routerTransition],
+ template: `
+
+ `,
})
export class AppComponent implements OnInit {
+ private lastActivity: number = null;
- private lastActivity: number = null;
+ constructor(
+ private toastrService: ToastrService,
+ private storageService: StorageService,
+ private broadcasterService: BroadcasterService,
+ private authService: AuthService,
+ private i18nService: I18nService,
+ private router: Router,
+ private stateService: StateService,
+ private messagingService: MessagingService,
+ private changeDetectorRef: ChangeDetectorRef,
+ private ngZone: NgZone,
+ private sanitizer: DomSanitizer,
+ private platformUtilsService: PlatformUtilsService,
+ private keyConnectoService: KeyConnectorService
+ ) {}
- constructor(private toastrService: ToastrService, private storageService: StorageService,
- private broadcasterService: BroadcasterService, private authService: AuthService,
- private i18nService: I18nService, private router: Router,
- private stateService: StateService, private messagingService: MessagingService,
- private changeDetectorRef: ChangeDetectorRef, private ngZone: NgZone,
- private sanitizer: DomSanitizer, private platformUtilsService: PlatformUtilsService,
- private keyConnectoService: KeyConnectorService) { }
+ ngOnInit() {
+ if (BrowserApi.getBackgroundPage() == null) {
+ return;
+ }
- ngOnInit() {
- if (BrowserApi.getBackgroundPage() == null) {
- return;
- }
+ this.ngZone.runOutsideAngular(() => {
+ window.onmousemove = () => this.recordActivity();
+ window.onmousedown = () => this.recordActivity();
+ window.ontouchstart = () => this.recordActivity();
+ window.onclick = () => this.recordActivity();
+ window.onscroll = () => this.recordActivity();
+ window.onkeypress = () => this.recordActivity();
+ });
- this.ngZone.runOutsideAngular(() => {
- window.onmousemove = () => this.recordActivity();
- window.onmousedown = () => this.recordActivity();
- window.ontouchstart = () => this.recordActivity();
- window.onclick = () => this.recordActivity();
- window.onscroll = () => this.recordActivity();
- window.onkeypress = () => this.recordActivity();
+ (window as any).bitwardenPopupMainMessageListener = async (
+ msg: any,
+ sender: any,
+ sendResponse: any
+ ) => {
+ if (msg.command === "doneLoggingOut") {
+ this.ngZone.run(async () => {
+ this.authService.logOut(() => {
+ if (msg.expired) {
+ this.showToast({
+ type: "warning",
+ title: this.i18nService.t("loggedOut"),
+ text: this.i18nService.t("loginExpired"),
+ });
+ }
+ this.router.navigate(["home"]);
+ this.stateService.purge();
+ });
+ this.changeDetectorRef.detectChanges();
});
-
- (window as any).bitwardenPopupMainMessageListener = async (msg: any, sender: any, sendResponse: any) => {
- if (msg.command === 'doneLoggingOut') {
- this.ngZone.run(async () => {
- this.authService.logOut(() => {
- if (msg.expired) {
- this.showToast({
- type: 'warning',
- title: this.i18nService.t('loggedOut'),
- text: this.i18nService.t('loginExpired'),
- });
- }
- this.router.navigate(['home']);
- this.stateService.purge();
- });
- this.changeDetectorRef.detectChanges();
- });
- } else if (msg.command === 'authBlocked') {
- this.ngZone.run(() => {
- this.router.navigate(['home']);
- });
- } else if (msg.command === 'locked') {
- this.stateService.purge();
- this.ngZone.run(() => {
- this.router.navigate(['lock']);
- });
- } else if (msg.command === 'showDialog') {
- await this.showDialog(msg);
- } else if (msg.command === 'showToast') {
- this.ngZone.run(() => {
- this.showToast(msg);
- });
- } else if (msg.command === 'reloadProcess') {
- const windowReload = this.platformUtilsService.isSafari() ||
- this.platformUtilsService.isFirefox() || this.platformUtilsService.isOpera();
- if (windowReload) {
- // Wait to make sure background has reloaded first.
- window.setTimeout(() => BrowserApi.reloadExtension(window), 2000);
- }
- } else if (msg.command === 'reloadPopup') {
- this.ngZone.run(() => {
- this.router.navigate(['/']);
- });
- } else if (msg.command === 'convertAccountToKeyConnector') {
- this.ngZone.run(async () => {
- await this.keyConnectoService.setConvertAccountRequired(true);
- this.router.navigate(['/remove-password']);
- });
- } else {
- msg.webExtSender = sender;
- this.broadcasterService.send(msg);
- }
- };
-
- BrowserApi.messageListener('app.component', (window as any).bitwardenPopupMainMessageListener);
-
- this.router.events.subscribe(event => {
- if (event instanceof NavigationEnd) {
- const url = event.urlAfterRedirects || event.url || '';
- if (url.startsWith('/tabs/') && (window as any).previousPopupUrl != null &&
- (window as any).previousPopupUrl.startsWith('/tabs/')) {
- this.stateService.remove('GroupingsComponent');
- this.stateService.remove('GroupingsComponentScope');
- this.stateService.remove('CiphersComponent');
- this.stateService.remove('SendGroupingsComponent');
- this.stateService.remove('SendGroupingsComponentScope');
- this.stateService.remove('SendTypeComponent');
- }
- if (url.startsWith('/tabs/')) {
- this.stateService.remove('addEditCipherInfo');
- }
- (window as any).previousPopupUrl = url;
-
- // Clear route direction after animation (400ms)
- if ((window as any).routeDirection != null) {
- window.setTimeout(() => {
- (window as any).routeDirection = null;
- }, 400);
- }
- }
+ } else if (msg.command === "authBlocked") {
+ this.ngZone.run(() => {
+ this.router.navigate(["home"]);
});
- }
-
- getState(outlet: RouterOutlet) {
- if (outlet.activatedRouteData.state === 'ciphers') {
- const routeDirection = (window as any).routeDirection != null ? (window as any).routeDirection : '';
- return 'ciphers_direction=' + routeDirection + '_' +
- (outlet.activatedRoute.queryParams as any).value.folderId + '_' +
- (outlet.activatedRoute.queryParams as any).value.collectionId;
- } else {
- return outlet.activatedRouteData.state;
- }
- }
-
- private async recordActivity() {
- const now = (new Date()).getTime();
- if (this.lastActivity != null && now - this.lastActivity < 250) {
- return;
- }
-
- this.lastActivity = now;
- this.storageService.save(ConstantsService.lastActiveKey, now);
- }
-
- private showToast(msg: any) {
- let message = '';
-
- const options: Partial
= {};
-
- if (typeof (msg.text) === 'string') {
- message = msg.text;
- } else if (msg.text.length === 1) {
- message = msg.text[0];
- } else {
- msg.text.forEach((t: string) =>
- message += ('' + this.sanitizer.sanitize(SecurityContext.HTML, t) + '
'));
- options.enableHtml = true;
- }
- if (msg.options != null) {
- if (msg.options.trustedHtml === true) {
- options.enableHtml = true;
- }
- if (msg.options.timeout != null && msg.options.timeout > 0) {
- options.timeOut = msg.options.timeout;
- }
- }
-
- this.toastrService.show(message, msg.title, options, 'toast-' + msg.type);
- }
-
- private async showDialog(msg: any) {
- let iconClasses: string = null;
- const type = msg.type;
- if (type != null) {
- // If you add custom types to this part, the type to SweetAlertIcon cast below needs to be changed.
- switch (type) {
- case 'success':
- iconClasses = 'fa-check text-success';
- break;
- case 'warning':
- iconClasses = 'fa-warning text-warning';
- break;
- case 'error':
- iconClasses = 'fa-bolt text-danger';
- break;
- case 'info':
- iconClasses = 'fa-info-circle text-info';
- break;
- default:
- break;
- }
- }
-
- const cancelText = msg.cancelText;
- const confirmText = msg.confirmText;
- const confirmed = await Swal.fire({
- heightAuto: false,
- buttonsStyling: false,
- icon: type as SweetAlertIcon, // required to be any of the SweetAlertIcons to output the iconHtml.
- iconHtml: iconClasses != null ? `` : undefined,
- text: msg.text,
- html: msg.html,
- titleText: msg.title,
- showCancelButton: (cancelText != null),
- cancelButtonText: cancelText,
- showConfirmButton: true,
- confirmButtonText: confirmText == null ? this.i18nService.t('ok') : confirmText,
- timer: 300000,
+ } else if (msg.command === "locked") {
+ this.stateService.purge();
+ this.ngZone.run(() => {
+ this.router.navigate(["lock"]);
});
-
- this.messagingService.send('showDialogResolve', {
- dialogId: msg.dialogId,
- confirmed: confirmed.value,
+ } else if (msg.command === "showDialog") {
+ await this.showDialog(msg);
+ } else if (msg.command === "showToast") {
+ this.ngZone.run(() => {
+ this.showToast(msg);
});
+ } else if (msg.command === "reloadProcess") {
+ const windowReload =
+ this.platformUtilsService.isSafari() ||
+ this.platformUtilsService.isFirefox() ||
+ this.platformUtilsService.isOpera();
+ if (windowReload) {
+ // Wait to make sure background has reloaded first.
+ window.setTimeout(() => BrowserApi.reloadExtension(window), 2000);
+ }
+ } else if (msg.command === "reloadPopup") {
+ this.ngZone.run(() => {
+ this.router.navigate(["/"]);
+ });
+ } else if (msg.command === "convertAccountToKeyConnector") {
+ this.ngZone.run(async () => {
+ await this.keyConnectoService.setConvertAccountRequired(true);
+ this.router.navigate(["/remove-password"]);
+ });
+ } else {
+ msg.webExtSender = sender;
+ this.broadcasterService.send(msg);
+ }
+ };
+
+ BrowserApi.messageListener("app.component", (window as any).bitwardenPopupMainMessageListener);
+
+ this.router.events.subscribe((event) => {
+ if (event instanceof NavigationEnd) {
+ const url = event.urlAfterRedirects || event.url || "";
+ if (
+ url.startsWith("/tabs/") &&
+ (window as any).previousPopupUrl != null &&
+ (window as any).previousPopupUrl.startsWith("/tabs/")
+ ) {
+ this.stateService.remove("GroupingsComponent");
+ this.stateService.remove("GroupingsComponentScope");
+ this.stateService.remove("CiphersComponent");
+ this.stateService.remove("SendGroupingsComponent");
+ this.stateService.remove("SendGroupingsComponentScope");
+ this.stateService.remove("SendTypeComponent");
+ }
+ if (url.startsWith("/tabs/")) {
+ this.stateService.remove("addEditCipherInfo");
+ }
+ (window as any).previousPopupUrl = url;
+
+ // Clear route direction after animation (400ms)
+ if ((window as any).routeDirection != null) {
+ window.setTimeout(() => {
+ (window as any).routeDirection = null;
+ }, 400);
+ }
+ }
+ });
+ }
+
+ getState(outlet: RouterOutlet) {
+ if (outlet.activatedRouteData.state === "ciphers") {
+ const routeDirection =
+ (window as any).routeDirection != null ? (window as any).routeDirection : "";
+ return (
+ "ciphers_direction=" +
+ routeDirection +
+ "_" +
+ (outlet.activatedRoute.queryParams as any).value.folderId +
+ "_" +
+ (outlet.activatedRoute.queryParams as any).value.collectionId
+ );
+ } else {
+ return outlet.activatedRouteData.state;
}
+ }
+
+ private async recordActivity() {
+ const now = new Date().getTime();
+ if (this.lastActivity != null && now - this.lastActivity < 250) {
+ return;
+ }
+
+ this.lastActivity = now;
+ this.storageService.save(ConstantsService.lastActiveKey, now);
+ }
+
+ private showToast(msg: any) {
+ let message = "";
+
+ const options: Partial = {};
+
+ if (typeof msg.text === "string") {
+ message = msg.text;
+ } else if (msg.text.length === 1) {
+ message = msg.text[0];
+ } else {
+ msg.text.forEach(
+ (t: string) =>
+ (message += "" + this.sanitizer.sanitize(SecurityContext.HTML, t) + "
")
+ );
+ options.enableHtml = true;
+ }
+ if (msg.options != null) {
+ if (msg.options.trustedHtml === true) {
+ options.enableHtml = true;
+ }
+ if (msg.options.timeout != null && msg.options.timeout > 0) {
+ options.timeOut = msg.options.timeout;
+ }
+ }
+
+ this.toastrService.show(message, msg.title, options, "toast-" + msg.type);
+ }
+
+ private async showDialog(msg: any) {
+ let iconClasses: string = null;
+ const type = msg.type;
+ if (type != null) {
+ // If you add custom types to this part, the type to SweetAlertIcon cast below needs to be changed.
+ switch (type) {
+ case "success":
+ iconClasses = "fa-check text-success";
+ break;
+ case "warning":
+ iconClasses = "fa-warning text-warning";
+ break;
+ case "error":
+ iconClasses = "fa-bolt text-danger";
+ break;
+ case "info":
+ iconClasses = "fa-info-circle text-info";
+ break;
+ default:
+ break;
+ }
+ }
+
+ const cancelText = msg.cancelText;
+ const confirmText = msg.confirmText;
+ const confirmed = await Swal.fire({
+ heightAuto: false,
+ buttonsStyling: false,
+ icon: type as SweetAlertIcon, // required to be any of the SweetAlertIcons to output the iconHtml.
+ iconHtml:
+ iconClasses != null ? `` : undefined,
+ text: msg.text,
+ html: msg.html,
+ titleText: msg.title,
+ showCancelButton: cancelText != null,
+ cancelButtonText: cancelText,
+ showConfirmButton: true,
+ confirmButtonText: confirmText == null ? this.i18nService.t("ok") : confirmText,
+ timer: 300000,
+ });
+
+ this.messagingService.send("showDialogResolve", {
+ dialogId: msg.dialogId,
+ confirmed: confirmed.value,
+ });
+ }
}
diff --git a/src/popup/app.module.ts b/src/popup/app.module.ts
index 8b7f1258d7..9d86c7a029 100644
--- a/src/popup/app.module.ts
+++ b/src/popup/app.module.ts
@@ -1,272 +1,265 @@
-import { A11yModule } from '@angular/cdk/a11y';
-import { DragDropModule } from '@angular/cdk/drag-drop';
-import { ScrollingModule } from '@angular/cdk/scrolling';
+import { A11yModule } from "@angular/cdk/a11y";
+import { DragDropModule } from "@angular/cdk/drag-drop";
+import { ScrollingModule } from "@angular/cdk/scrolling";
-import { AppRoutingModule } from './app-routing.module';
-import { ServicesModule } from './services/services.module';
+import { AppRoutingModule } from "./app-routing.module";
+import { ServicesModule } from "./services/services.module";
-import { NgModule } from '@angular/core';
-import { FormsModule, ReactiveFormsModule } from '@angular/forms';
-import { BrowserModule } from '@angular/platform-browser';
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { NgModule } from "@angular/core";
+import { FormsModule, ReactiveFormsModule } from "@angular/forms";
+import { BrowserModule } from "@angular/platform-browser";
+import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
-import { EnvironmentComponent } from './accounts/environment.component';
-import { HintComponent } from './accounts/hint.component';
-import { HomeComponent } from './accounts/home.component';
-import { LockComponent } from './accounts/lock.component';
-import { LoginComponent } from './accounts/login.component';
-import { RegisterComponent } from './accounts/register.component';
-import { RemovePasswordComponent } from './accounts/remove-password.component';
-import { SetPasswordComponent } from './accounts/set-password.component';
-import { SsoComponent } from './accounts/sso.component';
-import { TwoFactorOptionsComponent } from './accounts/two-factor-options.component';
-import { TwoFactorComponent } from './accounts/two-factor.component';
-import { UpdateTempPasswordComponent } from './accounts/update-temp-password.component';
+import { EnvironmentComponent } from "./accounts/environment.component";
+import { HintComponent } from "./accounts/hint.component";
+import { HomeComponent } from "./accounts/home.component";
+import { LockComponent } from "./accounts/lock.component";
+import { LoginComponent } from "./accounts/login.component";
+import { RegisterComponent } from "./accounts/register.component";
+import { RemovePasswordComponent } from "./accounts/remove-password.component";
+import { SetPasswordComponent } from "./accounts/set-password.component";
+import { SsoComponent } from "./accounts/sso.component";
+import { TwoFactorOptionsComponent } from "./accounts/two-factor-options.component";
+import { TwoFactorComponent } from "./accounts/two-factor.component";
+import { UpdateTempPasswordComponent } from "./accounts/update-temp-password.component";
-import { PasswordGeneratorHistoryComponent } from './generator/password-generator-history.component';
-import { PasswordGeneratorComponent } from './generator/password-generator.component';
+import { PasswordGeneratorHistoryComponent } from "./generator/password-generator-history.component";
+import { PasswordGeneratorComponent } from "./generator/password-generator.component";
-import { AppComponent } from './app.component';
-import { PrivateModeComponent } from './private-mode.component';
-import { TabsComponent } from './tabs.component';
+import { AppComponent } from "./app.component";
+import { PrivateModeComponent } from "./private-mode.component";
+import { TabsComponent } from "./tabs.component";
-import { ExcludedDomainsComponent } from './settings/excluded-domains.component';
-import { ExportComponent } from './settings/export.component';
-import { FolderAddEditComponent } from './settings/folder-add-edit.component';
-import { FoldersComponent } from './settings/folders.component';
-import { OptionsComponent } from './settings/options.component';
-import { PremiumComponent } from './settings/premium.component';
-import { SettingsComponent } from './settings/settings.component';
-import { SyncComponent } from './settings/sync.component';
-import { VaultTimeoutInputComponent } from './settings/vault-timeout-input.component';
+import { ExcludedDomainsComponent } from "./settings/excluded-domains.component";
+import { ExportComponent } from "./settings/export.component";
+import { FolderAddEditComponent } from "./settings/folder-add-edit.component";
+import { FoldersComponent } from "./settings/folders.component";
+import { OptionsComponent } from "./settings/options.component";
+import { PremiumComponent } from "./settings/premium.component";
+import { SettingsComponent } from "./settings/settings.component";
+import { SyncComponent } from "./settings/sync.component";
+import { VaultTimeoutInputComponent } from "./settings/vault-timeout-input.component";
-import { AddEditCustomFieldsComponent } from './vault/add-edit-custom-fields.component';
-import { AddEditComponent } from './vault/add-edit.component';
-import { AttachmentsComponent } from './vault/attachments.component';
-import { CiphersComponent } from './vault/ciphers.component';
-import { CollectionsComponent } from './vault/collections.component';
-import { CurrentTabComponent } from './vault/current-tab.component';
-import { GroupingsComponent } from './vault/groupings.component';
-import { PasswordHistoryComponent } from './vault/password-history.component';
-import { ShareComponent } from './vault/share.component';
-import { ViewCustomFieldsComponent } from './vault/view-custom-fields.component';
-import { ViewComponent } from './vault/view.component';
+import { AddEditCustomFieldsComponent } from "./vault/add-edit-custom-fields.component";
+import { AddEditComponent } from "./vault/add-edit.component";
+import { AttachmentsComponent } from "./vault/attachments.component";
+import { CiphersComponent } from "./vault/ciphers.component";
+import { CollectionsComponent } from "./vault/collections.component";
+import { CurrentTabComponent } from "./vault/current-tab.component";
+import { GroupingsComponent } from "./vault/groupings.component";
+import { PasswordHistoryComponent } from "./vault/password-history.component";
+import { ShareComponent } from "./vault/share.component";
+import { ViewCustomFieldsComponent } from "./vault/view-custom-fields.component";
+import { ViewComponent } from "./vault/view.component";
-import { EffluxDatesComponent as SendEffluxDatesComponent } from './send/efflux-dates.component';
-import { SendAddEditComponent } from './send/send-add-edit.component';
-import { SendGroupingsComponent } from './send/send-groupings.component';
-import { SendTypeComponent } from './send/send-type.component';
+import { EffluxDatesComponent as SendEffluxDatesComponent } from "./send/efflux-dates.component";
+import { SendAddEditComponent } from "./send/send-add-edit.component";
+import { SendGroupingsComponent } from "./send/send-groupings.component";
+import { SendTypeComponent } from "./send/send-type.component";
-import { A11yTitleDirective } from 'jslib-angular/directives/a11y-title.directive';
-import { ApiActionDirective } from 'jslib-angular/directives/api-action.directive';
-import { AutofocusDirective } from 'jslib-angular/directives/autofocus.directive';
-import { BlurClickDirective } from 'jslib-angular/directives/blur-click.directive';
-import { BoxRowDirective } from 'jslib-angular/directives/box-row.directive';
-import { CipherListVirtualScroll } from 'jslib-angular/directives/cipherListVirtualScroll.directive';
-import { FallbackSrcDirective } from 'jslib-angular/directives/fallback-src.directive';
-import { InputVerbatimDirective } from 'jslib-angular/directives/input-verbatim.directive';
-import { SelectCopyDirective } from 'jslib-angular/directives/select-copy.directive';
-import { StopClickDirective } from 'jslib-angular/directives/stop-click.directive';
-import { StopPropDirective } from 'jslib-angular/directives/stop-prop.directive';
-import { TrueFalseValueDirective } from 'jslib-angular/directives/true-false-value.directive';
+import { A11yTitleDirective } from "jslib-angular/directives/a11y-title.directive";
+import { ApiActionDirective } from "jslib-angular/directives/api-action.directive";
+import { AutofocusDirective } from "jslib-angular/directives/autofocus.directive";
+import { BlurClickDirective } from "jslib-angular/directives/blur-click.directive";
+import { BoxRowDirective } from "jslib-angular/directives/box-row.directive";
+import { CipherListVirtualScroll } from "jslib-angular/directives/cipherListVirtualScroll.directive";
+import { FallbackSrcDirective } from "jslib-angular/directives/fallback-src.directive";
+import { InputVerbatimDirective } from "jslib-angular/directives/input-verbatim.directive";
+import { SelectCopyDirective } from "jslib-angular/directives/select-copy.directive";
+import { StopClickDirective } from "jslib-angular/directives/stop-click.directive";
+import { StopPropDirective } from "jslib-angular/directives/stop-prop.directive";
+import { TrueFalseValueDirective } from "jslib-angular/directives/true-false-value.directive";
-import { ColorPasswordPipe } from 'jslib-angular/pipes/color-password.pipe';
-import { I18nPipe } from 'jslib-angular/pipes/i18n.pipe';
-import { SearchCiphersPipe } from 'jslib-angular/pipes/search-ciphers.pipe';
+import { ColorPasswordPipe } from "jslib-angular/pipes/color-password.pipe";
+import { I18nPipe } from "jslib-angular/pipes/i18n.pipe";
+import { SearchCiphersPipe } from "jslib-angular/pipes/search-ciphers.pipe";
-import { ActionButtonsComponent } from './components/action-buttons.component';
-import { CipherRowComponent } from './components/cipher-row.component';
-import { PasswordRepromptComponent } from './components/password-reprompt.component';
-import { PopOutComponent } from './components/pop-out.component';
-import { SendListComponent } from './components/send-list.component';
-import { SetPinComponent } from './components/set-pin.component';
-import { VerifyMasterPasswordComponent } from './components/verify-master-password.component';
+import { ActionButtonsComponent } from "./components/action-buttons.component";
+import { CipherRowComponent } from "./components/cipher-row.component";
+import { PasswordRepromptComponent } from "./components/password-reprompt.component";
+import { PopOutComponent } from "./components/pop-out.component";
+import { SendListComponent } from "./components/send-list.component";
+import { SetPinComponent } from "./components/set-pin.component";
+import { VerifyMasterPasswordComponent } from "./components/verify-master-password.component";
-import { CalloutComponent } from 'jslib-angular/components/callout.component';
-import { IconComponent } from 'jslib-angular/components/icon.component';
-import { BitwardenToastModule } from 'jslib-angular/components/toastr.component';
+import { CalloutComponent } from "jslib-angular/components/callout.component";
+import { IconComponent } from "jslib-angular/components/icon.component";
+import { BitwardenToastModule } from "jslib-angular/components/toastr.component";
-import {
- CurrencyPipe,
- DatePipe,
- registerLocaleData,
-} from '@angular/common';
-import localeAz from '@angular/common/locales/az';
-import localeBe from '@angular/common/locales/be';
-import localeBg from '@angular/common/locales/bg';
-import localeBn from '@angular/common/locales/bn';
-import localeCa from '@angular/common/locales/ca';
-import localeCs from '@angular/common/locales/cs';
-import localeDa from '@angular/common/locales/da';
-import localeDe from '@angular/common/locales/de';
-import localeEl from '@angular/common/locales/el';
-import localeEnGb from '@angular/common/locales/en-GB';
-import localeEnIn from '@angular/common/locales/en-IN';
-import localeEs from '@angular/common/locales/es';
-import localeEt from '@angular/common/locales/et';
-import localeFa from '@angular/common/locales/fa';
-import localeFi from '@angular/common/locales/fi';
-import localeFr from '@angular/common/locales/fr';
-import localeHe from '@angular/common/locales/he';
-import localeHr from '@angular/common/locales/hr';
-import localeHu from '@angular/common/locales/hu';
-import localeId from '@angular/common/locales/id';
-import localeIt from '@angular/common/locales/it';
-import localeJa from '@angular/common/locales/ja';
-import localeKn from '@angular/common/locales/kn';
-import localeKo from '@angular/common/locales/ko';
-import localeLv from '@angular/common/locales/lv';
-import localeMl from '@angular/common/locales/ml';
-import localeNb from '@angular/common/locales/nb';
-import localeNl from '@angular/common/locales/nl';
-import localePl from '@angular/common/locales/pl';
-import localePtBr from '@angular/common/locales/pt';
-import localePtPt from '@angular/common/locales/pt-PT';
-import localeRo from '@angular/common/locales/ro';
-import localeRu from '@angular/common/locales/ru';
-import localeSk from '@angular/common/locales/sk';
-import localeSr from '@angular/common/locales/sr';
-import localeSv from '@angular/common/locales/sv';
-import localeTh from '@angular/common/locales/th';
-import localeTr from '@angular/common/locales/tr';
-import localeUk from '@angular/common/locales/uk';
-import localeVi from '@angular/common/locales/vi';
-import localeZhCn from '@angular/common/locales/zh-Hans';
-import localeZhTw from '@angular/common/locales/zh-Hant';
+import { CurrencyPipe, DatePipe, registerLocaleData } from "@angular/common";
+import localeAz from "@angular/common/locales/az";
+import localeBe from "@angular/common/locales/be";
+import localeBg from "@angular/common/locales/bg";
+import localeBn from "@angular/common/locales/bn";
+import localeCa from "@angular/common/locales/ca";
+import localeCs from "@angular/common/locales/cs";
+import localeDa from "@angular/common/locales/da";
+import localeDe from "@angular/common/locales/de";
+import localeEl from "@angular/common/locales/el";
+import localeEnGb from "@angular/common/locales/en-GB";
+import localeEnIn from "@angular/common/locales/en-IN";
+import localeEs from "@angular/common/locales/es";
+import localeEt from "@angular/common/locales/et";
+import localeFa from "@angular/common/locales/fa";
+import localeFi from "@angular/common/locales/fi";
+import localeFr from "@angular/common/locales/fr";
+import localeHe from "@angular/common/locales/he";
+import localeHr from "@angular/common/locales/hr";
+import localeHu from "@angular/common/locales/hu";
+import localeId from "@angular/common/locales/id";
+import localeIt from "@angular/common/locales/it";
+import localeJa from "@angular/common/locales/ja";
+import localeKn from "@angular/common/locales/kn";
+import localeKo from "@angular/common/locales/ko";
+import localeLv from "@angular/common/locales/lv";
+import localeMl from "@angular/common/locales/ml";
+import localeNb from "@angular/common/locales/nb";
+import localeNl from "@angular/common/locales/nl";
+import localePl from "@angular/common/locales/pl";
+import localePtBr from "@angular/common/locales/pt";
+import localePtPt from "@angular/common/locales/pt-PT";
+import localeRo from "@angular/common/locales/ro";
+import localeRu from "@angular/common/locales/ru";
+import localeSk from "@angular/common/locales/sk";
+import localeSr from "@angular/common/locales/sr";
+import localeSv from "@angular/common/locales/sv";
+import localeTh from "@angular/common/locales/th";
+import localeTr from "@angular/common/locales/tr";
+import localeUk from "@angular/common/locales/uk";
+import localeVi from "@angular/common/locales/vi";
+import localeZhCn from "@angular/common/locales/zh-Hans";
+import localeZhTw from "@angular/common/locales/zh-Hant";
-registerLocaleData(localeAz, 'az');
-registerLocaleData(localeBe, 'be');
-registerLocaleData(localeBg, 'bg');
-registerLocaleData(localeBn, 'bn');
-registerLocaleData(localeCa, 'ca');
-registerLocaleData(localeCs, 'cs');
-registerLocaleData(localeDa, 'da');
-registerLocaleData(localeDe, 'de');
-registerLocaleData(localeEl, 'el');
-registerLocaleData(localeEnGb, 'en-GB');
-registerLocaleData(localeEnIn, 'en-IN');
-registerLocaleData(localeEs, 'es');
-registerLocaleData(localeEt, 'et');
-registerLocaleData(localeFa, 'fa');
-registerLocaleData(localeFi, 'fi');
-registerLocaleData(localeFr, 'fr');
-registerLocaleData(localeHe, 'he');
-registerLocaleData(localeHr, 'hr');
-registerLocaleData(localeHu, 'hu');
-registerLocaleData(localeId, 'id');
-registerLocaleData(localeIt, 'it');
-registerLocaleData(localeJa, 'ja');
-registerLocaleData(localeKo, 'ko');
-registerLocaleData(localeKn, 'kn');
-registerLocaleData(localeLv, 'lv');
-registerLocaleData(localeMl, 'ml');
-registerLocaleData(localeNb, 'nb');
-registerLocaleData(localeNl, 'nl');
-registerLocaleData(localePl, 'pl');
-registerLocaleData(localePtBr, 'pt-BR');
-registerLocaleData(localePtPt, 'pt-PT');
-registerLocaleData(localeRo, 'ro');
-registerLocaleData(localeRu, 'ru');
-registerLocaleData(localeSk, 'sk');
-registerLocaleData(localeSr, 'sr');
-registerLocaleData(localeSv, 'sv');
-registerLocaleData(localeTh, 'th');
-registerLocaleData(localeTr, 'tr');
-registerLocaleData(localeUk, 'uk');
-registerLocaleData(localeVi, 'vi');
-registerLocaleData(localeZhCn, 'zh-CN');
-registerLocaleData(localeZhTw, 'zh-TW');
+registerLocaleData(localeAz, "az");
+registerLocaleData(localeBe, "be");
+registerLocaleData(localeBg, "bg");
+registerLocaleData(localeBn, "bn");
+registerLocaleData(localeCa, "ca");
+registerLocaleData(localeCs, "cs");
+registerLocaleData(localeDa, "da");
+registerLocaleData(localeDe, "de");
+registerLocaleData(localeEl, "el");
+registerLocaleData(localeEnGb, "en-GB");
+registerLocaleData(localeEnIn, "en-IN");
+registerLocaleData(localeEs, "es");
+registerLocaleData(localeEt, "et");
+registerLocaleData(localeFa, "fa");
+registerLocaleData(localeFi, "fi");
+registerLocaleData(localeFr, "fr");
+registerLocaleData(localeHe, "he");
+registerLocaleData(localeHr, "hr");
+registerLocaleData(localeHu, "hu");
+registerLocaleData(localeId, "id");
+registerLocaleData(localeIt, "it");
+registerLocaleData(localeJa, "ja");
+registerLocaleData(localeKo, "ko");
+registerLocaleData(localeKn, "kn");
+registerLocaleData(localeLv, "lv");
+registerLocaleData(localeMl, "ml");
+registerLocaleData(localeNb, "nb");
+registerLocaleData(localeNl, "nl");
+registerLocaleData(localePl, "pl");
+registerLocaleData(localePtBr, "pt-BR");
+registerLocaleData(localePtPt, "pt-PT");
+registerLocaleData(localeRo, "ro");
+registerLocaleData(localeRu, "ru");
+registerLocaleData(localeSk, "sk");
+registerLocaleData(localeSr, "sr");
+registerLocaleData(localeSv, "sv");
+registerLocaleData(localeTh, "th");
+registerLocaleData(localeTr, "tr");
+registerLocaleData(localeUk, "uk");
+registerLocaleData(localeVi, "vi");
+registerLocaleData(localeZhCn, "zh-CN");
+registerLocaleData(localeZhTw, "zh-TW");
@NgModule({
- imports: [
- A11yModule,
- AppRoutingModule,
- BrowserAnimationsModule,
- BrowserModule,
- DragDropModule,
- FormsModule,
- ReactiveFormsModule,
- ScrollingModule,
- ServicesModule,
- BitwardenToastModule.forRoot({
- maxOpened: 2,
- autoDismiss: true,
- closeButton: true,
- positionClass: 'toast-bottom-full-width',
- }),
- ],
- declarations: [
- A11yTitleDirective,
- ActionButtonsComponent,
- AddEditComponent,
- AddEditCustomFieldsComponent,
- ApiActionDirective,
- AppComponent,
- AttachmentsComponent,
- AutofocusDirective,
- BlurClickDirective,
- BoxRowDirective,
- CalloutComponent,
- CipherListVirtualScroll,
- CipherRowComponent,
- CiphersComponent,
- CollectionsComponent,
- ColorPasswordPipe,
- CurrentTabComponent,
- EnvironmentComponent,
- ExcludedDomainsComponent,
- ExportComponent,
- FallbackSrcDirective,
- FolderAddEditComponent,
- FoldersComponent,
- GroupingsComponent,
- HintComponent,
- HomeComponent,
- I18nPipe,
- IconComponent,
- InputVerbatimDirective,
- LockComponent,
- LoginComponent,
- OptionsComponent,
- PasswordGeneratorComponent,
- PasswordGeneratorHistoryComponent,
- PasswordHistoryComponent,
- PasswordRepromptComponent,
- PopOutComponent,
- PremiumComponent,
- PrivateModeComponent,
- RegisterComponent,
- SearchCiphersPipe,
- SelectCopyDirective,
- SendAddEditComponent,
- SendEffluxDatesComponent,
- SendGroupingsComponent,
- SendListComponent,
- SendTypeComponent,
- SetPasswordComponent,
- SetPinComponent,
- SettingsComponent,
- ShareComponent,
- SsoComponent,
- StopClickDirective,
- StopPropDirective,
- SyncComponent,
- TabsComponent,
- TrueFalseValueDirective,
- TwoFactorComponent,
- TwoFactorOptionsComponent,
- UpdateTempPasswordComponent,
- VaultTimeoutInputComponent,
- VerifyMasterPasswordComponent,
- ViewComponent,
- ViewCustomFieldsComponent,
- RemovePasswordComponent,
- ],
- entryComponents: [],
- providers: [
- CurrencyPipe,
- DatePipe,
- ],
- bootstrap: [AppComponent],
+ imports: [
+ A11yModule,
+ AppRoutingModule,
+ BrowserAnimationsModule,
+ BrowserModule,
+ DragDropModule,
+ FormsModule,
+ ReactiveFormsModule,
+ ScrollingModule,
+ ServicesModule,
+ BitwardenToastModule.forRoot({
+ maxOpened: 2,
+ autoDismiss: true,
+ closeButton: true,
+ positionClass: "toast-bottom-full-width",
+ }),
+ ],
+ declarations: [
+ A11yTitleDirective,
+ ActionButtonsComponent,
+ AddEditComponent,
+ AddEditCustomFieldsComponent,
+ ApiActionDirective,
+ AppComponent,
+ AttachmentsComponent,
+ AutofocusDirective,
+ BlurClickDirective,
+ BoxRowDirective,
+ CalloutComponent,
+ CipherListVirtualScroll,
+ CipherRowComponent,
+ CiphersComponent,
+ CollectionsComponent,
+ ColorPasswordPipe,
+ CurrentTabComponent,
+ EnvironmentComponent,
+ ExcludedDomainsComponent,
+ ExportComponent,
+ FallbackSrcDirective,
+ FolderAddEditComponent,
+ FoldersComponent,
+ GroupingsComponent,
+ HintComponent,
+ HomeComponent,
+ I18nPipe,
+ IconComponent,
+ InputVerbatimDirective,
+ LockComponent,
+ LoginComponent,
+ OptionsComponent,
+ PasswordGeneratorComponent,
+ PasswordGeneratorHistoryComponent,
+ PasswordHistoryComponent,
+ PasswordRepromptComponent,
+ PopOutComponent,
+ PremiumComponent,
+ PrivateModeComponent,
+ RegisterComponent,
+ SearchCiphersPipe,
+ SelectCopyDirective,
+ SendAddEditComponent,
+ SendEffluxDatesComponent,
+ SendGroupingsComponent,
+ SendListComponent,
+ SendTypeComponent,
+ SetPasswordComponent,
+ SetPinComponent,
+ SettingsComponent,
+ ShareComponent,
+ SsoComponent,
+ StopClickDirective,
+ StopPropDirective,
+ SyncComponent,
+ TabsComponent,
+ TrueFalseValueDirective,
+ TwoFactorComponent,
+ TwoFactorOptionsComponent,
+ UpdateTempPasswordComponent,
+ VaultTimeoutInputComponent,
+ VerifyMasterPasswordComponent,
+ ViewComponent,
+ ViewCustomFieldsComponent,
+ RemovePasswordComponent,
+ ],
+ entryComponents: [],
+ providers: [CurrencyPipe, DatePipe],
+ bootstrap: [AppComponent],
})
-export class AppModule { }
+export class AppModule {}
diff --git a/src/popup/components/action-buttons.component.html b/src/popup/components/action-buttons.component.html
index a3caa2c933..20ebd35080 100644
--- a/src/popup/components/action-buttons.component.html
+++ b/src/popup/components/action-buttons.component.html
@@ -1,41 +1,87 @@
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
diff --git a/src/popup/components/action-buttons.component.ts b/src/popup/components/action-buttons.component.ts
index b7cc088ddf..1f073d1079 100644
--- a/src/popup/components/action-buttons.component.ts
+++ b/src/popup/components/action-buttons.component.ts
@@ -1,82 +1,88 @@
-import {
- Component,
- EventEmitter,
- Input,
- Output,
-} from '@angular/core';
+import { Component, EventEmitter, Input, Output } from "@angular/core";
-import { CipherRepromptType } from 'jslib-common/enums/cipherRepromptType';
-import { CipherType } from 'jslib-common/enums/cipherType';
-import { EventType } from 'jslib-common/enums/eventType';
+import { CipherRepromptType } from "jslib-common/enums/cipherRepromptType";
+import { CipherType } from "jslib-common/enums/cipherType";
+import { EventType } from "jslib-common/enums/eventType";
-import { CipherView } from 'jslib-common/models/view/cipherView';
+import { CipherView } from "jslib-common/models/view/cipherView";
-import { EventService } from 'jslib-common/abstractions/event.service';
-import { I18nService } from 'jslib-common/abstractions/i18n.service';
-import { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';
-import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
-import { TotpService } from 'jslib-common/abstractions/totp.service';
-import { UserService } from 'jslib-common/abstractions/user.service';
+import { EventService } from "jslib-common/abstractions/event.service";
+import { I18nService } from "jslib-common/abstractions/i18n.service";
+import { PasswordRepromptService } from "jslib-common/abstractions/passwordReprompt.service";
+import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
+import { TotpService } from "jslib-common/abstractions/totp.service";
+import { UserService } from "jslib-common/abstractions/user.service";
@Component({
- selector: 'app-action-buttons',
- templateUrl: 'action-buttons.component.html',
+ selector: "app-action-buttons",
+ templateUrl: "action-buttons.component.html",
})
export class ActionButtonsComponent {
- @Output() onView = new EventEmitter();
- @Output() launchEvent = new EventEmitter();
- @Input() cipher: CipherView;
- @Input() showView = false;
+ @Output() onView = new EventEmitter();
+ @Output() launchEvent = new EventEmitter();
+ @Input() cipher: CipherView;
+ @Input() showView = false;
- cipherType = CipherType;
- userHasPremiumAccess = false;
+ cipherType = CipherType;
+ userHasPremiumAccess = false;
- constructor(private i18nService: I18nService,
- private platformUtilsService: PlatformUtilsService, private eventService: EventService,
- private totpService: TotpService, private userService: UserService,
- private passwordRepromptService: PasswordRepromptService) { }
+ constructor(
+ private i18nService: I18nService,
+ private platformUtilsService: PlatformUtilsService,
+ private eventService: EventService,
+ private totpService: TotpService,
+ private userService: UserService,
+ private passwordRepromptService: PasswordRepromptService
+ ) {}
- async ngOnInit() {
- this.userHasPremiumAccess = await this.userService.canAccessPremium();
+ async ngOnInit() {
+ this.userHasPremiumAccess = await this.userService.canAccessPremium();
+ }
+
+ launchCipher() {
+ this.launchEvent.emit(this.cipher);
+ }
+
+ async copy(cipher: CipherView, value: string, typeI18nKey: string, aType: string) {
+ if (
+ this.cipher.reprompt !== CipherRepromptType.None &&
+ this.passwordRepromptService.protectedFields().includes(aType) &&
+ !(await this.passwordRepromptService.showPasswordPrompt())
+ ) {
+ return;
}
- launchCipher() {
- this.launchEvent.emit(this.cipher);
+ if (value == null || (aType === "TOTP" && !this.displayTotpCopyButton(cipher))) {
+ return;
+ } else if (value === cipher.login.totp) {
+ value = await this.totpService.getCode(value);
}
- async copy(cipher: CipherView, value: string, typeI18nKey: string, aType: string) {
- if (this.cipher.reprompt !== CipherRepromptType.None && this.passwordRepromptService.protectedFields().includes(aType) &&
- !await this.passwordRepromptService.showPasswordPrompt()) {
- return;
- }
-
- if (value == null || aType === 'TOTP' && !this.displayTotpCopyButton(cipher)) {
- return;
- } else if (value === cipher.login.totp) {
- value = await this.totpService.getCode(value);
- }
-
- if (!cipher.viewPassword) {
- return;
- }
-
- this.platformUtilsService.copyToClipboard(value, { window: window });
- this.platformUtilsService.showToast('info', null,
- this.i18nService.t('valueCopied', this.i18nService.t(typeI18nKey)));
-
- if (typeI18nKey === 'password' || typeI18nKey === 'verificationCodeTotp') {
- this.eventService.collect(EventType.Cipher_ClientToggledHiddenFieldVisible, cipher.id);
- } else if (typeI18nKey === 'securityCode') {
- this.eventService.collect(EventType.Cipher_ClientCopiedCardCode, cipher.id);
- }
+ if (!cipher.viewPassword) {
+ return;
}
- displayTotpCopyButton(cipher: CipherView) {
- return (cipher?.login?.hasTotp ?? false) &&
- (cipher.organizationUseTotp || this.userHasPremiumAccess);
- }
+ this.platformUtilsService.copyToClipboard(value, { window: window });
+ this.platformUtilsService.showToast(
+ "info",
+ null,
+ this.i18nService.t("valueCopied", this.i18nService.t(typeI18nKey))
+ );
- view() {
- this.onView.emit(this.cipher);
+ if (typeI18nKey === "password" || typeI18nKey === "verificationCodeTotp") {
+ this.eventService.collect(EventType.Cipher_ClientToggledHiddenFieldVisible, cipher.id);
+ } else if (typeI18nKey === "securityCode") {
+ this.eventService.collect(EventType.Cipher_ClientCopiedCardCode, cipher.id);
}
+ }
+
+ displayTotpCopyButton(cipher: CipherView) {
+ return (
+ (cipher?.login?.hasTotp ?? false) && (cipher.organizationUseTotp || this.userHasPremiumAccess)
+ );
+ }
+
+ view() {
+ this.onView.emit(this.cipher);
+ }
}
diff --git a/src/popup/components/cipher-row.component.html b/src/popup/components/cipher-row.component.html
index 1772566db9..5953c31d88 100644
--- a/src/popup/components/cipher-row.component.html
+++ b/src/popup/components/cipher-row.component.html
@@ -1,23 +1,38 @@
-