mirror of
https://github.com/bitwarden/browser
synced 2025-12-21 18:53:29 +00:00
Merge branch 'master' of github.com:bitwarden/browser into feature/safari-webext
# Conflicts: # src/browser/safariApp.ts # src/safari/safari/SafariExtensionViewController.swift # src/services/browserPlatformUtils.service.ts
This commit is contained in:
@@ -41,11 +41,11 @@ export class SsoComponent extends BaseSsoComponent {
|
||||
this.redirectUri = url + '/sso-connector.html';
|
||||
this.clientId = 'browser';
|
||||
|
||||
super.onSuccessfulLogin = () => {
|
||||
super.onSuccessfulLogin = async () => {
|
||||
await syncService.fullSync(true);
|
||||
BrowserApi.reloadOpenWindows();
|
||||
const thisWindow = window.open('', '_self');
|
||||
thisWindow.close();
|
||||
return syncService.fullSync(true);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,9 @@ export const routerTransition = trigger('routerTransition', [
|
||||
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('tabs => add-cipher', inSlideUp),
|
||||
transition('add-cipher => tabs', outSlideDown),
|
||||
|
||||
@@ -159,9 +162,6 @@ export const routerTransition = trigger('routerTransition', [
|
||||
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 => share-cipher', inSlideUp),
|
||||
transition('share-cipher => edit-cipher, share-cipher => view-cipher', outSlideDown),
|
||||
|
||||
transition('edit-cipher => attachments, edit-cipher => collections', inSlideLeft),
|
||||
transition('attachments => edit-cipher, collections => edit-cipher', outSlideRight),
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
[ngClass]="{disabled: (!cipher.login.password || !cipher.viewPassword)}">
|
||||
<i class="fa fa-lg fa-key" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="row-btn" appStopClick appStopProp appA11yTitle="{{'copyVerificationCode' | i18n}}"
|
||||
(click)="copy(cipher, cipher.login.totp, 'verificationCodeTotp', 'TOTP')"
|
||||
[ngClass]="{disabled: (!displayTotpCopyButton(cipher))}">
|
||||
<i class="fa fa-lg fa-clock-o" aria-hidden="true"></i>
|
||||
</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="cipher.type === cipherType.Card">
|
||||
<span class="row-btn" appStopClick appStopProp appA11yTitle="{{'copyNumber' | i18n}}"
|
||||
|
||||
@@ -18,6 +18,8 @@ import { CipherView } from 'jslib/models/view/cipherView';
|
||||
import { EventService } from 'jslib/abstractions/event.service';
|
||||
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
|
||||
import { TotpService } from 'jslib/abstractions/totp.service';
|
||||
import { UserService } from 'jslib/abstractions/user.service';
|
||||
|
||||
import { PopupUtilsService } from '../services/popup-utils.service';
|
||||
|
||||
@@ -31,10 +33,16 @@ export class ActionButtonsComponent {
|
||||
@Input() showView = false;
|
||||
|
||||
cipherType = CipherType;
|
||||
userHasPremiumAccess = false;
|
||||
|
||||
constructor(private analytics: Angulartics2, private toasterService: ToasterService,
|
||||
private i18nService: I18nService, private platformUtilsService: PlatformUtilsService,
|
||||
private popupUtilsService: PopupUtilsService, private eventService: EventService) { }
|
||||
private popupUtilsService: PopupUtilsService, private eventService: EventService,
|
||||
private totpService: TotpService, private userService: UserService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
this.userHasPremiumAccess = await this.userService.canAccessPremium();
|
||||
}
|
||||
|
||||
launch() {
|
||||
if (this.cipher.type !== CipherType.Login || !this.cipher.login.canLaunch) {
|
||||
@@ -48,9 +56,11 @@ export class ActionButtonsComponent {
|
||||
}
|
||||
}
|
||||
|
||||
copy(cipher: CipherView, value: string, typeI18nKey: string, aType: string) {
|
||||
if (value == null) {
|
||||
async copy(cipher: CipherView, value: string, typeI18nKey: string, aType: string) {
|
||||
if (value == null || aType === 'TOTP' && !this.displayTotpCopyButton(cipher)) {
|
||||
return;
|
||||
} else if (value === cipher.login.totp) {
|
||||
value = await this.totpService.getCode(value);
|
||||
}
|
||||
|
||||
if (!cipher.viewPassword) {
|
||||
@@ -62,13 +72,18 @@ export class ActionButtonsComponent {
|
||||
this.toasterService.popAsync('info', null,
|
||||
this.i18nService.t('valueCopied', this.i18nService.t(typeI18nKey)));
|
||||
|
||||
if (typeI18nKey === 'password') {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { CipherService } from 'jslib/abstractions/cipher.service';
|
||||
|
||||
import { ConsoleLogService } from 'jslib/services/consoleLog.service';
|
||||
import { SearchService } from 'jslib/services/search.service';
|
||||
|
||||
export class PopupSearchService extends SearchService {
|
||||
constructor(private mainSearchService: SearchService, cipherService: CipherService) {
|
||||
super(cipherService);
|
||||
constructor(private mainSearchService: SearchService, cipherService: CipherService,
|
||||
consoleLogService: ConsoleLogService) {
|
||||
super(cipherService, consoleLogService);
|
||||
}
|
||||
|
||||
clearIndex() {
|
||||
|
||||
@@ -50,6 +50,7 @@ import { AuthService } from 'jslib/services/auth.service';
|
||||
import { ConstantsService } from 'jslib/services/constants.service';
|
||||
import { SearchService } from 'jslib/services/search.service';
|
||||
import { StateService } from 'jslib/services/state.service';
|
||||
import { ConsoleLogService } from 'jslib/services/consoleLog.service';
|
||||
|
||||
import { Analytics } from 'jslib/misc/analytics';
|
||||
|
||||
@@ -69,11 +70,11 @@ export const authService = new AuthService(getBgService<CryptoService>('cryptoSe
|
||||
getBgService<ApiService>('apiService')(), getBgService<UserService>('userService')(),
|
||||
getBgService<TokenService>('tokenService')(), getBgService<AppIdService>('appIdService')(),
|
||||
getBgService<I18nService>('i18nService')(), getBgService<PlatformUtilsService>('platformUtilsService')(),
|
||||
messagingService, getBgService<VaultTimeoutService>('vaultTimeoutService')());
|
||||
messagingService, getBgService<VaultTimeoutService>('vaultTimeoutService')(), getBgService<ConsoleLogService>('consoleLogService')());
|
||||
export const searchService = new PopupSearchService(getBgService<SearchService>('searchService')(),
|
||||
getBgService<CipherService>('cipherService')());
|
||||
getBgService<CipherService>('cipherService')(), getBgService<ConsoleLogService>('consoleLogService')());
|
||||
|
||||
export function initFactory(i18nService: I18nService, storageService: StorageService,
|
||||
export function initFactory(platformUtilsService: PlatformUtilsService, i18nService: I18nService, storageService: StorageService,
|
||||
popupUtilsService: PopupUtilsService): Function {
|
||||
return async () => {
|
||||
if (!popupUtilsService.inPopup(window)) {
|
||||
@@ -90,7 +91,12 @@ export function initFactory(i18nService: I18nService, storageService: StorageSer
|
||||
|
||||
let theme = await storageService.get<string>(ConstantsService.themeKey);
|
||||
if (theme == null) {
|
||||
theme = 'light';
|
||||
theme = platformUtilsService.getDefaultSystemTheme();
|
||||
|
||||
platformUtilsService.onDefaultSystemThemeChange((theme) => {
|
||||
window.document.documentElement.classList.remove('theme_light', 'theme_dark');
|
||||
window.document.documentElement.classList.add('theme_' + theme);
|
||||
});
|
||||
}
|
||||
window.document.documentElement.classList.add('locale_' + i18nService.translationLocale);
|
||||
window.document.documentElement.classList.add('theme_' + theme);
|
||||
@@ -171,7 +177,7 @@ export function initFactory(i18nService: I18nService, storageService: StorageSer
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: initFactory,
|
||||
deps: [I18nService, StorageService, PopupUtilsService],
|
||||
deps: [PlatformUtilsService, I18nService, StorageService, PopupUtilsService],
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -41,13 +41,6 @@
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<p>{{'exportMasterPassword' | i18n}}</p>
|
||||
<strong>{{'warning' | i18n}}</strong>:
|
||||
<span *ngIf="!encryptedFormat">
|
||||
{{'exportWarningDesc' | i18n}}
|
||||
</span>
|
||||
<span *ngIf="encryptedFormat">
|
||||
{{'encExportWarningDesc' | i18n}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</content>
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
</div>
|
||||
</header>
|
||||
<content *ngIf="cipher">
|
||||
<app-callout type="info" *ngIf="allowOwnershipOptions() && !allowPersonal">
|
||||
{{'personalOwnershipPolicyInEffect' | i18n}}
|
||||
</app-callout>
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
{{'itemInformation' | i18n}}
|
||||
@@ -374,15 +377,6 @@
|
||||
</div>
|
||||
<div class="box list" *ngIf="editMode && !cloneMode">
|
||||
<div class="box-content single-line">
|
||||
<a class="box-content-row" href="#" appStopClick appBlurClick (click)="share()"
|
||||
*ngIf="!cipher.organizationId">
|
||||
<div class="row-main text-primary">
|
||||
<div class="icon text-primary" aria-hidden="true">
|
||||
<i class="fa fa-share-alt fa-lg fa-fw"></i>
|
||||
</div>
|
||||
<span>{{'shareItem' | i18n}}</span>
|
||||
</div>
|
||||
</a>
|
||||
<a class="box-content-row" href="#" appStopClick appBlurClick (click)="delete()"
|
||||
[appApiAction]="deletePromise" #deleteBtn>
|
||||
<div class="row-main text-danger">
|
||||
|
||||
@@ -118,12 +118,6 @@ export class AddEditComponent extends BaseAddEditComponent {
|
||||
this.router.navigate(['/attachments'], { queryParams: { cipherId: this.cipher.id } });
|
||||
}
|
||||
|
||||
share() {
|
||||
super.share();
|
||||
if (this.cipher.organizationId == null) {
|
||||
this.router.navigate(['/share-cipher'], { queryParams: { cipherId: this.cipher.id } });
|
||||
}
|
||||
}
|
||||
|
||||
editCollections() {
|
||||
super.editCollections();
|
||||
|
||||
@@ -41,14 +41,12 @@ export class ShareComponent extends BaseShareComponent {
|
||||
async submit(): Promise<boolean> {
|
||||
const success = await super.submit();
|
||||
if (success) {
|
||||
window.setTimeout(() => {
|
||||
this.location.back();
|
||||
}, 200);
|
||||
this.cancel();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.location.back();
|
||||
this.router.navigate(['/view-cipher'], { replaceUrl: true, queryParams: { cipherId: this.cipher.id } });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,6 +295,14 @@
|
||||
<span>{{'cloneItem' | i18n}}</span>
|
||||
</div>
|
||||
</a>
|
||||
<a class="box-content-row" href="#" appStopClick appBlurClick (click)="share()" *ngIf="!cipher.organizationId">
|
||||
<div class="row-main text-primary">
|
||||
<div class="icon text-primary" aria-hidden="true">
|
||||
<i class="fa fa-share-alt fa-lg fa-fw"></i>
|
||||
</div>
|
||||
<span>{{'shareItem' | i18n}}</span>
|
||||
</div>
|
||||
</a>
|
||||
<a class="box-content-row" href="#" appStopClick appBlurClick (click)="restore()" *ngIf="cipher.isDeleted">
|
||||
<div class="row-main text-primary">
|
||||
<div class="icon text-primary" aria-hidden="true">
|
||||
|
||||
@@ -129,6 +129,13 @@ export class ViewComponent extends BaseViewComponent {
|
||||
});
|
||||
}
|
||||
|
||||
share() {
|
||||
super.share();
|
||||
if (this.cipher.organizationId == null) {
|
||||
this.router.navigate(['/share-cipher'], { replaceUrl: true, queryParams: { cipherId: this.cipher.id } });
|
||||
}
|
||||
}
|
||||
|
||||
async fillCipher() {
|
||||
const didAutofill = await this.doAutofill();
|
||||
if (didAutofill) {
|
||||
|
||||
Reference in New Issue
Block a user