mirror of
https://github.com/bitwarden/browser
synced 2025-12-20 10:13:31 +00:00
Merge branch 'main' into vault/pm-5273
# Conflicts: # libs/common/src/state-migrations/migrate.ts
This commit is contained in:
@@ -264,7 +264,7 @@ export class SettingsComponent implements OnInit {
|
||||
enableDuckDuckGoBrowserIntegration:
|
||||
await this.stateService.getEnableDuckDuckGoBrowserIntegration(),
|
||||
theme: await this.stateService.getTheme(),
|
||||
locale: (await this.stateService.getLocale()) ?? null,
|
||||
locale: await firstValueFrom(this.i18nService.locale$),
|
||||
};
|
||||
this.form.setValue(initialValues, { emitEvent: false });
|
||||
|
||||
@@ -553,7 +553,7 @@ export class SettingsComponent implements OnInit {
|
||||
}
|
||||
|
||||
async saveLocale() {
|
||||
await this.stateService.setLocale(this.form.value.locale);
|
||||
await this.i18nService.setLocale(this.form.value.locale);
|
||||
}
|
||||
|
||||
async saveTheme() {
|
||||
|
||||
@@ -52,8 +52,7 @@ export class InitService {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.syncService.fullSync(true);
|
||||
await this.vaultTimeoutService.init(true);
|
||||
const locale = await this.stateService.getLocale();
|
||||
await (this.i18nService as I18nRendererService).init(locale);
|
||||
await (this.i18nService as I18nRendererService).init();
|
||||
(this.eventUploadService as EventUploadService).init(true);
|
||||
this.twoFactorService.init();
|
||||
setTimeout(() => this.notificationsService.init(), 3000);
|
||||
|
||||
@@ -43,7 +43,7 @@ import { GlobalState } from "@bitwarden/common/platform/models/domain/global-sta
|
||||
import { MemoryStorageService } from "@bitwarden/common/platform/services/memory-storage.service";
|
||||
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
|
||||
import { SystemService } from "@bitwarden/common/platform/services/system.service";
|
||||
import { StateProvider } from "@bitwarden/common/platform/state";
|
||||
import { GlobalStateProvider, StateProvider } from "@bitwarden/common/platform/state";
|
||||
// eslint-disable-next-line import/no-restricted-paths -- Implementation for memory storage
|
||||
import { MemoryStorageService as MemoryStorageServiceForStateProviders } from "@bitwarden/common/platform/state/storage/memory-storage.service";
|
||||
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
|
||||
@@ -104,7 +104,7 @@ const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK");
|
||||
{
|
||||
provide: I18nServiceAbstraction,
|
||||
useClass: I18nRendererService,
|
||||
deps: [SYSTEM_LANGUAGE, LOCALES_DIRECTORY],
|
||||
deps: [SYSTEM_LANGUAGE, LOCALES_DIRECTORY, GlobalStateProvider],
|
||||
},
|
||||
{
|
||||
provide: MessagingServiceAbstraction,
|
||||
@@ -126,6 +126,7 @@ const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK");
|
||||
StateServiceAbstraction,
|
||||
AutofillSettingsServiceAbstraction,
|
||||
VaultTimeoutSettingsService,
|
||||
BiometricStateService,
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<button type="submit" class="btn primary block" [disabled]="!accessibilityForm.valid">
|
||||
{{ "submit" | i18n }}
|
||||
</button>
|
||||
<button type="button" routerLink="/login" class="btn block">{{ "done" | i18n }}</button>
|
||||
<button type="button" (click)="close()" class="btn block">{{ "done" | i18n }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -2,14 +2,11 @@ import { Component, NgZone } from "@angular/core";
|
||||
import { UntypedFormControl, UntypedFormGroup, Validators } from "@angular/forms";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
|
||||
const BroadcasterSubscriptionId = "AccessibilityCookieComponent";
|
||||
|
||||
@Component({
|
||||
selector: "app-accessibility-cookie",
|
||||
templateUrl: "accessibility-cookie.component.html",
|
||||
@@ -27,40 +24,21 @@ export class AccessibilityCookieComponent {
|
||||
protected platformUtilsService: PlatformUtilsService,
|
||||
protected environmentService: EnvironmentService,
|
||||
protected i18nService: I18nService,
|
||||
private broadcasterService: BroadcasterService,
|
||||
protected ngZone: NgZone,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
|
||||
this.ngZone.run(() => {
|
||||
switch (message.command) {
|
||||
case "windowIsFocused":
|
||||
if (this.listenForCookie) {
|
||||
this.listenForCookie = false;
|
||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.checkForCookie();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
registerhCaptcha() {
|
||||
this.platformUtilsService.launchUri("https://www.hcaptcha.com/accessibility");
|
||||
}
|
||||
|
||||
async checkForCookie() {
|
||||
this.hCaptchaWindow.close();
|
||||
async close() {
|
||||
const [cookie] = await ipc.auth.getHcaptchaAccessibilityCookie();
|
||||
if (cookie) {
|
||||
this.onCookieSavedSuccess();
|
||||
} else {
|
||||
this.onCookieSavedFailure();
|
||||
}
|
||||
await this.router.navigate(["/login"]);
|
||||
}
|
||||
|
||||
onCookieSavedSuccess() {
|
||||
@@ -89,10 +67,6 @@ export class AccessibilityCookieComponent {
|
||||
return;
|
||||
}
|
||||
this.listenForCookie = true;
|
||||
this.hCaptchaWindow = window.open(this.accessibilityForm.value.link);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
|
||||
window.open(this.accessibilityForm.value.link, "_blank", "noopener noreferrer");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@
|
||||
"message": "길이"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"message": "Minimum password length"
|
||||
"message": "최소 비밀번호 길이"
|
||||
},
|
||||
"uppercase": {
|
||||
"message": "대문자 (A-Z)"
|
||||
@@ -561,10 +561,10 @@
|
||||
"message": "계정 생성이 완료되었습니다! 이제 로그인하실 수 있습니다."
|
||||
},
|
||||
"youSuccessfullyLoggedIn": {
|
||||
"message": "You successfully logged in"
|
||||
"message": "로그인에 성공했습니다."
|
||||
},
|
||||
"youMayCloseThisWindow": {
|
||||
"message": "You may close this window"
|
||||
"message": "이제 창을 닫으실 수 있습니다."
|
||||
},
|
||||
"masterPassSent": {
|
||||
"message": "마스터 비밀번호 힌트가 담긴 이메일을 보냈습니다."
|
||||
@@ -780,7 +780,7 @@
|
||||
"message": "문의하기"
|
||||
},
|
||||
"helpAndFeedback": {
|
||||
"message": "Help and feedback"
|
||||
"message": "도움말 및 피드백"
|
||||
},
|
||||
"getHelp": {
|
||||
"message": "도움말"
|
||||
@@ -1399,7 +1399,7 @@
|
||||
"message": "잘못된 PIN 코드입니다."
|
||||
},
|
||||
"tooManyInvalidPinEntryAttemptsLoggingOut": {
|
||||
"message": "Too many invalid PIN entry attempts. Logging out."
|
||||
"message": "잘못된 PIN 입력 시도가 너무 많습니다. 로그아웃 합니다."
|
||||
},
|
||||
"unlockWithWindowsHello": {
|
||||
"message": "Windows Hello를 사용하여 잠금 해제"
|
||||
@@ -1889,7 +1889,7 @@
|
||||
"message": "Verification required for this action. Set a PIN to continue."
|
||||
},
|
||||
"setPin": {
|
||||
"message": "Set PIN"
|
||||
"message": "PIN 설정"
|
||||
},
|
||||
"verifyWithBiometrics": {
|
||||
"message": "Verify with biometrics"
|
||||
|
||||
@@ -97,7 +97,6 @@ export class Main {
|
||||
}
|
||||
|
||||
this.logService = new ElectronLogMainService(null, app.getPath("userData"));
|
||||
this.i18nService = new I18nMainService("en", "./locales/");
|
||||
|
||||
const storageDefaults: any = {};
|
||||
// Default vault timeout to "on restart", and action to "lock"
|
||||
@@ -112,6 +111,8 @@ export class Main {
|
||||
);
|
||||
const globalStateProvider = new DefaultGlobalStateProvider(storageServiceProvider);
|
||||
|
||||
this.i18nService = new I18nMainService("en", "./locales/", globalStateProvider);
|
||||
|
||||
const accountService = new AccountServiceImplementation(
|
||||
new NoopMessagingService(),
|
||||
this.logService,
|
||||
@@ -218,8 +219,7 @@ export class Main {
|
||||
this.migrationRunner.run().then(
|
||||
async () => {
|
||||
await this.windowMain.init();
|
||||
const locale = await this.stateService.getLocale();
|
||||
await this.i18nService.init(locale != null ? locale : app.getLocale());
|
||||
await this.i18nService.init();
|
||||
this.messagingMain.init();
|
||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
|
||||
@@ -30,7 +30,7 @@ export class WindowMain {
|
||||
private windowStateChangeTimer: NodeJS.Timeout;
|
||||
private windowStates: { [key: string]: WindowState } = {};
|
||||
private enableAlwaysOnTop = false;
|
||||
private session: Electron.Session;
|
||||
session: Electron.Session;
|
||||
|
||||
readonly defaultWidth = 950;
|
||||
readonly defaultHeight = 600;
|
||||
|
||||
4
apps/desktop/src/package-lock.json
generated
4
apps/desktop/src/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@bitwarden/desktop",
|
||||
"version": "2024.2.2",
|
||||
"version": "2024.3.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@bitwarden/desktop",
|
||||
"version": "2024.2.2",
|
||||
"version": "2024.3.0",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@bitwarden/desktop-native": "file:../desktop_native"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@bitwarden/desktop",
|
||||
"productName": "Bitwarden",
|
||||
"description": "A secure and free password manager for all of your devices.",
|
||||
"version": "2024.2.2",
|
||||
"version": "2024.3.0",
|
||||
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
|
||||
"homepage": "https://bitwarden.com",
|
||||
"license": "GPL-3.0",
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
import { ipcMain } from "electron";
|
||||
import { app, ipcMain } from "electron";
|
||||
|
||||
import { I18nService as BaseI18nService } from "@bitwarden/common/platform/services/i18n.service";
|
||||
import { GlobalStateProvider } from "@bitwarden/common/platform/state";
|
||||
|
||||
export class I18nMainService extends BaseI18nService {
|
||||
constructor(systemLanguage: string, localesDirectory: string) {
|
||||
super(systemLanguage, localesDirectory, (formattedLocale: string) =>
|
||||
this.readLanguageFile(formattedLocale),
|
||||
constructor(
|
||||
systemLanguage: string,
|
||||
localesDirectory: string,
|
||||
globalStateProvider: GlobalStateProvider,
|
||||
) {
|
||||
super(
|
||||
systemLanguage,
|
||||
localesDirectory,
|
||||
(formattedLocale: string) => this.readLanguageFile(formattedLocale),
|
||||
globalStateProvider,
|
||||
);
|
||||
|
||||
ipcMain.handle("getLanguageFile", async (event, formattedLocale: string) =>
|
||||
@@ -76,6 +84,12 @@ export class I18nMainService extends BaseI18nService {
|
||||
];
|
||||
}
|
||||
|
||||
override async init(): Promise<void> {
|
||||
// Set system language to electron language
|
||||
this.systemLanguage = app.getLocale();
|
||||
await super.init();
|
||||
}
|
||||
|
||||
private readLanguageFile(formattedLocale: string): Promise<any> {
|
||||
// Check that the provided locale only contains letters and dashes and underscores to avoid possible path traversal
|
||||
if (!/^[a-zA-Z_-]+$/.test(formattedLocale)) {
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
import { I18nService as BaseI18nService } from "@bitwarden/common/platform/services/i18n.service";
|
||||
import { GlobalStateProvider } from "@bitwarden/common/platform/state";
|
||||
|
||||
export class I18nRendererService extends BaseI18nService {
|
||||
constructor(systemLanguage: string, localesDirectory: string) {
|
||||
super(systemLanguage, localesDirectory, (formattedLocale: string) => {
|
||||
return ipc.platform.getLanguageFile(formattedLocale);
|
||||
});
|
||||
constructor(
|
||||
systemLanguage: string,
|
||||
localesDirectory: string,
|
||||
globalStateProvider: GlobalStateProvider,
|
||||
) {
|
||||
super(
|
||||
systemLanguage,
|
||||
localesDirectory,
|
||||
(formattedLocale: string) => {
|
||||
return ipc.platform.getLanguageFile(formattedLocale);
|
||||
},
|
||||
globalStateProvider,
|
||||
);
|
||||
|
||||
// Please leave 'en' where it is, as it's our fallback language in case no translation can be found
|
||||
this.supportedTranslationLocales = [
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
import * as path from "path";
|
||||
|
||||
import {
|
||||
app,
|
||||
dialog,
|
||||
ipcMain,
|
||||
Menu,
|
||||
MenuItem,
|
||||
nativeTheme,
|
||||
session,
|
||||
Notification,
|
||||
shell,
|
||||
} from "electron";
|
||||
import { app, dialog, ipcMain, Menu, MenuItem, nativeTheme, Notification, shell } from "electron";
|
||||
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { ThemeType } from "@bitwarden/common/platform/enums";
|
||||
@@ -64,7 +54,7 @@ export class ElectronMainMessagingService implements MessagingService {
|
||||
});
|
||||
|
||||
ipcMain.handle("getCookie", async (event, options) => {
|
||||
return await session.defaultSession.cookies.get(options);
|
||||
return await this.windowMain.session.cookies.get(options);
|
||||
});
|
||||
|
||||
ipcMain.handle("loginRequest", async (event, options) => {
|
||||
|
||||
Reference in New Issue
Block a user