diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index dd3b6445edd..fadaabf57bb 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -18,6 +18,9 @@ - **NEVER** commit secrets, credentials, or sensitive information. +- **CRITICAL**: Tailwind CSS classes MUST use the `tw-` prefix (e.g., `tw-flex`, `tw-p-4`). + - Missing prefix breaks styling completely. + - **NEVER** log decrypted data, encryption keys, or PII - No vault data in error messages or console logs diff --git a/.claude/prompts/review-code.md b/.claude/prompts/review-code.md deleted file mode 100644 index 1888b7cd503..00000000000 --- a/.claude/prompts/review-code.md +++ /dev/null @@ -1,57 +0,0 @@ -# Bitwarden Clients Repo Code Review - Careful Consideration Required - -## Think Twice Before Recommending - -Angular has multiple valid patterns. Before suggesting changes: - -- **Consider the context** - Is this code part of an active modernization effort? -- **Check for established patterns** - Look for similar implementations in the codebase -- **Avoid premature optimization** - Don't suggest refactoring stable, working code without clear benefit -- **Respect incremental progress** - Teams may be modernizing gradually with feature flags - -## Angular Modernization - Handle with Care - -**Control Flow Syntax (@if, @for, @switch):** - -- When you see legacy structural directives (*ngIf, *ngFor), consider whether modernization is in scope -- Do not mandate changes to stable code unless part of the PR's objective -- If suggesting modernization, acknowledge it's optional unless required by PR goals - -**Standalone Components:** - -- New components should be standalone whenever feasible, but do not flag existing NgModule components as issues -- Legacy patterns exist for valid reasons - consider modernization effort vs benefit - -**Typed Forms:** - -- Recommend typed forms for NEW form code -- Don't suggest rewriting working untyped forms unless they're being modified - -## Tailwind CSS - Critical Pattern - -**tw- prefix is mandatory** - This is non-negotiable and should be flagged as ❌ major finding: - -- Missing tw- prefix breaks styling completely -- Check ALL Tailwind classes in modified files - -## Rust SDK Adoption - Tread Carefully - -When reviewing cipher operations: - -- Look for breaking changes in the TypeScript → Rust boundary -- Verify error handling matches established patterns -- Don't suggest alternative SDK patterns without strong justification - -## Component Library First - -Before suggesting custom implementations: - -- Check if Bitwarden's component library already provides the functionality -- Prefer existing components over custom Tailwind styling -- Don't add UI complexity that the component library already solves - -## When in Doubt - -- **Ask questions** (💭) rather than making definitive recommendations -- **Flag for human review** (⚠️) if you're uncertain -- **Acknowledge alternatives** exist when suggesting improvements diff --git a/.claude/skills/angular-modernization/SKILL.md b/.claude/skills/angular-modernization/SKILL.md new file mode 100644 index 00000000000..187f715bde2 --- /dev/null +++ b/.claude/skills/angular-modernization/SKILL.md @@ -0,0 +1,156 @@ +--- +name: angular-modernization +description: Modernizes Angular code such as components and directives to follow best practices using both automatic CLI migrations and Bitwarden-specific patterns. YOU must use this skill when someone requests modernizing Angular code. DO NOT invoke for general Angular discussions unrelated to modernization. +allowed-tools: Read, Write, Glob, Bash(npx ng generate:*) +--- + +# Angular Modernization + +Transforms legacy Angular components to modern architecture using a two-step approach: + +1. **Automated migrations** - Angular CLI schematics for standalone, control flow, and signals +2. **Bitwarden patterns** - ADR compliance, OnPush change detection, proper visibility, thin components + +## Workflow + +### Step 1: Run Angular CLI Migrations + +**⚠️ CRITICAL: ALWAYS use Angular CLI migrations when available. DO NOT manually migrate features that have CLI schematics.** + +Angular provides automated schematics that handle edge cases, update tests, and ensure correctness. Manual migration should ONLY be used for patterns not covered by CLI tools. + +**IMPORTANT:** + +- Always run the commands using `npx ng`. +- All the commands must be run on directories and NOT files. Use the `--path` option to target directories. +- Run migrations in order (some depend on others) + +#### 1. Standalone Components + +```bash +npx ng generate @angular/core:standalone --path= --mode=convert-to-standalone +``` + +NgModule-based → standalone architecture + +#### 2. Control Flow Syntax + +```bash +npx ng generate @angular/core:control-flow +``` + +`*ngIf`, `*ngFor`, `*ngSwitch` → `@if`, `@for`, `@switch` + +#### 3. Signal Inputs + +```bash +npx ng generate @angular/core:signal-input-migration +``` + +`@Input()` → signal inputs + +#### 4. Signal Outputs + +```bash +npx ng generate @angular/core:output-migration +``` + +`@Output()` → signal outputs + +#### 5. Signal Queries + +```bash +npx ng generate @angular/core:signal-queries-migration +``` + +`@ViewChild`, `@ContentChild`, etc. → signal queries + +#### 6. inject() Function + +```bash +npx ng generate @angular/core:inject-migration +``` + +Constructor injection → `inject()` function + +#### 7. Self-Closing Tag + +```bash +npx ng generate @angular/core:self-closing-tag +``` + +Updates templates to self-closing syntax + +#### 8. Unused Imports + +```bash +npx ng generate @angular/core:unused-imports +``` + +Removes unused imports + +### Step 2: Apply Bitwarden Patterns + +See [migration-patterns.md](migration-patterns.md) for detailed examples. + +1. Add OnPush change detection +2. Apply visibility modifiers (`protected` for template access, `private` for internal) +3. Convert local component state to signals +4. Keep service observables (don't convert to signals) +5. Extract business logic to services +6. Organize class members correctly +7. Update tests for standalone + +### Step 3: Validate + +- Fix linting and formatting using `npm run lint:fix` +- Run tests using `npm run test` + +If any errors occur, fix them accordingly. + +## Key Decisions + +### Signals vs Observables + +- **Signals** - Component-local state only (ADR-0027) +- **Observables** - Service state and cross-component communication (ADR-0003) +- Use `toSignal()` to bridge observables into signal-based components + +### Visibility + +- `protected` - Template-accessible members +- `private` - Internal implementation + +### Other Rules + +- Always add OnPush change detection +- No TypeScript enums (use const objects with type aliases per ADR-0025) +- No code regions (refactor instead) +- Thin components (business logic in services) + +## Validation Checklist + +Before completing migration: + +- [ ] OnPush change detection added +- [ ] Visibility modifiers applied (`protected`/`private`) +- [ ] Signals for component state, observables for service state +- [ ] Class members organized (see [migration-patterns.md](migration-patterns.md#class-member-organization)) +- [ ] Tests updated and passing +- [ ] No new TypeScript enums +- [ ] No code regions + +## References + +### Bitwarden ADRs + +- [ADR-0003: Observable Data Services](https://contributing.bitwarden.com/architecture/adr/observable-data-services) +- [ADR-0025: No TypeScript Enums](https://contributing.bitwarden.com/architecture/adr/no-enums) +- [ADR-0027: Angular Signals](https://contributing.bitwarden.com/architecture/adr/angular-signals) +- [Bitwarden Angular Style Guide](https://contributing.bitwarden.com/contributing/code-style/web/angular) + +### Angular Resources + +- [Angular Style Guide](https://angular.dev/style-guide) +- [Angular Migrations](https://angular.dev/reference/migrations) +- [Angular CLI Schematics](https://angular.dev/tools/cli/schematics) diff --git a/.claude/skills/angular-modernization/migration-patterns.md b/.claude/skills/angular-modernization/migration-patterns.md new file mode 100644 index 00000000000..284f90a410f --- /dev/null +++ b/.claude/skills/angular-modernization/migration-patterns.md @@ -0,0 +1,253 @@ +# Angular Migration Patterns Reference + +## Table of Contents + +- [Component Architecture](#component-architecture) +- [Dependency Injection](#dependency-injection) +- [Reactivity Patterns](#reactivity-patterns) +- [Template Syntax](#template-syntax) +- [Type Safety](#type-safety) + +## Component Architecture + +### Standalone Components + +Angular defaults to standalone components. Components should omit `standalone: true`, and any component specifying `standalone: false` SHALL be migrated to standalone. + +```typescript +@Component({ + selector: "app-user-profile", + imports: [CommonModule, ReactiveFormsModule, AsyncPipe], + templateUrl: "./user-profile.component.html", + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class UserProfileComponent {} +``` + +### Class Member Organization + +```typescript +@Component({...}) +export class MyComponent { + // 1. Inputs (public) + @Input() data: string; + + // 2. Outputs (public) + @Output() valueChange = new EventEmitter(); + + // 3. ViewChild/ContentChild + @ViewChild('template') template: TemplateRef; + + // 4. Injected dependencies (private/protected) + private userService = inject(UserService); + protected dialogService = inject(DialogService); + + // 5. Public properties + public formGroup: FormGroup; + + // 6. Protected properties (template-accessible) + protected isLoading = signal(false); + protected items$ = this.itemService.items$; + + // 7. Private properties + private cache = new Map(); + + // 8. Lifecycle hooks + ngOnInit() {} + + // 9. Public methods + public save() {} + + // 10. Protected methods (template-accessible) + protected handleClick() {} + + // 11. Private methods + private processData() {} +} +``` + +## Dependency Injection + +### Modern inject() Function + +**Before:** + +```typescript +constructor( + private userService: UserService, + private route: ActivatedRoute +) {} +``` + +**After:** + +```typescript +private userService = inject(UserService); +private route = inject(ActivatedRoute); +``` + +## Reactivity Patterns + +### Signals for Component State (ADR-0027) + +```typescript +// Local state +protected selectedFolder = signal(null); +protected isLoading = signal(false); + +// Derived state +protected hasSelection = computed(() => this.selectedFolder() !== null); +``` + +### Prefer computed() Over effect() + +Use `computed()` for derived values. Use `effect()` only for side effects (logging, analytics, DOM sync). + +**❌ Bad:** + +```typescript +constructor() { + effect(() => { + const id = this.selectedId(); + this.selectedItem.set(this.items().find(i => i.id === id) ?? null); + }); +} +``` + +**✅ Good:** + +```typescript +selectedItem = computed(() => this.items().find((i) => i.id === this.selectedId()) ?? null); +``` + +### Observables for Service Communication (ADR-0003) + +```typescript +// In component +protected folders$ = this.folderService.folders$; + +// Template +//
+ +// For explicit subscriptions +constructor() { + this.userService.user$ + .pipe(takeUntilDestroyed()) + .subscribe(user => this.handleUser(user)); +} +``` + +### Bridging Observables to Signals + +Use `toSignal()` to convert service observables to signals in components. Keep service state as observables (ADR-0003). + +**Before:** + +```typescript +private destroy$ = new Subject(); +users: User[] = []; + +ngOnInit() { + this.userService.users$.pipe(takeUntil(this.destroy$)) + .subscribe(users => this.users = users); +} + +ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); +} +``` + +**After:** + +```typescript +protected users = toSignal(this.userService.users$, { initialValue: [] }); +``` + +## Template Syntax + +### New Control Flow + +**Before:** + +```html +
+

{{ item.name }}

+
+Loading... +``` + +**After:** + +```html +@if (user$ | async; as user) { @for (item of user.items; track item.id) { +

{{ item.name }}

+} } @else { +

Loading...

+} +``` + +### Prefer Class/Style Bindings Over ngClass/ngStyle + +Use `[class.*]` and `[style.*]` bindings instead of `ngClass`/`ngStyle`. + +**❌ Bad:** + +```html +
+
+
+``` + +**✅ Good:** + +```html +
+
+
+``` + +## Type Safety + +### No TypeScript Enums (ADR-0025) + +**Before:** + +```typescript +enum CipherType { + Login = 1, + SecureNote = 2, +} +``` + +**After:** + +```typescript +export const CipherType = Object.freeze({ + Login: 1, + SecureNote: 2, +} as const); +export type CipherType = (typeof CipherType)[keyof typeof CipherType]; +``` + +### Reactive Forms + +```typescript +protected formGroup = new FormGroup({ + name: new FormControl('', { nonNullable: true }), + email: new FormControl('', { validators: [Validators.email] }), +}); +``` + +## Anti-Patterns to Avoid + +- ❌ Manually refactoring when CLI migrations exist +- ❌ Manual subscriptions without `takeUntilDestroyed()` +- ❌ TypeScript enums (use const objects per ADR-0025) +- ❌ Mixing constructor injection with `inject()` +- ❌ Signals in services shared with non-Angular code (ADR-0003) +- ❌ Business logic in components +- ❌ Code regions +- ❌ Converting service observables to signals (ADR-0003) +- ❌ Using `effect()` for derived state (use `computed()`) +- ❌ Using `ngClass`/`ngStyle` (use `[class.*]`/`[style.*]`) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ed7fcac96e6..99efec2fbbb 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,7 +8,9 @@ apps/desktop/desktop_native @bitwarden/team-platform-dev apps/desktop/desktop_native/objc/src/native/autofill @bitwarden/team-autofill-desktop-dev apps/desktop/desktop_native/core/src/autofill @bitwarden/team-autofill-desktop-dev +apps/desktop/desktop_native/macos_provider @bitwarden/team-autofill-desktop-dev apps/desktop/desktop_native/core/src/secure_memory @bitwarden/team-key-management-dev + ## No ownership for Cargo.lock and Cargo.toml to allow dependency updates apps/desktop/desktop_native/Cargo.lock apps/desktop/desktop_native/Cargo.toml @@ -230,3 +232,4 @@ libs/pricing @bitwarden/team-billing-dev .claude/ @bitwarden/team-ai-sme .github/workflows/respond.yml @bitwarden/team-ai-sme .github/workflows/review-code.yml @bitwarden/team-ai-sme +libs/subscription @bitwarden/team-billing-dev diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 997812735de..acd181310d6 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -3,6 +3,7 @@ extends: ["github>bitwarden/renovate-config"], // Extends our default configuration for pinned dependencies enabledManagers: ["cargo", "github-actions", "npm"], packageRules: [ + // ==================== Repo-Wide Update Behavior Rules ==================== { // Group all Github Action minor updates together to reduce PR noise. groupName: "Minor github-actions updates", @@ -16,13 +17,6 @@ matchDepNames: ["rust"], commitMessageTopic: "Rust", }, - { - // By default, we send patch updates to the Dependency Dashboard and do not generate a PR. - // We want to generate PRs for a select number of dependencies to ensure we stay up to date on these. - matchPackageNames: ["browserslist", "electron", "rxjs", "typescript", "webpack", "zone.js"], - matchUpdateTypes: ["patch"], - dependencyDashboardApproval: false, - }, { // Disable major and minor updates for TypeScript and Zone.js because they are managed by Angular. matchPackageNames: ["typescript", "zone.js"], @@ -44,6 +38,8 @@ description: "Manually updated using ng update", enabled: false, }, + + // ==================== Team Ownership Rules ==================== { matchPackageNames: ["buffer", "bufferutil", "core-js", "process", "url", "util"], description: "Admin Console owned dependencies", @@ -79,28 +75,6 @@ commitMessagePrefix: "[deps] Architecture:", reviewers: ["team:dept-architecture"], }, - { - matchPackageNames: [ - "@angular-eslint/schematics", - "@eslint/compat", - "@typescript-eslint/rule-tester", - "@typescript-eslint/utils", - "angular-eslint", - "eslint-config-prettier", - "eslint-import-resolver-typescript", - "eslint-plugin-import", - "eslint-plugin-rxjs-angular", - "eslint-plugin-rxjs", - "eslint-plugin-storybook", - "eslint-plugin-tailwindcss", - "eslint", - "husky", - "lint-staged", - "typescript-eslint", - ], - groupName: "Minor and patch linting updates", - matchUpdateTypes: ["minor", "patch"], - }, { matchPackageNames: [ "@emotion/css", @@ -154,7 +128,6 @@ "@types/glob", "@types/lowdb", "@types/node", - "@types/node-forge", "@types/node-ipc", "@yao-pkg/pkg", "anyhow", @@ -192,12 +165,10 @@ "napi", "napi-build", "napi-derive", - "node-forge", "node-ipc", "nx", "oo7", "oslog", - "parse5", "pin-project", "pkg", "postcss", @@ -215,6 +186,8 @@ "simplelog", "style-loader", "sysinfo", + "tokio", + "tokio-util", "tracing", "tracing-subscriber", "ts-node", @@ -242,55 +215,10 @@ reviewers: ["team:team-platform-dev"], }, { - // We need to group all napi-related packages together to avoid build errors caused by version incompatibilities. - groupName: "napi", - matchPackageNames: ["napi", "napi-build", "napi-derive"], - }, - { - // We need to group all macOS/iOS binding-related packages together to avoid build errors caused by version incompatibilities. - groupName: "macOS/iOS bindings", - matchPackageNames: ["core-foundation", "security-framework", "security-framework-sys"], - }, - { - // We need to group all zbus-related packages together to avoid build errors caused by version incompatibilities. - groupName: "zbus", - matchPackageNames: ["zbus", "zbus_polkit"], - }, - { - // We need to group all windows-related packages together to avoid build errors caused by version incompatibilities. - groupName: "windows", - matchPackageNames: ["windows", "windows-core", "windows-future", "windows-registry"], - }, - { - // We group all webpack build-related minor and patch updates together to reduce PR noise. - // We include patch updates here because we want PRs for webpack patch updates and it's in this group. - matchPackageNames: [ - "@babel/core", - "@babel/preset-env", - "babel-loader", - "base64-loader", - "browserslist", - "copy-webpack-plugin", - "css-loader", - "html-loader", - "html-webpack-injector", - "html-webpack-plugin", - "mini-css-extract-plugin", - "postcss-loader", - "postcss", - "sass-loader", - "sass", - "style-loader", - "ts-loader", - "tsconfig-paths-webpack-plugin", - "webpack-cli", - "webpack-dev-server", - "webpack-node-externals", - "webpack", - ], - description: "webpack-related build dependencies", - groupName: "Minor and patch webpack updates", - matchUpdateTypes: ["minor", "patch"], + matchUpdateTypes: ["lockFileMaintenance"], + description: "Platform owns lock file maintenance", + commitMessagePrefix: "[deps] Platform:", + reviewers: ["team:team-platform-dev"], }, { matchPackageNames: [ @@ -349,11 +277,6 @@ commitMessagePrefix: "[deps] SM:", reviewers: ["team:team-secrets-manager-dev"], }, - { - // We need to update several Jest-related packages together, for version compatibility. - groupName: "jest", - matchPackageNames: ["@types/jest", "jest", "ts-jest", "jest-preset-angular"], - }, { matchPackageNames: [ "@microsoft/signalr-protocol-msgpack", @@ -409,19 +332,203 @@ }, { matchPackageNames: [ + "@types/node-forge", "aes", "big-integer", "cbc", + "linux-keyutils", + "memsec", + "node-forge", "rsa", "russh-cryptovec", "sha2", - "memsec", - "linux-keyutils", ], description: "Key Management owned dependencies", commitMessagePrefix: "[deps] KM:", reviewers: ["team:team-key-management-dev"], }, + + // ==================== Grouping Rules ==================== + // These come after any specific team assignment rules to ensure + // that grouping is not overridden by subsequent rule definitions. + { + matchPackageNames: [ + "@angular-eslint/schematics", + "@eslint/compat", + "@typescript-eslint/rule-tester", + "@typescript-eslint/utils", + "angular-eslint", + "eslint-config-prettier", + "eslint-import-resolver-typescript", + "eslint-plugin-import", + "eslint-plugin-rxjs-angular", + "eslint-plugin-rxjs", + "eslint-plugin-storybook", + "eslint-plugin-tailwindcss", + "eslint", + "husky", + "lint-staged", + "typescript-eslint", + ], + groupName: "Minor and patch linting updates", + matchUpdateTypes: ["minor", "patch"], + }, + { + // We need to group all napi-related packages together to avoid build errors caused by version incompatibilities. + groupName: "napi", + matchPackageNames: ["napi", "napi-build", "napi-derive"], + }, + { + // We need to group all macOS/iOS binding-related packages together to avoid build errors caused by version incompatibilities. + groupName: "macOS/iOS bindings", + matchPackageNames: ["core-foundation", "security-framework", "security-framework-sys"], + }, + { + // We need to group all zbus-related packages together to avoid build errors caused by version incompatibilities. + groupName: "zbus", + matchPackageNames: ["zbus", "zbus_polkit"], + }, + { + // We need to group all windows-related packages together to avoid build errors caused by version incompatibilities. + groupName: "windows", + matchPackageNames: ["windows", "windows-core", "windows-future", "windows-registry"], + }, + { + // We need to group all tokio-related packages together to avoid build errors caused by version incompatibilities. + groupName: "tokio", + matchPackageNames: ["bytes", "tokio", "tokio-util"], + }, + { + // We group all webpack build-related minor and patch updates together to reduce PR noise. + // We include patch updates here because we want PRs for webpack patch updates and it's in this group. + matchPackageNames: [ + "@babel/core", + "@babel/preset-env", + "babel-loader", + "base64-loader", + "browserslist", + "copy-webpack-plugin", + "css-loader", + "html-loader", + "html-webpack-injector", + "html-webpack-plugin", + "mini-css-extract-plugin", + "postcss-loader", + "postcss", + "sass-loader", + "sass", + "style-loader", + "ts-loader", + "tsconfig-paths-webpack-plugin", + "webpack-cli", + "webpack-dev-server", + "webpack-node-externals", + "webpack", + ], + description: "webpack-related build dependencies", + groupName: "Minor and patch webpack updates", + matchUpdateTypes: ["minor", "patch"], + }, + { + // We need to update several Jest-related packages together, for version compatibility. + groupName: "jest", + matchPackageNames: ["@types/jest", "jest", "ts-jest", "jest-preset-angular"], + }, + + // ==================== Dashboard Rules ==================== + { + // For the packages below, we have decided we will only be creating PRs + // for major updates, and sending minor (as well as patch) to the dashboard. + // This rule comes AFTER grouping rules so that groups are respected while still + // sending minor/patch updates to the dependency dashboard for approval. + matchPackageNames: [ + "anyhow", + "arboard", + "babel-loader", + "base64-loader", + "base64", + "bindgen", + "byteorder", + "bytes", + "core-foundation", + "copy-webpack-plugin", + "css-loader", + "dirs", + "electron-builder", + "electron-log", + "electron-reload", + "electron-store", + "electron-updater", + "embed_plist", + "futures", + "hex", + "homedir", + "html-loader", + "html-webpack-injector", + "html-webpack-plugin", + "interprocess", + "json5", + "keytar", + "libc", + "lowdb", + "mini-css-extract-plugin", + "napi", + "napi-build", + "napi-derive", + "node-ipc", + "nx", + "oo7", + "oslog", + "pin-project", + "pkg", + "postcss", + "postcss-loader", + "rand", + "sass", + "sass-loader", + "scopeguard", + "security-framework", + "security-framework-sys", + "semver", + "serde", + "serde_json", + "simplelog", + "style-loader", + "sysinfo", + "tokio", + "tokio-util", + "tracing", + "tracing-subscriber", + "ts-node", + "ts-loader", + "tsconfig-paths-webpack-plugin", + "type-fest", + "typenum", + "typescript-strict-plugin", + "uniffi", + "webpack-cli", + "webpack-dev-server", + "webpack-node-externals", + "widestring", + "windows", + "windows-core", + "windows-future", + "windows-registry", + "zbus", + "zbus_polkit", + ], + matchUpdateTypes: ["minor", "patch"], + dependencyDashboardApproval: true, + }, + { + // By default, we send patch updates to the Dependency Dashboard and do not generate a PR. + // We want to generate PRs for a select number of dependencies to ensure we stay up to date on these. + matchPackageNames: ["browserslist", "electron", "rxjs", "typescript", "webpack", "zone.js"], + matchUpdateTypes: ["patch"], + dependencyDashboardApproval: false, + }, + + // ==================== Special Version Constraints ==================== { // Any versions of lowdb above 1.0.0 are not compatible with CommonJS. matchPackageNames: ["lowdb"], diff --git a/.github/whitelist-capital-letters.txt b/.github/whitelist-capital-letters.txt index db5097e5268..b9f904d7613 100644 --- a/.github/whitelist-capital-letters.txt +++ b/.github/whitelist-capital-letters.txt @@ -19,8 +19,6 @@ ./apps/cli/stores/chocolatey/tools/VERIFICATION.txt ./apps/browser/store/windows/AppxManifest.xml ./apps/browser/src/background/nativeMessaging.background.ts -./apps/browser/src/models/browserComponentState.ts -./apps/browser/src/models/browserGroupingsComponentState.ts ./apps/browser/src/models/biometricErrors.ts ./apps/browser/src/browser/safariApp.ts ./apps/browser/src/safari/desktop/ViewController.swift diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 949263b34b7..5a7703adb78 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -175,9 +175,23 @@ jobs: - name: Check out repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: + fetch-depth: 1 ref: ${{ github.event.pull_request.head.sha }} persist-credentials: false + - name: Free disk space for build + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/share/swift + sudo rm -rf /usr/local/.ghcup + sudo rm -rf /usr/share/miniconda + sudo rm -rf /usr/share/az_* + sudo rm -rf /usr/local/julia* + sudo rm -rf /usr/lib/mono + sudo rm -rf /usr/lib/heroku + sudo rm -rf /usr/local/aws-cli + sudo rm -rf /usr/local/aws-sam-cli + - name: Set up Node uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 with: @@ -195,7 +209,7 @@ jobs: - name: Set up environment run: | sudo apt-get update - sudo apt-get -y install pkg-config libxss-dev rpm musl-dev musl-tools flatpak flatpak-builder + sudo apt-get -y install pkg-config libxss-dev rpm flatpak flatpak-builder - name: Set up Snap run: sudo snap install snapcraft --classic @@ -232,7 +246,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 id: cache with: path: | @@ -248,10 +262,10 @@ jobs: env: PKG_CONFIG_ALLOW_CROSS: true PKG_CONFIG_ALL_STATIC: true - TARGET: musl + # Note: It is important that we use the release build because some compute heavy + # operations such as key derivation for oo7 on linux are too slow in debug mode run: | - rustup target add x86_64-unknown-linux-musl - node build.js --target=x86_64-unknown-linux-musl + node build.js --release - name: Build application run: npm run dist:lin @@ -351,7 +365,7 @@ jobs: - name: Set up environment run: | sudo apt-get update - sudo apt-get -y install pkg-config libxss-dev rpm musl-dev musl-tools flatpak flatpak-builder squashfs-tools ruby ruby-dev rubygems build-essential + sudo apt-get -y install pkg-config libxss-dev rpm flatpak flatpak-builder squashfs-tools ruby ruby-dev rubygems build-essential sudo gem install --no-document fpm - name: Set up Snap @@ -395,7 +409,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 id: cache with: path: | @@ -411,10 +425,10 @@ jobs: env: PKG_CONFIG_ALLOW_CROSS: true PKG_CONFIG_ALL_STATIC: true - TARGET: musl + # Note: It is important that we use the release build because some compute heavy + # operations such as key derivation for oo7 on linux are too slow in debug mode run: | - rustup target add aarch64-unknown-linux-musl - node build.js --target=aarch64-unknown-linux-musl + node build.js --release - name: Check index.d.ts generated if: github.event_name == 'pull_request' && steps.cache.outputs.cache-hit != 'true' @@ -558,7 +572,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 id: cache with: path: | @@ -569,7 +583,9 @@ jobs: - name: Build Native Module if: steps.cache.outputs.cache-hit != 'true' working-directory: apps/desktop/desktop_native - run: node build.js cross-platform + env: + MODE: ${{ github.event_name == 'workflow_call' && '--release' || '' }} + run: node build.js cross-platform "$env:MODE" - name: Build run: npm run build @@ -821,7 +837,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 id: cache with: path: | @@ -832,7 +848,9 @@ jobs: - name: Build Native Module if: steps.cache.outputs.cache-hit != 'true' working-directory: apps/desktop/desktop_native - run: node build.js cross-platform + env: + MODE: ${{ github.event_name == 'workflow_call' && '--release' || '' }} + run: node build.js cross-platform "$env:MODE" - name: Build run: npm run build @@ -1001,10 +1019,10 @@ jobs: - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: - python-version: '3.14' + python-version: '3.14.2' - name: Set up Node-gyp - run: python3 -m pip install setuptools + run: python -m pip install setuptools - name: Cache Rust dependencies uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 @@ -1020,17 +1038,18 @@ jobs: rustup show echo "GitHub ref: $GITHUB_REF" echo "GitHub event: $GITHUB_EVENT" + xcodebuild -showsdks - name: Cache Build id: build-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Cache Safari id: safari-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension @@ -1176,7 +1195,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 id: cache with: path: | @@ -1187,7 +1206,9 @@ jobs: - name: Build Native Module if: steps.cache.outputs.cache-hit != 'true' working-directory: apps/desktop/desktop_native - run: node build.js cross-platform + env: + MODE: ${{ github.event_name == 'workflow_call' && '--release' || '' }} + run: node build.js cross-platform "$MODE" - name: Build application (dev) run: npm run build @@ -1238,10 +1259,10 @@ jobs: - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: - python-version: '3.14' + python-version: '3.14.2' - name: Set up Node-gyp - run: python3 -m pip install setuptools + run: python -m pip install setuptools - name: Cache Rust dependencies uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 @@ -1257,17 +1278,18 @@ jobs: rustup show echo "GitHub ref: $GITHUB_REF" echo "GitHub event: $GITHUB_EVENT" + xcodebuild -showsdks - name: Get Build Cache id: build-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension @@ -1397,7 +1419,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 id: cache with: path: | @@ -1408,7 +1430,9 @@ jobs: - name: Build Native Module if: steps.cache.outputs.cache-hit != 'true' working-directory: apps/desktop/desktop_native - run: node build.js cross-platform + env: + MODE: ${{ github.event_name == 'workflow_call' && '--release' || '' }} + run: node build.js cross-platform "$MODE" - name: Build if: steps.build-cache.outputs.cache-hit != 'true' @@ -1510,10 +1534,10 @@ jobs: - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: - python-version: '3.14' + python-version: '3.14.2' - name: Set up Node-gyp - run: python3 -m pip install setuptools + run: python -m pip install setuptools - name: Cache Rust dependencies uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 @@ -1529,17 +1553,18 @@ jobs: rustup show echo "GitHub ref: $GITHUB_REF" echo "GitHub event: $GITHUB_EVENT" + xcodebuild -showsdks - name: Get Build Cache id: build-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension @@ -1677,7 +1702,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 id: cache with: path: | @@ -1688,7 +1713,9 @@ jobs: - name: Build Native Module if: steps.cache.outputs.cache-hit != 'true' working-directory: apps/desktop/desktop_native - run: node build.js cross-platform + env: + MODE: ${{ github.event_name == 'workflow_call' && '--release' || '' }} + run: node build.js cross-platform "$MODE" - name: Build if: steps.build-cache.outputs.cache-hit != 'true' diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 677d3dfc1df..44ea21276e2 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -65,7 +65,7 @@ jobs: - name: Cache NPM id: npm-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: path: "~/.npm" key: ${{ runner.os }}-npm-chromatic-${{ hashFiles('**/package-lock.json') }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 48d3eca2f4e..47c5e9faef0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -52,6 +52,7 @@ jobs: ! -path "*/Cargo.lock" \ ! -path "./apps/desktop/macos/*" \ ! -path "*/CLAUDE.md" \ + ! -path "*/SKILL.md" \ > tmp.txt diff <(sort .github/whitelist-capital-letters.txt) <(sort tmp.txt) @@ -141,7 +142,7 @@ jobs: run: cargo +nightly udeps --workspace --all-features --all-targets - name: Install cargo-deny - uses: taiki-e/install-action@81ee1d48d9194cdcab880cbdc7d36e87d39874cb # v2.62.45 + uses: taiki-e/install-action@073d46cba2cde38f6698c798566c1b3e24feeb44 # v2.62.67 with: tool: cargo-deny@0.18.5 diff --git a/.github/workflows/publish-web.yml b/.github/workflows/publish-web.yml index 62d9342cf61..fb1de5a1bc5 100644 --- a/.github/workflows/publish-web.yml +++ b/.github/workflows/publish-web.yml @@ -187,6 +187,8 @@ jobs: with: app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }} private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }} + owner: ${{ github.repository_owner }} + repositories: self-host - name: Trigger Bitwarden lite build uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index 7f87a1e5628..2239cb1268f 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -98,6 +98,14 @@ jobs: working-directory: apps/desktop/artifacts run: mv "Bitwarden-${PKG_VERSION}-universal.pkg" "Bitwarden-${PKG_VERSION}-universal.pkg.archive" + - name: Rename .tar.gz to include version + env: + PKG_VERSION: ${{ steps.version.outputs.version }} + working-directory: apps/desktop/artifacts + run: | + mv "bitwarden_desktop_x64.tar.gz" "bitwarden_${PKG_VERSION}_x64.tar.gz" + mv "bitwarden_desktop_arm64.tar.gz" "bitwarden_${PKG_VERSION}_arm64.tar.gz" + - name: Create Release uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b # v1.20.0 if: ${{ steps.release_channel.outputs.channel == 'latest' && github.event.inputs.release_type != 'Dry Run' }} diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index 246e0d48c5d..2a27a9b3101 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -15,7 +15,7 @@ jobs: pull-requests: write steps: - name: 'Run stale action' - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0 + uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1 with: stale-issue-label: 'needs-reply' stale-pr-label: 'needs-changes' diff --git a/.github/workflows/test-browser-interactions.yml b/.github/workflows/test-browser-interactions.yml index dfc0f28b9c6..c8f4c959c52 100644 --- a/.github/workflows/test-browser-interactions.yml +++ b/.github/workflows/test-browser-interactions.yml @@ -75,7 +75,7 @@ jobs: - name: Trigger test-all workflow in browser-interactions-testing if: steps.changed-files.outputs.monitored == 'true' - uses: peter-evans/repository-dispatch@5fc4efd1a4797ddb68ffd0714a238564e4cc0e6f # v4.0.0 + uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1 with: token: ${{ steps.app-token.outputs.token }} repository: "bitwarden/browser-interactions-testing" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index faee7220e7b..e3ba6112b7d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -190,7 +190,7 @@ jobs: path: ./apps/desktop/desktop_native - name: Upload coverage to codecov.io - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 with: files: | ./lcov.info diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index 03d5eb0a9f6..25cc1e31425 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "المزامنة" }, - "syncVaultNow": { - "message": "مزامنة الخزانة الآن" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "آخر مزامنة:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "تطبيق ويب Bitwarden" }, - "importItems": { - "message": "استيراد العناصر" - }, "select": { "message": "تحديد" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "التصدير من" }, - "exportVault": { - "message": "تصدير الخزانة" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "صيغة الملف" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "معرفة المزيد" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "مفتاح المصادقة (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "تم حفظ المرفقات" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "الملف" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "حدد ملفًا" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "الحجم الأقصى للملف هو 500 ميجابايت." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 جيغابايت وحدة تخزين مشفرة لمرفقات الملفات." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "الوصول الطارئ." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "لم يتم العثور على معرف فريد." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "تجاهل" }, - "importData": { - "message": "استيراد البيانات", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "خطأ في الاستيراد" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index 7dbd1ba3e7c..3f98313c2b8 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sinxr" }, - "syncVaultNow": { - "message": "Seyfi indi sinxronlaşdır" + "syncNow": { + "message": "İndi sinxr." }, "lastSync": { "message": "Son sinxr:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden veb tətbiqi" }, - "importItems": { - "message": "Elementləri daxilə köçür" - }, "select": { "message": "Seçin" }, @@ -586,7 +583,7 @@ "message": "Arxivlənmiş elementlər ümumi axtarış nəticələrindən və avto-doldurma təkliflərindən xaric ediləcək. Bu elementi arxivləmək istədiyinizə əminsiniz?" }, "upgradeToUseArchive": { - "message": "A premium membership is required to use Archive." + "message": "Arxivi istifadə etmək üçün premium üzvlük tələb olunur." }, "edit": { "message": "Düzəliş et" @@ -598,7 +595,7 @@ "message": "Hamısına bax" }, "showAll": { - "message": "Show all" + "message": "Hamısını göstər" }, "viewLess": { "message": "Daha azına bax" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Buradan xaricə köçür" }, - "exportVault": { - "message": "Seyfi xaricə köçür" + "exportVerb": { + "message": "Xaricə köçür", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Xaricə köçürmə", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Daxilə köçürmə", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Daxilə köçür", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Fayl formatı" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Daha ətraflı" }, + "migrationsFailed": { + "message": "Şifrələmə ayarlarını güncəlləyərkən bir xəta baş verdi." + }, + "updateEncryptionSettingsTitle": { + "message": "Şifrələmə ayarlarınızı güncəlləyin" + }, + "updateEncryptionSettingsDesc": { + "message": "Tövsiyə edilən yeni şifrələmə ayarları, hesabınızın təhlükəsizliyini artıracaq. İndi güncəlləmək üçün ana parolunuzu daxil edin." + }, + "confirmIdentityToContinue": { + "message": "Davam etmək üçün kimliyinizi təsdiqləyin" + }, + "enterYourMasterPassword": { + "message": "Ana parolunuzu daxil edin" + }, + "updateSettings": { + "message": "Ayarları güncəllə" + }, + "later": { + "message": "Sonra" + }, "authenticatorKeyTotp": { "message": "Kimlik doğrulayıcı açarı (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Qoşma saxlanıldı." }, + "fixEncryption": { + "message": "Şifrələməni düzəlt" + }, + "fixEncryptionTooltip": { + "message": "Bu fayl, köhnə bir şifrələmə üsulunu istifadə edir." + }, + "attachmentUpdated": { + "message": "Qoşma güncəllənib" + }, "file": { "message": "Fayl" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Bir fayl seçin" }, + "itemsTransferred": { + "message": "Elementlər köçürüldü" + }, "maxFileSize": { "message": "Maksimal fayl həcmi 500 MB-dır" }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "Fayl qoşmaları üçün 1 GB şifrələnmiş anbar sahəsi" }, + "premiumSignUpStorageV2": { + "message": "Fayl qoşmaları üçün $SIZE$ şifrələnmiş anbar sahəsi.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Fövqəladə hal erişimi." }, @@ -1874,7 +1926,7 @@ "message": "Son istifadə ili" }, "monthly": { - "message": "month" + "message": "ay" }, "expiration": { "message": "Bitmə vaxtı" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Unikal identifikator tapılmadı." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Aşağıdakı təşkilatların üzvləri üçün artıq ana parol tələb olunmur. Lütfən aşağıdakı domeni təşkilatınızın inzibatçısı ilə təsdiqləyin." - }, "organizationName": { "message": "Təşkilat adı" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Yox say" }, - "importData": { - "message": "Veriləri daxilə köçür", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Daxilə köçürmə xətası" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Hesab güvənliyi" }, + "phishingBlocker": { + "message": "Fişinq əngəlləyici" + }, + "enablePhishingDetection": { + "message": "Fişinq aşkarlama" + }, + "enablePhishingDetectionDesc": { + "message": "Şübhəli fişinq saytlarına erişməzdən əvvəl xəbərdarlıq nümayiş etdir" + }, "notifications": { "message": "Bildirişlər" }, @@ -4912,7 +4966,7 @@ "message": "Premium" }, "unlockFeaturesWithPremium": { - "message": "Unlock reporting, emergency access, and more security features with Premium." + "message": "Premium ilə şikayət göndərmə, fövqəladə hal erişimi və daha çox təhlükəsizlik özəlliyinin kilidini açın." }, "freeOrgsCannotUseAttachments": { "message": "Ödənişsiz təşkilatlar qoşmaları istifadə edə bilməz" @@ -5818,17 +5872,17 @@ "andMoreFeatures": { "message": "Və daha çoxu!" }, - "planDescPremium": { - "message": "Tam onlayn təhlükəsizlik" + "advancedOnlineSecurity": { + "message": "Qabaqcıl onlayn təhlükəsizlik" }, "upgradeToPremium": { "message": "\"Premium\"a yüksəlt" }, "unlockAdvancedSecurity": { - "message": "Unlock advanced security features" + "message": "Qabaqcıl təhlükəsizlik özəlliklərinin kilidini aç" }, "unlockAdvancedSecurityDesc": { - "message": "A Premium subscription gives you more tools to stay secure and in control" + "message": "Premium abunəlik, güvəndə qalmağınız və nəzarəti əlinizdə saxlamağınız üçün sizə daha çox alət verir" }, "explorePremium": { "message": "Premium-u kəşf et" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Kart nömrəsi" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Təşkilatınız, artıq Bitwarden-ə giriş etmək üçün ana parol istifadə etmir. Davam etmək üçün təşkilatı və domeni doğrulayın." + }, + "continueWithLogIn": { + "message": "Giriş etməyə davam" + }, + "doNotContinue": { + "message": "Davam etmə" + }, + "domain": { + "message": "Domen" + }, + "keyConnectorDomainTooltip": { + "message": "Bu domen, hesabınızın şifrələmə açarlarını saxlayacaq, ona görə də, bu domenə güvəndiyinizə əmin olun. Əmin deyilsinizsə, adminizlə əlaqə saxlayın." + }, + "verifyYourOrganization": { + "message": "Giriş etmək üçün təşkilatınızı doğrulayın" + }, + "organizationVerified": { + "message": "Təşkilat doğrulandı" + }, + "domainVerified": { + "message": "Domen doğrulandı" + }, + "leaveOrganizationContent": { + "message": "Təşkilatınızı doğrulamasanız, təşkilata erişiminiz ləğv ediləcək." + }, + "leaveNow": { + "message": "İndi tərk et" + }, + "verifyYourDomainToLogin": { + "message": "Giriş etmək üçün domeninizi doğrulayın" + }, + "verifyYourDomainDescription": { + "message": "Giriş prosesini davam etdirmək üçün bu domeni doğrulayın." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Giriş prosesini davam etdirmək üçün bu təşkilatı və domeni doğrulayın." + }, "sessionTimeoutSettingsAction": { "message": "Vaxt bitmə əməliyyatı" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Bu ayar, təşkilatınız tərəfindən idarə olunur." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Təşkilatınız, maksimum seyf bitmə vaxtını $HOURS$ saat $MINUTES$ dəqiqə olaraq ayarladı.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Təşkilatınız, seansın ilkin bitmə vaxtını dərhal olaraq təyin etdi." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Təşkilatınız, seansın ilkin bitmə vaxtını Sistem kilidi açılanda olaraq təyin etdi." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Təşkilatınız, seansın ilkin bitmə vaxtını Brauzer yenidən başladılanda olaraq təyin etdi." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maksimum bitmə vaxtı $HOURS$ saat $MINUTES$ dəqiqə dəyərini aşa bilməz", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Brauzer yenidən başladılanda" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Vaxt bitmə əməliyyatınızı dəyişdirmək üçün bir kilid açma üsulu qurun." + }, + "upgrade": { + "message": "Yüksəlt" + }, + "leaveConfirmationDialogTitle": { + "message": "Tərk etmək istədiyinizə əminsiniz?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Rədd cavabı versəniz, fərdi elementləriniz hesabınızda qalacaq, paylaşılan elementlərə və təşkilat özəlliklərinə erişimi itirəcəksiniz." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Erişimi təkrar qazanmaq üçün admininizlə əlaqə saxlayın." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Tərk et: $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Seyfimi necə idarə edim?" + }, + "transferItemsToOrganizationTitle": { + "message": "Elementləri bura köçür: $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$, təhlükəsizlik və riayətlilik üçün bütün elementlərin təşkilata aid olmasını tələb edir. Elementlərinizin sahibliyini transfer etmək üçün qəbul edin.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Transferi qəbul et" + }, + "declineAndLeave": { + "message": "Rədd et və tərk et" + }, + "whyAmISeeingThis": { + "message": "Bunu niyə görürəm?" } } diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 89651f0038e..fd4dbb780da 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Сінхранізаваць" }, - "syncVaultNow": { - "message": "Сінхранізаваць сховішча зараз" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Апошняя сінхранізацыя:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Вэб-праграма Bitwarden" }, - "importItems": { - "message": "Імпартаванне элементаў" - }, "select": { "message": "Выбраць" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Экспартаванне з" }, - "exportVault": { - "message": "Экспартаваць сховішча" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Фармат файла" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Даведацца больш" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Ключ аўтэнтыфікацыі (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Далучэнне захавана." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Файл" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Выберыце файл." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Максімальны памер файла 500 МБ." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 ГБ зашыфраванага сховішча для далучаных файлаў." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Экстранны доступ." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Не знойдзены ўнікальны ідэнтыфікатар." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Iгнараваць" }, - "importData": { - "message": "Імпартаванне даных", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Памылка імпартавання" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Бяспеке акаўнта" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Апавяшчэнні" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index b40f4b91cb4..1dc20d6ab65 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -436,7 +436,7 @@ "sync": { "message": "Синхронизиране" }, - "syncVaultNow": { + "syncNow": { "message": "Синхронизиране сега" }, "lastSync": { @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Уеб приложение" }, - "importItems": { - "message": "Внасяне на елементи" - }, "select": { "message": "Избор" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Изнасяне от" }, - "exportVault": { - "message": "Изнасяне на трезора" + "exportVerb": { + "message": "Изнасяне", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Изнасяне", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Внасяне", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Внасяне", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Формат на файла" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Научете повече" }, + "migrationsFailed": { + "message": "Възникна грешка при обновяването на настройките за шифроване." + }, + "updateEncryptionSettingsTitle": { + "message": "Обновете настройките си за шифроване" + }, + "updateEncryptionSettingsDesc": { + "message": "Новите препоръчани настройки за шифроване ще подобрят сигурността на акаунта Ви. Въведете главната си парола, за да ги обновите сега." + }, + "confirmIdentityToContinue": { + "message": "Потвърдете самоличността си, за да продължите" + }, + "enterYourMasterPassword": { + "message": "Въведете главната си парола" + }, + "updateSettings": { + "message": "Обновяване на настройките" + }, + "later": { + "message": "По-късно" + }, "authenticatorKeyTotp": { "message": "Удостоверителен ключ (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Прикаченият файл е запазен." }, + "fixEncryption": { + "message": "Поправяне на шифроването" + }, + "fixEncryptionTooltip": { + "message": "Този файл използва остарял метод на шифроване." + }, + "attachmentUpdated": { + "message": "Прикаченият файл е актуализиран" + }, "file": { "message": "Файл" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Изберете файл." }, + "itemsTransferred": { + "message": "Елементите са прехвърлени" + }, "maxFileSize": { "message": "Големината на файла е най-много 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB пространство за файлове, които се шифрират." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ пространство за файлове, които се шифрират.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Авариен достъп" }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Няма намерен уникален идентификатор." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "За членовете на следната организация вече не се изисква главна парола. Потвърдете домейна по-долу с администратора на организацията си." - }, "organizationName": { "message": "Име на организацията" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Пренебрегване" }, - "importData": { - "message": "Внасяне на данни", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Грешка при внасянето" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Защита на регистрацията" }, + "phishingBlocker": { + "message": "Блокатор на измами" + }, + "enablePhishingDetection": { + "message": "Разпознаване на измами" + }, + "enablePhishingDetectionDesc": { + "message": "Показване на предупреждение преди зареждане на уеб сайтове подозирани за измамни" + }, "notifications": { "message": "Известия" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "И още!" }, - "planDescPremium": { - "message": "Пълна сигурност в Интернет" + "advancedOnlineSecurity": { + "message": "Разширена сигурност в Интернет" }, "upgradeToPremium": { "message": "Надградете до Платения план" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Номер на картата" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Вашата организация вече не използва главни пароли за вписване в Битуорден. За да продължите, потвърдете организацията и домейна." + }, + "continueWithLogIn": { + "message": "Продължаване с вписването" + }, + "doNotContinue": { + "message": "Не продължавам" + }, + "domain": { + "message": "Домейн" + }, + "keyConnectorDomainTooltip": { + "message": "Този домейн ще съхранява ключовете за шифроване на акаунта Ви, така че се уверете, че му имате доверие. Ако имате съмнения, свържете се с администратора си." + }, + "verifyYourOrganization": { + "message": "Потвърдете организацията си, за да се впишете" + }, + "organizationVerified": { + "message": "Организацията е потвърдена" + }, + "domainVerified": { + "message": "Домейнът е потвърден" + }, + "leaveOrganizationContent": { + "message": "Ако не потвърдите организацията, достъпът Ви до нея ще бъде преустановен." + }, + "leaveNow": { + "message": "Напускане сега" + }, + "verifyYourDomainToLogin": { + "message": "Потвърдете домейна си, за да се впишете" + }, + "verifyYourDomainDescription": { + "message": "За да продължите с вписването, потвърдете този домейн." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "За да продължите с вписването, потвърдете организацията и домейна." + }, "sessionTimeoutSettingsAction": { "message": "Действие при изтичането на времето за достъп" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Тази настройка се управлява от организацията Ви." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Организацията Ви е настроила максималното разрешено време за достъп на [%1$i] час(а) и [%2$i] минути.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Организацията Ви е настроила стандартното разрешено време за достъп да бъде нула." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Организацията Ви е настроила стандартното разрешено време за достъп да бъде до заключване на системата." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Организацията Ви е настроила стандартното разрешено време за достъп да бъде до рестартиране на браузъра." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Максималното време на достъп не може да превишава $HOURS$ час(а) и $MINUTES$ минути", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "При рестартиране на браузъра" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Задайте метод за отключване, за да може да промените действието при изтичане на времето за достъп" + }, + "upgrade": { + "message": "Надграждане" + }, + "leaveConfirmationDialogTitle": { + "message": "Наистина ли искате да напуснете?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Ако откажете, Вашите собствени елементи ще останат в акаунта Ви, но ще загубите достъп до споделените елементи и функционалностите на организацията." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Свържете се с администратор, за да получите достъп отново." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Напускане на $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Как да управлявам трезора си?" + }, + "transferItemsToOrganizationTitle": { + "message": "Прехвърляне на елементи към $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ изисква всички елементи да станат притежание на организацията, за по-добра сигурност и съвместимост. Изберете, че приемате, за да прехвърлите собствеността на елементите си към организацията.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Приемане на прехвърлянето" + }, + "declineAndLeave": { + "message": "Отказване и напускане" + }, + "whyAmISeeingThis": { + "message": "Защо виждам това?" } } diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index 4f8e7054305..baf98bcb50a 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "সিঙ্ক" }, - "syncVaultNow": { - "message": "এখনই ভল্ট সিঙ্ক করুন" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "শেষ সিঙ্ক:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "বস্তু আমদানি" - }, "select": { "message": "নির্বাচন করুন" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "ভল্ট রফতানি" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "ফাইলের ধরণ" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "আরও জানুন" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "প্রমাণীকরণকারী কী (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "সংযুক্তিটি সংরক্ষণ করা হয়েছে।" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "ফাইল" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "একটি ফাইল নির্বাচন করুন।" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "সর্বোচ্চ ফাইলের আকার ১০০ এমবি।" }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "ফাইল সংযুক্তির জন্য ১ জিবি এনক্রিপ্টেড স্থান।" }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index 9d5631c47e2..df473b0192d 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sync" }, - "syncVaultNow": { - "message": "Sync vault now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Last sync:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import items" - }, "select": { "message": "Select" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Select a file" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index 255263a6da7..4bbfb9a418e 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sincronització" }, - "syncVaultNow": { - "message": "Sincronitza la caixa forta ara" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Última sincronització:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Aplicació web Bitwarden" }, - "importItems": { - "message": "Importa elements" - }, "select": { "message": "Selecciona" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Exporta des de" }, - "exportVault": { - "message": "Exporta caixa forta" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format de fitxer" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Més informació" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Clau d'autenticació (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "S'ha guardat el fitxer adjunt" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Fitxer" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Seleccioneu un fitxer" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "La mida màxima del fitxer és de 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB d'emmagatzematge xifrat per als fitxers adjunts." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Accés d’emergència." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No s'ha trobat cap identificador únic." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignora" }, - "importData": { - "message": "Importa dades", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Error d'importació" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Seguretat del compte" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notificacions" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index eff2c6c0ea7..e40edbb8091 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Synchronizace" }, - "syncVaultNow": { - "message": "Synchronizovat trezor nyní" + "syncNow": { + "message": "Synchronizovat nyní" }, "lastSync": { "message": "Poslední synchronizace:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Webová aplikace Bitwardenu" }, - "importItems": { - "message": "Importovat položky" - }, "select": { "message": "Vybrat" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Exportovat z" }, - "exportVault": { - "message": "Exportovat trezor" + "exportVerb": { + "message": "Exportovat", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importovat", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formát souboru" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Dozvědět se více" }, + "migrationsFailed": { + "message": "Došlo k chybě při aktualizaci nastavení šifrování." + }, + "updateEncryptionSettingsTitle": { + "message": "Aktualizovat nastavení šifrování" + }, + "updateEncryptionSettingsDesc": { + "message": "Nové doporučené nastavení šifrování zlepší bezpečnost Vašeho účtu. Pokud chcete aktualizovat nyní, zadejte hlavní heslo." + }, + "confirmIdentityToContinue": { + "message": "Pro pokračování potvrďte svou identitu" + }, + "enterYourMasterPassword": { + "message": "Zadejte své hlavní heslo" + }, + "updateSettings": { + "message": "Aktualizovat nastavení" + }, + "later": { + "message": "Později" + }, "authenticatorKeyTotp": { "message": "Autentizační klíč (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Příloha byla uložena" }, + "fixEncryption": { + "message": "Opravit šifrování" + }, + "fixEncryptionTooltip": { + "message": "Tento soubor používá zastaralou šifrovací metodu." + }, + "attachmentUpdated": { + "message": "Příloha byla aktualizována" + }, "file": { "message": "Soubor" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Zvolte soubor" }, + "itemsTransferred": { + "message": "Převedené položky" + }, "maxFileSize": { "message": "Maximální velikost souboru je 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB šifrovaného úložiště pro přílohy." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ šifrovaného úložiště pro přílohy.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Nouzový přístup" }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Nenalezen žádný jedinečný identifikátor." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Hlavní heslo již není vyžadováno pro členy následující organizace. Potvrďte níže uvedenou doménu u správce Vaší organizace." - }, "organizationName": { "message": "Název organizace" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignorovat" }, - "importData": { - "message": "Importovat data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Chyba importu" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Zabezpečení účtu" }, + "phishingBlocker": { + "message": "Blokování phishingu" + }, + "enablePhishingDetection": { + "message": "Detekce phishingu" + }, + "enablePhishingDetectionDesc": { + "message": "Zobrazí varování před přístupem k podezřelým phishingovým stránkám." + }, "notifications": { "message": "Oznámení" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "A ještě více!" }, - "planDescPremium": { - "message": "Dokončit online zabezpečení" + "advancedOnlineSecurity": { + "message": "Pokročilé zabezpečení online" }, "upgradeToPremium": { "message": "Aktualizovat na Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Číslo karty" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Vaše organizace již k přihlášení do Bitwardenu nepoužívá hlavní hesla. Chcete-li pokračovat, ověřte organizaci a doménu." + }, + "continueWithLogIn": { + "message": "Pokračovat s přihlášením" + }, + "doNotContinue": { + "message": "Nepokračovat" + }, + "domain": { + "message": "Doména" + }, + "keyConnectorDomainTooltip": { + "message": "Tato doména uloží šifrovací klíče Vašeho účtu, takže se ujistěte, že jí věříte. Pokud si nejste jisti, kontaktujte Vašeho správce." + }, + "verifyYourOrganization": { + "message": "Ověřte svou organizaci pro přihlášení" + }, + "organizationVerified": { + "message": "Organizace byla ověřena" + }, + "domainVerified": { + "message": "Doména byla ověřena" + }, + "leaveOrganizationContent": { + "message": "Pokud neověříte svou organizaci, Váš přístup k organizaci bude zrušen." + }, + "leaveNow": { + "message": "Opustit hned" + }, + "verifyYourDomainToLogin": { + "message": "Ověřte svou doménu pro přihlášení" + }, + "verifyYourDomainDescription": { + "message": "Chcete-li pokračovat v přihlášení, ověřte tuto doménu." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Chcete-li pokračovat v přihlášení, ověřte organizaci a doménu." + }, "sessionTimeoutSettingsAction": { "message": "Akce vypršení časového limitu" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Tato nastavení je spravováno Vaší organizací." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Vaše organizace nastavila maximální časový limit relace na $HOURS$ hodin a $MINUTES$ minut.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Vaše organizace nastavila výchozí časový limit relace na Okamžitě." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Vaše organizace nastavila výchozí časový limit relace na Při uzamknutí systému." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Vaše organizace nastavila výchozí časový limit relace na Při restartu prohlížeče." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximální časový limit nesmí překročit $HOURS$ hodin a $MINUTES$ minut", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Při restartu prohlížeče" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Nastavte metodu odemknutí, abyste změnili akci při vypršení časového limitu" + }, + "upgrade": { + "message": "Aktualizovat" + }, + "leaveConfirmationDialogTitle": { + "message": "Opravdu chcete odejít?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Odmítnutím zůstanou Vaše osobní položky ve Vašem účtu, ale ztratíte přístup ke sdíleným položkám a funkcím organizace." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Obraťte se na svého správce, abyste znovu získali přístup." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Opustit $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Jak mohu spravovat svůj trezor?" + }, + "transferItemsToOrganizationTitle": { + "message": "Přenést položky do $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ vyžaduje, aby byly všechny položky vlastněny organizací z důvodu bezpečnosti a shody. Klepnutím na tlačítko pro převod vlastnictví Vašich položek.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Přijmout převod" + }, + "declineAndLeave": { + "message": "Odmítnout a opustit" + }, + "whyAmISeeingThis": { + "message": "Proč se mi toto zobrazuje?" } } diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index 99fcdffcc97..896eee5af4f 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Cysoni" }, - "syncVaultNow": { - "message": "Cysoni'r gell nawr" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Wedi'i chysoni ddiwethaf:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Mewnforio eitemau" - }, "select": { "message": "Dewis" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Allforio'r gell" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Fformat y ffeil" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Dysgu mwy" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Ffeil" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Dewis ffeil" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "Storfa 1GB wedi'i hamgryptio ar gyfer atodiadau ffeiliau." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Anwybyddu" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Diogelwch eich cyfrif" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Hysbysiadau" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index 865e6ff7dda..ad6e5b0e90d 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Synkronisér" }, - "syncVaultNow": { - "message": "Synkronisér boks nu" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Seneste synkronisering:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web-app" }, - "importItems": { - "message": "Importér elementer" - }, "select": { "message": "Vælg" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Eksportér fra" }, - "exportVault": { - "message": "Eksportér boks" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Filformat" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Lær mere" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Autentificeringsnøgle (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Vedhæftning gemt" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Fil" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Vælg en fil" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maksimum filstørrelse er 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB krypteret lager til vedhæftede filer." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Nødadgang" }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Ingen entydig identifikator fundet." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignorér" }, - "importData": { - "message": "Importér data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Importfejl" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Kontosikkerhed" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifikationer" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index c013e4516ed..5ba6dd419a1 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Synchronisierung" }, - "syncVaultNow": { - "message": "Tresor jetzt synchronisieren" + "syncNow": { + "message": "Jetzt synchronisieren" }, "lastSync": { "message": "Zuletzt synchronisiert:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden Web-App" }, - "importItems": { - "message": "Einträge importieren" - }, "select": { "message": "Auswählen" }, @@ -562,7 +559,7 @@ "description": "Verb" }, "unArchive": { - "message": "Wiederherstellen" + "message": "Nicht mehr archivieren" }, "itemsInArchive": { "message": "Einträge im Archiv" @@ -577,7 +574,7 @@ "message": "Eintrag wurde archiviert" }, "itemUnarchived": { - "message": "Eintrag wurde wiederhergestellt" + "message": "Eintrag wird nicht mehr archiviert" }, "archiveItem": { "message": "Eintrag archivieren" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export aus" }, - "exportVault": { - "message": "Tresor exportieren" + "exportVerb": { + "message": "Exportieren", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importieren", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Dateiformat" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Erfahre mehr" }, + "migrationsFailed": { + "message": "Beim Aktualisieren der Verschlüsselungseinstellungen ist ein Fehler aufgetreten." + }, + "updateEncryptionSettingsTitle": { + "message": "Aktualisiere deine Verschlüsselungseinstellungen" + }, + "updateEncryptionSettingsDesc": { + "message": "Die neuen empfohlenen Verschlüsselungseinstellungen verbessern deine Kontosicherheit. Gib dein Master-Passwort ein, um sie zu aktualisieren." + }, + "confirmIdentityToContinue": { + "message": "Bestätige deine Identität, um fortzufahren" + }, + "enterYourMasterPassword": { + "message": "Gib dein Master-Passwort ein" + }, + "updateSettings": { + "message": "Einstellungen aktualisieren" + }, + "later": { + "message": "Später" + }, "authenticatorKeyTotp": { "message": "Authentifizierungsschlüssel (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Anhang gespeichert" }, + "fixEncryption": { + "message": "Verschlüsselung reparieren" + }, + "fixEncryptionTooltip": { + "message": "Diese Datei verwendet eine veraltete Verschlüsselungsmethode." + }, + "attachmentUpdated": { + "message": "Anhang aktualisiert" + }, "file": { "message": "Datei" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Wähle eine Datei" }, + "itemsTransferred": { + "message": "Einträge wurden übertragen" + }, "maxFileSize": { "message": "Die maximale Dateigröße beträgt 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB verschlüsselter Speicherplatz für Dateianhänge." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ verschlüsselter Speicher für Dateianhänge.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Notfallzugriff." }, @@ -1874,7 +1926,7 @@ "message": "Ablaufjahr" }, "monthly": { - "message": "Monatlich" + "message": "Monat" }, "expiration": { "message": "Gültig bis" @@ -2446,7 +2498,7 @@ } }, "topLayerHijackWarning": { - "message": "Diese Seite stört die Bitwarden-Nutzung. Das Bitwarden Inline-Menü wurde aus Sicherheitsgründen vorübergehend deaktiviert." + "message": "Diese Seite beeinträchtigt die Nutzung von Bitwarden. Das Bitwarden Inline-Menü wurde aus Sicherheitsgründen vorübergehend deaktiviert." }, "setMasterPassword": { "message": "Master-Passwort festlegen" @@ -2648,7 +2700,7 @@ "description": "A category title describing the concept of web domains" }, "blockedDomains": { - "message": "Gesperrte Domains" + "message": "Blockierte Domains" }, "learnMoreAboutBlockedDomains": { "message": "Erfahre mehr über blockierte Domains" @@ -2666,7 +2718,7 @@ "message": "Automatisches Ausfüllen und andere zugehörige Funktionen werden für diese Webseiten nicht angeboten. Du musst die Seite neu laden, damit die Änderungen wirksam werden." }, "autofillBlockedNoticeV2": { - "message": "Automatisches Ausfüllen ist für diese Website gesperrt." + "message": "Automatisches Ausfüllen ist für diese Website blockiert." }, "autofillBlockedNoticeGuidance": { "message": "Dies in den Einstellungen ändern" @@ -2820,7 +2872,7 @@ } }, "blockedDomainsSavedSuccess": { - "message": "Änderungen gesperrter Domains gespeichert" + "message": "Änderungen blockierter Domains gespeichert" }, "excludedDomainsSavedSuccess": { "message": "Änderungen der ausgeschlossenen Domain gespeichert" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Keine eindeutige Kennung gefunden." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Für Mitglieder der folgenden Organisation ist kein Master-Passwort mehr erforderlich. Bitte bestätige die folgende Domain bei deinem Organisations-Administrator." - }, "organizationName": { "message": "Name der Organisation" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignorieren" }, - "importData": { - "message": "Daten importieren", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Importfehler" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Kontosicherheit" }, + "phishingBlocker": { + "message": "Phishing-Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing-Erkennung" + }, + "enablePhishingDetectionDesc": { + "message": "Warnung vor dem Zugriff auf verdächtige Phishing-Seiten anzeigen" + }, "notifications": { "message": "Benachrichtigungen" }, @@ -5813,13 +5867,13 @@ "message": "Notfallzugriff" }, "breachMonitoring": { - "message": "Datenleck-Überwachung" + "message": "Datendiebstahl-Überwachung" }, "andMoreFeatures": { "message": "Und mehr!" }, - "planDescPremium": { - "message": "Umfassende Online-Sicherheit" + "advancedOnlineSecurity": { + "message": "Erweiterte Online-Sicherheit" }, "upgradeToPremium": { "message": "Upgrade auf Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Kartennummer" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Deine Organisation verwendet keine Master-Passwörter mehr, um sich bei Bitwarden anzumelden. Verifiziere die Organisation und Domain, um fortzufahren." + }, + "continueWithLogIn": { + "message": "Mit der Anmeldung fortfahren" + }, + "doNotContinue": { + "message": "Nicht fortfahren" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "Diese Domain speichert die Verschlüsselungsschlüssel deines Kontos. Stelle daher sicher, dass du ihr vertraust. Wenn du dir nicht sicher bist, wende dich an deinen Administrator." + }, + "verifyYourOrganization": { + "message": "Verifiziere deine Organisation, um dich anzumelden" + }, + "organizationVerified": { + "message": "Organisation verifiziert" + }, + "domainVerified": { + "message": "Domain verifiziert" + }, + "leaveOrganizationContent": { + "message": "Wenn du deine Organisation nicht verifizierst, wird dein Zugriff auf die Organisation widerrufen." + }, + "leaveNow": { + "message": "Jetzt verlassen" + }, + "verifyYourDomainToLogin": { + "message": "Verifiziere deine Domain, um dich anzumelden" + }, + "verifyYourDomainDescription": { + "message": "Verifiziere diese Domain, um mit der Anmeldung fortzufahren." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Um mit der Anmeldung fortzufahren, verifiziere die Organisation und Domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout-Aktion" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Diese Einstellung wird von deiner Organisation verwaltet." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Deine Organisation hat das maximale Sitzungs-Timeout auf $HOURS$ Stunde(n) und $MINUTES$ Minute(n) festgelegt.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Deine Organisation hat das Standard-Sitzungs-Timeout auf \"Sofort\" gesetzt." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Deine Organisation hat das Standard-Sitzungs-Timeout auf \"Wenn System gesperrt\" gesetzt." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Deine Organisation hat das Standard-Sitzungs-Timeout auf \"Bei Neustart des Browsers\" gesetzt." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Das maximale Timeout darf $HOURS$ Stunde(n) und $MINUTES$ Minute(n) nicht überschreiten", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Bei Neustart des Browsers" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Stell eine Entsperrmethode ein, um deine Timeout-Aktion zu ändern" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Bist du sicher, dass du gehen willst?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Wenn du ablehnst, bleiben deine persönlichen Einträge in deinem Konto erhalten, aber du wirst den Zugriff auf geteilte Einträge und Organisationsfunktionen verlieren." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Kontaktiere deinen Administrator, um wieder Zugriff zu erhalten." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "$ORGANIZATION$ verlassen", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Wie kann ich meinen Tresor verwalten?" + }, + "transferItemsToOrganizationTitle": { + "message": "Einträge zu $ORGANIZATION$ übertragen", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ erfordert zur Sicherheit und Compliance, dass alle Einträge der Organisation gehören. Klicke auf Akzeptieren, um den Besitz deiner Einträge zu übertragen.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Übertragung annehmen" + }, + "declineAndLeave": { + "message": "Ablehnen und verlassen" + }, + "whyAmISeeingThis": { + "message": "Warum wird mir das angezeigt?" } } diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index 476a6165a8e..29593380dd9 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Συγχρονισμός" }, - "syncVaultNow": { - "message": "Συγχρονισμός θησαυ/κιου τώρα" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Τελευταίος συγχρονισμός:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Διαδικτυακή εφαρμογή Bitwarden" }, - "importItems": { - "message": "Εισαγωγή στοιχείων" - }, "select": { "message": "Επιλογή" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Εξαγωγή από" }, - "exportVault": { - "message": "Εξαγωγή Vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Τύπος αρχείου" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Μάθετε περισσότερα" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Κλειδί επαλήθευσης (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Το συνημμένο αποθηκεύτηκε" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Αρχείο" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Επιλέξτε αρχείο" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Το μέγιστο μέγεθος αρχείου είναι 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB κρυπτογραφημένο αποθηκευτικό χώρο για συνημμένα αρχεία." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Πρόσβαση έκτακτης ανάγκης." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Δε βρέθηκε μοναδικό αναγνωριστικό." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Όνομα οργανισμού" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Παράβλεψη" }, - "importData": { - "message": "Εισαγωγή δεδομένων", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Σφάλμα εισαγωγής" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Ασφάλεια λογαριασμού" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Ειδοποιήσεις" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 6a7df1678bf..2b103555604 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sync" }, - "syncVaultNow": { - "message": "Sync vault now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Last sync:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import items" - }, "select": { "message": "Select" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Select a file" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -3219,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4185,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4775,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5827,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5858,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector":{ + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified":{ + "message": "Organization verified" + }, + "domainVerified":{ + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index 103d45f0685..f64bf387a5e 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sync" }, - "syncVaultNow": { - "message": "Sync vault now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Last sync:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import items" - }, "select": { "message": "Select" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Select a file" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access" }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organisation. Please confirm the domain below with your organisation administrator." - }, "organizationName": { "message": "Organisation name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organisation is no longer using master passwords to log into Bitwarden. To continue, verify the organisation and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organisation to log in" + }, + "organizationVerified": { + "message": "Organisation verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organisation, your access to the organisation will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organisation and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organisation." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organisation has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organisation has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organisation has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organisation has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organisation features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organisation for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index 2713381986c..34f2f0b1105 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sync" }, - "syncVaultNow": { - "message": "Sync vault now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Last sync:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import items" - }, "select": { "message": "Select" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "The attachment has been saved." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Select a file." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access" }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organisation. Please confirm the domain below with your organisation administrator." - }, "organizationName": { "message": "Organisation name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organisation is no longer using master passwords to log into Bitwarden. To continue, verify the organisation and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organisation to log in" + }, + "organizationVerified": { + "message": "Organisation verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organisation, your access to the organisation will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organisation and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organisation." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organisation has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organisation has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organisation has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organisation has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organisation features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organisation for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index e19bd11ba28..276d0dbedb2 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sincronizar" }, - "syncVaultNow": { - "message": "Sincronizar caja fuerte" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Última sincronización:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Aplicación web de Bitwarden" }, - "importItems": { - "message": "Importar elementos" - }, "select": { "message": "Seleccionar" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Exportar desde" }, - "exportVault": { - "message": "Exportar caja fuerte" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formato de archivo" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Más información" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Clave de autenticación (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "El adjunto se ha guardado." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Archivo" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Selecciona un archivo." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "El tamaño máximo de archivo es de 500MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB de espacio cifrado en disco para adjuntos." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Acceso de emergencia." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Identificador único no encontrado." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Ya no es necesaria una contraseña maestra para los miembros de la siguiente organización. Confirma el dominio que aparece a continuación con el administrador de tu organización." - }, "organizationName": { "message": "Nombre de la organización" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignorar" }, - "importData": { - "message": "Importar datos", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Error al importar" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Seguridad de la cuenta" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notificaciones" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index 7a9737f71ff..3efb771966d 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sünkroniseeri" }, - "syncVaultNow": { - "message": "Sünkroniseeri hoidla" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Viimane sünkronisatsioon:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwardeni veebirakendus" }, - "importItems": { - "message": "Impordi andmed" - }, "select": { "message": "Vali" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Ekspordi hoidla" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Failivorming" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Loe edasi" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Autentimise võti (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Manus on salvestatud." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Fail" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Vali fail." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maksimaalne faili suurus on 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB ulatuses krüpteeritud salvestusruum." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Unikaalset identifikaatorit ei leitud." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index b61213da989..d8f8c5230c6 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sinkronizatu" }, - "syncVaultNow": { - "message": "Sinkronizatu kutxa gotorra orain" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Azken sinkronizazioa:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Inportatu elementuak" - }, "select": { "message": "Hautatu" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Esportatu kutxa gotorra" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Fitxategiaren formatua" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Gehiago ikasi" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Autentifikazio-gakoa (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Eranskina gorde da." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Fitxategia" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Hautatu fitxategia." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Eranskinaren gehienezko tamaina 500MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "Eranskinentzako 1GB-eko zifratutako biltegia." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Ez da identifikatzaile bakarrik aurkitu." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ezikusi" }, - "importData": { - "message": "Inportatu datuak", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Errorea inportatzerakoan" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index 550de006cf6..c264b292761 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "همگام‌سازی" }, - "syncVaultNow": { - "message": "همگام‌سازی گاوصندوق" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "آخرین همگام‌سازی:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "برنامه وب Bitwarden" }, - "importItems": { - "message": "درون ریزی موارد" - }, "select": { "message": "انتخاب" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "برون ریزی از" }, - "exportVault": { - "message": "برون ریزی گاوصندوق" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "فرمت پرونده" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "بیشتر بدانید" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "کلید احراز هویت (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "پیوست ذخیره شد" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "پرونده" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "ﺍﻧﺘﺨﺎﺏ یک ﭘﺮﻭﻧﺪﻩ" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "بیشترین حجم پرونده ۵۰۰ مگابایت است." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "۱ گیگابایت فضای ذخیره‌سازی رمزگذاری شده برای پیوست‌های پرونده." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "دسترسی اضطراری." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "شناسه منحصر به فردی یافت نشد." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "برای اعضای سازمان زیر، کلمه عبور اصلی دیگر لازم نیست. لطفاً دامنه زیر را با مدیر سازمان خود تأیید کنید." - }, "organizationName": { "message": "نام سازمان" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "نادیده گرفتن" }, - "importData": { - "message": "وارد کردن اطلاعات", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "خطای درون ریزی" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "امنیت حساب کاربری" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "اعلان‌ها" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index bdf2ebd641c..38003bb31b2 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Synkronointi" }, - "syncVaultNow": { - "message": "Synkronoi holvi nyt" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Viimeisin synkronointi:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden Verkkosovellus" }, - "importItems": { - "message": "Tuo kohteita" - }, "select": { "message": "Valitse" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Vie lähteestä" }, - "exportVault": { - "message": "Vie holvi" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Tiedostomuoto" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Lue lisää" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Todennusavain (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Tiedostoliite tallennettiin" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Tiedosto" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Valitse tiedosto." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Tiedoston enimmäiskoko on 500 Mt." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 Gt salattua tallennustilaa tiedostoliitteille." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Varmuuskäyttö" }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Yksilöllistä tunnistetta ei löytynyt." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Pääsalasanaa ei enää tarvita tämän organisaation jäsenille. Ole hyvä ja vahvista alla oleva verkkotunnus organisaation ylläpitäjän kanssa." - }, "organizationName": { "message": "Organisaation nimi" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ohita" }, - "importData": { - "message": "Tuo tietoja", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Tuontivirhe" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Tilin suojaus" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Ilmoitukset" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Kortin numero" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index 31284265b2e..38702b940c4 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Ikintal" }, - "syncVaultNow": { - "message": "Isingit ang Vault ngayon" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Huling sinkronisasyon:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Isingit ang Vault ngayon" - }, "select": { "message": "Piliin" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "I-export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format ng file" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Matuto nang higit pa" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Susi ng Authenticator (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment na nai-save" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Mag-file" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Pumili ng File" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum na laki ng file ay 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage para sa mga file attachment." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Walang natagpuang natatanging nag-identipikar." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index dadcd0c041e..afc71011900 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Synchronisation" }, - "syncVaultNow": { - "message": "Synchroniser le coffre maintenant" + "syncNow": { + "message": "Synchroniser maintenant" }, "lastSync": { "message": "Dernière synchronisation :" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Application web Bitwarden" }, - "importItems": { - "message": "Importer des éléments" - }, "select": { "message": "Sélectionner" }, @@ -586,7 +583,7 @@ "message": "Les éléments archivés sont exclus des résultats de recherche généraux et des suggestions de remplissage automatique. Êtes-vous sûr de vouloir archiver cet élément ?" }, "upgradeToUseArchive": { - "message": "A premium membership is required to use Archive." + "message": "Une adhésion premium est requise pour utiliser Archive." }, "edit": { "message": "Modifier" @@ -598,7 +595,7 @@ "message": "Tout afficher" }, "showAll": { - "message": "Show all" + "message": "Tout afficher" }, "viewLess": { "message": "Afficher moins" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Exporter à partir de" }, - "exportVault": { - "message": "Exporter le coffre" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format de fichier" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "En savoir plus" }, + "migrationsFailed": { + "message": "Une erreur s'est produite lors de la mise à jour des paramètres de chiffrement." + }, + "updateEncryptionSettingsTitle": { + "message": "Mettre à jour vos paramètres de chiffrement" + }, + "updateEncryptionSettingsDesc": { + "message": "Les nouveaux paramètres de chiffrement recommandés amélioreront la sécurité de votre compte. Entrez votre mot de passe principal pour faire la mise à jour maintenant." + }, + "confirmIdentityToContinue": { + "message": "Confirmez votre identité pour continuer" + }, + "enterYourMasterPassword": { + "message": "Entrez votre mot de passe principal" + }, + "updateSettings": { + "message": "Mettre à jour les paramètres" + }, + "later": { + "message": "Plus tard" + }, "authenticatorKeyTotp": { "message": "Clé Authenticator (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "La pièce jointe a été enregistrée." }, + "fixEncryption": { + "message": "Corriger le chiffrement" + }, + "fixEncryptionTooltip": { + "message": "Ce fichier utilise une méthode de chiffrement obsolète." + }, + "attachmentUpdated": { + "message": "Pièce jointe mise à jour" + }, "file": { "message": "Fichier" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Sélectionnez un fichier." }, + "itemsTransferred": { + "message": "Éléments transférés" + }, "maxFileSize": { "message": "La taille maximale du fichier est de 500 Mo." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 Go de stockage chiffré pour les fichiers joints." }, + "premiumSignUpStorageV2": { + "message": "Stockage chiffré de $SIZE$ pour les pièces jointes.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Accès d'urgence." }, @@ -1874,7 +1926,7 @@ "message": "Année d'expiration" }, "monthly": { - "message": "month" + "message": "mois" }, "expiration": { "message": "Expiration" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Aucun identifiant unique trouvé." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Un mot de passe principal n’est plus requis pour les membres de l’organisation suivante. Veuillez confirmer le domaine ci-dessous auprès de l'administrateur de votre organisation." - }, "organizationName": { "message": "Nom de l'organisation" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignorer" }, - "importData": { - "message": "Importer des données", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Erreur lors de l'importation" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Sécurité du compte" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,17 +5872,17 @@ "andMoreFeatures": { "message": "Et encore plus !" }, - "planDescPremium": { - "message": "Sécurité en ligne complète" + "advancedOnlineSecurity": { + "message": "Sécurité en ligne avancée" }, "upgradeToPremium": { "message": "Mettre à niveau vers Premium" }, "unlockAdvancedSecurity": { - "message": "Unlock advanced security features" + "message": "Débloquer les fonctionnalités de sécurité avancées" }, "unlockAdvancedSecurityDesc": { - "message": "A Premium subscription gives you more tools to stay secure and in control" + "message": "Un abonnement Premium vous donne plus d'outils pour rester en sécurité et en contrôle" }, "explorePremium": { "message": "Explorer Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Numéro de carte" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Votre organisation n'utilise plus les mots de passe principaux pour se connecter à Bitwarden. Pour continuer, vérifiez l'organisation et le domaine." + }, + "continueWithLogIn": { + "message": "Continuer avec la connexion" + }, + "doNotContinue": { + "message": "Ne pas continuer" + }, + "domain": { + "message": "Domaine" + }, + "keyConnectorDomainTooltip": { + "message": "Ce domaine stockera les clés de chiffrement de votre compte, alors assurez-vous que vous lui faites confiance. Si vous n'êtes pas sûr, vérifiez auprès de votre administrateur." + }, + "verifyYourOrganization": { + "message": "Vérifiez votre organisation pour vous connecter" + }, + "organizationVerified": { + "message": "Organisation vérifiée" + }, + "domainVerified": { + "message": "Domaine vérifié" + }, + "leaveOrganizationContent": { + "message": "Si vous ne vérifiez pas votre organisation, votre accès à l'organisation sera révoqué." + }, + "leaveNow": { + "message": "Quitter maintenant" + }, + "verifyYourDomainToLogin": { + "message": "Vérifiez votre domaine pour vous connecter" + }, + "verifyYourDomainDescription": { + "message": "Pour continuer à vous connecter, vérifiez ce domaine." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Pour continuer à vous connecter, vérifiez l'organisation et le domaine." + }, "sessionTimeoutSettingsAction": { "message": "Action à l’expiration" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Ce paramètre est géré par votre organisation." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Votre organisation a réglé le délai d'expiration de session maximal à $HOURS$ heure(s) et $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Votre organisation a défini le délai d'expiration de session par défaut sur Immédiat." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Votre organisation a défini le délai d'expiration de session par défaut sur Au verrouillage du système." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Votre organisation a défini le délai d'expiration de session par défaut sur Au redémarrage du navigateur." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Le délai d'expiration de session maximal ne peut pas dépasser $HOURS$ heure(s) et $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Au redémarrage du navigateur" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Configurez une méthode de déverrouillage pour changer le délai d'expiration de votre coffre" + }, + "upgrade": { + "message": "Mettre à jour" + }, + "leaveConfirmationDialogTitle": { + "message": "Êtes-vous sûr de vouloir quitter ?" + }, + "leaveConfirmationDialogContentOne": { + "message": "En refusant, vos éléments personnels resteront dans votre compte, mais vous perdrez l'accès aux éléments partagés et aux fonctionnalités de l'organisation." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contactez votre administrateur pour regagner l'accès." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Quitter $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Comment gérer mon coffre ?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transférer les éléments vers $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ exige que tous les éléments soient détenus par l’organisation pour des raisons de sécurité et de conformité. Cliquez sur Accepter pour transférer la propriété de vos éléments.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index bd657b9d4b7..7bfe70bded5 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sincronizar" }, - "syncVaultNow": { - "message": "Sincronizar caixa forte agora" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Última sincronización:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Aplicación web de Bitwarden" }, - "importItems": { - "message": "Importar entradas" - }, "select": { "message": "Seleccionar" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Exportar dende" }, - "exportVault": { - "message": "Exportar caixa forte" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formato de ficheiro" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Máis información" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Clave de autenticación (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Anexo gardado" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Arquivo" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Selecciona un arquivo" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "O tamaño máximo é de 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB de almacenamento cifrado para arquivos anexos." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Acceso de emerxencia." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Non se atopou ningún identificador único." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignorar" }, - "importData": { - "message": "Importar datos", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Erro ó importar" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Seguridade da conta" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notificacións" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index 2e9243206b9..fd4e010ce60 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "סנכרן" }, - "syncVaultNow": { - "message": "סנכרן את הכספת עכשיו" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "סנכרון אחרון:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "יישום הרשת של Bitwarden" }, - "importItems": { - "message": "ייבא פריטים" - }, "select": { "message": "בחר" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "ייצא מ־" }, - "exportVault": { - "message": "ייצא כספת" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "פורמט הקובץ" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "למידע נוסף" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "מפתח מאמת (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "הצרופה נשמרה" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "קובץ" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "בחר קובץ" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "גודל הקובץ המרבי הוא 500MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 ג'יגה של מקום אחסון עבור קבצים מצורפים." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "גישת חירום." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "לא נמצא מזהה ייחודי." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "סיסמה ראשית אינה נדרשת עוד עבור חברים בארגון הבא. נא לאשר את הדומיין שלהלן עם מנהל הארגון שלך." - }, "organizationName": { "message": "שם הארגון" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "התעלם" }, - "importData": { - "message": "ייבא נתונים", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "שגיאת ייבוא" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "אבטחת החשבון" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "התראות" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "ועוד!" }, - "planDescPremium": { - "message": "השלם אבטחה מקוונת" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "שדרג לפרימיום" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "מספר כרטיס" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "פעולת פסק זמן" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 58db7ac8ad6..dc91aa89197 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "सिंक" }, - "syncVaultNow": { - "message": "Sync Vault Now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Last Sync:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import Items" - }, "select": { "message": "चयन करें" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export Vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File Format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "अधिक जानें" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator Key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "अटैचमेंट बच गया है।" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "फ़ाइल" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "फ़ाइल का चयन करें।" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "अधिकतम फाइल आकार 500 MB है।" }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB of encrypted file storage." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "उन्नत ऑनलाइन सुरक्षा" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index 8a5a09aec9c..c472bfa50cd 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sinkronizacija" }, - "syncVaultNow": { - "message": "Odmah sinkroniziraj trezor" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Posljednja sinkronizacija:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web trezor" }, - "importItems": { - "message": "Uvoz stavki" - }, "select": { "message": "Odaberi" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Izvezi iz" }, - "exportVault": { - "message": "Izvezi trezor" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format datoteke" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Saznaj više" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Ključ autentifikatora (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Privitak spremljen" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Datoteka" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Odaberi datoteku." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Najveća veličina datoteke je 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB šifriranog prostora za pohranu podataka." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Pristup u nuždi." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Nije nađen jedinstveni identifikator." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Glavna lozinka više nije obavezna za članove sljedeće organizacije. Provjeri prikazanu domenu sa svojim administratorom." - }, "organizationName": { "message": "Naziv Organizacije" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Zanemari" }, - "importData": { - "message": "Uvezi podatke", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Greška prilikom uvoza" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Sigurnost računa" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Obavijesti" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "I više!" }, - "planDescPremium": { - "message": "Dovrši online sigurnost" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": " Nadogradi na Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Broj kartice" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Radnja kod isteka" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index bacda584ba1..438c574bba9 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Szinkronizálás" }, - "syncVaultNow": { - "message": "Széf szinkronizálása most" + "syncNow": { + "message": "Szinkronizálás most" }, "lastSync": { "message": "Utolsó szinkronizálás:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden webes alkalmazás" }, - "importItems": { - "message": "Elemek importálása" - }, "select": { "message": "Kiválaszt" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Exportálás innen:" }, - "exportVault": { - "message": "Széf exportálása" + "exportVerb": { + "message": "Exportálás", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Exportálás", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Importálás", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importálás", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Fájlformátum" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Tudjon meg többet" }, + "migrationsFailed": { + "message": "Hiba történt a titkosítási beállítások frissítésekor." + }, + "updateEncryptionSettingsTitle": { + "message": "A titkosítási beállítások frissítése" + }, + "updateEncryptionSettingsDesc": { + "message": "Az új ajánlott titkosítási beállítások javítják a fiók biztonságát. Adjuk meg a mesterjelszót a frissítéshez most." + }, + "confirmIdentityToContinue": { + "message": "A folytatáshoz meg kell erősíteni a személyazonosságot." + }, + "enterYourMasterPassword": { + "message": "Mesterjelszó megadása" + }, + "updateSettings": { + "message": "Beállítások frissítése" + }, + "later": { + "message": "Később" + }, "authenticatorKeyTotp": { "message": "Hitelesítő kulcs (egyszeri időalapú)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "A melléklet mentésre került." }, + "fixEncryption": { + "message": "Titkosítás javítása" + }, + "fixEncryptionTooltip": { + "message": "Ez a fájl elavult titkosítási módszert használ." + }, + "attachmentUpdated": { + "message": "A melléklet frissítésre került." + }, "file": { "message": "Fájl" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Válasszunk egy fájlt." }, + "itemsTransferred": { + "message": "Az elemek átvitelre kerültek." + }, "maxFileSize": { "message": "A naximális fájlméret 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB titkosított tárhely a fájlmellékleteknek." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ titkosított tárhely a fájlmellékletekhez.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Sürgősségi hozzáférés" }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Nincs egyedi azonosító." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A következő szervezet tagjai számára már nincs szükség mesterjelszóra. Erősítsük meg az alábbi tartományt a szervezet adminisztrátorával." - }, "organizationName": { "message": "Szervezet neve" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Mellőz" }, - "importData": { - "message": "Adatok importálása", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Importálási hiba" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Fiókbiztonság" }, + "phishingBlocker": { + "message": "Adathalászat blokkoló" + }, + "enablePhishingDetection": { + "message": "Adathalászat érzékelés" + }, + "enablePhishingDetectionDesc": { + "message": "Figyelmeztetés megjelenítése a gyanús adathalász webhelyek elérése előtt." + }, "notifications": { "message": "Értesítések" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "És még több!" }, - "planDescPremium": { - "message": "Teljes körű online biztonság" + "advancedOnlineSecurity": { + "message": "Bővített online biztonság" }, "upgradeToPremium": { "message": "Áttérés Prémium csomagra" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Kártya szám" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "A szervezet már nem használ mesterjelszavakat a Bitwardenbe bejelentkezéshez. A folytatáshoz ellenőrizzük a szervezetet és a tartományt." + }, + "continueWithLogIn": { + "message": "Folytatás bejelentkezéssel" + }, + "doNotContinue": { + "message": "Nincs folytatás" + }, + "domain": { + "message": "Tartomány" + }, + "keyConnectorDomainTooltip": { + "message": "Ez a tartomány tárolja a fiók titkosítási kulcsait, ezért győződjünk meg róla, hogy megbízunk-e benne. Ha nem vagyunk biztos benne, érdeklődjünk adminisztrátornál." + }, + "verifyYourOrganization": { + "message": "Szervezet ellenőrzése a bejelentkezéshez" + }, + "organizationVerified": { + "message": "A szervezet ellenőrzésre került." + }, + "domainVerified": { + "message": "A tartomány ellenőrzésre került." + }, + "leaveOrganizationContent": { + "message": "Ha nem ellenőrizzük a szervezetet, a szervezethez hozzáférés visszavonásra kerül." + }, + "leaveNow": { + "message": "Elhagyás most" + }, + "verifyYourDomainToLogin": { + "message": "Tartomány ellenőrzése a bejelentkezéshez" + }, + "verifyYourDomainDescription": { + "message": "A bejelentkezés folytatásához ellenőrizzük ezt a tartományt." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "A bejelentkezés folytatásához ellenőrizzük a szervezetet és a tartományt." + }, "sessionTimeoutSettingsAction": { "message": "Időkifutási művelet" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Ezt a beállítást a szervezet lezeli." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "A szervezet a munkamenet maximális munkamenet időkifutását $HOURS$ órára és $MINUTES$ percre állította be.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "A szervezet az alapértelmezett munkamenet időkifutást Azonnal értékre állította." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "A szervezet az alapértelmezett munkamenet időkifutástr Rendszerzár be értékre állította." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "A szervezet az alapértelmezett munkamenet időkifutást a Böngésző újraindításakor értékre állította." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "A maximális időtúllépés nem haladhatja meg a $HOURS$ óra és $MINUTES$ perc értéket.", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Böngésző újraindításkor" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Állítsunk be egy feloldási módot a széf időkifutási műveletének módosításához." + }, + "upgrade": { + "message": "Áttérés" + }, + "leaveConfirmationDialogTitle": { + "message": "Biztosan szeretnénk kilépni?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Az elutasítással a személyes elemek a fiókban maradnak, de elveszítjük hozzáférést a megosztott elemekhez és a szervezeti funkciókhoz." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Lépjünk kapcsolatba az adminisztrátorral a hozzáférés visszaszerzéséért." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "$ORGANIZATION$ elhagyása", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Hogyan kezeljem a széfet?" + }, + "transferItemsToOrganizationTitle": { + "message": "Elemek átvitele $ORGANIZATION$ szervezethez", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ megköveteli, hogy minden elem a szervezet tulajdonában legyen a biztonság és a megfelelőség érdekében. Kattintás az elfogadásra az elemek tulajdonjogának átruházásához.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Átvitel elfogadása" + }, + "declineAndLeave": { + "message": "Elutasítás és kilépés" + }, + "whyAmISeeingThis": { + "message": "Miért látható ez?" } } diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index 88147f804d1..4d636a5a79d 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sinkronisasi" }, - "syncVaultNow": { - "message": "Sinkronkan Brankas Sekarang" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Sinkronisasi Terakhir:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Aplikasi web Bitwarden" }, - "importItems": { - "message": "Impor Item" - }, "select": { "message": "Pilih" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Ekspor dari" }, - "exportVault": { - "message": "Ekspor Brankas" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format Berkas" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Pelajari lebih lanjut" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Kunci Otentikasi (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Lampiran telah disimpan." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Berkas" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Pilih berkas." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Ukuran berkas maksimal adalah 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB penyimpanan berkas yang dienkripsi." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Akses darurat." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Tidak ada pengidentifikasi unik yang ditemukan." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Sebuah kata sandi utama tidak lagi dibutuhkan untuk para anggota dari organisasi berikut. Silakan konfirmasi domain berikut kepada pengelola organisasi Anda." - }, "organizationName": { "message": "Nama organisasi" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Abaikan" }, - "importData": { - "message": "Impor data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Kesalahan impor" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Keamanan akun" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Pemberitahuan" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index d4d032737b8..2615640df0a 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -35,7 +35,7 @@ "message": "La tua organizzazione richiede un accesso Single Sign-On (SSO)." }, "welcomeBack": { - "message": "Bentornato/a" + "message": "Bentornato" }, "setAStrongPassword": { "message": "Imposta una password robusta" @@ -436,8 +436,8 @@ "sync": { "message": "Sincronizza" }, - "syncVaultNow": { - "message": "Sincronizza cassaforte ora" + "syncNow": { + "message": "Sincronizza" }, "lastSync": { "message": "Ultima sincronizzazione:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Importa elementi" - }, "select": { "message": "Seleziona" }, @@ -586,7 +583,7 @@ "message": "Gli elementi archiviati sono esclusi dai risultati di ricerca e suggerimenti di autoriempimento. Vuoi davvero archiviare questo elemento?" }, "upgradeToUseArchive": { - "message": "A premium membership is required to use Archive." + "message": "Per utilizzare Archivio è necessario un abbonamento premium." }, "edit": { "message": "Modifica" @@ -598,7 +595,7 @@ "message": "Mostra tutto" }, "showAll": { - "message": "Show all" + "message": "Mostra tutto" }, "viewLess": { "message": "Vedi meno" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Esporta da" }, - "exportVault": { - "message": "Esporta cassaforte" + "exportVerb": { + "message": "Esporta", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Esporta", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Importa", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importa", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formato file" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Ulteriori informazioni" }, + "migrationsFailed": { + "message": "Si è verificato un errore durante l'aggiornamento delle impostazioni di cifratura." + }, + "updateEncryptionSettingsTitle": { + "message": "Aggiorna le impostazioni di crittografia" + }, + "updateEncryptionSettingsDesc": { + "message": "Le nuove impostazioni di crittografia consigliate miglioreranno la sicurezza del tuo account. Inserisci la tua password principale per aggiornare." + }, + "confirmIdentityToContinue": { + "message": "Conferma la tua identità per continuare" + }, + "enterYourMasterPassword": { + "message": "Inserisci la tua password principale" + }, + "updateSettings": { + "message": "Aggiorna impostazioni" + }, + "later": { + "message": "Più tardi" + }, "authenticatorKeyTotp": { "message": "Chiave di autenticazione (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Allegato salvato" }, + "fixEncryption": { + "message": "Correggi la crittografia" + }, + "fixEncryptionTooltip": { + "message": "Questo file usa un metodo di crittografia obsoleto." + }, + "attachmentUpdated": { + "message": "Allegato aggiornato" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Seleziona un file" }, + "itemsTransferred": { + "message": "Elementi trasferiti" + }, "maxFileSize": { "message": "La dimensione massima del file è 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB di spazio di archiviazione crittografato per gli allegati." }, + "premiumSignUpStorageV2": { + "message": "Archivio crittografato di $SIZE$ per allegati.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Accesso di emergenza." }, @@ -1874,7 +1926,7 @@ "message": "Anno di scadenza" }, "monthly": { - "message": "month" + "message": "mese" }, "expiration": { "message": "Scadenza" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Nessun identificatore univoco trovato." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "La password principale non è più richiesta per i membri dell'organizzazione. Per favore, conferma il dominio qui sotto con l'amministratore." - }, "organizationName": { "message": "Nome organizzazione" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignora" }, - "importData": { - "message": "Importa dati", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Errore di importazione" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Sicurezza dell'account" }, + "phishingBlocker": { + "message": "Blocco phishing" + }, + "enablePhishingDetection": { + "message": "Rilevazione phishing" + }, + "enablePhishingDetectionDesc": { + "message": "Mostra un avviso prima di accedere ai siti sospetti di phishing" + }, "notifications": { "message": "Notifiche" }, @@ -5818,17 +5872,17 @@ "andMoreFeatures": { "message": "E molto altro!" }, - "planDescPremium": { - "message": "Sicurezza online completa" + "advancedOnlineSecurity": { + "message": "Sicurezza online avanzata" }, "upgradeToPremium": { "message": "Aggiorna a Premium" }, "unlockAdvancedSecurity": { - "message": "Unlock advanced security features" + "message": "Sblocca funzionalità di sicurezza avanzate" }, "unlockAdvancedSecurityDesc": { - "message": "A Premium subscription gives you more tools to stay secure and in control" + "message": "Un abbonamento Premium ti offre più strumenti per rimanere sicuro e in controllo" }, "explorePremium": { "message": "Scopri Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Numero di carta" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "La tua organizzazione non utilizza più le password principali per accedere a Bitwarden. Per continuare, verifica l'organizzazione e il dominio." + }, + "continueWithLogIn": { + "message": "Accedi e continua" + }, + "doNotContinue": { + "message": "Non continuare" + }, + "domain": { + "message": "Dominio" + }, + "keyConnectorDomainTooltip": { + "message": "Questo dominio memorizzerà le chiavi di crittografia del tuo account, quindi assicurati di impostarlo come affidabile. Se non hai la certezza che lo sia, verifica con l'amministratore." + }, + "verifyYourOrganization": { + "message": "Verifica la tua organizzazione per accedere" + }, + "organizationVerified": { + "message": "Organizzazione verificata" + }, + "domainVerified": { + "message": "Dominio verificato" + }, + "leaveOrganizationContent": { + "message": "Se non verifichi l'organizzazione, il tuo accesso sarà revocato." + }, + "leaveNow": { + "message": "Abbandona" + }, + "verifyYourDomainToLogin": { + "message": "Verifica il tuo dominio per accedere" + }, + "verifyYourDomainDescription": { + "message": "Per continuare con l'accesso, verifica questo dominio." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Per continuare con l'accesso, verifica l'organizzazione e il dominio." + }, "sessionTimeoutSettingsAction": { "message": "Azione al timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Questa impostazione è gestita dalla tua organizzazione." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "La tua organizzazione ha impostato $HOURS$ ora/e e $MINUTES$ minuto/i come durata massima della sessione.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "In base alle impostazioni della tua organizzazione, la sessione terminerà immediatamente." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "In base alle impostazioni della tua organizzazione, la sessione terminerà al blocco del dispositivo." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "In base alle impostazioni della tua organizzazione, la sessione terminerà ogni volta che la pagina sarà chiusa o ricaricata." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "La durata della sessione non può superare $HOURS$ ora/e e $MINUTES$ minuto/i", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Al riavvio del browser" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Imposta un metodo di sblocco per modificare l'azione al timeout" + }, + "upgrade": { + "message": "Aggiorna" + }, + "leaveConfirmationDialogTitle": { + "message": "Vuoi davvero abbandonare?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Se rifiuti, tutti gli elementi esistenti resteranno nel tuo account, ma perderai l'accesso agli oggetti condivisi e alle funzioni organizzative." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contatta il tuo amministratore per recuperare l'accesso." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Abbandona $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Come si gestisce la cassaforte?" + }, + "transferItemsToOrganizationTitle": { + "message": "Trasferisci gli elementi in $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ richiede che tutti gli elementi siano di proprietà dell'organizzazione per motivi di conformità e sicurezza. Clicca su 'Accetta' per trasferire la proprietà.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accetta il trasferimento" + }, + "declineAndLeave": { + "message": "Rifiuta e abbandona" + }, + "whyAmISeeingThis": { + "message": "Perché vedo questo avviso?" } } diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index c13b139e13a..91c006fccca 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "同期" }, - "syncVaultNow": { - "message": "保管庫を同期する" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "前回の同期:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden ウェブアプリ" }, - "importItems": { - "message": "アイテムのインポート" - }, "select": { "message": "選択" }, @@ -551,7 +548,7 @@ "message": "保管庫を検索" }, "resetSearch": { - "message": "Reset search" + "message": "検索をリセット" }, "archiveNoun": { "message": "アーカイブ", @@ -565,28 +562,28 @@ "message": "アーカイブ解除" }, "itemsInArchive": { - "message": "Items in archive" + "message": "アーカイブ済みのアイテム" }, "noItemsInArchive": { - "message": "No items in archive" + "message": "アーカイブにアイテムがありません" }, "noItemsInArchiveDesc": { - "message": "Archived items will appear here and will be excluded from general search results and autofill suggestions." + "message": "アーカイブされたアイテムはここに表示され、通常の検索結果および自動入力の候補から除外されます。" }, "itemWasSentToArchive": { - "message": "Item was sent to archive" + "message": "アイテムはアーカイブに送信されました" }, "itemUnarchived": { - "message": "Item was unarchived" + "message": "アイテムはアーカイブから解除されました" }, "archiveItem": { - "message": "Archive item" + "message": "アイテムをアーカイブ" }, "archiveItemConfirmDesc": { - "message": "Archived items are excluded from general search results and autofill suggestions. Are you sure you want to archive this item?" + "message": "アーカイブされたアイテムはここに表示され、通常の検索結果および自動入力の候補から除外されます。このアイテムをアーカイブしますか?" }, "upgradeToUseArchive": { - "message": "A premium membership is required to use Archive." + "message": "アーカイブを使用するにはプレミアムメンバーシップが必要です。" }, "edit": { "message": "編集" @@ -595,13 +592,13 @@ "message": "表示" }, "viewAll": { - "message": "View all" + "message": "すべて表示" }, "showAll": { - "message": "Show all" + "message": "すべて表示" }, "viewLess": { - "message": "View less" + "message": "表示を減らす" }, "viewLogin": { "message": "ログイン情報を表示" @@ -749,7 +746,7 @@ "message": "マスターパスワードが間違っています" }, "invalidMasterPasswordConfirmEmailAndHost": { - "message": "Invalid master password. Confirm your email is correct and your account was created on $HOST$.", + "message": "マスターパスワードが正しくありません。メールアドレスが正しく、アカウントが $HOST$ で作成されたことを確認してください。", "placeholders": { "host": { "content": "$1", @@ -806,10 +803,10 @@ "message": "ロック時" }, "onIdle": { - "message": "On system idle" + "message": "アイドル時" }, "onSleep": { - "message": "On system sleep" + "message": "スリープ時" }, "onRestart": { "message": "ブラウザ再起動時" @@ -955,7 +952,7 @@ "message": "以下の手順に従ってログインを完了してください。" }, "followTheStepsBelowToFinishLoggingInWithSecurityKey": { - "message": "Follow the steps below to finish logging in with your security key." + "message": "セキュリティキーでログインを完了するには、以下の手順に従ってください。" }, "restartRegistration": { "message": "登録を再度始める" @@ -1140,7 +1137,7 @@ "message": "このパスワードを Bitwarden に保存しますか?" }, "notificationAddSave": { - "message": "保存する" + "message": "保存" }, "notificationViewAria": { "message": "View $ITEMNAME$, opens in new window", @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "エクスポート元" }, - "exportVault": { - "message": "保管庫のエクスポート" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "ファイル形式" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "さらに詳しく" }, + "migrationsFailed": { + "message": "暗号化設定の更新中にエラーが発生しました。" + }, + "updateEncryptionSettingsTitle": { + "message": "暗号化設定を更新する" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "続行するには本人確認を行ってください" + }, + "enterYourMasterPassword": { + "message": "マスターパスワードを入力" + }, + "updateSettings": { + "message": "設定を更新" + }, + "later": { + "message": "後で" + }, "authenticatorKeyTotp": { "message": "認証キー (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "添付ファイルを保存しました。" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "ファイル" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "ファイルを選択してください。" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "最大ファイルサイズ: 500 MB" }, @@ -1452,7 +1495,7 @@ "message": "サービスが利用できません" }, "legacyEncryptionUnsupported": { - "message": "Legacy encryption is no longer supported. Please contact support to recover your account." + "message": "従来の暗号化はサポートされていません。アカウントを復元するにはサポートにお問い合わせください。" }, "premiumMembership": { "message": "プレミアム会員" @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1GB の暗号化されたファイルストレージ" }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ の暗号化されたファイルストレージ。", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "緊急アクセス" }, @@ -1710,16 +1762,16 @@ "message": "Confirm autofill" }, "confirmAutofillDesc": { - "message": "This site doesn't match your saved login details. Before you fill in your login credentials, make sure it's a trusted site." + "message": "このサイトは保存されたログイン情報と一致しません。ログイン情報を入力する前に、信頼できるサイトであることを確認してください。" }, "showInlineMenuLabel": { "message": "フォームフィールドに自動入力の候補を表示する" }, "howDoesBitwardenProtectFromPhishing": { - "message": "How does Bitwarden protect your data from phishing?" + "message": "Bitwarden はどのようにフィッシングからデータを保護しますか?" }, "currentWebsite": { - "message": "Current website" + "message": "現在のウェブサイト" }, "autofillAndAddWebsite": { "message": "Autofill and add this website" @@ -1874,7 +1926,7 @@ "message": "有効期限年" }, "monthly": { - "message": "month" + "message": "月" }, "expiration": { "message": "有効期限" @@ -2048,7 +2100,7 @@ "description": "Header for new text send" }, "newItemHeaderFileSend": { - "message": "New File Send", + "message": "新しい Send ファイル", "description": "Header for new file send" }, "editItemHeaderLogin": { @@ -2060,7 +2112,7 @@ "description": "Header for edit card item type" }, "editItemHeaderIdentity": { - "message": "Edit Identity", + "message": "ID を編集", "description": "Header for edit identity item type" }, "editItemHeaderNote": { @@ -2076,7 +2128,7 @@ "description": "Header for edit text send" }, "editItemHeaderFileSend": { - "message": "Edit File Send", + "message": "Send ファイルを編集", "description": "Header for edit file send" }, "viewItemHeaderLogin": { @@ -2088,7 +2140,7 @@ "description": "Header for view card item type" }, "viewItemHeaderIdentity": { - "message": "View Identity", + "message": "ID を表示", "description": "Header for view identity item type" }, "viewItemHeaderNote": { @@ -2222,7 +2274,7 @@ "message": "種類" }, "allItems": { - "message": "全てのアイテム" + "message": "すべてのアイテム" }, "noPasswordsInList": { "message": "表示するパスワードがありません" @@ -2304,7 +2356,7 @@ "message": "Bitwarden のロックを解除するための PIN コードを設定します。アプリから完全にログアウトすると、PIN 設定はリセットされます。" }, "setPinCode": { - "message": "You can use this PIN to unlock Bitwarden. Your PIN will be reset if you ever fully log out of the application." + "message": "Bitwarden のロックを解除するために PIN を使用使用することができます。アプリからログアウトすると PIN はリセットされます。" }, "pinRequired": { "message": "PIN コードが必要です。" @@ -2725,7 +2777,7 @@ } }, "atRiskChangePrompt": { - "message": "Your password for this site is at-risk. $ORGANIZATION$ has requested that you change it.", + "message": "このサイトのパスワードは危険です。$ORGANIZATION$ が変更を要求しています。", "placeholders": { "organization": { "content": "$1", @@ -3070,7 +3122,7 @@ "message": "この機能を使用するにはメールアドレスを確認する必要があります。ウェブ保管庫でメールアドレスを確認できます。" }, "masterPasswordSuccessfullySet": { - "message": "Master password successfully set" + "message": "マスターパスワードを設定しました" }, "updatedMasterPassword": { "message": "マスターパスワードを更新しました" @@ -3210,14 +3262,11 @@ "copyCustomFieldNameNotUnique": { "message": "一意の識別子が見つかりませんでした。" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "組織名" }, "keyConnectorDomain": { - "message": "Key Connector domain" + "message": "キーコネクタードメイン" }, "leaveOrganization": { "message": "組織から脱退する" @@ -3274,7 +3323,7 @@ } }, "exportingOrganizationVaultFromPasswordManagerWithDataOwnershipDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported.", + "message": "$ORGANIZATION$ に関連付けられた組織の保管庫のみがエクスポートされます。", "placeholders": { "organization": { "content": "$1", @@ -3298,7 +3347,7 @@ "message": "復号エラー" }, "errorGettingAutoFillData": { - "message": "Error getting autofill data" + "message": "自動入力データの取得に失敗しました" }, "couldNotDecryptVaultItemsBelow": { "message": "Bitwarden は以下の保管庫のアイテムを復号できませんでした。" @@ -3853,7 +3902,7 @@ "message": "ログインを完了できません" }, "loginOnTrustedDeviceOrAskAdminToAssignPassword": { - "message": "You need to log in on a trusted device or ask your administrator to assign you a password." + "message": "信頼できるデバイスにログインするか、管理者にパスワードの割り当てを依頼する必要があります。" }, "ssoIdentifierRequired": { "message": "組織の SSO ID が必要です。" @@ -3917,7 +3966,7 @@ "message": "信頼されたデバイス" }, "trustOrganization": { - "message": "Trust organization" + "message": "組織を信頼" }, "trust": { "message": "信頼する" @@ -3938,7 +3987,7 @@ "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." }, "trustUser": { - "message": "Trust user" + "message": "ユーザーを信頼" }, "sendsTitleNoItems": { "message": "機密情報を安全に送信", @@ -4176,10 +4225,6 @@ "ignore": { "message": "無視" }, - "importData": { - "message": "データのインポート", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "インポート エラー" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "アカウントのセキュリティ" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "通知" }, @@ -4888,7 +4942,7 @@ "message": "モバイルアプリを入手" }, "getTheMobileAppDesc": { - "message": "Access your passwords on the go with the Bitwarden mobile app." + "message": "Bitwarden モバイルアプリで外出先からでもパスワードにアクセスしましょう。" }, "getTheDesktopApp": { "message": "デスクトップアプリを入手" @@ -5275,7 +5329,7 @@ "message": "アカウントへのアクセスが要求されました" }, "confirmAccessAttempt": { - "message": "Confirm access attempt for $EMAIL$", + "message": "$EMAIL$ のログイン試行を確認", "placeholders": { "email": { "content": "$1", @@ -5662,16 +5716,16 @@ "message": "保管庫へようこそ!" }, "phishingPageTitleV2": { - "message": "Phishing attempt detected" + "message": "フィッシングの試行が検出されました" }, "phishingPageSummary": { - "message": "The site you are attempting to visit is a known malicious site and a security risk." + "message": "訪問しようとしているサイトは既知の悪意のあるサイトであり、セキュリティ上のリスクがあります。" }, "phishingPageCloseTabV2": { "message": "このタブを閉じる" }, "phishingPageContinueV2": { - "message": "Continue to this site (not recommended)" + "message": "このサイトに進む (非推奨)" }, "phishingPageExplanation1": { "message": "This site was found in ", @@ -5727,13 +5781,13 @@ "message": "With cards, easily autofill payment forms securely and accurately." }, "newIdentityNudgeTitle": { - "message": "Simplify creating accounts" + "message": "アカウント作成を簡素化" }, "newIdentityNudgeBody": { "message": "With identities, quickly autofill long registration or contact forms." }, "newNoteNudgeTitle": { - "message": "Keep your sensitive data safe" + "message": "機密データを安全に保管" }, "newNoteNudgeBody": { "message": "With notes, securely store sensitive data like banking or insurance details." @@ -5755,7 +5809,7 @@ "message": "パスワードをすばやく作成" }, "generatorNudgeBodyOne": { - "message": "Easily create strong and unique passwords by clicking on", + "message": "クリックすることで、強力でユニークなパスワードを簡単に作成できます", "description": "Two part message", "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." }, @@ -5778,7 +5832,7 @@ "message": "You do not have permissions to view this page. Try logging in with a different account." }, "wasmNotSupported": { - "message": "WebAssembly is not supported on your browser or is not enabled. WebAssembly is required to use the Bitwarden app.", + "message": "WebAssembly はお使いのブラウザでサポートされていないか、有効になっていません。WebAssembly は Bitwarden アプリを使用するために必要です。", "description": "'WebAssembly' is a technical term and should not be translated." }, "showMore": { @@ -5807,7 +5861,7 @@ "message": "認証機を内蔵" }, "secureFileStorage": { - "message": "Secure file storage" + "message": "セキュアなファイルストレージ" }, "emergencyAccess": { "message": "緊急アクセス" @@ -5816,10 +5870,10 @@ "message": "Breach monitoring" }, "andMoreFeatures": { - "message": "And more!" + "message": "などなど!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "プレミアムにアップグレード" @@ -5834,10 +5888,10 @@ "message": "Explore Premium" }, "loadingVault": { - "message": "Loading vault" + "message": "保管庫の読み込み中" }, "vaultLoaded": { - "message": "Vault loaded" + "message": "保管庫が読み込まれました" }, "settingDisabledByPolicy": { "message": "This setting is disabled by your organization's policy.", @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "カード番号" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { - "message": "Timeout action" + "message": "タイムアウト時のアクション" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index a54a0f2c657..85c2b04f469 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "სინქრონიზაცია" }, - "syncVaultNow": { - "message": "Sync vault now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "ბოლო სინქი:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import items" - }, "select": { "message": "არჩევა" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "გაიგეთ მეტი" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "ფაილი" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "აირჩიეთ ფაილი" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "იგნორი" }, - "importData": { - "message": "მონაცემების შემოტანა", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "შემოტანის შეცდომა" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "ანგარიშის უსაფრთხოება" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "გაფრთხილებები" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index f829937ac51..04386b72930 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sync" }, - "syncVaultNow": { - "message": "Sync vault now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Last sync:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import items" - }, "select": { "message": "Select" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Select a file" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index bd2be23828c..c29ecc2d04f 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "ಸಿಂಕ್" }, - "syncVaultNow": { - "message": "ವಾಲ್ಟ್ ಅನ್ನು ಈಗ ಸಿಂಕ್ ಮಾಡಿ" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "ಕೊನೆಯ ಸಿಂಕ್" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "ವಸ್ತುಗಳನ್ನು ಆಮದು ಮಾಡಿ" - }, "select": { "message": "ಆಯ್ಕೆಮಾಡಿ" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "ರಫ್ತು ವಾಲ್ಟ್" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "ಕಡತದ ಮಾದರಿ" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "ದೃಢೀಕರಣ ಕೀ (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "ಲಗತ್ತನ್ನು ಉಳಿಸಲಾಗಿದೆ." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "ಫೈಲ್" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "ಕಡತವನ್ನು ಆಯ್ಕೆಮಾಡು." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "ಗರಿಷ್ಠ ಫೈಲ್ ಗಾತ್ರ 500 ಎಂಬಿ." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "ಫೈಲ್ ಲಗತ್ತುಗಳಿಗಾಗಿ 1 ಜಿಬಿ ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಿದ ಸಂಗ್ರಹ." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index 1ad08accfc9..ccf3d96d366 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "동기화" }, - "syncVaultNow": { - "message": "지금 보관함 동기화" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "마지막 동기화:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden 웹 앱" }, - "importItems": { - "message": "항목 가져오기" - }, "select": { "message": "선택" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "~(으)로부터 내보내기" }, - "exportVault": { - "message": "보관함 내보내기" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "파일 형식" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "더 알아보기" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "인증 키 (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "첨부 파일을 저장했습니다." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "파일" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "파일을 선택하세요." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "최대 파일 크기는 500MB입니다." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1GB의 암호화된 파일 저장소." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "비상 접근" }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "고유 식별자를 찾을 수 없습니다." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "무시하기" }, - "importData": { - "message": "데이터 가져오기", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "가져오기 오류" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "계정 보안" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "알림" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index 46ffb24e3df..a1e3e287892 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sinchronizuoti" }, - "syncVaultNow": { - "message": "Sinchronizuoti saugyklą dabar" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Paskutinis sinchronizavimas:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden Interneto svetainė" }, - "importItems": { - "message": "Importuoti elementus" - }, "select": { "message": "Pasirinkti" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Eksportuoti saugyklą" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Failo formatas" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Sužinoti daugiau" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Vienkartinio autentifikavimo raktas (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Priedas išsaugotas" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Failas" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Pasirinkite failą." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Didžiausias failo dydis – 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB užšifruotos vietos diske bylų prisegimams." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Unikalus identifikatorius nerastas." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignoruoti" }, - "importData": { - "message": "Importuoti duomenis", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Importavimo klaida" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Paskyros saugumas" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Pranešimai" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 754781dc4f7..95e5d2399e6 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sinhronizēt" }, - "syncVaultNow": { - "message": "Sinhronizēt glabātavu" + "syncNow": { + "message": "Sinhronizēt tūlīt" }, "lastSync": { "message": "Pēdējā sinhronizēšana:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden tīmekļa lietotne" }, - "importItems": { - "message": "Ievietot vienumus" - }, "select": { "message": "Izvēlēties" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Izgūt no" }, - "exportVault": { - "message": "Izgūt glabātavas saturu" + "exportVerb": { + "message": "Izgūt", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Izgūšana", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Ievietošana", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Ievietot", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Datnes veids" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Uzzināt vairāk" }, + "migrationsFailed": { + "message": "Atgadījās kļūda šifrēšanas iestatījumu atjaunināšanā." + }, + "updateEncryptionSettingsTitle": { + "message": "Atjaunini savus šifrēšanas iestatījumus" + }, + "updateEncryptionSettingsDesc": { + "message": "Jaunie ieteicamie šifrēšanas iestatījumi uzlabos Tava konta drošību. Jāievada sava galvenā parole, lai atjauninātu tagad." + }, + "confirmIdentityToContinue": { + "message": "Jāapliecina sava identitāte, lai turpinātu" + }, + "enterYourMasterPassword": { + "message": "Jāievada sava galvenā parole" + }, + "updateSettings": { + "message": "Atjaunināt Iestatījumus" + }, + "later": { + "message": "Vēlāk" + }, "authenticatorKeyTotp": { "message": "Autentificētāja atslēga (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Pielikums tika saglabāts." }, + "fixEncryption": { + "message": "Salabot šifrēšanu" + }, + "fixEncryptionTooltip": { + "message": "Šī datne izmanto novecojušu šifrēšanas veidu." + }, + "attachmentUpdated": { + "message": "Pielikums atjaunināts" + }, "file": { "message": "Datne" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Atlasīt datni" }, + "itemsTransferred": { + "message": "Vienumi pārcelti" + }, "maxFileSize": { "message": "Lielākais pieļaujamais datnes izmērs ir 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB šifrētas krātuves datņu pielikumiem." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ šifrētas krātuves datņu pielikumiem.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Ārkārtas piekļuve" }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Nav atrasts neviens neatkārtojams identifikators" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Galvenā parole vairs nav nepieciešama turpmāk minētās apvienības dalībniekiem. Lūgums saskaņot zemāk esošo domēnu ar savas apvienības pārvaldītāju." - }, "organizationName": { "message": "Apvienības nosaukums" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Neņemt vērā" }, - "importData": { - "message": "Ievietot datus", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Ievietošanas kļūda" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Konta drošība" }, + "phishingBlocker": { + "message": "Pikšķerēšanas aizturētājs" + }, + "enablePhishingDetection": { + "message": "Pikšķerēšanas noteikšana" + }, + "enablePhishingDetectionDesc": { + "message": "Attēlot brīdinājumu pirms piekļūšanas iespējamām piekšķerēšanas vietnēm" + }, "notifications": { "message": "Paziņojumi" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "Un vēl!" }, - "planDescPremium": { - "message": "Pilnīga drošība tiešsaistē" + "advancedOnlineSecurity": { + "message": "Izvērsta tiešsaistes drošība" }, "upgradeToPremium": { "message": "Uzlabot uz Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Kartes numurs" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Apvienība vairs neizmanto galvenās paroles, lai pieteiktos Bitwarden. Lai turpinātu, jāapliecina apvienība un domēns." + }, + "continueWithLogIn": { + "message": "Turpināt ar pieteikšanos" + }, + "doNotContinue": { + "message": "Neturpināt" + }, + "domain": { + "message": "Domēns" + }, + "keyConnectorDomainTooltip": { + "message": "Šajā domēnā tiks glabātas konta šifrēšanas atslēgas, tādēļ jāpārliecinās par uzticamību. Ja nav pārliecības, jāsazinās ar savu pārvaldītāju." + }, + "verifyYourOrganization": { + "message": "Jāapliecina apvienība, lai pieteiktos" + }, + "organizationVerified": { + "message": "Apvienība apliecināta" + }, + "domainVerified": { + "message": "Domēns ir apliecināts" + }, + "leaveOrganizationContent": { + "message": "Ja neapliecināsi apvienību, tiks atsaukta piekļuve tai." + }, + "leaveNow": { + "message": "Pamest tagad" + }, + "verifyYourDomainToLogin": { + "message": "Jāapliecina domēns, lai pieteiktos" + }, + "verifyYourDomainDescription": { + "message": "Lai turpinātu pieteikšanos, jāapliecina šis domēns." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Lai turpinātu pieteikšanos, jāapliecina apvienība un domēns." + }, "sessionTimeoutSettingsAction": { "message": "Noildzes darbība" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Uzlabot" + }, + "leaveConfirmationDialogTitle": { + "message": "Vai tiešām pamest?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Pēc noraidīšanas personīgie vienumi paliks Tavā kontā, bet Tu zaudēsi piekļvuvi kopīgotajiem vienumiem un apvienību iespējām." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Jāsazinās ar savu pārvaldītāju, lai atgūtu piekļuvi." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Pamest $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Kā es varu pārvaldīt savu glabātavu?" + }, + "transferItemsToOrganizationTitle": { + "message": "Pārcelt vienumus uz $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index 2f7f8d30e74..3257c4c745c 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "സമന്വയിപ്പിക്കുക" }, - "syncVaultNow": { - "message": "വാൾട് ഇപ്പോൾ സമന്വയിപ്പിക്കുക" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "അവസാന സമന്വയം:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "ഇനങ്ങൾ ഇമ്പോർട് ചെയ്യുക" - }, "select": { "message": "തിരഞ്ഞെടുക്കുക" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "വാൾട് എക്സ്പോർട്" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "ഫയൽ ഫോർമാറ്റ്" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "കൂടുതലറിവ് നേടുക" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "ഓതന്റിക്കേറ്റർ കീ (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "അറ്റാച്ചുമെന്റ് സംരക്ഷിച്ചു." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "ഫയൽ" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "ഒരു ഫയൽ തിരഞ്ഞെടുക്കുക" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "പരമാവധി ഫയൽ വലുപ്പം 500 MB ആണ്." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "ഫയൽ അറ്റാച്ചുമെന്റുകൾക്കായി 1 ജിബി എൻക്രിപ്റ്റുചെയ്‌ത സംഭരണം." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 70f8fe5393c..38487d00f9d 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "संकालन" }, - "syncVaultNow": { - "message": "तिजोरी संकालन आता करा" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "शेवटचे संकालन:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "वस्तू आयात करा" - }, "select": { "message": "Select" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Select a file" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index f829937ac51..04386b72930 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sync" }, - "syncVaultNow": { - "message": "Sync vault now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Last sync:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import items" - }, "select": { "message": "Select" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Select a file" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 0eba9c953a3..9056ce4ad8e 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Synkroniser" }, - "syncVaultNow": { - "message": "Synkroniser hvelvet nå" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Forrige synkronisering:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwardens nett-app" }, - "importItems": { - "message": "Importer elementer" - }, "select": { "message": "Velg" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Eksporter fra" }, - "exportVault": { - "message": "Eksporter hvelvet" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Filformat" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Lær mer" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Autentiseringsnøkkel (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Vedlegget har blitt lagret." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Fil" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Velg en fil." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Den maksimale filstørrelsen er 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB med kryptert fillagring for filvedlegg." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Nødtilgang." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Ingen unik identifikator ble funnet." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organisasjonens navn" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignorer" }, - "importData": { - "message": "Importer data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Importeringsfeil" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Kontosikkerhet" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Varsler" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index f829937ac51..04386b72930 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sync" }, - "syncVaultNow": { - "message": "Sync vault now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Last sync:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import items" - }, "select": { "message": "Select" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Select a file" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 601aac16f94..ea040cb057b 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Synchroniseren" }, - "syncVaultNow": { - "message": "Kluis nu synchroniseren" + "syncNow": { + "message": "Nu synchroniseren" }, "lastSync": { "message": "Laatste synchronisatie:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden webapp" }, - "importItems": { - "message": "Items importeren" - }, "select": { "message": "Selecteren" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Exporteren vanuit" }, - "exportVault": { - "message": "Kluis exporteren" + "exportVerb": { + "message": "Exporteren", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Exporteren", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Importeren", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importeren", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Bestandsindeling" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Meer informatie" }, + "migrationsFailed": { + "message": "Er is een fout opgetreden bij het bijwerken van de versleutelingsinstellingen." + }, + "updateEncryptionSettingsTitle": { + "message": "Je versleutelingsinstellingen bijwerken" + }, + "updateEncryptionSettingsDesc": { + "message": "De nieuwe aanbevolen versleutelingsinstellingen verbeteren de beveiliging van je account. Voer je hoofdwachtwoord in om nu bij te werken." + }, + "confirmIdentityToContinue": { + "message": "Bevestig je identiteit om door te gaan" + }, + "enterYourMasterPassword": { + "message": "Voer je hoofdwachtwoord in" + }, + "updateSettings": { + "message": "Instellingen bijwerken" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticatiecode (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Bijlage opgeslagen" }, + "fixEncryption": { + "message": "Versleuteling repareren" + }, + "fixEncryptionTooltip": { + "message": "Dit bestand gebruikt een verouderde versleutelingsmethode." + }, + "attachmentUpdated": { + "message": "Bijlagen bijgewerkt" + }, "file": { "message": "Bestand" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Selecteer een bestand" }, + "itemsTransferred": { + "message": "Items overgedragen" + }, "maxFileSize": { "message": "Maximale bestandsgrootte is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB versleutelde opslag voor bijlagen." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ versleutelde opslag voor bijlagen.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Noodtoegang." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Geen unieke id gevonden." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Voor leden van de volgende organisatie is een hoofdwachtwoord niet langer nodig. Bevestig het domein hieronder met de beheerder van je organisatie." - }, "organizationName": { "message": "Organisatienaam" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Negeren" }, - "importData": { - "message": "Data importeren", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Fout bij importeren" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Accountbeveiliging" }, + "phishingBlocker": { + "message": "Phishing-blocker" + }, + "enablePhishingDetection": { + "message": "Phishingdetectie" + }, + "enablePhishingDetectionDesc": { + "message": "Waarschuwing weergeven voor het benaderen van vermoedelijke phishingsites" + }, "notifications": { "message": "Meldingen" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "En meer!" }, - "planDescPremium": { - "message": "Online beveiliging voltooien" + "advancedOnlineSecurity": { + "message": "Geavanceerde online beveiliging" }, "upgradeToPremium": { "message": "Opwaarderen naar Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Kaartnummer" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Je organisatie maakt niet langer gebruik van hoofdwachtwoorden om in te loggen op Bitwarden. Controleer de organisatie en het domein om door te gaan." + }, + "continueWithLogIn": { + "message": "Doorgaan met inloggen" + }, + "doNotContinue": { + "message": "Niet verder gaan" + }, + "domain": { + "message": "Domein" + }, + "keyConnectorDomainTooltip": { + "message": "Dit domein zal de encryptiesleutels van je account opslaan, dus zorg ervoor dat je het vertrouwt. Als je het niet zeker weet, controleer dan bij je beheerder." + }, + "verifyYourOrganization": { + "message": "Verifieer je organisatie om in te loggen" + }, + "organizationVerified": { + "message": "Organisatie geverifieerd" + }, + "domainVerified": { + "message": "Domein geverifieerd" + }, + "leaveOrganizationContent": { + "message": "Als je je organisatie niet verifieert, wordt je toegang tot de organisatie ingetrokken." + }, + "leaveNow": { + "message": "Nu verlaten" + }, + "verifyYourDomainToLogin": { + "message": "Verifieer je domein om in te loggen" + }, + "verifyYourDomainDescription": { + "message": "Bevestig dit domein om verder te gaan met inloggen." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Bevestig organisatie en domein om verder te gaan met inloggen." + }, "sessionTimeoutSettingsAction": { "message": "Time-out actie" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Deze instelling wordt beheerd door je organisatie." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Je organisatie heeft de maximale sessietime-out ingesteld op $HOURS$ uur en $MINUTES$ minuten.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Je organisatie heeft de standaard sessie time-out ingesteld op Onmiddellijk." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Je organisatie heeft de standaard sessietime-out ingesteld op Systeem vergrendelen." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Je organisatie heeft de standaard sessietime-out ingesteld op Browser verversen." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximale time-out kan niet langer zijn dan $HOURS$ uur en $MINUTES$ minu(u) t(en)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Browser herstart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Stel een ontgrendelingsmethode in om je kluis time-out actie te wijzigen" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Weet je zeker dat je wilt verlaten?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Door te weigeren, blijven je persoonlijke items in je account, maar verlies je toegang tot gedeelde items en organisatiefunctionaliteit." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Neem contact op met je beheerder om weer toegang te krijgen." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "$ORGANIZATION$ verlaten", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Hoe beheer ik mijn kluis?" + }, + "transferItemsToOrganizationTitle": { + "message": "Items overdragen aan $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ vereist dat alle items eigendom zijn van de organisatie voor veiligheid en naleving. Klik op accepteren voor het overdragen van eigendom van je items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Overdacht accepteren" + }, + "declineAndLeave": { + "message": "Weigeren en verlaten" + }, + "whyAmISeeingThis": { + "message": "Waarom zie ik dit?" } } diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index f829937ac51..04386b72930 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sync" }, - "syncVaultNow": { - "message": "Sync vault now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Last sync:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import items" - }, "select": { "message": "Select" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Select a file" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index f829937ac51..04386b72930 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sync" }, - "syncVaultNow": { - "message": "Sync vault now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Last sync:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import items" - }, "select": { "message": "Select" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Select a file" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 9741f94da36..67e7a2a2a00 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Synchronizacja" }, - "syncVaultNow": { - "message": "Synchronizuj sejf" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Ostatnia synchronizacja:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Aplikacja internetowa Bitwarden" }, - "importItems": { - "message": "Importuj elementy" - }, "select": { "message": "Wybierz" }, @@ -598,7 +595,7 @@ "message": "Pokaż wszystko" }, "showAll": { - "message": "Show all" + "message": "Pokaż wszystko" }, "viewLess": { "message": "Pokaż mniej" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Eksportuj z" }, - "exportVault": { - "message": "Eksportuj sejf" + "exportVerb": { + "message": "Eksportuj", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Importuj", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format pliku" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Dowiedz się więcej" }, + "migrationsFailed": { + "message": "Wystąpił błąd podczas aktualizacji ustawień szyfrowania." + }, + "updateEncryptionSettingsTitle": { + "message": "Zaktualizuj ustawienia szyfrowania" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Zaktualizuj ustawienia" + }, + "later": { + "message": "Później" + }, "authenticatorKeyTotp": { "message": "Klucz uwierzytelniający (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Załącznik został zapisany" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Plik" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Wybierz plik" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maksymalny rozmiar pliku to 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB miejsca na zaszyfrowane załączniki." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Dostęp awaryjny." }, @@ -1874,7 +1926,7 @@ "message": "Rok wygaśnięcia" }, "monthly": { - "message": "month" + "message": "miesiąc" }, "expiration": { "message": "Data wygaśnięcia" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Nie znaleziono unikatowego identyfikatora." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Hasło główne nie jest już wymagane dla członków następującej organizacji. Potwierdź poniższą domenę z administratorem organizacji." - }, "organizationName": { "message": "Nazwa organizacji" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignoruj" }, - "importData": { - "message": "Importuj dane", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Błąd importowania" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Bezpieczeństwo konta" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Powiadomienia" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "I jeszcze więcej!" }, - "planDescPremium": { - "message": "Pełne bezpieczeństwo w Internecie" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Ulepsz do Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Numer karty" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domena" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Akcja przekroczenia limitu czasu" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index 319d415b612..c7ecfe3f81d 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -68,7 +68,7 @@ "message": "Uma dica de senha principal pode ajudá-lo(a) a lembrá-la caso você esqueça." }, "masterPassHintText": { - "message": "Se você esquecer sua senha, a dica de senha pode ser enviada ao seu e-mail. $CURRENT$/$MAXIMUM$ caracteres máximos.", + "message": "Se você esquecer sua senha, a dica da senha pode ser enviada ao seu e-mail. $CURRENT$ do máximo de $MAXIMUM$ caracteres.", "placeholders": { "current": { "content": "$1", @@ -436,8 +436,8 @@ "sync": { "message": "Sincronizar" }, - "syncVaultNow": { - "message": "Sincronizar cofre agora" + "syncNow": { + "message": "Sincronizar agora" }, "lastSync": { "message": "Última sincronização:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Aplicativo web do Bitwarden" }, - "importItems": { - "message": "Importar itens" - }, "select": { "message": "Selecionar" }, @@ -688,16 +685,16 @@ "message": "Opções de desbloqueio" }, "unlockMethodNeededToChangeTimeoutActionDesc": { - "message": "Configure um método de desbloqueio para alterar a ação do tempo limite do cofre." + "message": "Configure um método de desbloqueio para alterar a ação do limite de tempo do cofre." }, "unlockMethodNeeded": { "message": "Configure um método de desbloqueio nas Configurações" }, "sessionTimeoutHeader": { - "message": "Tempo limite da sessão" + "message": "Limite de tempo da sessão" }, "vaultTimeoutHeader": { - "message": "Tempo limite do cofre" + "message": "Limite de tempo do cofre" }, "otherOptions": { "message": "Outras opções" @@ -758,10 +755,10 @@ } }, "vaultTimeout": { - "message": "Tempo limite do cofre" + "message": "Limite de tempo do cofre" }, "vaultTimeout1": { - "message": "Tempo limite" + "message": "Limite de tempo" }, "lockNow": { "message": "Bloquear agora" @@ -1126,7 +1123,7 @@ "message": "Clique em itens na tela do Cofre para preencher automaticamente" }, "clickToAutofill": { - "message": "Clique em um item para preenchê-lo automaticamente" + "message": "Clicar itens na sugestão para preenchê-lo" }, "clearClipboard": { "message": "Limpar área de transferência", @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Exportar de" }, - "exportVault": { - "message": "Exportar cofre" + "exportVerb": { + "message": "Exportar", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Exportação", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Importação", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importar", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formato do arquivo" @@ -1367,7 +1377,7 @@ "message": "Confirmar exportação do cofre" }, "exportWarningDesc": { - "message": "Esta exportação contém os dados do seu cofre em um formato não criptografado. Você não deve armazenar ou enviar o arquivo exportado por canais inseguros (como e-mail). Apague o arquivo imediatamente após terminar de usá-lo." + "message": "Esta exportação contém os dados do seu cofre em um formato sem criptografia. Você não deve armazenar ou enviar o arquivo exportado por canais inseguros (como e-mail). Apague o arquivo imediatamente após terminar de usá-lo." }, "encExportKeyWarningDesc": { "message": "Esta exportação criptografa seus dados usando a chave de criptografia da sua conta. Se você rotacionar a chave de criptografia da sua conta, você deve exportar novamente, já que você não será capaz de descriptografar este arquivo de exportação." @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Saiba mais" }, + "migrationsFailed": { + "message": "Ocorreu um erro ao atualizar as configurações de criptografia." + }, + "updateEncryptionSettingsTitle": { + "message": "Atualize suas configurações de criptografia" + }, + "updateEncryptionSettingsDesc": { + "message": "As novas configurações de criptografia recomendadas melhorarão a segurança da sua conta. Digite sua senha principal para atualizar agora." + }, + "confirmIdentityToContinue": { + "message": "Confirme sua identidade para continuar" + }, + "enterYourMasterPassword": { + "message": "Digite sua senha principal" + }, + "updateSettings": { + "message": "Atualizar configurações" + }, + "later": { + "message": "Depois" + }, "authenticatorKeyTotp": { "message": "Chave do autenticador (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Anexo salvo" }, + "fixEncryption": { + "message": "Corrigir criptografia" + }, + "fixEncryptionTooltip": { + "message": "Este arquivo está usando um método de criptografia desatualizado." + }, + "attachmentUpdated": { + "message": "Anexo atualizado" + }, "file": { "message": "Arquivo" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Selecione um arquivo" }, + "itemsTransferred": { + "message": "Itens transferidos" + }, "maxFileSize": { "message": "O tamanho máximo do arquivo é de 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB de armazenamento criptografado para anexo de arquivos." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ de armazenamento criptografado para anexos de arquivo.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Acesso de emergência." }, @@ -1539,7 +1591,7 @@ "message": "Pedir biometria ao abrir" }, "authenticationTimeout": { - "message": "Tempo limite da autenticação atingido" + "message": "Limite de tempo da autenticação atingido" }, "authenticationSessionTimedOut": { "message": "A sessão de autenticação expirou. Reinicie o processo de autenticação." @@ -2375,10 +2427,10 @@ "message": "Personalização do cofre" }, "vaultTimeoutAction": { - "message": "Ação do tempo limite do cofre" + "message": "Ação do limite de tempo do cofre" }, "vaultTimeoutAction1": { - "message": "Ação do tempo limite" + "message": "Ação do limite de tempo" }, "lock": { "message": "Bloquear", @@ -2410,10 +2462,10 @@ "message": "Já tem uma conta?" }, "vaultTimeoutLogOutConfirmation": { - "message": "Desconectar-se irá remover todo o acesso ao seu cofre e requirirá autenticação online após o período de tempo limite. Tem certeza de que deseja usar esta configuração?" + "message": "Desconectar-se irá remover todo o acesso ao seu cofre e requirirá autenticação online após o período de limite de tempo. Tem certeza de que deseja usar esta configuração?" }, "vaultTimeoutLogOutConfirmationTitle": { - "message": "Confirmação da ação do tempo limite" + "message": "Confirmação da ação do limite de tempo" }, "autoFillAndSave": { "message": "Preencher automaticamente e salvar" @@ -3128,10 +3180,10 @@ "message": "Minutos" }, "vaultTimeoutPolicyAffectingOptions": { - "message": "Os requisitos de política empresarial foram aplicados às suas opções de tempo limite" + "message": "Os requisitos de política empresarial foram aplicados às suas opções de limite de tempo" }, "vaultTimeoutPolicyInEffect": { - "message": "As políticas da sua organização configuraram o seu máximo permitido do tempo limite do cofre para $HOURS$ hora(s) e $MINUTES$ minuto(s).", + "message": "As políticas da sua organização configuraram o seu máximo permitido do limite de tempo do cofre para $HOURS$ hora(s) e $MINUTES$ minuto(s).", "placeholders": { "hours": { "content": "$1", @@ -3157,7 +3209,7 @@ } }, "vaultTimeoutPolicyMaximumError": { - "message": "Tempo limite excede a restrição definida pela sua organização: máximo de $HOURS$ hora(s) e $MINUTES$ minuto(s)", + "message": "Limite de tempo excede a restrição definida pela sua organização: máximo de $HOURS$ hora(s) e $MINUTES$ minuto(s)", "placeholders": { "hours": { "content": "$1", @@ -3170,7 +3222,7 @@ } }, "vaultTimeoutPolicyWithActionInEffect": { - "message": "As políticas da sua organização estão afetando o tempo limite do seu cofre. \nO tempo limite máximo permitido para o cofre é $HOURS$ hora(s) e $MINUTES$ minuto(s). A ação de tempo limite do seu cofre está configurada como $ACTION$.", + "message": "As políticas da sua organização estão afetando o limite de tempo do seu cofre. \nO limite de tempo máximo permitido para o cofre é $HOURS$ hora(s) e $MINUTES$ minuto(s). A ação de limite de tempo do seu cofre está configurada como $ACTION$.", "placeholders": { "hours": { "content": "$1", @@ -3187,7 +3239,7 @@ } }, "vaultTimeoutActionPolicyInEffect": { - "message": "As políticas da sua organização configuraram a ação do tempo limite do seu cofre para $ACTION$.", + "message": "As políticas da sua organização configuraram a ação do limite de tempo do seu cofre para $ACTION$.", "placeholders": { "action": { "content": "$1", @@ -3196,7 +3248,7 @@ } }, "vaultTimeoutTooLarge": { - "message": "O tempo limite do seu cofre excede as restrições estabelecidas pela sua organização." + "message": "O limite de tempo do seu cofre excede as restrições estabelecidas pela sua organização." }, "vaultExportDisabled": { "message": "Exportação de cofre indisponível" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Nenhum identificador único encontrado." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Uma senha principal não é mais necessária para os membros da seguinte organização. Confirme o domínio abaixo com o administrador da sua organização." - }, "organizationName": { "message": "Nome da organização" }, @@ -3467,7 +3516,7 @@ } }, "forwarderNoAccountId": { - "message": "Não foi possível obter o ID da conta de e-mail mascarado $SERVICENAME$.", + "message": "Não é possível obter o ID da conta de e-mail mascarado do $SERVICENAME$.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -3626,7 +3675,7 @@ "message": "Solicitação enviada" }, "loginRequestApprovedForEmailOnDevice": { - "message": "Solicitação de autenticação aprovada para $EMAIL$ em $DEVICE$", + "message": "Solicitação de acesso aprovada para $EMAIL$ em $DEVICE$", "placeholders": { "email": { "content": "$1", @@ -3639,7 +3688,7 @@ } }, "youDeniedLoginAttemptFromAnotherDevice": { - "message": "Você negou uma tentativa de autenticação de outro dispositivo. Se era você, tente se conectar com o dispositivo novamente." + "message": "Você negou uma tentativa de acesso de outro dispositivo. Se era você, tente se conectar com o dispositivo novamente." }, "device": { "message": "Dispositivo" @@ -3663,7 +3712,7 @@ "message": "Senha fraca identificada e encontrada em um vazamento de dados. Use uma senha forte e única para proteger a sua conta. Tem certeza de que deseja usar essa senha?" }, "checkForBreaches": { - "message": "Conferir vazamentos de dados conhecidos por esta senha" + "message": "Conferir se esta senha vazou ao público" }, "important": { "message": "Importante:" @@ -3808,13 +3857,13 @@ "message": "Tipo do dispositivo" }, "loginRequest": { - "message": "Solicitação de autenticação" + "message": "Solicitação de acesso" }, "thisRequestIsNoLongerValid": { "message": "Esta solicitação não é mais válida." }, "loginRequestHasAlreadyExpired": { - "message": "A solicitação de autenticação já expirou." + "message": "A solicitação de acesso já expirou." }, "justNow": { "message": "Agora há pouco" @@ -3905,7 +3954,7 @@ "message": "Problemas para acessar?" }, "loginApproved": { - "message": "Autenticação aprovada" + "message": "Acesso aprovado" }, "userEmailMissing": { "message": "E-mail do usuário ausente" @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignorar" }, - "importData": { - "message": "Importar dados", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Erro ao importar" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Segurança da conta" }, + "phishingBlocker": { + "message": "Bloqueador de phishing" + }, + "enablePhishingDetection": { + "message": "Detecção de phishing" + }, + "enablePhishingDetectionDesc": { + "message": "Exiba um aviso antes de acessar sites suspeitos de phishing" + }, "notifications": { "message": "Notificações" }, @@ -5269,7 +5323,7 @@ "message": "Ações da conta" }, "showNumberOfAutofillSuggestions": { - "message": "Mostrar número de sugestões de preenchimento automático de credenciais no ícone da extensão" + "message": "Mostrar número de sugestões de preenchimento no ícone da extensão" }, "accountAccessRequested": { "message": "Acesso à conta solicitado" @@ -5320,7 +5374,7 @@ "message": "Tentar novamente" }, "vaultCustomTimeoutMinimum": { - "message": "Tempo limite mínimo personalizado é 1 minuto." + "message": "Limite de tempo mínimo personalizado é 1 minuto." }, "fileSavedToDevice": { "message": "Arquivo salvo no dispositivo. Gerencie a partir dos downloads do seu dispositivo." @@ -5383,7 +5437,7 @@ "message": "Desbloqueie seu cofre em segundos" }, "unlockVaultDesc": { - "message": "Você pode personalizar suas configurações de desbloqueio e tempo limite para acessar seu cofre mais rapidamente." + "message": "Você pode personalizar suas configurações de desbloqueio e limite de tempo para acessar seu cofre mais rapidamente." }, "unlockPinSet": { "message": "PIN de desbloqueio configurado" @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "E mais!" }, - "planDescPremium": { - "message": "Segurança on-line completa" + "advancedOnlineSecurity": { + "message": "Segurança on-line avançada" }, "upgradeToPremium": { "message": "Faça upgrade para o Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Número do cartão" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "A sua organização não está mais usando senhas principais para se conectar ao Bitwarden. Para continuar, verifique a organização e o domínio." + }, + "continueWithLogIn": { + "message": "Continuar acessando" + }, + "doNotContinue": { + "message": "Não continuar" + }, + "domain": { + "message": "Domínio" + }, + "keyConnectorDomainTooltip": { + "message": "Este domínio armazenará as chaves de criptografia da sua conta, então certifique-se que confia nele. Se não tiver certeza, verifique com o seu administrador." + }, + "verifyYourOrganization": { + "message": "Verifique sua organização para se conectar" + }, + "organizationVerified": { + "message": "Organização verificada" + }, + "domainVerified": { + "message": "Domínio verificado" + }, + "leaveOrganizationContent": { + "message": "Se você não verificar a sua organização, o seu acesso à organização será revogado." + }, + "leaveNow": { + "message": "Sair agora" + }, + "verifyYourDomainToLogin": { + "message": "Verifique seu domínio para se conectar" + }, + "verifyYourDomainDescription": { + "message": "Para continuar se conectando, verifique este domínio." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Para continuar se conectando, verifique a organização e o domínio." + }, "sessionTimeoutSettingsAction": { - "message": "Ação do tempo limite" + "message": "Ação do limite de tempo" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Esta configuração é gerenciada pela sua organização." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "A sua organização configurou o limite de tempo máximo da sessão para $HOURS$ hora(s) e $MINUTES$ minuto(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "A sua organização configurou o limite de tempo padrão da sessão para imediatamente." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "A sua organização configurou o limite de tempo padrão da sessão para ser no bloqueio do sistema." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "A sua organização configurou o limite de tempo padrão da sessão para ser no reinício do navegador." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "O limite de tempo máximo não pode exceder $HOURS$ hora(s) e $MINUTES$ minuto(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "No reinício do navegador" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Configure um método de desbloqueio para alterar a ação do limite de tempo" + }, + "upgrade": { + "message": "Fazer upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Tem certeza de que quer sair?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Se recusar, seus itens pessoais continuarão na sua conta, mas você perderá o acesso aos itens compartilhados e os recursos de organização." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Entre em contato com o seu administrador para recuperar o acesso." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Sair de $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Como gerencio meu cofre?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transferir itens para $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ exige que todos os itens sejam propriedade da organização por segurança e conformidade. Clique em aceitar para transferir a propriedade dos seus itens.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Aceitar transferência" + }, + "declineAndLeave": { + "message": "Recusar e sair" + }, + "whyAmISeeingThis": { + "message": "Por que estou vendo isso?" } } diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 6b8568ddb1b..d766e8f95fb 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -200,7 +200,7 @@ "description": "This string is used on the vault page to indicate autofilling. Horizontal space is limited in the interface here so try and keep translations as concise as possible." }, "autoFill": { - "message": "Preencher automaticamente" + "message": "Preenchimento automático" }, "autoFillLogin": { "message": "Preencher automaticamente credencial" @@ -436,8 +436,8 @@ "sync": { "message": "Sincronizar" }, - "syncVaultNow": { - "message": "Sincronizar o cofre agora" + "syncNow": { + "message": "Sincronizar agora" }, "lastSync": { "message": "Última sincronização:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Aplicação web Bitwarden" }, - "importItems": { - "message": "Importar itens" - }, "select": { "message": "Selecionar" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Exportar de" }, - "exportVault": { - "message": "Exportar cofre" + "exportVerb": { + "message": "Exportar", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Exportação", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Importar", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importação", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formato do ficheiro" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Saber mais" }, + "migrationsFailed": { + "message": "Ocorreu um erro ao atualizar as definições de encriptação." + }, + "updateEncryptionSettingsTitle": { + "message": "Atualize as suas definições de encriptação" + }, + "updateEncryptionSettingsDesc": { + "message": "As novas definições de encriptação recomendadas irão melhorar a segurança da sua conta. Introduza a sua palavra-passe mestra para atualizar agora." + }, + "confirmIdentityToContinue": { + "message": "Confirme a sua identidade para continuar" + }, + "enterYourMasterPassword": { + "message": "Introduza a sua palavra-passe mestra" + }, + "updateSettings": { + "message": "Atualizar definições" + }, + "later": { + "message": "Mais tarde" + }, "authenticatorKeyTotp": { "message": "Chave de autenticação (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Anexo guardado" }, + "fixEncryption": { + "message": "Corrigir encriptação" + }, + "fixEncryptionTooltip": { + "message": "Este ficheiro está a utilizar um método de encriptação desatualizado." + }, + "attachmentUpdated": { + "message": "Anexo atualizado" + }, "file": { "message": "Ficheiro" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Selecionar um ficheiro" }, + "itemsTransferred": { + "message": "Itens transferidos" + }, "maxFileSize": { "message": "O tamanho máximo do ficheiro é de 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB de armazenamento encriptado para anexos de ficheiros." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ de armazenamento encriptado para anexos de ficheiros.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Acesso de emergência." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Não foi encontrado um identificador único." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Já não é necessária uma palavra-passe mestra para os membros da seguinte organização. Por favor, confirme o domínio abaixo com o administrador da sua organização." - }, "organizationName": { "message": "Nome da organização" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignorar" }, - "importData": { - "message": "Importar dados", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Erro de importação" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Segurança da conta" }, + "phishingBlocker": { + "message": "Bloqueador de phishing" + }, + "enablePhishingDetection": { + "message": "Deteção de phishing" + }, + "enablePhishingDetectionDesc": { + "message": "Mostrar aviso antes de aceder a sites suspeitos de phishing" + }, "notifications": { "message": "Notificações" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "E muito mais!" }, - "planDescPremium": { - "message": "Segurança total online" + "advancedOnlineSecurity": { + "message": "Segurança online avançada" }, "upgradeToPremium": { "message": "Atualizar para o Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Número do cartão" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "A sua organização já não utiliza palavras-passe mestras para iniciar sessão no Bitwarden. Para continuar, verifique a organização e o domínio." + }, + "continueWithLogIn": { + "message": "Continuar com o início de sessão" + }, + "doNotContinue": { + "message": "Não continuar" + }, + "domain": { + "message": "Domínio" + }, + "keyConnectorDomainTooltip": { + "message": "Este domínio armazenará as chaves de encriptação da sua conta, portanto certifique-se de que confia nele. Se não tiver a certeza, verifique com o seu administrador." + }, + "verifyYourOrganization": { + "message": "Verifique a sua organização para iniciar sessão" + }, + "organizationVerified": { + "message": "Organização verificada" + }, + "domainVerified": { + "message": "Domínio verificado" + }, + "leaveOrganizationContent": { + "message": "Se não verificar a sua organização, o seu acesso à organização será revogado." + }, + "leaveNow": { + "message": "Sair agora" + }, + "verifyYourDomainToLogin": { + "message": "Verifique o seu domínio para iniciar sessão" + }, + "verifyYourDomainDescription": { + "message": "Para continuar com o início de sessão, verifique este domínio." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Para continuar com o início de sessão, verifique a organização e o domínio." + }, "sessionTimeoutSettingsAction": { "message": "Ação de tempo limite" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Esta configuração é gerida pela sua organização." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "A sua organização definiu o tempo limite máximo da sessão para $HOURS$ hora(s) e $MINUTES$ minuto(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "A sua organização definiu o tempo limite predefinido da sessão como Imediatamente." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "A sua organização definiu o tempo limite de sessão predefinido para Ao bloquear o sistema." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "A sua organização definiu o tempo limite de sessão predefinido para Ao reiniciar o navegador." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "O tempo limite máximo não pode ser superior a $HOURS$ hora(s) e $MINUTES$ minuto(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Ao reiniciar o navegador" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Configure um método de desbloqueio para alterar a sua ação de tempo limite" + }, + "upgrade": { + "message": "Atualizar" + }, + "leaveConfirmationDialogTitle": { + "message": "Tem a certeza de que pretende sair?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Ao recusar, os seus itens pessoais permanecerão na sua conta, mas perderá o acesso aos itens partilhados e às funcionalidades da organização." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Entre em contacto com o seu administrador para recuperar o acesso." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Sair de $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Como posso gerir o meu cofre?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transferir itens para $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ exige que todos os itens sejam propriedade da organização por motivos de segurança e conformidade. Clique em Aceitar para transferir a propriedade dos seus itens.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Aceitar transferência" + }, + "declineAndLeave": { + "message": "Recusar e sair" + }, + "whyAmISeeingThis": { + "message": "Porque é que estou a ver isto?" } } diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index db7a1b8c657..f0f71168074 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sincronizare" }, - "syncVaultNow": { - "message": "Sincronizare seif acum" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Ultima sincronizare:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Aplicația web Bitwarden" }, - "importItems": { - "message": "Import de articole" - }, "select": { "message": "Selectare" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export seif" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format fișier" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Aflați mai multe" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Cheie de autentificare (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Atașamentul a fost salvat" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Fișier" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Selectare fișier" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Mărimea maximă a fișierului este de 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB spațiu de stocare criptat pentru atașamente de fișiere." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Nu a fost găsit niciun identificator unic." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index 0535027daa9..3185edea5d5 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -436,7 +436,7 @@ "sync": { "message": "Синхронизация" }, - "syncVaultNow": { + "syncNow": { "message": "Синхронизировать" }, "lastSync": { @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Веб-приложение Bitwarden" }, - "importItems": { - "message": "Импорт элементов" - }, "select": { "message": "Выбрать" }, @@ -931,7 +928,7 @@ "message": "Вы вышли из своего аккаунта." }, "loginExpired": { - "message": "Истек срок действия вашего сеанса." + "message": "Истек срок действия вашей сессии." }, "logIn": { "message": "Войти" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Экспорт из" }, - "exportVault": { - "message": "Экспорт хранилища" + "exportVerb": { + "message": "Экспортировать", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Экспорт", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Импорт", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Импортировать", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Формат файла" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Подробнее" }, + "migrationsFailed": { + "message": "Произошла ошибка при обновлении настроек шифрования." + }, + "updateEncryptionSettingsTitle": { + "message": "Обновите настройки шифрования" + }, + "updateEncryptionSettingsDesc": { + "message": "Новые рекомендуемые настройки шифрования повысят безопасность вашего аккаунта. Введите мастер-пароль, чтобы обновить сейчас." + }, + "confirmIdentityToContinue": { + "message": "Подтвердите вашу личность, чтобы продолжить" + }, + "enterYourMasterPassword": { + "message": "Введите ваш мастер-пароль" + }, + "updateSettings": { + "message": "Обновить настройки" + }, + "later": { + "message": "Позже" + }, "authenticatorKeyTotp": { "message": "Ключ аутентификатора (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Вложение сохранено." }, + "fixEncryption": { + "message": "Исправить шифрование" + }, + "fixEncryptionTooltip": { + "message": "Этот файл использует устаревший метод шифрования." + }, + "attachmentUpdated": { + "message": "Вложение обновлено" + }, "file": { "message": "Файл" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Выбрать файл" }, + "itemsTransferred": { + "message": "Элементы переданы" + }, "maxFileSize": { "message": "Максимальный размер файла 500 МБ." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 ГБ зашифрованного хранилища для вложенных файлов." }, + "premiumSignUpStorageV2": { + "message": "Зашифрованного хранилища для вложенных файлов: $SIZE$", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Экстренный доступ" }, @@ -1542,7 +1594,7 @@ "message": "Таймаут аутентификации" }, "authenticationSessionTimedOut": { - "message": "Сеанс аутентификации завершился по времени. Пожалуйста, попробуйте войти еще раз." + "message": "Сессия аутентификации завершилась по времени. Пожалуйста, перезапустите процесс авторизации." }, "verificationCodeEmailSent": { "message": "Отправлено письмо подтверждения на $EMAIL$.", @@ -3079,10 +3131,10 @@ "message": "Обновить мастер-пароль" }, "updateMasterPasswordWarning": { - "message": "Мастер-пароль недавно был изменен администратором вашей организации. Чтобы получить доступ к хранилищу, вы должны обновить его сейчас. В результате текущий сеанс будет завершен, потребуется повторный вход. Сеансы на других устройствах могут оставаться активными в течение одного часа." + "message": "Мастер-пароль недавно был изменен администратором вашей организации. Чтобы получить доступ к хранилищу, вы должны обновить его сейчас. В результате текущая сессия будет завершена, потребуется повторный вход. Сессии на других устройствах могут оставаться активными в течение одного часа." }, "updateWeakMasterPasswordWarning": { - "message": "Ваш мастер-пароль не соответствует требованиям политики вашей организации. Для доступа к хранилищу вы должны обновить свой мастер-пароль прямо сейчас. При этом текущий сеанс будет завершен и потребуется повторная авторизация. Сеансы на других устройствах могут оставаться активными в течение часа." + "message": "Ваш мастер-пароль не соответствует требованиям политики вашей организации. Для доступа к хранилищу вы должны обновить свой мастер-пароль прямо сейчас. При этом текущая сессия будет завершена и потребуется повторная авторизация. Сессии на других устройствах могут оставаться активными в течение часа." }, "tdeDisabledMasterPasswordRequired": { "message": "В вашей организации отключено шифрование доверенных устройств. Пожалуйста, установите мастер-пароль для доступа к вашему хранилищу." @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Уникальный идентификатор не найден." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Мастер-пароль больше не требуется для членов следующей организации. Пожалуйста, подтвердите указанный ниже домен у администратора вашей организации." - }, "organizationName": { "message": "Название организации" }, @@ -3238,7 +3287,7 @@ "message": "Показать количество символов" }, "sessionTimeout": { - "message": "Время вашего сеанса истекло. Пожалуйста, вернитесь и попробуйте войти снова." + "message": "Время вашей сессии истекло. Пожалуйста, вернитесь и попробуйте войти снова." }, "exportingPersonalVaultTitle": { "message": "Экспорт личного хранилища" @@ -4176,10 +4225,6 @@ "ignore": { "message": "Игнорировать" }, - "importData": { - "message": "Импорт данных", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Ошибка импорта" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Безопасность аккаунта" }, + "phishingBlocker": { + "message": "Блокировщик фишинга" + }, + "enablePhishingDetection": { + "message": "Обнаружение фишинга" + }, + "enablePhishingDetectionDesc": { + "message": "Отображать предупреждение перед доступом к подозрительным фишинговым сайтам" + }, "notifications": { "message": "Уведомления" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "И многое другое!" }, - "planDescPremium": { - "message": "Полная онлайн-защищенность" + "advancedOnlineSecurity": { + "message": "Расширенная онлайн-безопасность" }, "upgradeToPremium": { "message": "Обновить до Премиум" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Номер карты" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Ваша организация больше не использует мастер-пароли для входа в Bitwarden. Чтобы продолжить, подтвердите организацию и домен." + }, + "continueWithLogIn": { + "message": "Продолжить с логином" + }, + "doNotContinue": { + "message": "Не продолжать" + }, + "domain": { + "message": "Домен" + }, + "keyConnectorDomainTooltip": { + "message": "В этом домене будут храниться ключи шифрования вашего аккаунта, поэтому убедитесь, что вы ему доверяете. Если вы не уверены, обратитесь к своему администратору." + }, + "verifyYourOrganization": { + "message": "Подтвердите свою организацию для входа" + }, + "organizationVerified": { + "message": "Организация подтверждена" + }, + "domainVerified": { + "message": "Домен верифицирован" + }, + "leaveOrganizationContent": { + "message": "Если вы не подтвердите свою организацию, ваш доступ к ней будет аннулирован." + }, + "leaveNow": { + "message": "Покинуть" + }, + "verifyYourDomainToLogin": { + "message": "Подтвердите свой домен для входа" + }, + "verifyYourDomainDescription": { + "message": "Чтобы продолжить с логином, подтвердите этот домен." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Чтобы продолжить с логином, подтвердите организацию и домен." + }, "sessionTimeoutSettingsAction": { "message": "Тайм-аут действия" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Эта настройка управляется вашей организацией." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "В вашей организации максимальный тайм-аут сессии установлен равным $HOURS$ час. и $MINUTES$ мин.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Ваша организация не установила тайм-аут сессии на Немедленно." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Ваша организация установила тайм-аут сессии по умолчанию на При блокировке системы." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Ваша организация установила тайм-аут сессии по умолчанию на При перезапуске браузера." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Максимальный тайм-аут не может превышать $HOURS$ час. и $MINUTES$ мин.", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "При перезапуске браузера" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Установите способ разблокировки для изменения действия при истечении тайм-аута" + }, + "upgrade": { + "message": "Перейти" + }, + "leaveConfirmationDialogTitle": { + "message": "Вы уверены, что хотите покинуть?" + }, + "leaveConfirmationDialogContentOne": { + "message": "В случае отказа ваши личные данные останутся в вашем аккаунте, но вы потеряете доступ к общим элементам и возможностям организации." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Свяжитесь с вашим администратором для восстановления доступа." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Покинуть $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Как я могу управлять своим хранилищем?" + }, + "transferItemsToOrganizationTitle": { + "message": "Перенести элементы в $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ требует, чтобы все элементы принадлежали организации для обеспечения безопасности и соответствия требованиям. Нажмите Принять, чтобы передать собственность на ваши элементы.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Принять передачу" + }, + "declineAndLeave": { + "message": "Отклонить и покинуть" + }, + "whyAmISeeingThis": { + "message": "Почему я это вижу?" } } diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index bb46b283322..7ef837967c9 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "සමමුහූර්තනය" }, - "syncVaultNow": { - "message": "සුරක්ෂිතාගාරය දැන් සමමුහුර්ත කරන්න" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "අවසන් සමමුහුර්ත කරන්න:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "ආනයන අයිතම" - }, "select": { "message": "තෝරන්න" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "අපනයන සුරක්ෂිතාගාරය" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "ගොනු ආකෘතිය" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "වැඩිදුර ඉගෙන ගන්න" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "සත්යාපන යතුර (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "ඇමුණුම ගැලවීම කර ඇත." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "ගොනුව" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "ගොනුවක් තෝරන්න." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "උපරිම ගොනු ප්රමාණය 500 MB වේ." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "ගොනු ඇමුණුම් සඳහා 1 GB සංකේතාත්මක ගබඩා." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "අද්විතීය හඳුනාගැනීමක් සොයාගත නොහැකි විය." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 283442d95da..ffda610b8f0 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Synchronizácia" }, - "syncVaultNow": { - "message": "Synchronizovať trezor teraz" + "syncNow": { + "message": "Synchronizovať teraz" }, "lastSync": { "message": "Posledná synchronizácia:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Webová aplikácia Bitwarden" }, - "importItems": { - "message": "Importovať položky" - }, "select": { "message": "Vybrať" }, @@ -803,7 +800,7 @@ "message": "4 hodiny" }, "onLocked": { - "message": "Keď je systém uzamknutý" + "message": "Pri uzamknutí systému" }, "onIdle": { "message": "Pri nečinnosti systému" @@ -812,7 +809,7 @@ "message": "V režime spánku" }, "onRestart": { - "message": "Po reštarte prehliadača" + "message": "Pri reštarte prehliadača" }, "never": { "message": "Nikdy" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Exportovať z" }, - "exportVault": { - "message": "Export trezoru" + "exportVerb": { + "message": "Exportovať", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importovať", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formát súboru" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Zistiť viac" }, + "migrationsFailed": { + "message": "Pri aktualizácii nastavení šifrovania došlo k chybe." + }, + "updateEncryptionSettingsTitle": { + "message": "Aktualizujte nastavenie šifrovania" + }, + "updateEncryptionSettingsDesc": { + "message": "Nové odporúčané nastavenia šifrovania zlepšia bezpečnosť vášho účtu. Ak ich chcete aktualizovať teraz, zadajte hlavné heslo." + }, + "confirmIdentityToContinue": { + "message": "Ak chcete pokračovať, potvrďte svoju identitu" + }, + "enterYourMasterPassword": { + "message": "Zadajte hlavné heslo" + }, + "updateSettings": { + "message": "Aktualizovať nastavenia" + }, + "later": { + "message": "Neskôr" + }, "authenticatorKeyTotp": { "message": "Overovací kľúč (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Príloha bola uložená" }, + "fixEncryption": { + "message": "Opraviť šifrovanie" + }, + "fixEncryptionTooltip": { + "message": "Tento súbor používa zastaranú metódu šifrovania." + }, + "attachmentUpdated": { + "message": "Príloha bola aktualizovaná" + }, "file": { "message": "Súbor" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Vyberte súbor" }, + "itemsTransferred": { + "message": "Položky boli prenesené" + }, "maxFileSize": { "message": "Maximálna veľkosť súboru je 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB šifrovaného úložiska na prílohy." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ šifrovaného úložiska na prílohy.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Núdzový prístup." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Nenašiel sa žiadny jedinečný identifikátor." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Hlavné heslo sa už nevyžaduje pre členov tejto organizácie. Nižšie uvedenú doménu potvrďte u správcu organizácie." - }, "organizationName": { "message": "Názov organizácie" }, @@ -3359,10 +3408,10 @@ "message": "Použiť možnosti subadresovania svojho poskytovateľa e-mailu." }, "catchallEmail": { - "message": "Catch-all e-mail" + "message": "Doménový kôš" }, "catchallEmailDesc": { - "message": "Použiť doručenú poštu typu catch-all nastavenú na doméne." + "message": "Použiť nastavený doménový kôš." }, "random": { "message": "Náhodné" @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignorovať" }, - "importData": { - "message": "Import údajov", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Chyba importu" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Zabezpečenie účtu" }, + "phishingBlocker": { + "message": "Blokovač phishingu" + }, + "enablePhishingDetection": { + "message": "Detekcia phishingu" + }, + "enablePhishingDetectionDesc": { + "message": "Zobrazí upozornenie pred prístupom na podozrivé phishingové stránky" + }, "notifications": { "message": "Upozornenia" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "A ešte viac!" }, - "planDescPremium": { - "message": "Úplné online zabezpečenie" + "advancedOnlineSecurity": { + "message": "Pokročilá online ochrana" }, "upgradeToPremium": { "message": "Upgradovať na Prémium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Číslo karty" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Vaša organizácia už nepoužíva hlavné heslá na prihlásenie do Bitwardenu. Ak chcete pokračovať, overte organizáciu a doménu." + }, + "continueWithLogIn": { + "message": "Pokračujte prihlásením" + }, + "doNotContinue": { + "message": "Nepokračovať" + }, + "domain": { + "message": "Doména" + }, + "keyConnectorDomainTooltip": { + "message": "Táto doména bude ukladať šifrovacie kľúče vášho účtu, takže sa uistite, že jej dôverujete. Ak si nie ste istí, overte si to u správcu." + }, + "verifyYourOrganization": { + "message": "Na prihlásenie overte organizáciu" + }, + "organizationVerified": { + "message": "Organizácia je overená" + }, + "domainVerified": { + "message": "Doména je overená" + }, + "leaveOrganizationContent": { + "message": "Ak organizáciu neoveríte, váš prístup k nej bude zrušený." + }, + "leaveNow": { + "message": "Opustiť teraz" + }, + "verifyYourDomainToLogin": { + "message": "Na prihlásenie overte doménu" + }, + "verifyYourDomainDescription": { + "message": "Na pokračovanie prihlásením, overte túto doménu." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Na pokračovanie prihlásením, overte organizáciu a doménu." + }, "sessionTimeoutSettingsAction": { "message": "Akcia pri vypršaní časového limitu" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Toto nastavenie spravuje vaša organizácia." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Vaša organizácia nastavila maximálny časový limit relácie na $HOURS$ hod. a $MINUTES$ min.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Vaša organizácia nastavila predvolený časový limit relácie na Okamžite." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Vaša organizácia nastavila predvolený časový limit relácie na Pri uzamknutí systému." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Vaša organizácia nastavila predvolený časový limit relácie na Pri reštarte prehliadača." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximálny časový limit nesmie prekročiť $HOURS$ hod. a $MINUTES$ min.", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Pri reštarte prehliadača" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Nastavte metódu odomknutia, aby ste zmenili akciu pri vypršaní časového limitu" + }, + "upgrade": { + "message": "Upgradovať" + }, + "leaveConfirmationDialogTitle": { + "message": "Naozaj chcete odísť?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Ak odmietnete, vaše osobné položky zostanú vo vašom účte, ale stratíte prístup k zdieľaným položkám a funkciám organizácie." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Ak chcete obnoviť prístup, obráťte sa na správcu." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Opustiť $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Ako môžem spravovať svoj trezor?" + }, + "transferItemsToOrganizationTitle": { + "message": "Prenos položiek do $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ vyžaduje, aby všetky položky boli vo vlastníctve organizácie z dôvodu bezpečnosti a dodržiavania predpisov. Ak chcete previesť vlastníctvo položiek, kliknite na tlačidlo Prijať.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Prijať prenos" + }, + "declineAndLeave": { + "message": "Zamietnuť a odísť" + }, + "whyAmISeeingThis": { + "message": "Prečo to vidím?" } } diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index 2d20050d7f1..2806020d5f0 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sinhronizacija" }, - "syncVaultNow": { - "message": "Sinhroniziraj trezor zdaj" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Zadnja sinhronizacija:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Uvozi elemente" - }, "select": { "message": "Izberi" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Izvoz trezorja" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format datoteke" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Več o tem" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Ključ avtentikatorja (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Priponka je bila shranjena." }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "Datoteka" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Izberite datoteko." }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Največja velikost datoteke je 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB šifriranega prostora za shrambo podatkov." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index 0c7562987fc..4a23b7e7141 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Синхронизација" }, - "syncVaultNow": { - "message": "Одмах синхронизуј сеф" + "syncNow": { + "message": "Синхронизуј сада" }, "lastSync": { "message": "Задња синронизација:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden веб апликација" }, - "importItems": { - "message": "Увоз ставки" - }, "select": { "message": "Изабери" }, @@ -586,7 +583,7 @@ "message": "Архивиране ставке су искључене из општих резултата претраге и предлога за ауто попуњавање. Јесте ли сигурни да желите да архивирате ову ставку?" }, "upgradeToUseArchive": { - "message": "A premium membership is required to use Archive." + "message": "Премијум чланство је неопходно за употребу Архиве." }, "edit": { "message": "Уреди" @@ -598,10 +595,10 @@ "message": "Прегледај све" }, "showAll": { - "message": "Show all" + "message": "Прикажи све" }, "viewLess": { - "message": "View less" + "message": "Прикажи мање" }, "viewLogin": { "message": "Преглед пријаве" @@ -806,10 +803,10 @@ "message": "На закључавање система" }, "onIdle": { - "message": "On system idle" + "message": "На мировање система" }, "onSleep": { - "message": "On system sleep" + "message": "Након спавања система" }, "onRestart": { "message": "На покретање прегледача" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Извоз од" }, - "exportVault": { - "message": "Извоз сефа" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Формат датотеке" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Сазнај више" }, + "migrationsFailed": { + "message": "Дошло је до грешке при ажурирању подешавања шифровања." + }, + "updateEncryptionSettingsTitle": { + "message": "Ажурирај своје поставке за шифровање" + }, + "updateEncryptionSettingsDesc": { + "message": "Нова препоручена подешавања шифрирања побољшаће вашу сигурност налога. Унесите своју главну лозинку за ажурирање." + }, + "confirmIdentityToContinue": { + "message": "Да бисте наставили потврдите ваш идентитет" + }, + "enterYourMasterPassword": { + "message": "Унети вашу главну лозинку" + }, + "updateSettings": { + "message": "Ажурирај подешавања" + }, + "later": { + "message": "Касније" + }, "authenticatorKeyTotp": { "message": "Једнократни код" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Прилог је сачуван." }, + "fixEncryption": { + "message": "Поправи шифровање" + }, + "fixEncryptionTooltip": { + "message": "Ова датотека користи застарели метод шифровања." + }, + "attachmentUpdated": { + "message": "Прилог је ажуриран" + }, "file": { "message": "Датотека" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Изабери датотеку." }, + "itemsTransferred": { + "message": "Пренете ставке" + }, "maxFileSize": { "message": "Максимална величина је 500МБ." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1ГБ шифровано складиште за прилоге." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ шифровано складиште за прилоге.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Хитан приступ." }, @@ -1874,7 +1926,7 @@ "message": "Година истека" }, "monthly": { - "message": "month" + "message": "месец" }, "expiration": { "message": "Истек" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Није пронађен ниједан јединствени идентификатор." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Главна лозинка више није потребна за чланове следеће организације. Молимо потврдите домен са администратором организације." - }, "organizationName": { "message": "Назив организације" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Игнориши" }, - "importData": { - "message": "Увези податке", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Грешка при увозу" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Безбедност налога" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Обавештења" }, @@ -4912,7 +4966,7 @@ "message": "Премијум" }, "unlockFeaturesWithPremium": { - "message": "Unlock reporting, emergency access, and more security features with Premium." + "message": "Откључајте извештавање, приступ хитним случајевима и више безбедносних функција уз Премиум." }, "freeOrgsCannotUseAttachments": { "message": "Бесплатне организације не могу да користе прилоге" @@ -5818,26 +5872,26 @@ "andMoreFeatures": { "message": "И још више!" }, - "planDescPremium": { - "message": "Потпуна онлајн безбедност" + "advancedOnlineSecurity": { + "message": "Напредна онлајн безбедност" }, "upgradeToPremium": { "message": "Надоградите на Premium" }, "unlockAdvancedSecurity": { - "message": "Unlock advanced security features" + "message": "Откључајте напредне безбедносне функције" }, "unlockAdvancedSecurityDesc": { - "message": "A Premium subscription gives you more tools to stay secure and in control" + "message": "Премиум претплата вам даје више алата да останете сигурни и под контролом" }, "explorePremium": { - "message": "Explore Premium" + "message": "Прегледати Премијум" }, "loadingVault": { - "message": "Loading vault" + "message": "Учитавање сефа" }, "vaultLoaded": { - "message": "Vault loaded" + "message": "Сеф учитан" }, "settingDisabledByPolicy": { "message": "Ово подешавање је онемогућено смерницама ваше организације.", @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Број картице" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Ваша организација више не користи главне лозинке за пријаву на Bitwarden. Да бисте наставили, верификујте организацију и домен." + }, + "continueWithLogIn": { + "message": "Наставити са пријавом" + }, + "doNotContinue": { + "message": "Не настави" + }, + "domain": { + "message": "Домен" + }, + "keyConnectorDomainTooltip": { + "message": "Овај домен ће чувати кључеве за шифровање вашег налога, па се уверите да му верујете. Ако нисте сигурни, проверите код свог администратора." + }, + "verifyYourOrganization": { + "message": "Верификујте своју организацију да бисте се пријавили" + }, + "organizationVerified": { + "message": "Организација верификована" + }, + "domainVerified": { + "message": "Домен верификован" + }, + "leaveOrganizationContent": { + "message": "Ако не верификујете своју организацију, ваш приступ организацији ће бити опозван." + }, + "leaveNow": { + "message": "Напусти сада" + }, + "verifyYourDomainToLogin": { + "message": "Верификујте домен да бисте се пријавили" + }, + "verifyYourDomainDescription": { + "message": "Да бисте наставили са пријављивањем, верификујте овај домен." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Да бисте наставили са пријављивањем, верификујте организацију и домен." + }, "sessionTimeoutSettingsAction": { - "message": "Timeout action" + "message": "Акција тајмаута" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Овим подешавањем управља ваша организација." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Ваша организација је подесила максимално временско ограничење сесије на $HOURS$ сати и $MINUTES$ минута.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Ваша организација је поставила подразумевано временско ограничење сесије на Одмах." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Ваша организација је поставила подразумевано временско ограничење сесије на Блокирање система." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Ваша организација је поставила подразумевано временско ограничење сесије на При рестартовању прегледача." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Максимално временско ограничење не може да пређе $HOURS$ сат(а) и $MINUTES$ минут(а)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "На покретање прегледача" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Подесите метод откључавања да бисте променили радњу временског ограничења" + }, + "upgrade": { + "message": "Надогради" + }, + "leaveConfirmationDialogTitle": { + "message": "Да ли сте сигурни да желите да напустите?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Ако одбијете, ваши лични предмети ће остати на вашем налогу, али ћете изгубити приступ дељеним ставкама и организационим функцијама." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Контактирајте свог администратора да бисте поново добили приступ." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Напустити $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Како да управљам својим сефом?" + }, + "transferItemsToOrganizationTitle": { + "message": "Премести ставке у $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ захтева да све ставке буду у власништву организације ради безбедности и усклађености. Кликните на прихвати да бисте пренели власништво над својим ставкама.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Прихвати трансфер" + }, + "declineAndLeave": { + "message": "Одбиј и напусти" + }, + "whyAmISeeingThis": { + "message": "Зашто видите ово?" } } diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index f5d55585b80..d04202f5c0b 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Synkronisera" }, - "syncVaultNow": { - "message": "Synkronisera valv nu" + "syncNow": { + "message": "Synkronisera nu" }, "lastSync": { "message": "Senaste synkronisering:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden webbapp" }, - "importItems": { - "message": "Importera objekt" - }, "select": { "message": "Välj" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Exportera från" }, - "exportVault": { - "message": "Exportera valv" + "exportVerb": { + "message": "Exportera", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importera", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Filformat" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Läs mer" }, + "migrationsFailed": { + "message": "Ett fel inträffade när krypteringsinställningarna skulle uppdateras." + }, + "updateEncryptionSettingsTitle": { + "message": "Uppdatera dina krypteringsinställningar" + }, + "updateEncryptionSettingsDesc": { + "message": "De nya rekommenderade krypteringsinställningarna kommer att förbättra säkerheten för ditt konto. Ange ditt huvudlösenord för att uppdatera nu." + }, + "confirmIdentityToContinue": { + "message": "Bekräfta din identitet för att fortsätta" + }, + "enterYourMasterPassword": { + "message": "Ange ditt huvudlösenord" + }, + "updateSettings": { + "message": "Uppdatera inställningar" + }, + "later": { + "message": "Senare" + }, "authenticatorKeyTotp": { "message": "Autentiseringsnyckel (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Bilaga sparad" }, + "fixEncryption": { + "message": "Fixa kryptering" + }, + "fixEncryptionTooltip": { + "message": "Denna fil använder en föråldrad krypteringsmetod." + }, + "attachmentUpdated": { + "message": "Bilaga uppdaterad" + }, "file": { "message": "Fil" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Välj en fil" }, + "itemsTransferred": { + "message": "Objekt överförda" + }, "maxFileSize": { "message": "Filen får vara maximalt 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB lagring av krypterade filer." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ krypterad lagring för filbilagor.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Nödåtkomst." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Ingen unik identifierare hittades." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Ett huvudlösenord krävs inte längre för medlemmar i följande organisation. Vänligen bekräfta domänen nedan med din organisationsadministratör." - }, "organizationName": { "message": "Organisationsnamn" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignorera" }, - "importData": { - "message": "Importera data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Fel vid import" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Kontosäkerhet" }, + "phishingBlocker": { + "message": "Nätfiskeblockerare" + }, + "enablePhishingDetection": { + "message": "Nätfiskedetektering" + }, + "enablePhishingDetectionDesc": { + "message": "Visa varning innan du öppnar misstänkta nätfiskeplatser" + }, "notifications": { "message": "Aviseringar" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "och mer!" }, - "planDescPremium": { - "message": "Komplett säkerhet online" + "advancedOnlineSecurity": { + "message": "Avancerad säkerhet online" }, "upgradeToPremium": { "message": "Uppgradera till Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Kortnummer" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Din organisation använder inte längre huvudlösenord för att logga in på Bitwarden. För att fortsätta, verifiera organisationen och domänen." + }, + "continueWithLogIn": { + "message": "Fortsätt med inloggning" + }, + "doNotContinue": { + "message": "Fortsätt inte" + }, + "domain": { + "message": "Domän" + }, + "keyConnectorDomainTooltip": { + "message": "Denna domän kommer att lagra dina krypteringsnycklar, så se till att du litar på den. Om du inte är säker, kontrollera med din administratör." + }, + "verifyYourOrganization": { + "message": "Verifiera din organisation för att logga in" + }, + "organizationVerified": { + "message": "Organisation verifierad" + }, + "domainVerified": { + "message": "Domän verifierad" + }, + "leaveOrganizationContent": { + "message": "Om du inte verifierar din organisation kommer din åtkomst till organisationen att återkallas." + }, + "leaveNow": { + "message": "Lämna nu" + }, + "verifyYourDomainToLogin": { + "message": "Verifiera din domän för att logga in" + }, + "verifyYourDomainDescription": { + "message": "För att fortsätta med inloggning, verifiera denna domän." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "För att fortsätta logga in, verifiera organisationen och domänen." + }, "sessionTimeoutSettingsAction": { "message": "Tidsgränsåtgärd" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Den här inställningen hanteras av din organisation." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Din organisation har ställt in maximal sessionstidsgräns till $HOURS$ timmar och $MINUTES$ minut(er).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Din organisation har ställt in tidsgräns för standardsessionen till Omedelbart." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Din organisation har ställt in tidsgräns för standardsessionen till Vid systemlåsning." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Din organisation har ställt in tidsgräns för standardsessionen till Vid omstart av webbläsaren." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximal tidsgräns får inte överstiga $HOURS$ timmar och $MINUTES$ minut(er)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Vid omstart av webbläsaren" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Ställ in en upplåsningsmetod för att ändra din tidsgränsåtgärd" + }, + "upgrade": { + "message": "Uppgradera" + }, + "leaveConfirmationDialogTitle": { + "message": "Är du säker på att du vill lämna?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Genom att avböja kommer dina personliga objekt att stanna på ditt konto, men du kommer att förlora åtkomst till delade objekt och organisationsfunktioner." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Kontakta administratören för att återfå åtkomst." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Lämna $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Hur hanterar jag mitt valv?" + }, + "transferItemsToOrganizationTitle": { + "message": "Överför objekt till $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ kräver att alla objekt ägs av organisationen för säkerhet och efterlevnad. Klicka på godkänn för att överföra ägarskapet för dina objekt.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Godkänn överföring" + }, + "declineAndLeave": { + "message": "Avböj och lämna" + }, + "whyAmISeeingThis": { + "message": "Varför ser jag det här?" } } diff --git a/apps/browser/src/_locales/ta/messages.json b/apps/browser/src/_locales/ta/messages.json index 4d185501855..1e25b5157ef 100644 --- a/apps/browser/src/_locales/ta/messages.json +++ b/apps/browser/src/_locales/ta/messages.json @@ -32,7 +32,7 @@ "message": "ஒற்றை உள்நுழைவைப் பயன்படுத்தவும்" }, "yourOrganizationRequiresSingleSignOn": { - "message": "Your organization requires single sign-on." + "message": "உங்கள் நிறுவனத்திற்கு ஒற்றை உள்நுழைவு தேவை." }, "welcomeBack": { "message": "மீண்டும் வருக" @@ -436,8 +436,8 @@ "sync": { "message": "ஒத்திசை" }, - "syncVaultNow": { - "message": "இப்போது வால்ட்டை ஒத்திசை" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "கடைசி ஒத்திசைவு:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden வலை பயன்பாடு" }, - "importItems": { - "message": "உருப்படிகளை இறக்குமதிசெய்" - }, "select": { "message": "தேர்ந்தெடு" }, @@ -554,39 +551,39 @@ "message": "தேடலை மீட்டமை" }, "archiveNoun": { - "message": "Archive", + "message": "காப்பகம்", "description": "Noun" }, "archiveVerb": { - "message": "Archive", + "message": "காப்பகப்படுத்து", "description": "Verb" }, "unArchive": { - "message": "Unarchive" + "message": "காப்பகத்தை அகற்று" }, "itemsInArchive": { - "message": "Items in archive" + "message": "காப்பகத்தில் உள்ள உருப்படிகள்" }, "noItemsInArchive": { - "message": "No items in archive" + "message": "காப்பகத்தில் எந்த உருப்படிகளும் இல்லை" }, "noItemsInArchiveDesc": { - "message": "Archived items will appear here and will be excluded from general search results and autofill suggestions." + "message": "காப்பகப்படுத்தப்பட்ட உருப்படிகள் இங்கே தோன்றும், மேலும் அவை பொதுவான தேடல் முடிவுகள் மற்றும் தானியங்குநிரப்பு பரிந்துரைகளிலிருந்து விலக்கப்படும்." }, "itemWasSentToArchive": { - "message": "Item was sent to archive" + "message": "ஆவணம் காப்பகத்திற்கு அனுப்பப்பட்டது" }, "itemUnarchived": { - "message": "Item was unarchived" + "message": "காப்பகம் மீட்டெடுக்கப்பட்டது" }, "archiveItem": { - "message": "Archive item" + "message": "உருப்படியைக் காப்பகப்படுத்து" }, "archiveItemConfirmDesc": { - "message": "Archived items are excluded from general search results and autofill suggestions. Are you sure you want to archive this item?" + "message": "காப்பகப்படுத்தப்பட்ட உருப்படிகள் பொதுவான தேடல் முடிவுகள் மற்றும் தானியங்குநிரப்பு பரிந்துரைகளிலிருந்து விலக்கப்பட்டுள்ளன. இந்த உருப்படியை காப்பகப்படுத்த விரும்புகிறீர்களா?" }, "upgradeToUseArchive": { - "message": "A premium membership is required to use Archive." + "message": "காப்பகத்தைப் பயன்படுத்த பிரீமியம் உறுப்பினர் தேவை." }, "edit": { "message": "திருத்து" @@ -595,13 +592,13 @@ "message": "காண்" }, "viewAll": { - "message": "View all" + "message": "அனைத்தையும் காண்க" }, "showAll": { - "message": "Show all" + "message": "அனைத்தையும் காட்டு" }, "viewLess": { - "message": "View less" + "message": "குறைவாகக் காண்க" }, "viewLogin": { "message": "உள்நுழைவைக் காண்க" @@ -749,7 +746,7 @@ "message": "தவறான முதன்மை கடவுச்சொல்" }, "invalidMasterPasswordConfirmEmailAndHost": { - "message": "Invalid master password. Confirm your email is correct and your account was created on $HOST$.", + "message": "தவறான முதன்மை கடவுச்சொல். உங்கள் மின்னஞ்சல் முகவரி சரியானதா என்பதையும், உங்கள் கணக்கு $HOST$ இல் உருவாக்கப்பட்டது என்பதையும் உறுதிப்படுத்தவும்.", "placeholders": { "host": { "content": "$1", @@ -806,10 +803,10 @@ "message": "சிஸ்டம் பூட்டப்பட்டவுடன்" }, "onIdle": { - "message": "On system idle" + "message": "கணினி செயலற்ற நிலையில்" }, "onSleep": { - "message": "On system sleep" + "message": "கணினி உறக்கநிலையில்" }, "onRestart": { "message": "உலாவி மறுதொடக்கம் செய்யப்பட்டவுடன்" @@ -1050,10 +1047,10 @@ "message": "உருப்படி சேமிக்கப்பட்டது" }, "savedWebsite": { - "message": "Saved website" + "message": "சேமிக்கப்பட்ட வலைத்தளம்" }, "savedWebsites": { - "message": "Saved websites ( $COUNT$ )", + "message": "சேமிக்கப்பட்ட வலைத்தளங்கள் ( $COUNT$ )", "placeholders": { "count": { "content": "$1", @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "இதிலிருந்து ஏற்றுமதிசெய்" }, - "exportVault": { - "message": "வால்ட்டை ஏற்றுமதிசெய்" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "கோப்பு வடிவம்" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "மேலும் அறிக" }, + "migrationsFailed": { + "message": "குறியாக்க அமைப்புகளைப் புதுப்பிக்கும்போது பிழை ஏற்பட்டது." + }, + "updateEncryptionSettingsTitle": { + "message": "உங்கள் குறியாக்க அமைப்புகளைப் புதுப்பிக்கவும்" + }, + "updateEncryptionSettingsDesc": { + "message": "பரிந்துரைக்கப்பட்ட புதிய குறியாக்க அமைப்புகள் உங்கள் கணக்கு பாதுகாப்பை மேம்படுத்தும். இப்போதே புதுப்பிக்க உங்கள் முதன்மை கடவுச்சொல்லை உள்ளிடவும்." + }, + "confirmIdentityToContinue": { + "message": "தொடர உங்கள் அடையாளத்தை உறுதிப்படுத்தவும்" + }, + "enterYourMasterPassword": { + "message": "உங்கள் முதன்மை கடவுச்சொல்லை உள்ளிடவும்" + }, + "updateSettings": { + "message": "அமைப்புகளைப் புதுப்பிக்கவும்" + }, + "later": { + "message": "பின்னர்" + }, "authenticatorKeyTotp": { "message": "அங்கீகரிப்பு விசை (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "இணைப்பு சேமிக்கப்பட்டது" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "கோப்பு" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "ஒரு கோப்பைத் தேர்ந்தெடுக்கவும்" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "அதிகபட்ச கோப்பு அளவு 500 MB ஆகும்." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "கோப்பு இணைப்புகளுக்கு 1 GB என்க்ரிப்ட் செய்யப்பட்ட ஸ்டோரேஜ்." }, + "premiumSignUpStorageV2": { + "message": "கோப்பு இணைப்புகளுக்கான $SIZE$ மறைகுறியாக்கப்பட்ட சேமிப்பிடம்.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "அவசர அணுகல்." }, @@ -1576,13 +1628,13 @@ "message": "பாதுகாப்பு விசையைப் படி" }, "readingPasskeyLoading": { - "message": "Reading passkey..." + "message": "கடவுச்சொற்களைப் படிக்கிறது..." }, "passkeyAuthenticationFailed": { - "message": "Passkey authentication failed" + "message": "கடவுச்சொல் அங்கீகாரம் தோல்வியடைந்தது" }, "useADifferentLogInMethod": { - "message": "Use a different log in method" + "message": "வேறு உள்நுழைவு முறையைப் பயன்படுத்தவும்" }, "awaitingSecurityKeyInteraction": { "message": "பாதுகாப்பு விசை தொடர்புகொள்ளக் காத்திருக்கிறது..." @@ -1651,7 +1703,7 @@ "message": "நீங்கள் பேஸ் சர்வர் URL-ஐ அல்லது குறைந்தது ஒரு தனிப்பயன் சூழலைச் சேர்க்க வேண்டும்." }, "selfHostedEnvMustUseHttps": { - "message": "URLs must use HTTPS." + "message": "URLகள் HTTPS ஐப் பயன்படுத்த வேண்டும்." }, "customEnvironment": { "message": "தனிப்பயன் சூழல்" @@ -1707,28 +1759,28 @@ "message": "ஆட்டோஃபில்லை முடக்கு" }, "confirmAutofill": { - "message": "Confirm autofill" + "message": "தானியங்கு நிரப்புதலை உறுதிப்படுத்தவும்" }, "confirmAutofillDesc": { - "message": "This site doesn't match your saved login details. Before you fill in your login credentials, make sure it's a trusted site." + "message": "இந்த தளம் உங்கள் சேமிக்கப்பட்ட உள்நுழைவு விவரங்களுடன் பொருந்தவில்லை. உங்கள் உள்நுழைவு சான்றுகளை நிரப்புவதற்கு முன், அது நம்பகமான தளம்தானா என்பதை உறுதிப்படுத்திக் கொள்ளுங்கள்." }, "showInlineMenuLabel": { "message": "படிவப் புலங்களில் ஆட்டோஃபில் பரிந்துரைகளைக் காட்டு" }, "howDoesBitwardenProtectFromPhishing": { - "message": "How does Bitwarden protect your data from phishing?" + "message": "Bitwarden உங்கள் தரவை ஃபிஷிங்கிலிருந்து எவ்வாறு பாதுகாக்கிறது?" }, "currentWebsite": { - "message": "Current website" + "message": "தற்போதைய வலைத்தளம்" }, "autofillAndAddWebsite": { - "message": "Autofill and add this website" + "message": "இந்த வலைத்தளத்தைத் தானாக நிரப்பிச் சேர்க்கவும்" }, "autofillWithoutAdding": { - "message": "Autofill without adding" + "message": "சேர்க்காமல் தானாக நிரப்பு" }, "doNotAutofill": { - "message": "Do not autofill" + "message": "தானாக நிரப்ப வேண்டாம்" }, "showInlineMenuIdentitiesLabel": { "message": "பரிந்துரைகளாக அடையாளங்களைக் காட்டு" @@ -1856,7 +1908,7 @@ "message": "உங்கள் சரிபார்ப்புக் குறியீட்டிற்கான உங்கள் மின்னஞ்சலைச் சரிபார்க்க, பாப்அப் சாளரத்திற்கு வெளியே கிளிக் செய்வதால், இந்த பாப்அப் மூடப்படும். இந்த பாப்அப் மூடாமல் இருக்க, புதிய சாளரத்தில் திறக்க விரும்புகிறீர்களா?" }, "showIconsChangePasswordUrls": { - "message": "Show website icons and retrieve change password URLs" + "message": "வலைத்தள ஐகான்களைக் காண்பி, கடவுச்சொல் மாற்று URLகளை மீட்டெடுக்கவும்" }, "cardholderName": { "message": "அட்டைதாரர் பெயர்" @@ -1874,7 +1926,7 @@ "message": "காலாவதி ஆண்டு" }, "monthly": { - "message": "month" + "message": "மாதம்" }, "expiration": { "message": "காலாவதி" @@ -2024,79 +2076,79 @@ "message": "குறிப்பு" }, "newItemHeaderLogin": { - "message": "New Login", + "message": "புதிய உள்நுழைவு", "description": "Header for new login item type" }, "newItemHeaderCard": { - "message": "New Card", + "message": "புதிய அட்டை", "description": "Header for new card item type" }, "newItemHeaderIdentity": { - "message": "New Identity", + "message": "புதிய அடையாளம்", "description": "Header for new identity item type" }, "newItemHeaderNote": { - "message": "New Note", + "message": "புதிய குறிப்பு", "description": "Header for new note item type" }, "newItemHeaderSshKey": { - "message": "New SSH key", + "message": "புதிய SSH விசை", "description": "Header for new SSH key item type" }, "newItemHeaderTextSend": { - "message": "New Text Send", + "message": "புதிய உரை அனுப்புதல்", "description": "Header for new text send" }, "newItemHeaderFileSend": { - "message": "New File Send", + "message": "புதிய கோப்பு அனுப்புதல்", "description": "Header for new file send" }, "editItemHeaderLogin": { - "message": "Edit Login", + "message": "உள்நுழைவைத் திருத்து", "description": "Header for edit login item type" }, "editItemHeaderCard": { - "message": "Edit Card", + "message": "கார்டைத் திருத்து", "description": "Header for edit card item type" }, "editItemHeaderIdentity": { - "message": "Edit Identity", + "message": "அடையாளத்தைத் திருத்து", "description": "Header for edit identity item type" }, "editItemHeaderNote": { - "message": "Edit Note", + "message": "குறிப்பைத் திருத்து", "description": "Header for edit note item type" }, "editItemHeaderSshKey": { - "message": "Edit SSH key", + "message": "SSH விசையைத் திருத்து", "description": "Header for edit SSH key item type" }, "editItemHeaderTextSend": { - "message": "Edit Text Send", + "message": "உரை அனுப்புதலைத் திருத்து", "description": "Header for edit text send" }, "editItemHeaderFileSend": { - "message": "Edit File Send", + "message": "கோப்பைத் திருத்து அனுப்பு", "description": "Header for edit file send" }, "viewItemHeaderLogin": { - "message": "View Login", + "message": "உள்நுழைவைக் காண்க", "description": "Header for view login item type" }, "viewItemHeaderCard": { - "message": "View Card", + "message": "கார்டைப் பார்க்கவும்", "description": "Header for view card item type" }, "viewItemHeaderIdentity": { - "message": "View Identity", + "message": "அடையாளத்தைக் காண்க", "description": "Header for view identity item type" }, "viewItemHeaderNote": { - "message": "View Note", + "message": "குறிப்பைக் காண்க", "description": "Header for view note item type" }, "viewItemHeaderSshKey": { - "message": "View SSH key", + "message": "SSH விசையைக் காண்க", "description": "Header for view SSH key item type" }, "passwordHistory": { @@ -2446,7 +2498,7 @@ } }, "topLayerHijackWarning": { - "message": "This page is interfering with the Bitwarden experience. The Bitwarden inline menu has been temporarily disabled as a safety measure." + "message": "இந்தப் பக்கம் பிட்வார்டன் அனுபவத்தில் குறுக்கிடுகிறது. பாதுகாப்பு நடவடிக்கையாக பிட்வார்டன் இன்லைன் மெனு தற்காலிகமாக முடக்கப்பட்டுள்ளது." }, "setMasterPassword": { "message": "முதன்மை கடவுச்சொல்லை அமை" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "தனிப்பட்ட அடையாளங்காட்டி எதுவும் இல்லை." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "பின்வரும் நிறுவனத்தின் உறுப்பினர்களுக்கு இனி ஒரு முதன்மை கடவுச்சொல் தேவையில்லை. உங்கள் நிறுவன நிர்வாகியுடன் கீழே உள்ள டொமைனை உறுதிப்படுத்தவும்." - }, "organizationName": { "message": "நிறுவன பெயர்" }, @@ -3274,7 +3323,7 @@ } }, "exportingOrganizationVaultFromPasswordManagerWithDataOwnershipDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported.", + "message": "$ORGANIZATION$ உடன் தொடர்புடைய நிறுவன பெட்டகம் மட்டுமே ஏற்றுமதி செய்யப்படும்.", "placeholders": { "organization": { "content": "$1", @@ -3283,7 +3332,7 @@ } }, "exportingOrganizationVaultFromAdminConsoleWithDataOwnershipDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. My items collections will not be included.", + "message": "$ORGANIZATION$ உடன் தொடர்புடைய நிறுவன பெட்டகம் மட்டுமே ஏற்றுமதி செய்யப்படும். எனது பொருட்களின் தொகுப்புகள் சேர்க்கப்படாது.", "placeholders": { "organization": { "content": "$1", @@ -3298,7 +3347,7 @@ "message": "குறியாக்கம் நீக்கப் பிழை" }, "errorGettingAutoFillData": { - "message": "Error getting autofill data" + "message": "தானியங்குநிரப்பு தரவைப் பெறுவதில் பிழை" }, "couldNotDecryptVaultItemsBelow": { "message": "Bitwarden கீழே பட்டியலிடப்பட்ட பெட்டக பொருளை குறியாக்கம் நீக்க முடியவில்லை." @@ -4072,13 +4121,13 @@ "description": "Toast message for informing the user that autofill on page load has been set to the default setting." }, "cannotAutofill": { - "message": "Cannot autofill" + "message": "தானாக நிரப்ப முடியாது" }, "cannotAutofillExactMatch": { - "message": "Default matching is set to 'Exact Match'. The current website does not exactly match the saved login details for this item." + "message": "இயல்புநிலை பொருத்தம் 'சரியான பொருத்தம்' என அமைக்கப்பட்டுள்ளது. தற்போதைய வலைத்தளம் இந்த உருப்படிக்கான சேமிக்கப்பட்ட உள்நுழைவு விவரங்களுடன் சரியாகப் பொருந்தவில்லை." }, "okay": { - "message": "Okay" + "message": "சரி" }, "toggleSideNavigation": { "message": "பக்க வழிசெலுத்தலை மாற்று" @@ -4176,10 +4225,6 @@ "ignore": { "message": "புறக்கணி" }, - "importData": { - "message": "தரவை இறக்குமதி செய்", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "இறக்குமதி பிழை" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "கணக்கு பாதுகாப்பு" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "அறிவிப்புகள்" }, @@ -4912,7 +4966,7 @@ "message": "பிரீமியம்" }, "unlockFeaturesWithPremium": { - "message": "Unlock reporting, emergency access, and more security features with Premium." + "message": "Premium மூலம் அறிக்கையிடல், அவசரகால அணுகல் மற்றும் கூடுதல் பாதுகாப்பு அம்சங்களைத் திறக்கவும்." }, "freeOrgsCannotUseAttachments": { "message": "இலவச நிறுவனங்கள் இணைப்புகளைப் பயன்படுத்த முடியாது" @@ -4999,7 +5053,7 @@ } }, "defaultLabelWithValue": { - "message": "Default ( $VALUE$ )", + "message": "இயல்புநிலை ($VALUE$ )", "description": "A label that indicates the default value for a field with the current default value in parentheses.", "placeholders": { "value": { @@ -5662,30 +5716,30 @@ "message": "உங்கள் சேமிப்பு பெட்டகத்திற்கு நல்வரவு!" }, "phishingPageTitleV2": { - "message": "Phishing attempt detected" + "message": "ஃபிஷிங் முயற்சி கண்டறியப்பட்டது" }, "phishingPageSummary": { - "message": "The site you are attempting to visit is a known malicious site and a security risk." + "message": "நீங்கள் பார்வையிட முயற்சிக்கும் தளம் ஒரு அறியப்பட்ட தீங்கிழைக்கும் தளம் மற்றும் பாதுகாப்பு அபாயத்தைக் கொண்டுள்ளது." }, "phishingPageCloseTabV2": { - "message": "Close this tab" + "message": "இந்த தாவலை மூடு" }, "phishingPageContinueV2": { - "message": "Continue to this site (not recommended)" + "message": "இந்த தளத்திற்குத் தொடரவும் (பரிந்துரைக்கப்படவில்லை)" }, "phishingPageExplanation1": { - "message": "This site was found in ", + "message": "இந்த தளம் காணப்பட்ட இடம் ", "description": "This is in multiple parts to allow for bold text in the middle of the sentence. A proper name follows this." }, "phishingPageExplanation2": { - "message": ", an open-source list of known phishing sites used for stealing personal and sensitive information.", + "message": ", தனிப்பட்ட மற்றும் முக்கியமான தகவல்களைத் திருடப் பயன்படுத்தப்படும் அறியப்பட்ட ஃபிஷிங் தளங்களின் திறந்த மூல பட்டியல்.", "description": "This is in multiple parts to allow for bold text in the middle of the sentence. A proper name precedes this." }, "phishingPageLearnMore": { - "message": "Learn more about phishing detection" + "message": "ஃபிஷிங் கண்டறிதல் பற்றி மேலும் அறிக" }, "protectedBy": { - "message": "Protected by $PRODUCT$", + "message": "$PRODUCT$ ஆல் பாதுகாக்கப்பட்டது", "placeholders": { "product": { "content": "$1", @@ -5769,10 +5823,10 @@ "description": "Aria label for the body content of the generator nudge" }, "aboutThisSetting": { - "message": "About this setting" + "message": "இந்த அமைப்பைப் பற்றி" }, "permitCipherDetailsDescription": { - "message": "Bitwarden will use saved login URIs to identify which icon or change password URL should be used to improve your experience. No information is collected or saved when you use this service." + "message": "உங்கள் அனுபவத்தை மேம்படுத்த எந்த ஐகான் அல்லது கடவுச்சொல்லை மாற்ற URL ஐப் பயன்படுத்த வேண்டும் என்பதை அடையாளம் காண பிட்வார்டன் சேமிக்கப்பட்ட உள்நுழைவு URIகளைப் பயன்படுத்தும். நீங்கள் இந்த சேவையைப் பயன்படுத்தும்போது எந்த தகவலும் சேகரிக்கப்படாது அல்லது சேமிக்கப்படாது." }, "noPermissionsViewPage": { "message": "இந்த பக்கத்தைக் காண உங்களுக்கு அனுமதிகள் இல்லை. வேறு கணக்குடன் உள்நுழைய முயற்சிக்கவும்." @@ -5798,58 +5852,192 @@ "message": "Key Connector டொமைனை உறுதிப்படுத்து" }, "atRiskLoginsSecured": { - "message": "Great job securing your at-risk logins!" + "message": "உங்கள் ஆபத்தில் உள்ள உள்நுழைவுகளைப் பாதுகாப்பது மிகச் சிறந்த வேலை!" }, "upgradeNow": { - "message": "Upgrade now" + "message": "இப்போதே மேம்படுத்து" }, "builtInAuthenticator": { - "message": "Built-in authenticator" + "message": "உள்ளமைக்கப்பட்ட அங்கீகரிப்பான்" }, "secureFileStorage": { - "message": "Secure file storage" + "message": "பாதுகாப்பான கோப்பு சேமிப்பு" }, "emergencyAccess": { - "message": "Emergency access" + "message": "அவசர அணுகல்" }, "breachMonitoring": { - "message": "Breach monitoring" + "message": "மீறல் கண்காணிப்பு" }, "andMoreFeatures": { - "message": "And more!" + "message": "இன்னமும் அதிகமாக!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "மேம்பட்ட ஆன்லைன் பாதுகாப்பு" }, "upgradeToPremium": { - "message": "Upgrade to Premium" + "message": "பிரீமியத்திற்கு மேம்படுத்து" }, "unlockAdvancedSecurity": { - "message": "Unlock advanced security features" + "message": "மேம்பட்ட பாதுகாப்பு அம்சங்களைத் திறக்கவும்" }, "unlockAdvancedSecurityDesc": { - "message": "A Premium subscription gives you more tools to stay secure and in control" + "message": "பிரீமியம் சந்தா உங்களுக்குப் பாதுகாப்பாகவும் கட்டுப்பாட்டிலும் இருக்க கூடுதல் கருவிகளை வழங்குகிறது" }, "explorePremium": { - "message": "Explore Premium" + "message": "பிரீமியத்தை ஆராயுங்கள்" }, "loadingVault": { - "message": "Loading vault" + "message": "பெட்டகத்தை ஏற்றுகிறது" }, "vaultLoaded": { - "message": "Vault loaded" + "message": "பெட்டகம் ஏற்றப்பட்டது" }, "settingDisabledByPolicy": { - "message": "This setting is disabled by your organization's policy.", + "message": "இந்த அமைப்பு உங்கள் நிறுவனத்தின் கொள்கையால் முடக்கப்பட்டுள்ளது.", "description": "This hint text is displayed when a user setting is disabled due to an organization policy." }, "zipPostalCodeLabel": { - "message": "ZIP / Postal code" + "message": "அஞ்சல் குறியீடு" }, "cardNumberLabel": { - "message": "Card number" + "message": "அட்டை எண்" + }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." }, "sessionTimeoutSettingsAction": { - "message": "Timeout action" + "message": "காலாவதி நடவடிக்கை" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "இந்த அமைப்பை உங்கள் நிறுவனம் நிர்வகிக்கிறது." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "உங்கள் நிறுவனம் அதிகபட்ச அமர்வு நேர முடிவை $HOURS$ மணிநேரம்(கள்) மற்றும் $MINUTES$ நிமிடம்(கள்) என அமைத்துள்ளது.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "உங்கள் நிறுவனம் இயல்புநிலை அமர்வு நேர முடிவை உடனடியாக அமைத்துள்ளது." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "உங்கள் நிறுவனம் இயல்புநிலை அமர்வு நேர முடிவை கணினி பூட்டிற்கு அமைத்துள்ளது." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "உங்கள் நிறுவனம் இயல்புநிலை அமர்வு நேர முடிவை உலாவி மறுதொடக்கம் ஆன் என அமைத்துள்ளது." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "அதிகபட்ச நேர முடிவு $HOURS$ மணிநேரம்(கள்) மற்றும் $MINUTES$ நிமிடம்(கள்) ஐ விட அதிகமாக இருக்கக்கூடாது", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "உலாவியை மறுதொடக்கம் செய்யும்போது" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "உங்கள் காலாவதி செயலை மாற்ற ஒரு திறத்தல் முறையை அமைக்கவும்" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index f829937ac51..04386b72930 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Sync" }, - "syncVaultNow": { - "message": "Sync vault now" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Last sync:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web app" }, - "importItems": { - "message": "Import items" - }, "select": { "message": "Select" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, + "later": { + "message": "Later" + }, "authenticatorKeyTotp": { "message": "Authenticator key (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Attachment saved" }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "file": { "message": "File" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Select a file" }, + "itemsTransferred": { + "message": "Items transferred" + }, "maxFileSize": { "message": "Maximum file size is 500 MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Emergency access." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ignore" }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Import error" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Account security" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Notifications" }, @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Card number" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Your organization has set the default session timeout to Immediately." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On browser restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On browser restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index ef6ba5b2077..49bda58b558 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -1,12 +1,12 @@ { "appName": { - "message": "bitwarden" + "message": "Bitwarden" }, "appLogoLabel": { "message": "โลโก้ Bitwarden" }, "extName": { - "message": "Bitwarden - จัดการรหัสผ่าน", + "message": "Bitwarden Password Manager", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { @@ -14,7 +14,7 @@ "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { - "message": "ล็อกอิน หรือ สร้างบัญชีใหม่ เพื่อใช้งานตู้นิรภัยของคุณ" + "message": "เข้าสู่ระบบหรือสร้างบัญชีใหม่เพื่อเข้าถึงตู้นิรภัยของคุณ" }, "inviteAccepted": { "message": "ตอบรับคำเชิญแล้ว" @@ -23,28 +23,28 @@ "message": "สร้างบัญชี" }, "newToBitwarden": { - "message": "เพิ่งเริ่มใช้ Bitwarden ใช่ไหม?" + "message": "เพิ่งเคยใช้งาน Bitwarden ใช่หรือไม่" }, "logInWithPasskey": { "message": "เข้าสู่ระบบด้วยพาสคีย์" }, "useSingleSignOn": { - "message": "ใช้การลงชื่อเพียงครั้งเดียว" + "message": "ใช้การลงชื่อเข้าใช้แบบ SSO" }, "yourOrganizationRequiresSingleSignOn": { - "message": "Your organization requires single sign-on." + "message": "องค์กรของคุณบังคับใช้ Single Sign-On" }, "welcomeBack": { - "message": "ยินดีต้อนรับกลับมา" + "message": "ยินดีต้อนรับกลับ" }, "setAStrongPassword": { "message": "ตั้งรหัสผ่านที่รัดกุม" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "ดำเนินการสร้างบัญชีของคุณให้เสร็จสมบูรณ์โดยการตั้งรหัสผ่าน" + "message": "ตั้งรหัสผ่านเพื่อเสร็จสิ้นการสร้างบัญชี" }, "enterpriseSingleSignOn": { - "message": "Enterprise Single Sign-On" + "message": "SSO สำหรับองค์กร" }, "cancel": { "message": "ยกเลิก" @@ -53,22 +53,22 @@ "message": "ปิด" }, "submit": { - "message": "ส่งข้อมูล" + "message": "ส่ง" }, "emailAddress": { "message": "ที่อยู่อีเมล" }, "masterPass": { - "message": "Master Password" + "message": "รหัสผ่านหลัก" }, "masterPassDesc": { - "message": "รหัสผ่านหลัก คือ รหัสผ่านที่ใช้เข้าถึงตู้นิรภัยของคุณ สิ่งสำคัญมาก คือ คุณจะต้องไม่ลืมรหัสผ่านหลักโดยเด็ดขาด เพราะหากคุณลืมแล้วล่ะก็ จะไม่มีวิธีที่สามารถกู้รหัสผ่านของคุณได้เลย" + "message": "รหัสผ่านหลักคือรหัสที่คุณใช้เข้าถึงตู้นิรภัย สิ่งสำคัญคือห้ามลืมรหัสผ่านหลักเด็ดขาด เนื่องจากไม่มีวิธีกู้คืนรหัสผ่านหากคุณลืม" }, "masterPassHintDesc": { - "message": "คำใบ้เกี่ยวกับรหัสผ่านหลักสามารถช่วยให้คุณนึกรหัสผ่านหลักออกได้หากลืม" + "message": "คำใบ้รหัสผ่านหลักช่วยเตือนความจำหากคุณลืมรหัสผ่าน" }, "masterPassHintText": { - "message": "หากคุณลืมรหัสผ่าน ระบบสามารถส่งคำใบ้รหัสผ่านไปยังอีเมลของคุณได้ จำกัด $CURRENT$/$MAXIMUM$ ตัวอักษร", + "message": "หากลืมรหัสผ่าน ระบบจะส่งคำใบ้ไปที่อีเมลของคุณ สูงสุด $CURRENT$/$MAXIMUM$ ตัวอักษร", "placeholders": { "current": { "content": "$1", @@ -81,13 +81,13 @@ } }, "reTypeMasterPass": { - "message": "Re-type Master Password" + "message": "ป้อนรหัสผ่านหลักอีกครั้ง" }, "masterPassHint": { - "message": "Master Password Hint (optional)" + "message": "คำใบ้รหัสผ่านหลัก (ไม่บังคับ)" }, "passwordStrengthScore": { - "message": "คะแนนความรัดกุมของรหัสผ่าน $SCORE$", + "message": "ระดับความรัดกุมของรหัสผ่าน $SCORE$", "placeholders": { "score": { "content": "$1", @@ -96,10 +96,10 @@ } }, "joinOrganization": { - "message": "Join organization" + "message": "เข้าร่วมองค์กร" }, "joinOrganizationName": { - "message": "Join $ORGANIZATIONNAME$", + "message": "เข้าร่วม $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -108,7 +108,7 @@ } }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "ตั้งรหัสผ่านหลักเพื่อเสร็จสิ้นการเข้าร่วมองค์กรนี้" }, "tab": { "message": "แท็บ" @@ -117,7 +117,7 @@ "message": "ตู้นิรภัย" }, "myVault": { - "message": "My Vault" + "message": "ตู้นิรภัยของฉัน" }, "allVaults": { "message": "ตู้นิรภัยทั้งหมด" @@ -135,10 +135,10 @@ "message": "คัดลอกรหัสผ่าน" }, "copyPassphrase": { - "message": "Copy passphrase" + "message": "คัดลอกวลีรหัสผ่าน" }, "copyNote": { - "message": "Copy Note" + "message": "คัดลอกโน้ต" }, "copyUri": { "message": "คัดลอก URI" @@ -150,34 +150,34 @@ "message": "คัดลอกหมายเลข" }, "copySecurityCode": { - "message": "คัดลอกรหัสรักษาความปลอดภัย" + "message": "คัดลอกรหัสความปลอดภัย" }, "copyName": { - "message": "Copy name" + "message": "คัดลอกชื่อ" }, "copyCompany": { - "message": "Copy company" + "message": "คัดลอกบริษัท" }, "copySSN": { - "message": "Copy Social Security number" + "message": "คัดลอกหมายเลขประกันสังคม" }, "copyPassportNumber": { - "message": "Copy passport number" + "message": "คัดลอกเลขหนังสือเดินทาง" }, "copyLicenseNumber": { - "message": "Copy license number" + "message": "คัดลอกเลขใบขับขี่" }, "copyPrivateKey": { - "message": "Copy private key" + "message": "คัดลอกกุญแจส่วนตัว" }, "copyPublicKey": { - "message": "Copy public key" + "message": "คัดลอกกุญแจสาธารณะ" }, "copyFingerprint": { - "message": "Copy fingerprint" + "message": "คัดลอกลายนิ้วมือ" }, "copyCustomField": { - "message": "Copy $FIELD$", + "message": "คัดลอก $FIELD$", "placeholders": { "field": { "content": "$1", @@ -186,186 +186,186 @@ } }, "copyWebsite": { - "message": "Copy website" + "message": "คัดลอกเว็บไซต์" }, "copyNotes": { - "message": "Copy notes" + "message": "คัดลอกโน้ต" }, "copy": { - "message": "Copy", + "message": "คัดลอก", "description": "Copy to clipboard" }, "fill": { - "message": "Fill", + "message": "ป้อน", "description": "This string is used on the vault page to indicate autofilling. Horizontal space is limited in the interface here so try and keep translations as concise as possible." }, "autoFill": { - "message": "กรอกข้อมูลอัตโนมัติ" + "message": "ป้อนอัตโนมัติ" }, "autoFillLogin": { - "message": "Autofill login" + "message": "ป้อนข้อมูลเข้าสู่ระบบอัตโนมัติ" }, "autoFillCard": { - "message": "Autofill card" + "message": "ป้อนข้อมูลบัตรอัตโนมัติ" }, "autoFillIdentity": { - "message": "Autofill identity" + "message": "ป้อนข้อมูลระบุตัวตนอัตโนมัติ" }, "fillVerificationCode": { - "message": "Fill verification code" + "message": "ป้อนรหัสยืนยัน" }, "fillVerificationCodeAria": { - "message": "Fill Verification Code", + "message": "ป้อนรหัสยืนยัน", "description": "Aria label for the heading displayed the inline menu for totp code autofill" }, "generatePasswordCopied": { - "message": "Generate Password (copied)" + "message": "สร้างรหัสผ่าน (คัดลอกแล้ว)" }, "copyElementIdentifier": { - "message": "คัดลอกชื่อของช่องที่กำหนดเอง" + "message": "คัดลอกชื่อฟิลด์ที่กำหนดเอง" }, "noMatchingLogins": { - "message": "ไม่พบข้อมูลล็อกอินที่ตรงกัน" + "message": "ไม่พบข้อมูลเข้าสู่ระบบที่ตรงกัน" }, "noCards": { - "message": "No cards" + "message": "ไม่มีบัตร" }, "noIdentities": { - "message": "No identities" + "message": "ไม่มีข้อมูลระบุตัวตน" }, "addLoginMenu": { - "message": "Add login" + "message": "เพิ่มข้อมูลเข้าสู่ระบบ" }, "addCardMenu": { - "message": "Add card" + "message": "เพิ่มบัตร" }, "addIdentityMenu": { - "message": "Add identity" + "message": "เพิ่มข้อมูลระบุตัวตน" }, "unlockVaultMenu": { - "message": "ปลดล็อกกตู้นิรภัยของคุณ" + "message": "ปลดล็อกตู้นิรภัย" }, "loginToVaultMenu": { - "message": "ลงชื่อเข้าใช้ตู้นิรภัยของคุณ" + "message": "เข้าสู่ระบบตู้นิรภัย" }, "autoFillInfo": { - "message": "ไม่พบข้อมูลล็อกอินเพื่อใช้กรอกข้อมูลอัตโนมัติ สำหรับแท็บปัจจุบันของเบราว์เซอร์" + "message": "ไม่มีข้อมูลเข้าสู่ระบบสำหรับป้อนในแท็บเบราว์เซอร์ปัจจุบัน" }, "addLogin": { - "message": "Add a Login" + "message": "เพิ่มข้อมูลเข้าสู่ระบบ" }, "addItem": { "message": "เพิ่มรายการ" }, "accountEmail": { - "message": "Account email" + "message": "อีเมลบัญชี" }, "requestHint": { - "message": "Request hint" + "message": "ขอคำใบ้" }, "requestPasswordHint": { - "message": "Request password hint" + "message": "ขอคำใบ้รหัสผ่าน" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "กรอกที่อยู่อีเมลบัญชีของคุณ แล้วระบบจะส่งคำใบ้รหัสผ่านไปให้คุณ" + "message": "กรอกอีเมลบัญชี แล้วระบบจะส่งคำใบ้รหัสผ่านไปให้" }, "getMasterPasswordHint": { - "message": "รับคำใบ้เกี่ยวกับรหัสผ่านหลักของคุณ" + "message": "รับคำใบ้รหัสผ่านหลัก" }, "continue": { - "message": "ดำเนินการต่อไป" + "message": "ดำเนินการต่อ" }, "sendVerificationCode": { - "message": "ส่งโค้ดยืนยันไปยังอีเมลของคุณ" + "message": "ส่งรหัสยืนยันไปที่อีเมล" }, "sendCode": { - "message": "ส่งโค้ด" + "message": "ส่งรหัส" }, "codeSent": { - "message": "ส่งโค้ดแล้ว" + "message": "ส่งรหัสแล้ว" }, "verificationCode": { - "message": "Verification Code" + "message": "รหัสยืนยัน" }, "confirmIdentity": { - "message": "ยืนยันตัวตนของคุณเพื่อดำเนินการต่อ" + "message": "ยืนยันตัวตนเพื่อดำเนินการต่อ" }, "changeMasterPassword": { - "message": "Change Master Password" + "message": "เปลี่ยนรหัสผ่านหลัก" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "ไปที่เว็บแอปหรือไม่" }, "continueToWebAppDesc": { - "message": "Explore more features of your Bitwarden account on the web app." + "message": "สำรวจฟีเจอร์เพิ่มเติมของบัญชี Bitwarden บนเว็บแอป" }, "continueToHelpCenter": { - "message": "Continue to Help Center?" + "message": "ไปที่ศูนย์ช่วยเหลือหรือไม่" }, "continueToHelpCenterDesc": { - "message": "Learn more about how to use Bitwarden on the Help Center." + "message": "เรียนรู้วิธีการใช้งาน Bitwarden เพิ่มเติมได้ที่ศูนย์ช่วยเหลือ" }, "continueToBrowserExtensionStore": { - "message": "Continue to browser extension store?" + "message": "ไปที่ร้านค้าส่วนขยายหรือไม่" }, "continueToBrowserExtensionStoreDesc": { - "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now." + "message": "ช่วยบอกต่อว่า Bitwarden ดีอย่างไร แวะไปที่ร้านค้าส่วนขยายของเบราว์เซอร์และให้คะแนนเลย" }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "คุณสามารถเปลี่ยนรหัสผ่านหลักได้ที่เว็บแอป Bitwarden" }, "fingerprintPhrase": { - "message": "Fingerprint Phrase", + "message": "วลีลายนิ้วมือ", "description": "A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing." }, "yourAccountsFingerprint": { - "message": "ข้อความลายนิ้วมือของบัญชีของคุณ", + "message": "วลีลายนิ้วมือของบัญชี", "description": "A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing." }, "twoStepLogin": { - "message": "Two-step Login" + "message": "การยืนยันตัวตนสองขั้นตอน" }, "logOut": { "message": "ออกจากระบบ" }, "aboutBitwarden": { - "message": "About Bitwarden" + "message": "เกี่ยวกับ Bitwarden" }, "about": { "message": "เกี่ยวกับ" }, "moreFromBitwarden": { - "message": "More from Bitwarden" + "message": "เพิ่มเติมจาก Bitwarden" }, "continueToBitwardenDotCom": { - "message": "Continue to bitwarden.com?" + "message": "ไปที่ bitwarden.com หรือไม่" }, "bitwardenForBusiness": { - "message": "Bitwarden for Business" + "message": "Bitwarden สำหรับธุรกิจ" }, "bitwardenAuthenticator": { "message": "Bitwarden Authenticator" }, "continueToAuthenticatorPageDesc": { - "message": "Bitwarden Authenticator allows you to store authenticator keys and generate TOTP codes for 2-step verification flows. Learn more on the bitwarden.com website" + "message": "Bitwarden Authenticator ช่วยจัดเก็บคีย์และสร้างรหัส TOTP สำหรับการยืนยันตัวตนสองขั้นตอน เรียนรู้เพิ่มเติมที่เว็บไซต์ bitwarden.com" }, "bitwardenSecretsManager": { "message": "Bitwarden Secrets Manager" }, "continueToSecretsManagerPageDesc": { - "message": "Securely store, manage, and share developer secrets with Bitwarden Secrets Manager. Learn more on the bitwarden.com website." + "message": "จัดเก็บ จัดการ และแชร์ความลับสำหรับนักพัฒนาอย่างปลอดภัยด้วย Bitwarden Secrets Manager เรียนรู้เพิ่มเติมที่เว็บไซต์ bitwarden.com" }, "passwordlessDotDev": { "message": "Passwordless.dev" }, "continueToPasswordlessDotDevPageDesc": { - "message": "Create smooth and secure login experiences free from traditional passwords with Passwordless.dev. Learn more on the bitwarden.com website." + "message": "สร้างประสบการณ์การเข้าสู่ระบบที่ลื่นไหลและปลอดภัย ปราศจากรหัสผ่านแบบเดิม ๆ ด้วย Passwordless.dev เรียนรู้เพิ่มเติมที่เว็บไซต์ bitwarden.com" }, "freeBitwardenFamilies": { - "message": "Free Bitwarden Families" + "message": "Bitwarden Families ฟรี" }, "freeBitwardenFamiliesPageDesc": { - "message": "You are eligible for Free Bitwarden Families. Redeem this offer today in the web app." + "message": "คุณได้รับสิทธิ์ใช้งาน Bitwarden Families ฟรี รับสิทธิ์ข้อเสนอนี้ได้ทันทีในเว็บแอป" }, "version": { "message": "เวอร์ชัน" @@ -386,7 +386,7 @@ "message": "แก้ไขโฟลเดอร์" }, "editFolderWithName": { - "message": "Edit folder: $FOLDERNAME$", + "message": "แก้ไขโฟลเดอร์: $FOLDERNAME$", "placeholders": { "foldername": { "content": "$1", @@ -395,22 +395,22 @@ } }, "newFolder": { - "message": "New folder" + "message": "โฟลเดอร์ใหม่" }, "folderName": { - "message": "Folder name" + "message": "ชื่อโฟลเดอร์" }, "folderHintText": { - "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + "message": "ซ้อนโฟลเดอร์โดยการใส่ชื่อโฟลเดอร์หลักตามด้วยเครื่องหมาย “/” ตัวอย่าง: โซเชียล/ฟอรัม" }, "noFoldersAdded": { - "message": "No folders added" + "message": "ยังไม่ได้เพิ่มโฟลเดอร์" }, "createFoldersToOrganize": { - "message": "Create folders to organize your vault items" + "message": "สร้างโฟลเดอร์เพื่อจัดระเบียบรายการในตู้นิรภัย" }, "deleteFolderPermanently": { - "message": "Are you sure you want to permanently delete this folder?" + "message": "ยืนยันที่จะลบโฟลเดอร์นี้ถาวรหรือไม่" }, "deleteFolder": { "message": "ลบโฟลเดอร์" @@ -419,68 +419,65 @@ "message": "โฟลเดอร์" }, "noFolders": { - "message": "ไม่มีโฟลเดอร์" + "message": "ไม่มีโฟลเดอร์ที่จะแสดง" }, "helpFeedback": { - "message": "Help & Feedback" + "message": "ความช่วยเหลือและข้อเสนอแนะ" }, "helpCenter": { - "message": "Bitwarden Help center" + "message": "ศูนย์ช่วยเหลือ Bitwarden" }, "communityForums": { - "message": "Explore Bitwarden community forums" + "message": "สำรวจฟอรัมชุมชน Bitwarden" }, "contactSupport": { - "message": "Contact Bitwarden support" + "message": "ติดต่อฝ่ายสนับสนุน Bitwarden" }, "sync": { "message": "ซิงค์" }, - "syncVaultNow": { - "message": "Sync Vault Now" + "syncNow": { + "message": "ซิงค์ทันที" }, "lastSync": { - "message": "Last Sync:" + "message": "ซิงค์ล่าสุด:" }, "passGen": { - "message": "Password Generator" + "message": "ตัวสร้างรหัสผ่าน" }, "generator": { - "message": "สุ่มรหัส", + "message": "ตัวสร้าง", "description": "Short for 'credential generator'." }, "passGenInfo": { - "message": "สร้างรหัสผ่านที่รัดกุมและไม่ซ้ำใครโดยอัตโนมัติสำหรับการเข้าสู่ระบบของคุณ" + "message": "สร้างรหัสผ่านที่รัดกุมและไม่ซ้ำกันสำหรับข้อมูลเข้าสู่ระบบของคุณโดยอัตโนมัติ" }, "bitWebVaultApp": { - "message": "Bitwarden web app" - }, - "importItems": { - "message": "Import Items" + "message": "เว็บแอป Bitwarden" }, "select": { "message": "เลือก" }, "generatePassword": { - "message": "Generate Password" + "message": "สร้างรหัสผ่าน" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "สร้างวลีรหัสผ่าน" }, "passwordGenerated": { - "message": "Password generated" + "message": "สร้างรหัสผ่านแล้ว" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "สร้างวลีรหัสผ่านแล้ว" }, "usernameGenerated": { - "message": "Username generated" + "message": "สร้างชื่อผู้ใช้แล้ว" }, "emailGenerated": { - "message": "Email generated" + "message": "สร้างอีเมลแล้ว" }, "regeneratePassword": { - "message": "Regenerate Password" + "message": "สร้างรหัสผ่านใหม่" }, "options": { "message": "ตัวเลือก" @@ -489,11 +486,11 @@ "message": "ความยาว" }, "include": { - "message": "Include", + "message": "รวม", "description": "Card header for password generator include block" }, "uppercaseDescription": { - "message": "Include uppercase characters", + "message": "รวมตัวอักษรพิมพ์ใหญ่", "description": "Tooltip for the password generator uppercase character checkbox" }, "uppercaseLabel": { @@ -501,7 +498,7 @@ "description": "Label for the password generator uppercase character checkbox" }, "lowercaseDescription": { - "message": "Include lowercase characters", + "message": "รวมตัวอักษรพิมพ์เล็ก", "description": "Full description for the password generator lowercase character checkbox" }, "lowercaseLabel": { @@ -509,7 +506,7 @@ "description": "Label for the password generator lowercase character checkbox" }, "numbersDescription": { - "message": "Include numbers", + "message": "รวมตัวเลข", "description": "Full description for the password generator numbers checkbox" }, "numbersLabel": { @@ -517,100 +514,100 @@ "description": "Label for the password generator numbers checkbox" }, "specialCharactersDescription": { - "message": "Include special characters", + "message": "รวมอักขระพิเศษ", "description": "Full description for the password generator special characters checkbox" }, "numWords": { - "message": "Number of Words" + "message": "จำนวนคำ" }, "wordSeparator": { - "message": "Word Separator" + "message": "ตัวคั่นคำ" }, "capitalize": { "message": "ขึ้นต้นด้วยตัวพิมพ์ใหญ่", "description": "Make the first letter of a work uppercase." }, "includeNumber": { - "message": "ต่อท้ายด้วยตัวเลข" + "message": "รวมตัวเลข" }, "minNumbers": { - "message": "Minimum Numbers" + "message": "จำนวนตัวเลขขั้นต่ำ" }, "minSpecial": { - "message": "Minimum Special" + "message": "จำนวนอักขระพิเศษขั้นต่ำ" }, "avoidAmbiguous": { - "message": "Avoid ambiguous characters", + "message": "หลีกเลี่ยงอักขระที่กำกวม", "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "มีการใช้นโยบายองค์กรกับตัวเลือกของตัวสร้างรหัสผ่าน", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { "message": "ค้นหาในตู้นิรภัย" }, "resetSearch": { - "message": "Reset search" + "message": "รีเซ็ตการค้นหา" }, "archiveNoun": { - "message": "Archive", + "message": "รายการจัดเก็บถาวร", "description": "Noun" }, "archiveVerb": { - "message": "Archive", + "message": "จัดเก็บถาวร", "description": "Verb" }, "unArchive": { - "message": "Unarchive" + "message": "เลิกจัดเก็บถาวร" }, "itemsInArchive": { - "message": "Items in archive" + "message": "รายการในที่จัดเก็บถาวร" }, "noItemsInArchive": { - "message": "No items in archive" + "message": "ไม่มีรายการจัดเก็บถาวร" }, "noItemsInArchiveDesc": { - "message": "Archived items will appear here and will be excluded from general search results and autofill suggestions." + "message": "รายการที่จัดเก็บถาวรจะปรากฏที่นี่ และจะไม่ถูกรวมในผลการค้นหาทั่วไปหรือคำแนะนำการป้อนอัตโนมัติ" }, "itemWasSentToArchive": { - "message": "Item was sent to archive" + "message": "ย้ายรายการไปที่จัดเก็บถาวรแล้ว" }, "itemUnarchived": { - "message": "Item was unarchived" + "message": "เลิกจัดเก็บถาวรรายการแล้ว" }, "archiveItem": { - "message": "Archive item" + "message": "จัดเก็บรายการถาวร" }, "archiveItemConfirmDesc": { - "message": "Archived items are excluded from general search results and autofill suggestions. Are you sure you want to archive this item?" + "message": "รายการที่จัดเก็บถาวรจะไม่ถูกรวมในผลการค้นหาทั่วไปและคำแนะนำการป้อนอัตโนมัติ ยืนยันที่จะจัดเก็บรายการนี้ถาวรหรือไม่" }, "upgradeToUseArchive": { - "message": "A premium membership is required to use Archive." + "message": "ต้องเป็นสมาชิกพรีเมียมจึงจะใช้งานฟีเจอร์จัดเก็บถาวรได้" }, "edit": { "message": "แก้ไข" }, "view": { - "message": "แสดง" + "message": "ดู" }, "viewAll": { - "message": "View all" + "message": "ดูทั้งหมด" }, "showAll": { - "message": "Show all" + "message": "แสดงทั้งหมด" }, "viewLess": { - "message": "View less" + "message": "ดูน้อยลง" }, "viewLogin": { - "message": "View login" + "message": "ดูข้อมูลเข้าสู่ระบบ" }, "noItemsInList": { - "message": "ไม่มีรายการ" + "message": "ไม่มีรายการที่จะแสดง" }, "itemInformation": { - "message": "Item Information" + "message": "ข้อมูลรายการ" }, "username": { "message": "ชื่อผู้ใช้" @@ -619,28 +616,28 @@ "message": "รหัสผ่าน" }, "totp": { - "message": "Authenticator secret" + "message": "รหัสลับยืนยันตัวตน" }, "passphrase": { - "message": "ข้อความรหัสผ่าน" + "message": "วลีรหัสผ่าน" }, "favorite": { "message": "รายการโปรด" }, "unfavorite": { - "message": "Unfavorite" + "message": "เลิกเป็นรายการโปรด" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "เพิ่มรายการในรายการโปรดแล้ว" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "ลบรายการออกจากรายการโปรดแล้ว" }, "notes": { "message": "โน้ต" }, "privateNote": { - "message": "Private note" + "message": "โน้ตส่วนตัว" }, "note": { "message": "โน้ต" @@ -658,13 +655,13 @@ "message": "ดูรายการ" }, "launch": { - "message": "เริ่ม" + "message": "เปิด" }, "launchWebsite": { - "message": "Launch website" + "message": "เปิดเว็บไซต์" }, "launchWebsiteName": { - "message": "Launch website $ITEMNAME$", + "message": "เปิดเว็บไซต์ $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -676,7 +673,7 @@ "message": "เว็บไซต์" }, "toggleVisibility": { - "message": "Toggle Visibility" + "message": "สลับการแสดงผล" }, "manage": { "message": "จัดการ" @@ -685,55 +682,55 @@ "message": "อื่น ๆ" }, "unlockMethods": { - "message": "Unlock options" + "message": "ตัวเลือกการปลดล็อก" }, "unlockMethodNeededToChangeTimeoutActionDesc": { - "message": "Set up an unlock method to change your vault timeout action." + "message": "ตั้งค่าวิธีการปลดล็อกเพื่อเปลี่ยนการดำเนินการเมื่อตู้นิรภัยหมดเวลา" }, "unlockMethodNeeded": { - "message": "Set up an unlock method in Settings" + "message": "ตั้งค่าวิธีการปลดล็อกในการตั้งค่า" }, "sessionTimeoutHeader": { - "message": "Session timeout" + "message": "เซสชันหมดเวลา" }, "vaultTimeoutHeader": { - "message": "Vault timeout" + "message": "ตู้นิรภัยหมดเวลา" }, "otherOptions": { - "message": "Other options" + "message": "ตัวเลือกอื่น ๆ" }, "rateExtension": { - "message": "Rate the Extension" + "message": "ให้คะแนนส่วนขยาย" }, "browserNotSupportClipboard": { - "message": "เว็บเบราว์เซอร์ของคุณไม่รองรับการคัดลอกคลิปบอร์ดอย่างง่าย คัดลอกด้วยตนเองแทน" + "message": "เว็บเบราว์เซอร์ของคุณไม่รองรับการคัดลอกไปยังคลิปบอร์ดแบบง่าย โปรดคัดลอกด้วยตนเองแทน" }, "verifyYourIdentity": { - "message": "Verify your identity" + "message": "ยืนยันตัวตนของคุณ" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "เราไม่รู้จักอุปกรณ์นี้ ป้อนรหัสที่ส่งไปยังอีเมลของคุณเพื่อยืนยันตัวตน" }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "ดำเนินการเข้าสู่ระบบต่อ" }, "yourVaultIsLocked": { - "message": "ตู้เซฟของคุณถูกล็อก ยืนยันตัวตนของคุณเพื่อดำเนินการต่อ" + "message": "ตู้นิรภัยล็อกอยู่ ยืนยันตัวตนเพื่อดำเนินการต่อ" }, "yourVaultIsLockedV2": { - "message": "ห้องนิรภัยของคุณถูกล็อก" + "message": "ตู้นิรภัยล็อกอยู่" }, "yourAccountIsLocked": { - "message": "Your account is locked" + "message": "บัญชีของคุณถูกล็อก" }, "or": { - "message": "or" + "message": "หรือ" }, "unlock": { - "message": "ปลดล็อค" + "message": "ปลดล็อก" }, "loggedInAsOn": { - "message": "ล็อกอินด้วย $EMAIL$ บน $HOSTNAME$", + "message": "เข้าสู่ระบบในชื่อ $EMAIL$ บน $HOSTNAME$", "placeholders": { "email": { "content": "$1", @@ -749,7 +746,7 @@ "message": "รหัสผ่านหลักไม่ถูกต้อง" }, "invalidMasterPasswordConfirmEmailAndHost": { - "message": "Invalid master password. Confirm your email is correct and your account was created on $HOST$.", + "message": "รหัสผ่านหลักไม่ถูกต้อง โปรดยืนยันว่าอีเมลของคุณถูกต้องและบัญชีถูกสร้างขึ้นบน $HOST$", "placeholders": { "host": { "content": "$1", @@ -758,16 +755,16 @@ } }, "vaultTimeout": { - "message": "ระยะเวลาล็อกตู้เซฟ" + "message": "ระยะเวลาหมดเวลาตู้นิรภัย" }, "vaultTimeout1": { - "message": "Timeout" + "message": "หมดเวลา" }, "lockNow": { - "message": "Lock Now" + "message": "ล็อกทันที" }, "lockAll": { - "message": "Lock all" + "message": "ล็อกทั้งหมด" }, "immediately": { "message": "ทันที" @@ -803,52 +800,52 @@ "message": "4 ชั่วโมง" }, "onLocked": { - "message": "On Locked" + "message": "เมื่อล็อกระบบ" }, "onIdle": { - "message": "On system idle" + "message": "เมื่อระบบไม่ได้ใช้งาน" }, "onSleep": { - "message": "On system sleep" + "message": "เมื่อระบบสลีป" }, "onRestart": { - "message": "On Restart" + "message": "เมื่อรีสตาร์ตเบราว์เซอร์" }, "never": { - "message": "ไม่อีกเลย" + "message": "ไม่เลย" }, "security": { "message": "ความปลอดภัย" }, "confirmMasterPassword": { - "message": "Confirm master password" + "message": "ยืนยันรหัสผ่านหลัก" }, "masterPassword": { - "message": "Master password" + "message": "รหัสผ่านหลัก" }, "masterPassImportant": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "รหัสผ่านหลักไม่สามารถกู้คืนได้หากคุณลืม!" }, "masterPassHintLabel": { - "message": "Master password hint" + "message": "คำใบ้รหัสผ่านหลัก" }, "errorOccurred": { - "message": "พบข้อผิดพลาด" + "message": "เกิดข้อผิดพลาด" }, "emailRequired": { - "message": "ต้องระบุอีเมล" + "message": "จำเป็นต้องระบุที่อยู่อีเมล" }, "invalidEmail": { "message": "ที่อยู่อีเมลไม่ถูกต้อง" }, "masterPasswordRequired": { - "message": "ต้องใช้รหัสผ่านหลัก" + "message": "จำเป็นต้องระบุรหัสผ่านหลัก" }, "confirmMasterPasswordRequired": { - "message": "ต้องพิมพ์รหัสผ่านหลักอีกครั้ง" + "message": "จำเป็นต้องป้อนรหัสผ่านหลักซ้ำ" }, "masterPasswordMinlength": { - "message": "Master password must be at least $VALUE$ characters long.", + "message": "รหัสผ่านหลักต้องมีความยาวอย่างน้อย $VALUE$ ตัวอักษร", "description": "The Master Password must be at least a specific number of characters long.", "placeholders": { "value": { @@ -858,37 +855,37 @@ } }, "masterPassDoesntMatch": { - "message": "การยืนยันรหัสผ่านหลักไม่ตรงกัน" + "message": "ยืนยันรหัสผ่านหลักไม่ตรงกัน" }, "newAccountCreated": { - "message": "บัญชีใหม่ของคุณถูกสร้างขึ้นแล้ว! ตอนนี้คุณสามารถเข้าสู่ระบบ" + "message": "สร้างบัญชีใหม่แล้ว! คุณสามารถเข้าสู่ระบบได้ทันที" }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "สร้างบัญชีใหม่แล้ว!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "เข้าสู่ระบบแล้ว!" }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "คุณเข้าสู่ระบบสำเร็จ" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "คุณสามารถปิดหน้าต่างนี้ได้" }, "masterPassSent": { - "message": "เราได้ส่งอีเมลพร้อมคำใบ้รหัสผ่านหลักของคุณออกไปแล้ว" + "message": "ส่งอีเมลแจ้งคำใบ้รหัสผ่านหลักให้คุณแล้ว" }, "verificationCodeRequired": { - "message": "ต้องระบุโค้ดยืนยัน" + "message": "จำเป็นต้องระบุรหัสยืนยัน" }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "การยืนยันตัวตนถูกยกเลิกหรือใช้เวลานานเกินไป โปรดลองอีกครั้ง" }, "invalidVerificationCode": { - "message": "โค้ดยืนยันไม่ถูกต้อง" + "message": "รหัสยืนยันไม่ถูกต้อง" }, "valueCopied": { - "message": "$VALUE$ copied", + "message": "คัดลอก $VALUE$ แล้ว", "description": "Value has been copied to the clipboard.", "placeholders": { "value": { @@ -898,127 +895,127 @@ } }, "autofillError": { - "message": "Unable to auto-fill the selected login on this page. Copy/paste your username and/or password instead." + "message": "ไม่สามารถป้อนข้อมูลรายการที่เลือกบนหน้านี้ได้อัตโนมัติ โปรดคัดลอกและวางข้อมูลแทน" }, "totpCaptureError": { - "message": "Unable to scan QR code from the current webpage" + "message": "ไม่สามารถสแกน QR Code จากหน้าเว็บปัจจุบัน" }, "totpCaptureSuccess": { - "message": "Authenticator key added" + "message": "เพิ่มคีย์ยืนยันตัวตนแล้ว" }, "totpCapture": { - "message": "Scan authenticator QR code from current webpage" + "message": "สแกน QR Code สำหรับแอปยืนยันตัวตนจากหน้าเว็บปัจจุบัน" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "ทำให้การยืนยันตัวตน 2 ขั้นตอนราบรื่นยิ่งขึ้น" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden สามารถจัดเก็บและป้อนรหัสยืนยัน 2 ขั้นตอนได้ คัดลอกและวางคีย์ลงในช่องนี้" }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden สามารถจัดเก็บและป้อนรหัสยืนยัน 2 ขั้นตอนได้ เลือกไอคอนกล้องเพื่อถ่ายภาพหน้าจอ QR Code ของแอปยืนยันตัวตนจากเว็บไซต์นี้ หรือคัดลอกและวางคีย์ลงในช่องนี้" }, "learnMoreAboutAuthenticators": { - "message": "Learn more about authenticators" + "message": "เรียนรู้เพิ่มเติมเกี่ยวกับแอปยืนยันตัวตน" }, "copyTOTP": { - "message": "Copy Authenticator key (TOTP)" + "message": "คัดลอกคีย์ยืนยันตัวตน (TOTP)" }, "loggedOut": { - "message": "ออกจากระบบ" + "message": "ออกจากระบบแล้ว" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "คุณออกจากระบบบัญชีแล้ว" }, "loginExpired": { - "message": "เซสชันของคุณหมดอายุแล้ว" + "message": "เซสชันการเข้าสู่ระบบหมดอายุ" }, "logIn": { - "message": "Log in" + "message": "เข้าสู่ระบบ" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "เข้าสู่ระบบ Bitwarden" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "ป้อนรหัสที่ส่งไปยังอีเมลของคุณ" }, "enterTheCodeFromYourAuthenticatorApp": { - "message": "Enter the code from your authenticator app" + "message": "ป้อนรหัสจากแอปยืนยันตัวตน" }, "pressYourYubiKeyToAuthenticate": { - "message": "Press your YubiKey to authenticate" + "message": "กด YubiKey ของคุณเพื่อยืนยันตัวตน" }, "duoTwoFactorRequiredPageSubtitle": { - "message": "Duo two-step login is required for your account. Follow the steps below to finish logging in." + "message": "บัญชีของคุณจำเป็นต้องเข้าสู่ระบบ 2 ขั้นตอนผ่าน Duo ทำตามขั้นตอนด้านล่างเพื่อเสร็จสิ้นการเข้าสู่ระบบ" }, "followTheStepsBelowToFinishLoggingIn": { - "message": "Follow the steps below to finish logging in." + "message": "ทำตามขั้นตอนด้านล่างเพื่อเสร็จสิ้นการเข้าสู่ระบบ" }, "followTheStepsBelowToFinishLoggingInWithSecurityKey": { - "message": "Follow the steps below to finish logging in with your security key." + "message": "ทำตามขั้นตอนด้านล่างเพื่อเสร็จสิ้นการเข้าสู่ระบบด้วยคีย์ความปลอดภัย" }, "restartRegistration": { - "message": "Restart registration" + "message": "เริ่มการลงทะเบียนใหม่" }, "expiredLink": { - "message": "Expired link" + "message": "ลิงก์หมดอายุ" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "โปรดเริ่มการลงทะเบียนใหม่หรือลองเข้าสู่ระบบ" }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "คุณอาจมีบัญชีอยู่แล้ว" }, "logOutConfirmation": { - "message": "คุณต้องการล็อกเอาต์ใช่หรือไม่?" + "message": "ยืนยันที่จะออกจากระบบหรือไม่" }, "yes": { "message": "ใช่" }, "no": { - "message": "ไม่ใช่" + "message": "ไม่" }, "location": { - "message": "Location" + "message": "ตำแหน่งที่ตั้ง" }, "unexpectedError": { - "message": "An unexpected error has occured." + "message": "เกิดข้อผิดพลาดที่ไม่คาดคิด" }, "nameRequired": { - "message": "ต้องระบุชื่อ" + "message": "จำเป็นต้องระบุชื่อ" }, "addedFolder": { "message": "เพิ่มโฟลเดอร์แล้ว" }, "twoStepLoginConfirmation": { - "message": "Two-step login makes your account more secure by requiring you to enter a security code from an authenticator app whenever you log in. Two-step login can be enabled on the bitwarden.com web vault. Do you want to visit the website now?" + "message": "การเข้าสู่ระบบ 2 ขั้นตอนช่วยให้บัญชีปลอดภัยยิ่งขึ้น โดยกำหนดให้คุณยืนยันการเข้าสู่ระบบด้วยอุปกรณ์อื่น เช่น คีย์ความปลอดภัย แอปยืนยันตัวตน SMS โทรศัพท์ หรืออีเมล สามารถตั้งค่าได้ที่เว็บตู้นิรภัย bitwarden.com ต้องการไปที่เว็บไซต์ตอนนี้หรือไม่" }, "twoStepLoginConfirmationContent": { - "message": "Make your account more secure by setting up two-step login in the Bitwarden web app." + "message": "ทำให้บัญชีปลอดภัยยิ่งขึ้นด้วยการตั้งค่าการเข้าสู่ระบบ 2 ขั้นตอนในเว็บแอป Bitwarden" }, "twoStepLoginConfirmationTitle": { - "message": "Continue to web app?" + "message": "ไปที่เว็บแอปหรือไม่" }, "editedFolder": { - "message": "Edited Folder" + "message": "บันทึกโฟลเดอร์แล้ว" }, "deleteFolderConfirmation": { - "message": "คุณแน่ใจหรือไม่ว่าต้องการลบโฟลเดอร์นี้" + "message": "ยืนยันที่จะลบโฟลเดอร์นี้หรือไม่" }, "deletedFolder": { "message": "ลบโฟลเดอร์แล้ว" }, "gettingStartedTutorial": { - "message": "Getting Started Tutorial" + "message": "บทแนะนำการเริ่มต้นใช้งาน" }, "gettingStartedTutorialVideo": { - "message": "ดูบทช่วยสอนการเริ่มต้นของเราเพื่อเรียนรู้วิธีใช้ประโยชน์สูงสุดจากส่วนขยายเบราว์เซอร์" + "message": "ดูวิดีโอแนะนำการเริ่มต้นใช้งานเพื่อเรียนรู้วิธีใช้งานส่วนขยายเบราว์เซอร์ให้คุ้มค่าที่สุด" }, "syncingComplete": { - "message": "การซิงก์เสร็จสมบูรณ์" + "message": "ซิงค์เสร็จสมบูรณ์" }, "syncingFailed": { - "message": "การซิงก์ล้มเหลว" + "message": "การซิงค์ล้มเหลว" }, "passwordCopied": { "message": "คัดลอกรหัสผ่านแล้ว" @@ -1037,23 +1034,23 @@ } }, "newUri": { - "message": "เพิ่ม URI ใหม่" + "message": "URI ใหม่" }, "addDomain": { - "message": "Add domain", + "message": "เพิ่มโดเมน", "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." }, "addedItem": { "message": "เพิ่มรายการแล้ว" }, "editedItem": { - "message": "แก้ไขรายการแล้ว" + "message": "บันทึกรายการแล้ว" }, "savedWebsite": { - "message": "Saved website" + "message": "เว็บไซต์ที่บันทึก" }, "savedWebsites": { - "message": "Saved websites ( $COUNT$ )", + "message": "เว็บไซต์ที่บันทึก ( $COUNT$ )", "placeholders": { "count": { "content": "$1", @@ -1062,88 +1059,88 @@ } }, "deleteItemConfirmation": { - "message": "คุณต้องการส่งไปยังถังขยะใช่หรือไม่?" + "message": "ยืนยันที่จะย้ายไปถังขยะหรือไม่" }, "deletedItem": { - "message": "ส่งรายการไปยังถังขยะแล้ว" + "message": "ย้ายรายการไปถังขยะแล้ว" }, "overwritePassword": { - "message": "Overwrite Password" + "message": "เขียนทับรหัสผ่าน" }, "overwritePasswordConfirmation": { - "message": "คุณต้องการเขียนทับรหัสผ่านปัจจุบันใช่หรือไม่?" + "message": "ยืนยันที่จะเขียนทับรหัสผ่านปัจจุบันหรือไม่" }, "overwriteUsername": { "message": "เขียนทับชื่อผู้ใช้" }, "overwriteUsernameConfirmation": { - "message": "คุณแน่ใจหรือไม่ว่าต้องการเขียนทับชื่อผู้ใช้ปัจจุบัน" + "message": "ยืนยันที่จะเขียนทับชื่อผู้ใช้ปัจจุบันหรือไม่" }, "searchFolder": { - "message": "ค้นหาในโพลเดอร์" + "message": "ค้นหาโฟลเดอร์" }, "searchCollection": { - "message": "คอลเลกชันการค้นหา" + "message": "ค้นหาคอลเลกชัน" }, "searchType": { "message": "ประเภทการค้นหา" }, "noneFolder": { - "message": "No Folder", + "message": "ไม่มีโฟลเดอร์", "description": "This is the folder for uncategorized items" }, "enableAddLoginNotification": { - "message": "ถามเพื่อให้เพิ่มการเข้าสู่ระบบ" + "message": "ถามเพื่อเพิ่มข้อมูลเข้าสู่ระบบ" }, "vaultSaveOptionsTitle": { - "message": "Save to vault options" + "message": "ตัวเลือกการบันทึกลงตู้นิรภัย" }, "addLoginNotificationDesc": { - "message": "The \"Add Login Notification\" automatically prompts you to save new logins to your vault whenever you log into them for the first time." + "message": "ถามเพื่อเพิ่มรายการหากไม่พบข้อมูลในตู้นิรภัย" }, "addLoginNotificationDescAlt": { - "message": "หากไม่พบรายการในห้องนิรภัยของคุณ ระบบจะถามเพื่อเพิ่มรายการ มีผลกับทุกบัญชีที่ลงชื่อเข้าใช้" + "message": "ถามเพื่อเพิ่มรายการหากไม่พบข้อมูลในตู้นิรภัย (สำหรับทุกบัญชีที่เข้าสู่ระบบ)" }, "showCardsInVaultViewV2": { - "message": "Always show cards as Autofill suggestions on Vault view" + "message": "แสดงบัตรเป็นคำแนะนำการป้อนอัตโนมัติในมุมมองตู้นิรภัยเสมอ" }, "showCardsCurrentTab": { - "message": "แสดงการ์ดบนหน้าแท็บ" + "message": "แสดงบัตรในหน้าแท็บ" }, "showCardsCurrentTabDesc": { - "message": "บัตรรายการในหน้าแท็บเพื่อให้ป้อนอัตโนมัติได้ง่าย" + "message": "แสดงรายการบัตรในหน้าแท็บเพื่อให้ป้อนอัตโนมัติได้ง่าย" }, "showIdentitiesInVaultViewV2": { - "message": "Always show identities as Autofill suggestions on Vault view" + "message": "แสดงข้อมูลระบุตัวตนเป็นคำแนะนำการป้อนอัตโนมัติในมุมมองตู้นิรภัยเสมอ" }, "showIdentitiesCurrentTab": { - "message": "แสดงตัวตนบนหน้าแท็บ" + "message": "แสดงข้อมูลระบุตัวตนในหน้าแท็บ" }, "showIdentitiesCurrentTabDesc": { - "message": "แสดงรายการข้อมูลประจำตัวในหน้าแท็บเพื่อให้ป้อนอัตโนมัติได้ง่าย" + "message": "แสดงรายการข้อมูลระบุตัวตนในหน้าแท็บเพื่อให้ป้อนอัตโนมัติได้ง่าย" }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "คลิกรายการเพื่อป้อนข้อมูลอัตโนมัติในมุมมองตู้นิรภัย" }, "clickToAutofill": { - "message": "Click items in autofill suggestion to fill" + "message": "คลิกรายการในคำแนะนำเพื่อป้อนข้อมูล" }, "clearClipboard": { "message": "ล้างคลิปบอร์ด", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "clearClipboardDesc": { - "message": "ล้างค่าที่คัดลอกโดยอัตโนมัติจากคลิปบอร์ดของคุณ", + "message": "ล้างค่าที่คัดลอกออกจากคลิปบอร์ดโดยอัตโนมัติ", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "notificationAddDesc": { - "message": "Should bitwarden remember this password for you?" + "message": "ต้องการให้ Bitwarden จำรหัสผ่านนี้หรือไม่" }, "notificationAddSave": { - "message": "Yes, Save Now" + "message": "บันทึก" }, "notificationViewAria": { - "message": "View $ITEMNAME$, opens in new window", + "message": "ดู $ITEMNAME$ เปิดในหน้าต่างใหม่", "placeholders": { "itemName": { "content": "$1" @@ -1152,18 +1149,18 @@ "description": "Aria label for the view button in notification bar confirmation message" }, "notificationNewItemAria": { - "message": "New Item, opens in new window", + "message": "รายการใหม่ เปิดในหน้าต่างใหม่", "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" }, "notificationEditTooltip": { - "message": "Edit before saving", + "message": "แก้ไขก่อนบันทึก", "description": "Tooltip and Aria label for edit button on cipher item" }, "newNotification": { - "message": "New notification" + "message": "การแจ้งเตือนใหม่" }, "labelWithNotification": { - "message": "$LABEL$: New notification", + "message": "$LABEL$: การแจ้งเตือนใหม่", "description": "Label for the notification with a new login suggestion.", "placeholders": { "label": { @@ -1173,15 +1170,15 @@ } }, "notificationLoginSaveConfirmation": { - "message": "saved to Bitwarden.", + "message": "บันทึกลง Bitwarden แล้ว", "description": "Shown to user after item is saved." }, "notificationLoginUpdatedConfirmation": { - "message": "updated in Bitwarden.", + "message": "อัปเดตใน Bitwarden แล้ว", "description": "Shown to user after item is updated." }, "selectItemAriaLabel": { - "message": "Select $ITEMTYPE$, $ITEMNAME$", + "message": "เลือก $ITEMTYPE$, $ITEMNAME$", "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", "placeholders": { "itemType": { @@ -1193,35 +1190,35 @@ } }, "saveAsNewLoginAction": { - "message": "Save as new login", + "message": "บันทึกเป็นข้อมูลเข้าสู่ระบบใหม่", "description": "Button text for saving login details as a new entry." }, "updateLoginAction": { - "message": "Update login", + "message": "อัปเดตข้อมูลเข้าสู่ระบบ", "description": "Button text for updating an existing login entry." }, "unlockToSave": { - "message": "Unlock to save this login", + "message": "ปลดล็อกเพื่อบันทึกข้อมูลเข้าสู่ระบบนี้", "description": "User prompt to take action in order to save the login they just entered." }, "saveLogin": { - "message": "Save login", + "message": "บันทึกข้อมูลเข้าสู่ระบบ", "description": "Prompt asking the user if they want to save their login details." }, "updateLogin": { - "message": "Update existing login", + "message": "อัปเดตข้อมูลเข้าสู่ระบบเดิม", "description": "Prompt asking the user if they want to update an existing login entry." }, "loginSaveSuccess": { - "message": "Login saved", + "message": "บันทึกข้อมูลเข้าสู่ระบบแล้ว", "description": "Message displayed when login details are successfully saved." }, "loginUpdateSuccess": { - "message": "Login updated", + "message": "อัปเดตข้อมูลเข้าสู่ระบบแล้ว", "description": "Message displayed when login details are successfully updated." }, "loginUpdateTaskSuccess": { - "message": "Great job! You took the steps to make you and $ORGANIZATION$ more secure.", + "message": "เยี่ยมมาก! คุณได้ดำเนินการเพื่อทำให้คุณและ $ORGANIZATION$ ปลอดภัยยิ่งขึ้น", "placeholders": { "organization": { "content": "$1" @@ -1230,7 +1227,7 @@ "description": "Shown to user after login is updated." }, "loginUpdateTaskSuccessAdditional": { - "message": "Thank you for making $ORGANIZATION$ more secure. You have $TASK_COUNT$ more passwords to update.", + "message": "ขอบคุณที่ช่วยให้ $ORGANIZATION$ ปลอดภัยยิ่งขึ้น คุณยังมีรหัสผ่านที่ต้องอัปเดตอีก $TASK_COUNT$ รายการ", "placeholders": { "organization": { "content": "$1" @@ -1242,77 +1239,77 @@ "description": "Shown to user after login is updated." }, "nextSecurityTaskAction": { - "message": "Change next password", + "message": "เปลี่ยนรหัสผ่านถัดไป", "description": "Message prompting user to undertake completion of another security task." }, "saveFailure": { - "message": "Error saving", + "message": "เกิดข้อผิดพลาดในการบันทึก", "description": "Error message shown when the system fails to save login details." }, "saveFailureDetails": { - "message": "Oh no! We couldn't save this. Try entering the details manually.", + "message": "แย่แล้ว! เราไม่สามารถบันทึกรายการนี้ได้ ลองป้อนรายละเอียดด้วยตนเอง", "description": "Detailed error message shown when saving login details fails." }, "changePasswordWarning": { - "message": "After changing your password, you will need to log in with your new password. Active sessions on other devices will be logged out within one hour." + "message": "หลังจากเปลี่ยนรหัสผ่าน คุณจะต้องเข้าสู่ระบบด้วยรหัสผ่านใหม่ เซสชันที่ใช้งานอยู่บนอุปกรณ์อื่นจะถูกออกจากระบบภายใน 1 ชั่วโมง" }, "accountRecoveryUpdateMasterPasswordSubtitle": { - "message": "Change your master password to complete account recovery." + "message": "เปลี่ยนรหัสผ่านหลักเพื่อเสร็จสิ้นการกู้คืนบัญชี" }, "enableChangedPasswordNotification": { - "message": "ขอให้ปรับปรุงการเข้าสู่ระบบที่มีอยู่" + "message": "ถามเพื่ออัปเดตข้อมูลเข้าสู่ระบบที่มีอยู่" }, "changedPasswordNotificationDesc": { - "message": "Ask to update a login's password when a change is detected on a website." + "message": "ถามเพื่ออัปเดตรหัสผ่านของข้อมูลเข้าสู่ระบบเมื่อตรวจพบการเปลี่ยนแปลงบนเว็บไซต์" }, "changedPasswordNotificationDescAlt": { - "message": "Ask to update a login's password when a change is detected on a website. Applies to all logged in accounts." + "message": "ถามเพื่ออัปเดตรหัสผ่านของข้อมูลเข้าสู่ระบบเมื่อตรวจพบการเปลี่ยนแปลงบนเว็บไซต์ (สำหรับทุกบัญชีที่เข้าสู่ระบบ)" }, "enableUsePasskeys": { - "message": "Ask to save and use passkeys" + "message": "ถามเพื่อบันทึกและใช้พาสคีย์" }, "usePasskeysDesc": { - "message": "Ask to save new passkeys or log in with passkeys stored in your vault. Applies to all logged in accounts." + "message": "ถามเพื่อบันทึกพาสคีย์ใหม่หรือเข้าสู่ระบบด้วยพาสคีย์ที่เก็บในตู้นิรภัย (สำหรับทุกบัญชีที่เข้าสู่ระบบ)" }, "notificationChangeDesc": { - "message": "คุณต้องการอัปเดตรหัสผ่านนี้ใน Bitwarden หรือไม่?" + "message": "คุณต้องการอัปเดตรหัสผ่านนี้ใน Bitwarden หรือไม่" }, "notificationChangeSave": { - "message": "Yes, Update Now" + "message": "อัปเดต" }, "notificationUnlockDesc": { - "message": "Unlock your Bitwarden vault to complete the autofill request." + "message": "ปลดล็อกตู้นิรภัย Bitwarden เพื่อดำเนินการตามคำขอกรอกข้อมูลอัตโนมัติ" }, "notificationUnlock": { - "message": "Unlock" + "message": "ปลดล็อก" }, "additionalOptions": { - "message": "Additional options" + "message": "ตัวเลือกเพิ่มเติม" }, "enableContextMenuItem": { "message": "แสดงตัวเลือกเมนูบริบท" }, "contextMenuItemDesc": { - "message": "ใช้การคลิกสำรองเพื่อเข้าถึงการสร้างรหัสผ่านและการเข้าสู่ระบบที่ตรงกันสำหรับเว็บไซต์ " + "message": "ใช้การคลิกขวาเพื่อเข้าถึงการสร้างรหัสผ่านและข้อมูลเข้าสู่ระบบที่ตรงกันสำหรับเว็บไซต์" }, "contextMenuItemDescAlt": { - "message": "Use a secondary click to access password generation and matching logins for the website. Applies to all logged in accounts." + "message": "ใช้การคลิกขวาเพื่อเข้าถึงการสร้างรหัสผ่านและข้อมูลเข้าสู่ระบบที่ตรงกันสำหรับเว็บไซต์ (สำหรับทุกบัญชีที่เข้าสู่ระบบ)" }, "defaultUriMatchDetection": { - "message": "การตรวจจับการจับคู่ URI เริ่มต้น", + "message": "การตรวจสอบการจับคู่ URI เริ่มต้น", "description": "Default URI match detection for autofill." }, "defaultUriMatchDetectionDesc": { - "message": "เลือกวิธีเริ่มต้นในการจัดการการตรวจหาการจับคู่ URI สำหรับการเข้าสู่ระบบเมื่อดำเนินการต่างๆ เช่น การป้อนอัตโนมัติ" + "message": "เลือกวิธีเริ่มต้นในการจัดการการจับคู่ URI สำหรับข้อมูลเข้าสู่ระบบเมื่อดำเนินการ เช่น การป้อนอัตโนมัติ" }, "theme": { "message": "ธีม" }, "themeDesc": { - "message": "Change the application's color theme." + "message": "เปลี่ยนธีมสีของแอปพลิเคชัน" }, "themeDescAlt": { - "message": "Change the application's color theme. Applies to all logged in accounts." + "message": "เปลี่ยนธีมสีของแอปพลิเคชัน (สำหรับทุกบัญชีที่เข้าสู่ระบบ)" }, "dark": { "message": "มืด", @@ -1323,72 +1320,85 @@ "description": "Light color" }, "exportFrom": { - "message": "Export from" + "message": "ส่งออกจาก" }, - "exportVault": { - "message": "Export Vault" + "exportVerb": { + "message": "ส่งออก", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "ส่งออก", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "นำเข้า", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "นำเข้า", + "description": "The verb form of the word Import" }, "fileFormat": { - "message": "File Format" + "message": "รูปแบบไฟล์" }, "fileEncryptedExportWarningDesc": { - "message": "This file export will be password protected and require the file password to decrypt." + "message": "ไฟล์ส่งออกนี้จะได้รับการป้องกันด้วยรหัสผ่าน และต้องใช้รหัสผ่านไฟล์เพื่อถอดรหัส" }, "filePassword": { - "message": "File password" + "message": "รหัสผ่านไฟล์" }, "exportPasswordDescription": { - "message": "This password will be used to export and import this file" + "message": "รหัสผ่านนี้จะถูกใช้เพื่อส่งออกและนำเข้าไฟล์นี้" }, "accountRestrictedOptionDescription": { - "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account." + "message": "ใช้กุญแจเข้ารหัสบัญชีของคุณ ซึ่งได้มาจากชื่อผู้ใช้และรหัสผ่านหลัก เพื่อเข้ารหัสไฟล์ส่งออก และจำกัดการนำเข้าเฉพาะบัญชี Bitwarden ปัจจุบันเท่านั้น" }, "passwordProtectedOptionDescription": { - "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption." + "message": "ตั้งรหัสผ่านไฟล์เพื่อเข้ารหัสไฟล์ส่งออก และสามารถนำเข้าสู่บัญชี Bitwarden ใดก็ได้โดยใช้รหัสผ่านเพื่อถอดรหัส" }, "exportTypeHeading": { - "message": "Export type" + "message": "ประเภทการส่งออก" }, "accountRestricted": { - "message": "Account restricted" + "message": "จำกัดเฉพาะบัญชี" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { - "message": "“File password” and “Confirm file password“ do not match." + "message": "“รหัสผ่านไฟล์” และ “ยืนยันรหัสผ่านไฟล์” ไม่ตรงกัน" }, "warning": { "message": "คำเตือน", "description": "WARNING (should stay in capitalized letters if the language permits)" }, "warningCapitalized": { - "message": "Warning", + "message": "คำเตือน", "description": "Warning (should maintain locale-relevant capitalization)" }, "confirmVaultExport": { "message": "ยืนยันการส่งออกตู้นิรภัย" }, "exportWarningDesc": { - "message": "This export contains your vault data in an unencrypted format. You should not store or send the exported file over unsecure channels (such as email). Delete it immediately after you are done using it." + "message": "การส่งออกนี้มีข้อมูลตู้นิรภัยในรูปแบบที่ไม่ได้เข้ารหัส คุณไม่ควรจัดเก็บหรือส่งไฟล์ที่ส่งออกผ่านช่องทางที่ไม่ปลอดภัย (เช่น อีเมล) ลบไฟล์ทันทีหลังจากใช้งานเสร็จ" }, "encExportKeyWarningDesc": { - "message": "การส่งออกนี้เข้ารหัสข้อมูลของคุณโดยใช้คีย์เข้ารหัสของบัญชีของคุณ หากคุณเคยหมุนเวียนคีย์เข้ารหัสของบัญชี คุณควรส่งออกอีกครั้ง เนื่องจากคุณจะไม่สามารถถอดรหัสไฟล์ส่งออกนี้ได้" + "message": "การส่งออกนี้เข้ารหัสข้อมูลของคุณโดยใช้กุญแจเข้ารหัสบัญชีของคุณ หากคุณหมุนเวียนกุญแจเข้ารหัสบัญชี คุณควรส่งออกใหม่อีกครั้ง เนื่องจากคุณจะไม่สามารถถอดรหัสไฟล์ส่งออกนี้ได้" }, "encExportAccountWarningDesc": { - "message": "คีย์การเข้ารหัสบัญชีจะไม่ซ้ำกันสำหรับบัญชีผู้ใช้ Bitwarden แต่ละบัญชี ดังนั้นคุณจึงไม่สามารถนำเข้าการส่งออกที่เข้ารหัสไปยังบัญชีอื่นได้" + "message": "กุญแจเข้ารหัสบัญชีเป็นกุญแจเฉพาะสำหรับผู้ใช้ Bitwarden แต่ละบัญชี ดังนั้นคุณไม่สามารถนำเข้าไฟล์ส่งออกที่เข้ารหัสไปยังบัญชีอื่นได้" }, "exportMasterPassword": { - "message": "ป้อนรหัสผ่านหลักของคุณเพื่อส่งออกข้อมูลตู้นิรภัยของคุณ" + "message": "ป้อนรหัสผ่านหลักเพื่อส่งออกข้อมูลตู้นิรภัย" }, "shared": { "message": "แชร์แล้ว" }, "bitwardenForBusinessPageDesc": { - "message": "Bitwarden for Business allows you to share your vault items with others by using an organization. Learn more on the bitwarden.com website." + "message": "Bitwarden สำหรับธุรกิจช่วยให้คุณแชร์รายการในตู้นิรภัยกับผู้อื่นโดยใช้องค์กร เรียนรู้เพิ่มเติมที่เว็บไซต์ bitwarden.com" }, "moveToOrganization": { - "message": "ย้ายไปยังแบบองค์กร" + "message": "ย้ายไปที่องค์กร" }, "movedItemToOrg": { - "message": "ย้าย $ITEMNAME$ ไปยัง $ORGNAME$ แล้ว", + "message": "ย้าย $ITEMNAME$ ไปที่ $ORGNAME$ แล้ว", "placeholders": { "itemname": { "content": "$1", @@ -1401,19 +1411,40 @@ } }, "moveToOrgDesc": { - "message": "เลือกองค์กรที่คุณต้องการย้ายรายการนี้ไป การย้ายไปยังองค์กรจะโอนความเป็นเจ้าของรายการไปยังองค์กรนั้น คุณจะไม่ได้เป็นเจ้าของโดยตรงของรายการนี้อีกต่อไปเมื่อมีการย้ายแล้ว" + "message": "เลือกองค์กรที่คุณต้องการย้ายรายการนี้ไป การย้ายไปที่องค์กรจะโอนกรรมสิทธิ์ของรายการนั้นไปยังองค์กร คุณจะไม่เป็นเจ้าของโดยตรงของรายการนี้อีกต่อไปหลังจากย้ายแล้ว" }, "learnMore": { "message": "เรียนรู้เพิ่มเติม" }, + "migrationsFailed": { + "message": "เกิดข้อผิดพลาดในการอัปเดตการตั้งค่าการเข้ารหัส" + }, + "updateEncryptionSettingsTitle": { + "message": "อัปเดตการตั้งค่าการเข้ารหัส" + }, + "updateEncryptionSettingsDesc": { + "message": "การตั้งค่าการเข้ารหัสใหม่ที่แนะนำจะช่วยปรับปรุงความปลอดภัยของบัญชี ป้อนรหัสผ่านหลักเพื่ออัปเดตทันที" + }, + "confirmIdentityToContinue": { + "message": "ยืนยันตัวตนเพื่อดำเนินการต่อ" + }, + "enterYourMasterPassword": { + "message": "ป้อนรหัสผ่านหลัก" + }, + "updateSettings": { + "message": "อัปเดตการตั้งค่า" + }, + "later": { + "message": "ไว้ทีหลัง" + }, "authenticatorKeyTotp": { - "message": "Authenticator Key (TOTP)" + "message": "คีย์ยืนยันตัวตน (TOTP)" }, "verificationCodeTotp": { - "message": "Verification Code (TOTP)" + "message": "รหัสยืนยัน (TOTP)" }, "copyVerificationCode": { - "message": "Copy Verification Code" + "message": "คัดลอกรหัสยืนยัน" }, "attachments": { "message": "ไฟล์แนบ" @@ -1422,7 +1453,7 @@ "message": "ลบไฟล์แนบ" }, "deleteAttachmentConfirmation": { - "message": "คุณต้องการลบไฟล์แนบนี้ใช่หรือไม่?" + "message": "ยืนยันที่จะลบไฟล์แนบนี้หรือไม่" }, "deletedAttachment": { "message": "ลบไฟล์แนบแล้ว" @@ -1436,80 +1467,101 @@ "attachmentSaved": { "message": "บันทึกไฟล์แนบแล้ว" }, + "fixEncryption": { + "message": "ซ่อมแซมการเข้ารหัส" + }, + "fixEncryptionTooltip": { + "message": "ไฟล์นี้ใช้วิธีการเข้ารหัสที่ล้าสมัย" + }, + "attachmentUpdated": { + "message": "อัปเดตไฟล์แนบแล้ว" + }, "file": { "message": "ไฟล์" }, "fileToShare": { - "message": "File to share" + "message": "ไฟล์ที่จะแชร์" }, "selectFile": { "message": "เลือกไฟล์" }, + "itemsTransferred": { + "message": "รายการที่โอนย้าย" + }, "maxFileSize": { - "message": "ขนาดไฟล์สูงสุด คือ 500 MB" + "message": "ขนาดไฟล์สูงสุดคือ 500 MB" }, "featureUnavailable": { - "message": "Feature Unavailable" + "message": "ฟีเจอร์ไม่พร้อมใช้งาน" }, "legacyEncryptionUnsupported": { - "message": "Legacy encryption is no longer supported. Please contact support to recover your account." + "message": "ไม่รองรับการเข้ารหัสแบบเก่าอีกต่อไป โปรดติดต่อฝ่ายสนับสนุนเพื่อกู้คืนบัญชีของคุณ" }, "premiumMembership": { - "message": "Premium Membership" + "message": "สมาชิกพรีเมียม" }, "premiumManage": { - "message": "Manage Membership" + "message": "จัดการการเป็นสมาชิก" }, "premiumManageAlert": { - "message": "คุณสามารถจัดการการเป็นสมาชิกของคุณได้ที่ bitwarden.com web vault คุณต้องการเข้าชมเว็บไซต์ตอนนี้หรือไม่?" + "message": "คุณสามารถจัดการการเป็นสมาชิกได้ที่เว็บตู้นิรภัย bitwarden.com ต้องการไปที่เว็บไซต์ตอนนี้หรือไม่" }, "premiumRefresh": { - "message": "Refresh Membership" + "message": "รีเฟรชสถานะสมาชิก" }, "premiumNotCurrentMember": { - "message": "คุณยังไม่ได้เป็นสมาชิกพรีเมียม" + "message": "ปัจจุบันคุณไม่ได้เป็นสมาชิกพรีเมียม" }, "premiumSignUpAndGet": { - "message": "สมัครสมาชิกพรีเมี่ยมและรับ:" + "message": "สมัครสมาชิกพรีเมียมแล้วรับ:" }, "ppremiumSignUpStorage": { - "message": "1 GB of encrypted file storage." + "message": "พื้นที่จัดเก็บไฟล์แนบเข้ารหัสขนาด 1 GB" + }, + "premiumSignUpStorageV2": { + "message": "พื้นที่จัดเก็บไฟล์แนบเข้ารหัสขนาด $SIZE$", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } }, "premiumSignUpEmergency": { - "message": "Emergency access." + "message": "การเข้าถึงฉุกเฉิน" }, "premiumSignUpTwoStepOptions": { - "message": "Proprietary two-step login options such as YubiKey and Duo." + "message": "ตัวเลือกการเข้าสู่ระบบ 2 ขั้นตอนแบบพิเศษ เช่น YubiKey และ Duo" }, "ppremiumSignUpReports": { - "message": "สุขอนามัยของรหัสผ่าน ความสมบูรณ์ของบัญชี และรายงานการละเมิดข้อมูลเพื่อให้ตู้นิรภัยของคุณปลอดภัย" + "message": "รายงานความปลอดภัยของรหัสผ่าน สุขภาพบัญชี และข้อมูลรั่วไหล เพื่อรักษาตู้นิรภัยให้ปลอดภัย" }, "ppremiumSignUpTotp": { - "message": "ตัวสร้างรหัสยืนยัน TOTP (2FA) สำหรับการเข้าสู่ระบบในตู้นิรภัยของคุณ" + "message": "ตัวสร้างรหัสยืนยัน TOTP (2FA) สำหรับข้อมูลเข้าสู่ระบบในตู้นิรภัย" }, "ppremiumSignUpSupport": { - "message": "Priority customer support." + "message": "บริการลูกค้าสัมพันธ์ระดับพรีเมียม" }, "ppremiumSignUpFuture": { - "message": "All future Premium features. More coming soon!" + "message": "ฟีเจอร์พรีเมียมในอนาคตทั้งหมด และอื่น ๆ ที่กำลังจะมาเร็ว ๆ นี้!" }, "premiumPurchase": { - "message": "Purchase Premium" + "message": "ซื้อพรีเมียม" }, "premiumPurchaseAlertV2": { - "message": "You can purchase Premium from your account settings on the Bitwarden web app." + "message": "คุณสามารถซื้อพรีเมียมได้จากการตั้งค่าบัญชีในเว็บแอป Bitwarden" }, "premiumCurrentMember": { - "message": "You are a Premium member!" + "message": "คุณเป็นสมาชิกพรีเมียมแล้ว!" }, "premiumCurrentMemberThanks": { - "message": "Thank you for supporting bitwarden." + "message": "ขอบคุณที่สนับสนุน Bitwarden" }, "premiumFeatures": { - "message": "Upgrade to Premium and receive:" + "message": "อัปเกรดเป็นพรีเมียมเพื่อรับ:" }, "premiumPrice": { - "message": "All for just $PRICE$ /year!", + "message": "ทั้งหมดนี้เพียง $PRICE$ /ปี!", "placeholders": { "price": { "content": "$1", @@ -1518,7 +1570,7 @@ } }, "premiumPriceV2": { - "message": "All for just $PRICE$ per year!", + "message": "ทั้งหมดนี้เพียง $PRICE$ ต่อปี!", "placeholders": { "price": { "content": "$1", @@ -1527,25 +1579,25 @@ } }, "refreshComplete": { - "message": "Refresh complete" + "message": "รีเฟรชเสร็จสมบูรณ์" }, "enableAutoTotpCopy": { - "message": "Copy TOTP automatically" + "message": "คัดลอก TOTP อัตโนมัติ" }, "disableAutoTotpCopyDesc": { - "message": "If a login has an authenticator key, copy the TOTP verification code to your clip-board when you autofill the login." + "message": "หากข้อมูลเข้าสู่ระบบมีคีย์ยืนยันตัวตน ให้คัดลอกรหัสยืนยัน TOTP ไปยังคลิปบอร์ดเมื่อคุณป้อนข้อมูลเข้าสู่ระบบอัตโนมัติ" }, "enableAutoBiometricsPrompt": { - "message": "Ask for biometrics on launch" + "message": "ถามหาไบโอเมตริกเมื่อเปิดแอป" }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "การยืนยันตัวตนหมดเวลา" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "เซสชันการยืนยันตัวตนหมดเวลา โปรดเริ่มกระบวนการเข้าสู่ระบบใหม่" }, "verificationCodeEmailSent": { - "message": "ส่งโค้ดยืนยันไปยังอีเมล $EMAIL$ แล้ว", + "message": "ส่งอีเมลยืนยันไปที่ $EMAIL$ แล้ว", "placeholders": { "email": { "content": "$1", @@ -1554,148 +1606,148 @@ } }, "dontAskAgainOnThisDeviceFor30Days": { - "message": "Don't ask again on this device for 30 days" + "message": "ไม่ต้องถามอีกบนอุปกรณ์นี้เป็นเวลา 30 วัน" }, "selectAnotherMethod": { - "message": "Select another method", + "message": "เลือกวิธีอื่น", "description": "Select another two-step login method" }, "useYourRecoveryCode": { - "message": "Use your recovery code" + "message": "ใช้รหัสกู้คืนของคุณ" }, "insertU2f": { - "message": "Insert your security key into your computer's USB port. If it has a button, touch it." + "message": "เสียบคีย์ความปลอดภัยเข้ากับพอร์ต USB ของคอมพิวเตอร์ หากมีปุ่มให้แตะที่ปุ่ม" }, "openInNewTab": { - "message": "Open in new tab" + "message": "เปิดในแท็บใหม่" }, "webAuthnAuthenticate": { - "message": "Authenticate WebAuthn" + "message": "ยืนยันตัวตน WebAuthn" }, "readSecurityKey": { - "message": "Read security key" + "message": "อ่านคีย์ความปลอดภัย" }, "readingPasskeyLoading": { - "message": "Reading passkey..." + "message": "กำลังอ่านพาสคีย์..." }, "passkeyAuthenticationFailed": { - "message": "Passkey authentication failed" + "message": "การยืนยันตัวตนด้วยพาสคีย์ล้มเหลว" }, "useADifferentLogInMethod": { - "message": "Use a different log in method" + "message": "ใช้วิธีเข้าสู่ระบบอื่น" }, "awaitingSecurityKeyInteraction": { - "message": "Awaiting security key interaction..." + "message": "กำลังรอการตอบสนองจากคีย์ความปลอดภัย..." }, "loginUnavailable": { - "message": "Login Unavailable" + "message": "ไม่สามารถเข้าสู่ระบบได้" }, "noTwoStepProviders": { - "message": "This account has two-step login enabled, however, none of the configured two-step providers are supported by this web browser." + "message": "บัญชีนี้ตั้งค่าการเข้าสู่ระบบ 2 ขั้นตอนไว้ แต่เว็บเบราว์เซอร์นี้ไม่รองรับผู้ให้บริการ 2 ขั้นตอนใด ๆ ที่กำหนดค่าไว้" }, "noTwoStepProviders2": { - "message": "Please use a supported web browser (such as Chrome) and/or add additional providers that are better supported across web browsers (such as an authenticator app)." + "message": "โปรดใช้เว็บเบราว์เซอร์ที่รองรับ (เช่น Chrome) และ/หรือเพิ่มผู้ให้บริการอื่นที่รองรับบนเว็บเบราว์เซอร์ได้ดีกว่า (เช่น แอปยืนยันตัวตน)" }, "twoStepOptions": { - "message": "Two-step Login Options" + "message": "ตัวเลือกการเข้าสู่ระบบ 2 ขั้นตอน" }, "selectTwoStepLoginMethod": { - "message": "Select two-step login method" + "message": "เลือกวิธีการเข้าสู่ระบบ 2 ขั้นตอน" }, "recoveryCodeTitle": { - "message": "Recovery Code" + "message": "รหัสกู้คืน" }, "authenticatorAppTitle": { - "message": "Authenticator App" + "message": "แอปยืนยันตัวตน" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "ป้อนรหัสที่สร้างโดยแอปยืนยันตัวตน เช่น Bitwarden Authenticator", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP Security Key" + "message": "คีย์ความปลอดภัย Yubico OTP" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." + "message": "ใช้ YubiKey เพื่อเข้าถึงบัญชีของคุณ ใช้งานได้กับอุปกรณ์ YubiKey 4, 4 Nano, 4C และ NEO" }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "ป้อนรหัสที่สร้างโดย Duo Security", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { - "message": "Verify with Duo Security for your organization using the Duo Mobile app, SMS, phone call, or U2F security key.", + "message": "ยืนยันตัวตนกับ Duo Security สำหรับองค์กรของคุณโดยใช้แอป Duo Mobile, SMS, โทรศัพท์ หรือคีย์ความปลอดภัย U2F", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "webAuthnTitle": { "message": "FIDO2 WebAuthn" }, "webAuthnDesc": { - "message": "ใช้กุญแจความปลอดภัยที่รองรับ WebAuthn ใดก็ได้เพื่อเข้าถึงบัญชีของคุณ" + "message": "ใช้คีย์ความปลอดภัยที่รองรับ WebAuthn เพื่อเข้าถึงบัญชีของคุณ" }, "emailTitle": { "message": "อีเมล" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "ป้อนรหัสที่ส่งไปยังอีเมลของคุณ" }, "selfHostedEnvironment": { - "message": "Self-hosted Environment" + "message": "สภาพแวดล้อมโฮสต์เอง" }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "ระบุ URL เซิร์ฟเวอร์ของการติดตั้ง Bitwarden ที่คุณโฮสต์เอง ตัวอย่าง: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "สำหรับการกำหนดค่าขั้นสูง คุณสามารถระบุ URL ของแต่ละบริการได้อย่างอิสระ" }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "คุณต้องเพิ่ม URL เซิร์ฟเวอร์หลัก หรือสภาพแวดล้อมที่กำหนดเองอย่างน้อยหนึ่งรายการ" }, "selfHostedEnvMustUseHttps": { - "message": "URLs must use HTTPS." + "message": "URL ต้องใช้ HTTPS" }, "customEnvironment": { - "message": "Custom Environment" + "message": "สภาพแวดล้อมที่กำหนดเอง" }, "baseUrl": { - "message": "URL ของเซิร์ฟเวอร์" + "message": "URL เซิร์ฟเวอร์" }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "URL เซิร์ฟเวอร์โฮสต์เอง", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { - "message": "API Server URL" + "message": "URL เซิร์ฟเวอร์ API" }, "webVaultUrl": { - "message": "Web Vault Server URL" + "message": "URL เซิร์ฟเวอร์เว็บตู้นิรภัย" }, "identityUrl": { - "message": "Identity Server URL" + "message": "URL เซิร์ฟเวอร์ข้อมูลระบุตัวตน" }, "notificationsUrl": { - "message": "Notifications Server URL" + "message": "URL เซิร์ฟเวอร์การแจ้งเตือน" }, "iconsUrl": { - "message": "Icons Server URL" + "message": "URL เซิร์ฟเวอร์ไอคอน" }, "environmentSaved": { - "message": "Environment URLs saved" + "message": "บันทึก URL สภาพแวดล้อมแล้ว" }, "showAutoFillMenuOnFormFields": { - "message": "Show autofill menu on form fields", + "message": "แสดงเมนูป้อนอัตโนมัติบนช่องกรอกข้อมูล", "description": "Represents the message for allowing the user to enable the autofill overlay" }, "autofillSuggestionsSectionTitle": { - "message": "คำแนะนำการกรอกข้อมูลอัตโนมัติ" + "message": "คำแนะนำการป้อนอัตโนมัติ" }, "autofillSpotlightTitle": { - "message": "Easily find autofill suggestions" + "message": "ค้นหาคำแนะนำการป้อนอัตโนมัติได้ง่ายขึ้น" }, "autofillSpotlightDesc": { - "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + "message": "ปิดการตั้งค่าป้อนอัตโนมัติของเบราว์เซอร์ เพื่อไม่ให้ขัดแย้งกับ Bitwarden" }, "turnOffBrowserAutofill": { - "message": "Turn off $BROWSER$ autofill", + "message": "ปิดการป้อนอัตโนมัติของ $BROWSER$", "placeholders": { "browser": { "content": "$1", @@ -1704,162 +1756,162 @@ } }, "turnOffAutofill": { - "message": "Turn off autofill" + "message": "ปิดการป้อนอัตโนมัติ" }, "confirmAutofill": { - "message": "Confirm autofill" + "message": "ยืนยันการป้อนอัตโนมัติ" }, "confirmAutofillDesc": { - "message": "This site doesn't match your saved login details. Before you fill in your login credentials, make sure it's a trusted site." + "message": "เว็บไซต์นี้ไม่ตรงกับรายละเอียดการเข้าสู่ระบบที่คุณบันทึกไว้ ก่อนป้อนข้อมูล โปรดตรวจสอบให้แน่ใจว่าเป็นเว็บไซต์ที่เชื่อถือได้" }, "showInlineMenuLabel": { - "message": "Show autofill suggestions on form fields" + "message": "แสดงคำแนะนำการป้อนอัตโนมัติบนช่องกรอกข้อมูล" }, "howDoesBitwardenProtectFromPhishing": { - "message": "How does Bitwarden protect your data from phishing?" + "message": "Bitwarden ปกป้องข้อมูลของคุณจากการฟิชชิงได้อย่างไร" }, "currentWebsite": { - "message": "Current website" + "message": "เว็บไซต์ปัจจุบัน" }, "autofillAndAddWebsite": { - "message": "Autofill and add this website" + "message": "ป้อนอัตโนมัติและเพิ่มเว็บไซต์นี้" }, "autofillWithoutAdding": { - "message": "Autofill without adding" + "message": "ป้อนอัตโนมัติโดยไม่เพิ่ม" }, "doNotAutofill": { - "message": "Do not autofill" + "message": "ไม่ต้องป้อนอัตโนมัติ" }, "showInlineMenuIdentitiesLabel": { - "message": "Display identities as suggestions" + "message": "แสดงข้อมูลระบุตัวตนเป็นคำแนะนำ" }, "showInlineMenuCardsLabel": { - "message": "Display cards as suggestions" + "message": "แสดงบัตรเป็นคำแนะนำ" }, "showInlineMenuOnIconSelectionLabel": { - "message": "Display suggestions when icon is selected" + "message": "แสดงคำแนะนำเมื่อเลือกไอคอน" }, "showInlineMenuOnFormFieldsDescAlt": { - "message": "Applies to all logged in accounts." + "message": "สำหรับทุกบัญชีที่เข้าสู่ระบบ" }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser's built in password manager settings to avoid conflicts." + "message": "ปิดการตั้งค่าตัวจัดการรหัสผ่านในตัวของเบราว์เซอร์เพื่อหลีกเลี่ยงความขัดแย้ง" }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { - "message": "Edit browser settings." + "message": "แก้ไขการตั้งค่าเบราว์เซอร์" }, "autofillOverlayVisibilityOff": { - "message": "Off", + "message": "ปิด", "description": "Overlay setting select option for disabling autofill overlay" }, "autofillOverlayVisibilityOnFieldFocus": { - "message": "When field is selected (on focus)", + "message": "เมื่อเลือกช่อง (โฟกัส)", "description": "Overlay appearance select option for showing the field on focus of the input element" }, "autofillOverlayVisibilityOnButtonClick": { - "message": "When autofill icon is selected", + "message": "เมื่อเลือกไอคอนป้อนอัตโนมัติ", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, "enableAutoFillOnPageLoadSectionTitle": { - "message": "Autofill on page load" + "message": "ป้อนอัตโนมัติเมื่อโหลดหน้าเว็บ" }, "enableAutoFillOnPageLoad": { - "message": "Enable Auto-fill On Page Load." + "message": "ป้อนอัตโนมัติเมื่อโหลดหน้าเว็บ" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, autofill when the web page loads." + "message": "หากตรวจพบแบบฟอร์มเข้าสู่ระบบ ให้ป้อนข้อมูลอัตโนมัติเมื่อหน้าเว็บโหลดเสร็จ" }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit autofill on page load." + "message": "เว็บไซต์ที่ไม่น่าเชื่อถือหรือถูกแฮ็กอาจใช้ประโยชน์จากการป้อนอัตโนมัติเมื่อโหลดหน้าเว็บได้" }, "learnMoreAboutAutofillOnPageLoadLinkText": { - "message": "Learn more about risks" + "message": "เรียนรู้เพิ่มเติมเกี่ยวกับความเสี่ยง" }, "learnMoreAboutAutofill": { - "message": "Learn more about autofill" + "message": "เรียนรู้เพิ่มเติมเกี่ยวกับการป้อนอัตโนมัติ" }, "defaultAutoFillOnPageLoad": { - "message": "Default autofill setting for login items" + "message": "การตั้งค่าเริ่มต้นสำหรับการป้อนข้อมูลเข้าสู่ระบบอัตโนมัติ" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off autofill on page load for individual login items from the item's Edit view." + "message": "คุณสามารถปิดการป้อนอัตโนมัติเมื่อโหลดหน้าเว็บสำหรับแต่ละรายการได้จากหน้าแก้ไขรายการ" }, "autoFillOnPageLoadUseDefault": { - "message": "Use default setting" + "message": "ใช้การตั้งค่าเริ่มต้น" }, "autoFillOnPageLoadYes": { - "message": "Autofill on page load" + "message": "ป้อนอัตโนมัติเมื่อโหลดหน้าเว็บ" }, "autoFillOnPageLoadNo": { - "message": "Do not autofill on page load" + "message": "ไม่ป้อนอัตโนมัติเมื่อโหลดหน้าเว็บ" }, "commandOpenPopup": { - "message": "Open vault popup" + "message": "เปิดป๊อปอัปตู้นิรภัย" }, "commandOpenSidebar": { - "message": "Open vault in sidebar" + "message": "เปิดตู้นิรภัยในแถบด้านข้าง" }, "commandAutofillLoginDesc": { - "message": "Autofill the last used login for the current website" + "message": "ป้อนข้อมูลเข้าสู่ระบบที่ใช้ล่าสุดสำหรับเว็บไซต์ปัจจุบันโดยอัตโนมัติ" }, "commandAutofillCardDesc": { - "message": "Autofill the last used card for the current website" + "message": "ป้อนข้อมูลบัตรที่ใช้ล่าสุดสำหรับเว็บไซต์ปัจจุบันโดยอัตโนมัติ" }, "commandAutofillIdentityDesc": { - "message": "Autofill the last used identity for the current website" + "message": "ป้อนข้อมูลระบุตัวตนที่ใช้ล่าสุดสำหรับเว็บไซต์ปัจจุบันโดยอัตโนมัติ" }, "commandGeneratePasswordDesc": { - "message": "Generate and copy a new random password to the clipboard." + "message": "สร้างและคัดลอกรหัสผ่านแบบสุ่มใหม่ไปยังคลิปบอร์ด" }, "commandLockVaultDesc": { - "message": "ล็อกตู้เซฟ" + "message": "ล็อกตู้นิรภัย" }, "customFields": { - "message": "Custom Fields" + "message": "ฟิลด์ที่กำหนดเอง" }, "copyValue": { - "message": "Copy Value" + "message": "คัดลอกค่า" }, "value": { "message": "ค่า" }, "newCustomField": { - "message": "New Custom Field" + "message": "ฟิลด์ที่กำหนดเองใหม่" }, "dragToSort": { - "message": "Drag to sort" + "message": "ลากเพื่อเรียงลำดับ" }, "dragToReorder": { - "message": "Drag to reorder" + "message": "ลากเพื่อจัดลำดับใหม่" }, "cfTypeText": { "message": "ข้อความ" }, "cfTypeHidden": { - "message": "Hidden" + "message": "ซ่อน" }, "cfTypeBoolean": { - "message": "Boolean" + "message": "บูลีน" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "ช่องทำเครื่องหมาย" }, "cfTypeLinked": { - "message": "Linked", + "message": "เชื่อมโยง", "description": "This describes a field that is 'linked' (tied) to another field." }, "linkedValue": { - "message": "Linked value", + "message": "ค่าที่เชื่อมโยง", "description": "This describes a value that is 'linked' (tied) to another value." }, "popup2faCloseMessage": { - "message": "Clicking outside the popup window to check your email for your verification code will cause this popup to close. Do you want to open this popup in a new window so that it does not close?" + "message": "การคลิกนอกหน้าต่างป๊อปอัปเพื่อตรวจสอบรหัสยืนยันในอีเมลจะทำให้ป๊อปอัปปิดลง คุณต้องการเปิดป๊อปอัปนี้ในหน้าต่างใหม่เพื่อไม่ให้ปิดหรือไม่" }, "showIconsChangePasswordUrls": { - "message": "Show website icons and retrieve change password URLs" + "message": "แสดงไอคอนเว็บไซต์และดึง URL เปลี่ยนรหัสผ่าน" }, "cardholderName": { - "message": "Cardholder Name" + "message": "ชื่อผู้ถือบัตร" }, "number": { "message": "หมายเลข" @@ -1868,13 +1920,13 @@ "message": "แบรนด์" }, "expirationMonth": { - "message": "Expiration Month" + "message": "เดือนที่หมดอายุ" }, "expirationYear": { - "message": "Expiration Year" + "message": "ปีที่หมดอายุ" }, "monthly": { - "message": "month" + "message": "เดือน" }, "expiration": { "message": "วันหมดอายุ" @@ -1916,13 +1968,13 @@ "message": "ธันวาคม" }, "securityCode": { - "message": "Security Code" + "message": "รหัสความปลอดภัย" }, "cardNumber": { - "message": "card number" + "message": "หมายเลขบัตร" }, "ex": { - "message": "ex." + "message": "ตัวอย่าง" }, "title": { "message": "คำนำหน้า" @@ -1940,22 +1992,22 @@ "message": "ดร." }, "mx": { - "message": "Mx" + "message": "คุณ" }, "firstName": { - "message": "First Name" + "message": "ชื่อจริง" }, "middleName": { - "message": "Middle Name" + "message": "ชื่อกลาง" }, "lastName": { - "message": "Last Name" + "message": "นามสกุล" }, "fullName": { "message": "ชื่อเต็ม" }, "identityName": { - "message": "Identity Name" + "message": "ชื่อข้อมูลระบุตัวตน" }, "company": { "message": "บริษัท" @@ -1967,7 +2019,7 @@ "message": "หมายเลขหนังสือเดินทาง" }, "licenseNumber": { - "message": "หมายเลขใบอนุญาต" + "message": "หมายเลขใบขับขี่" }, "email": { "message": "อีเมล" @@ -1988,7 +2040,7 @@ "message": "ที่อยู่ 3" }, "cityTown": { - "message": "เมือง" + "message": "เมือง / ตำบล" }, "stateProvince": { "message": "รัฐ / จังหวัด" @@ -2000,116 +2052,116 @@ "message": "ประเทศ" }, "type": { - "message": "ชนิด" + "message": "ประเภท" }, "typeLogin": { - "message": "ล็อกอิน" + "message": "ข้อมูลเข้าสู่ระบบ" }, "typeLogins": { - "message": "ล็อกอิน" + "message": "ข้อมูลเข้าสู่ระบบ" }, "typeSecureNote": { - "message": "Secure Note" + "message": "โน้ตความปลอดภัย" }, "typeCard": { - "message": "บัตรเครดิต" + "message": "บัตร" }, "typeIdentity": { "message": "ข้อมูลระบุตัวตน" }, "typeSshKey": { - "message": "SSH key" + "message": "คีย์ SSH" }, "typeNote": { - "message": "Note" + "message": "โน้ต" }, "newItemHeaderLogin": { - "message": "New Login", + "message": "ข้อมูลเข้าสู่ระบบใหม่", "description": "Header for new login item type" }, "newItemHeaderCard": { - "message": "New Card", + "message": "บัตรใหม่", "description": "Header for new card item type" }, "newItemHeaderIdentity": { - "message": "New Identity", + "message": "ข้อมูลระบุตัวตนใหม่", "description": "Header for new identity item type" }, "newItemHeaderNote": { - "message": "New Note", + "message": "โน้ตใหม่", "description": "Header for new note item type" }, "newItemHeaderSshKey": { - "message": "New SSH key", + "message": "คีย์ SSH ใหม่", "description": "Header for new SSH key item type" }, "newItemHeaderTextSend": { - "message": "New Text Send", + "message": "ข้อความ Send ใหม่", "description": "Header for new text send" }, "newItemHeaderFileSend": { - "message": "New File Send", + "message": "ไฟล์ Send ใหม่", "description": "Header for new file send" }, "editItemHeaderLogin": { - "message": "Edit Login", + "message": "แก้ไขข้อมูลเข้าสู่ระบบ", "description": "Header for edit login item type" }, "editItemHeaderCard": { - "message": "Edit Card", + "message": "แก้ไขบัตร", "description": "Header for edit card item type" }, "editItemHeaderIdentity": { - "message": "Edit Identity", + "message": "แก้ไขข้อมูลระบุตัวตน", "description": "Header for edit identity item type" }, "editItemHeaderNote": { - "message": "Edit Note", + "message": "แก้ไขโน้ต", "description": "Header for edit note item type" }, "editItemHeaderSshKey": { - "message": "Edit SSH key", + "message": "แก้ไขคีย์ SSH", "description": "Header for edit SSH key item type" }, "editItemHeaderTextSend": { - "message": "Edit Text Send", + "message": "แก้ไขข้อความ Send", "description": "Header for edit text send" }, "editItemHeaderFileSend": { - "message": "Edit File Send", + "message": "แก้ไขไฟล์ Send", "description": "Header for edit file send" }, "viewItemHeaderLogin": { - "message": "View Login", + "message": "ดูข้อมูลเข้าสู่ระบบ", "description": "Header for view login item type" }, "viewItemHeaderCard": { - "message": "View Card", + "message": "ดูบัตร", "description": "Header for view card item type" }, "viewItemHeaderIdentity": { - "message": "View Identity", + "message": "ดูข้อมูลระบุตัวตน", "description": "Header for view identity item type" }, "viewItemHeaderNote": { - "message": "View Note", + "message": "ดูโน้ต", "description": "Header for view note item type" }, "viewItemHeaderSshKey": { - "message": "View SSH key", + "message": "ดูคีย์ SSH", "description": "Header for view SSH key item type" }, "passwordHistory": { - "message": "ประวัติของรหัสผ่าน" + "message": "ประวัติรหัสผ่าน" }, "generatorHistory": { - "message": "Generator history" + "message": "ประวัติตัวสร้างรหัสผ่าน" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "ล้างประวัติตัวสร้างรหัสผ่าน" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "หากดำเนินการต่อ รายการทั้งหมดจะถูกลบออกจากประวัติของตัวสร้างอย่างถาวร ยืนยันที่จะดำเนินการต่อหรือไม่" }, "back": { "message": "ย้อนกลับ" @@ -2118,7 +2170,7 @@ "message": "คอลเลกชัน" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ คอลเลกชัน", "placeholders": { "count": { "content": "$1", @@ -2130,7 +2182,7 @@ "message": "รายการโปรด" }, "popOutNewWindow": { - "message": "เปิดหน้าต่างใหม่" + "message": "แยกหน้าต่างใหม่" }, "refresh": { "message": "รีเฟรช" @@ -2142,23 +2194,23 @@ "message": "ข้อมูลระบุตัวตน" }, "logins": { - "message": "เข้าสู่ระบบ" + "message": "ข้อมูลเข้าสู่ระบบ" }, "secureNotes": { - "message": "Secure Notes" + "message": "โน้ตความปลอดภัย" }, "sshKeys": { - "message": "SSH Keys" + "message": "คีย์ SSH" }, "clear": { - "message": "ลบทิ้ง", + "message": "ล้าง", "description": "To clear something out. example: To clear browser history." }, "checkPassword": { - "message": "ตรวจสอบว่ารหัสผ่านถูกเปิดเผยหรือไม่" + "message": "ตรวจสอบว่ารหัสผ่านรั่วไหลหรือไม่" }, "passwordExposed": { - "message": "This password has been exposed $VALUE$ time(s) in data breaches. You should change it.", + "message": "รหัสผ่านนี้รั่วไหล $VALUE$ ครั้งในเหตุการณ์ข้อมูลรั่วไหล คุณควรเปลี่ยนรหัสผ่านนี้", "placeholders": { "value": { "content": "$1", @@ -2167,14 +2219,14 @@ } }, "passwordSafe": { - "message": "ไม่พบรหัสผ่านนี้ในการละเมิดข้อมูลที่มี ควรใช้อย่างปลอดภัย" + "message": "ไม่พบรหัสผ่านนี้ในเหตุการณ์ข้อมูลรั่วไหลที่รู้จัก ควรจะปลอดภัยต่อการใช้งาน" }, "baseDomain": { - "message": "โดเมนพื้นฐาน", + "message": "โดเมนฐาน", "description": "Domain name. Ex. website.com" }, "baseDomainOptionRecommended": { - "message": "Base domain (recommended)", + "message": "โดเมนฐาน (แนะนำ)", "description": "Domain name. Ex. website.com" }, "domainName": { @@ -2186,25 +2238,25 @@ "description": "A URL's host value. For example, the host of https://sub.domain.com:443 is 'sub.domain.com:443'." }, "exact": { - "message": "ถูกต้อง" + "message": "ตรงกันทุกตัวอักษร" }, "startsWith": { - "message": "เริ่มต้นด้วย" + "message": "ขึ้นต้นด้วย" }, "regEx": { - "message": "นิพจน์ทั่วไป", + "message": "Regular expression", "description": "A programming term, also known as 'RegEx'." }, "matchDetection": { - "message": "Match Detection", + "message": "การตรวจสอบการจับคู่", "description": "URI match detection for autofill." }, "defaultMatchDetection": { - "message": "การตรวจจับการจับคู่เริ่มต้น", + "message": "การตรวจสอบการจับคู่เริ่มต้น", "description": "Default URI match detection for autofill." }, "toggleOptions": { - "message": "Toggle Options" + "message": "สลับตัวเลือก" }, "toggleCurrentUris": { "message": "สลับ URI ปัจจุบัน", @@ -2219,7 +2271,7 @@ "description": "An entity of multiple related people (ex. a team or business organization)." }, "types": { - "message": "ชนิด" + "message": "ประเภท" }, "allItems": { "message": "รายการทั้งหมด" @@ -2228,64 +2280,64 @@ "message": "ไม่มีรหัสผ่านที่จะแสดง" }, "clearHistory": { - "message": "Clear history" + "message": "ล้างประวัติ" }, "nothingToShow": { - "message": "Nothing to show" + "message": "ไม่มีข้อมูลที่จะแสดง" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "คุณไม่ได้สร้างรหัสผ่านใด ๆ ในช่วงนี้" }, "remove": { - "message": "ลบ" + "message": "เอาออก" }, "default": { "message": "ค่าเริ่มต้น" }, "dateUpdated": { - "message": "อัปเดตแล้ว", + "message": "อัปเดต", "description": "ex. Date this item was updated" }, "dateCreated": { - "message": "สร้างเมื่อ", + "message": "สร้าง", "description": "ex. Date this item was created" }, "datePasswordUpdated": { - "message": "อัปเดต Password แล้ว", + "message": "รหัสผ่านอัปเดต", "description": "ex. Date this password was updated" }, "neverLockWarning": { - "message": "คุณแน่ใจหรือไม่ว่าต้องการใช้ตัวเลือก \"ไม่เคย\" การตั้งค่าตัวเลือกการล็อกเป็น \"ไม่\" จะเก็บคีย์เข้ารหัสของห้องนิรภัยไว้ในอุปกรณ์ของคุณ หากคุณใช้ตัวเลือกนี้ คุณควรตรวจสอบให้แน่ใจว่าคุณปกป้องอุปกรณ์ของคุณอย่างเหมาะสม" + "message": "ยืนยันที่จะใช้ตัวเลือก “ไม่เลย” หรือไม่ การตั้งค่าตัวเลือกการล็อกเป็น “ไม่เลย” จะจัดเก็บกุญแจเข้ารหัสตู้นิรภัยไว้บนอุปกรณ์ หากใช้ตัวเลือกนี้ คุณควรตรวจสอบให้แน่ใจว่าอุปกรณ์ได้รับการปกป้องอย่างเหมาะสม" }, "noOrganizationsList": { - "message": "You do not belong to any organizations. Organizations allow you to securely share items with other users." + "message": "คุณไม่ได้เป็นสมาชิกขององค์กรใด ๆ องค์กรช่วยให้คุณแชร์รายการกับผู้ใช้อื่นได้อย่างปลอดภัย" }, "noCollectionsInList": { "message": "ไม่มีคอลเลกชันที่จะแสดง" }, "ownership": { - "message": "เจ้าของ" + "message": "ความเป็นเจ้าของ" }, "whoOwnsThisItem": { - "message": "ใครเป็นเจ้าของรายการนี้?" + "message": "ใครเป็นเจ้าของรายการนี้" }, "strong": { - "message": "แข็งแรง", + "message": "รัดกุม", "description": "ex. A strong password. Scale: Weak -> Good -> Strong" }, "good": { - "message": "ไม่เลว", + "message": "ดี", "description": "ex. A good password. Scale: Weak -> Good -> Strong" }, "weak": { - "message": "ง่ายเกินไป", + "message": "อ่อน", "description": "ex. A weak password. Scale: Weak -> Good -> Strong" }, "weakMasterPassword": { - "message": "Weak Master Password" + "message": "รหัสผ่านหลักไม่ปลอดภัย" }, "weakMasterPasswordDesc": { - "message": "รหัสผ่านหลักที่คุณเลือกนั้นไม่รัดกุม คุณควรใช้รหัสผ่านหลักที่รัดกุม (หรือวลีรหัสผ่าน) เพื่อปกป้องบัญชี Bitwarden ของคุณอย่างเหมาะสม คุณแน่ใจหรือไม่ว่าต้องการใช้รหัสผ่านหลักนี้" + "message": "รหัสผ่านหลักที่คุณเลือกไม่ปลอดภัย คุณควรใช้รหัสผ่านหลักที่รัดกุม (หรือวลีรหัสผ่าน) เพื่อปกป้องบัญชี Bitwarden ของคุณอย่างเหมาะสม ยืนยันที่จะใช้รหัสผ่านหลักนี้หรือไม่" }, "pin": { "message": "PIN", @@ -2295,43 +2347,43 @@ "message": "ปลดล็อกด้วย PIN" }, "setYourPinTitle": { - "message": "ตั้ง PIN" + "message": "ตั้งค่า PIN" }, "setYourPinButton": { - "message": "ตั้ง PIN" + "message": "ตั้งค่า PIN" }, "setYourPinCode": { - "message": "ตั้ง PIN เพื่อใช้ปลดล็อก Bitwarden ทั้งนี้ หากคุณล็อกเอาต์ออกจากแอปโดยสมบูรณ์จะเป็นการลบการตั้งค่า PIN ของคุณด้วย" + "message": "ตั้งรหัส PIN สำหรับปลดล็อก Bitwarden การตั้งค่า PIN จะถูกรีเซ็ตหากคุณออกจากระบบแอปพลิเคชันโดยสมบูรณ์" }, "setPinCode": { - "message": "ตั้ง PIN เพื่อใช้ปลดล็อก Bitwarden และหากคุณล็อกเอาต์ออกจากแอปโดยสมบูรณ์จะเป็นการลบการตั้งค่า PIN ของคุณ" + "message": "คุณสามารถใช้ PIN นี้เพื่อปลดล็อก Bitwarden PIN จะถูกรีเซ็ตหากคุณออกจากระบบแอปพลิเคชันโดยสมบูรณ์" }, "pinRequired": { - "message": "ต้องระบุ PIN" + "message": "จำเป็นต้องระบุรหัส PIN" }, "invalidPin": { - "message": "PIN ไม่ถูกต้อง" + "message": "รหัส PIN ไม่ถูกต้อง" }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "Too many invalid PIN entry attempts. Logging out." + "message": "พยายามป้อน PIN ผิดหลายครั้งเกินไป กำลังออกจากระบบ" }, "unlockWithBiometrics": { "message": "ปลดล็อกด้วยไบโอเมตริก" }, "unlockWithMasterPassword": { - "message": "เข้าสู่ระบบด้วยรหัสผ่านหลัก" + "message": "ปลดล็อกด้วยรหัสผ่านหลัก" }, "awaitDesktop": { - "message": "Awaiting confirmation from desktop" + "message": "กำลังรอการยืนยันจากเดสก์ท็อป" }, "awaitDesktopDesc": { - "message": "โปรดยืนยันการใช้ไบโอเมตริกในแอปพลิเคชันเดสก์ท็อป Bitwarden เพื่อตั้งค่าไบโอเมตริกสำหรับเบราว์เซอร์" + "message": "โปรดยืนยันโดยใช้ไบโอเมตริกในแอปพลิเคชัน Bitwarden บนเดสก์ท็อปเพื่อตั้งค่าไบโอเมตริกสำหรับเบราว์เซอร์" }, "lockWithMasterPassOnRestart": { - "message": "ล็อคด้วยรหัสผ่านหลักเมื่อรีสตาร์ทเบราว์เซอร์" + "message": "ล็อกด้วยรหัสผ่านหลักเมื่อรีสตาร์ตเบราว์เซอร์" }, "lockWithMasterPassOnRestart1": { - "message": "กำหนดให้ป้อนรหัสผ่านหลักเมื่อรีสตาร์ทเบราว์เซอร์" + "message": "ต้องใช้รหัสผ่านหลักเมื่อรีสตาร์ตเบราว์เซอร์" }, "selectOneCollection": { "message": "คุณต้องเลือกอย่างน้อยหนึ่งคอลเลกชัน" @@ -2343,42 +2395,42 @@ "message": "โคลน" }, "passwordGenerator": { - "message": "Password generator" + "message": "ตัวสร้างรหัสผ่าน" }, "usernameGenerator": { - "message": "Username generator" + "message": "ตัวสร้างชื่อผู้ใช้" }, "useThisEmail": { - "message": "Use this email" + "message": "ใช้อีเมลนี้" }, "useThisPassword": { - "message": "Use this password" + "message": "ใช้รหัสผ่านนี้" }, "useThisPassphrase": { - "message": "Use this passphrase" + "message": "ใช้วลีรหัสผ่านนี้" }, "useThisUsername": { - "message": "Use this username" + "message": "ใช้ชื่อผู้ใช้นี้" }, "securePasswordGenerated": { - "message": "Secure password generated! Don't forget to also update your password on the website." + "message": "สร้างรหัสผ่านที่รัดกุมแล้ว! อย่าลืมอัปเดตรหัสผ่านบนเว็บไซต์ด้วย" }, "useGeneratorHelpTextPartOne": { - "message": "Use the generator", + "message": "ใช้ตัวสร้าง", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "useGeneratorHelpTextPartTwo": { - "message": "to create a strong unique password", + "message": "เพื่อสร้างรหัสผ่านที่รัดกุมและไม่ซ้ำกัน", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultCustomization": { - "message": "Vault customization" + "message": "การปรับแต่งตู้นิรภัย" }, "vaultTimeoutAction": { - "message": "การดำเนินการหลังหมดเวลาล็อคตู้เซฟ" + "message": "การดำเนินการเมื่อตู้นิรภัยหมดเวลา" }, "vaultTimeoutAction1": { - "message": "Timeout action" + "message": "การดำเนินการเมื่อหมดเวลา" }, "lock": { "message": "ล็อก", @@ -2392,52 +2444,52 @@ "message": "ค้นหาในถังขยะ" }, "permanentlyDeleteItem": { - "message": "ลบรายการอย่างถาวร" + "message": "ลบรายการถาวร" }, "permanentlyDeleteItemConfirmation": { - "message": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการนี้อย่างถาวร?" + "message": "ยืนยันที่จะลบรายการนี้ถาวรหรือไม่" }, "permanentlyDeletedItem": { - "message": "ลบรายการอย่างถาวรแล้ว" + "message": "ลบรายการถาวรแล้ว" }, "restoreItem": { "message": "กู้คืนรายการ" }, "restoredItem": { - "message": "คืนค่ารายการแล้ว" + "message": "กู้คืนรายการแล้ว" }, "alreadyHaveAccount": { - "message": "Already have an account?" + "message": "มีบัญชีอยู่แล้วใช่หรือไม่" }, "vaultTimeoutLogOutConfirmation": { - "message": "การออกจากระบบจะลบการเข้าถึงตู้นิรภัยของคุณทั้งหมด และต้องมีการตรวจสอบสิทธิ์ออนไลน์หลังจากหมดเวลา คุณแน่ใจหรือไม่ว่าต้องการใช้การตั้งค่านี้" + "message": "การออกจากระบบจะทำให้สิทธิ์เข้าถึงตู้นิรภัยทั้งหมดถูกยกเลิก และต้องยืนยันตัวตนออนไลน์ใหม่หลังจากหมดเวลา ยืนยันที่จะใช้การตั้งค่านี้หรือไม่" }, "vaultTimeoutLogOutConfirmationTitle": { - "message": "การยืนยันการดำเนินการหมดเวลา" + "message": "ยืนยันการดำเนินการเมื่อหมดเวลา" }, "autoFillAndSave": { - "message": "กรอกอัตโนมัติและบันทึก" + "message": "ป้อนอัตโนมัติและบันทึก" }, "fillAndSave": { - "message": "Fill and save" + "message": "ป้อนและบันทึก" }, "autoFillSuccessAndSavedUri": { - "message": "เติมรายการอัตโนมัติและบันทึก URI แล้ว" + "message": "ป้อนข้อมูลรายการอัตโนมัติและบันทึก URI แล้ว" }, "autoFillSuccess": { - "message": "รายการเติมอัตโนมัติ " + "message": "ป้อนข้อมูลรายการอัตโนมัติแล้ว" }, "insecurePageWarning": { - "message": "Warning: This is an unsecured HTTP page, and any information you submit can potentially be seen and changed by others. This Login was originally saved on a secure (HTTPS) page." + "message": "คำเตือน: หน้านี้เป็นหน้า HTTP ที่ไม่ปลอดภัย ข้อมูลที่คุณส่งอาจถูกดักจับหรือแก้ไขโดยผู้อื่นได้ ข้อมูลเข้าสู่ระบบนี้ถูกบันทึกไว้บนหน้าเว็บที่ปลอดภัย (HTTPS)" }, "insecurePageWarningFillPrompt": { - "message": "Do you still wish to fill this login?" + "message": "ยังต้องการป้อนข้อมูลเข้าสู่ระบบนี้หรือไม่" }, "autofillIframeWarning": { - "message": "The form is hosted by a different domain than the URI of your saved login. Choose OK to autofill anyway, or Cancel to stop." + "message": "แบบฟอร์มนี้โฮสต์โดยโดเมนที่ต่างจาก URI ของข้อมูลเข้าสู่ระบบที่คุณบันทึกไว้ เลือก ตกลง เพื่อป้อนข้อมูลอัตโนมัติ หรือ ยกเลิก เพื่อหยุด" }, "autofillIframeWarningTip": { - "message": "To prevent this warning in the future, save this URI, $HOSTNAME$, to your Bitwarden login item for this site.", + "message": "เพื่อป้องกันการแจ้งเตือนนี้ในอนาคต ให้บันทึก URI $HOSTNAME$ ลงในรายการข้อมูลเข้าสู่ระบบ Bitwarden สำหรับไซต์นี้", "placeholders": { "hostname": { "content": "$1", @@ -2446,22 +2498,22 @@ } }, "topLayerHijackWarning": { - "message": "This page is interfering with the Bitwarden experience. The Bitwarden inline menu has been temporarily disabled as a safety measure." + "message": "หน้านี้รบกวนการทำงานของ Bitwarden เมนูในบรรทัดของ Bitwarden ถูกปิดใช้งานชั่วคราวเพื่อความปลอดภัย" }, "setMasterPassword": { "message": "ตั้งรหัสผ่านหลัก" }, "currentMasterPass": { - "message": "Current master password" + "message": "รหัสผ่านหลักปัจจุบัน" }, "newMasterPass": { - "message": "New master password" + "message": "รหัสผ่านหลักใหม่" }, "confirmNewMasterPass": { - "message": "Confirm new master password" + "message": "ยืนยันรหัสผ่านหลักใหม่" }, "masterPasswordPolicyInEffect": { - "message": "นโยบายองค์กรอย่างน้อยหนึ่งนโยบายกำหนดให้รหัสผ่านหลักของคุณเป็นไปตามข้อกำหนดต่อไปนี้:" + "message": "นโยบายองค์กรอย่างน้อยหนึ่งรายการกำหนดให้รหัสผ่านหลักของคุณต้องเป็นไปตามข้อกำหนดดังนี้:" }, "policyInEffectMinComplexity": { "message": "คะแนนความซับซ้อนขั้นต่ำ $SCORE$", @@ -2473,7 +2525,7 @@ } }, "policyInEffectMinLength": { - "message": "ความยาวอย่างน้อย $LENGTH$ อักขระ", + "message": "ความยาวขั้นต่ำ $LENGTH$ ตัวอักษร", "placeholders": { "length": { "content": "$1", @@ -2482,16 +2534,16 @@ } }, "policyInEffectUppercase": { - "message": "มีตัวพิมพ์ใหญ่อย่างน้อย 1 ตัว" + "message": "มีตัวอักษรพิมพ์ใหญ่อย่างน้อยหนึ่งตัว" }, "policyInEffectLowercase": { - "message": "มีตัวพิมพ์เล็กอย่างน้อย 1 ตัว" + "message": "มีตัวอักษรพิมพ์เล็กอย่างน้อยหนึ่งตัว" }, "policyInEffectNumbers": { - "message": "มีตัวเลขอย่างน้อย 1 ตัว" + "message": "มีตัวเลขอย่างน้อยหนึ่งตัว" }, "policyInEffectSpecial": { - "message": "มีอักขระพิเศษต่อไปนี้อย่างน้อย 1 อักขระ: $CHARS$ ", + "message": "มีอักขระพิเศษต่อไปนี้อย่างน้อยหนึ่งตัว $CHARS$", "placeholders": { "chars": { "content": "$1", @@ -2500,186 +2552,186 @@ } }, "masterPasswordPolicyRequirementsNotMet": { - "message": "รหัสผ่านหลักใหม่ของคุณไม่เป็นไปตามข้อกำหนดของนโยบาย" + "message": "รหัสผ่านหลักใหม่ของคุณไม่ตรงตามข้อกำหนดของนโยบาย" }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "รับคำแนะนำ ประกาศ และโอกาสในการทำวิจัยจาก Bitwarden ทางอีเมล" }, "unsubscribe": { - "message": "Unsubscribe" + "message": "ยกเลิกการรับข่าวสาร" }, "atAnyTime": { - "message": "at any time." + "message": "ได้ทุกเมื่อ" }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "เมื่อดำเนินการต่อ ถือว่าคุณยอมรับ" }, "and": { - "message": "and" + "message": "และ" }, "acceptPolicies": { - "message": "By checking this box you agree to the following:" + "message": "การเลือกช่องนี้หมายความว่าคุณยอมรับสิ่งต่อไปนี้:" }, "acceptPoliciesRequired": { - "message": "Terms of Service and Privacy Policy have not been acknowledged." + "message": "ยังไม่ได้ยอมรับข้อกำหนดในการให้บริการและนโยบายความเป็นส่วนตัว" }, "termsOfService": { - "message": "Terms of Service" + "message": "ข้อกำหนดในการให้บริการ" }, "privacyPolicy": { - "message": "Privacy Policy" + "message": "นโยบายความเป็นส่วนตัว" }, "yourNewPasswordCannotBeTheSameAsYourCurrentPassword": { - "message": "Your new password cannot be the same as your current password." + "message": "รหัสผ่านใหม่ต้องไม่ซ้ำกับรหัสผ่านปัจจุบัน" }, "hintEqualsPassword": { - "message": "Your password hint cannot be the same as your password." + "message": "คำใบ้รหัสผ่านต้องไม่เหมือนกับรหัสผ่าน" }, "ok": { "message": "ตกลง" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "เกิดข้อผิดพลาดในการรีเฟรชโทเค็นการเข้าถึง" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "ไม่พบโทเค็นรีเฟรชหรือคีย์ API โปรดลองออกจากระบบแล้วเข้าสู่ระบบใหม่" }, "desktopSyncVerificationTitle": { - "message": "Desktop sync verification" + "message": "การยืนยันการซิงค์เดสก์ท็อป" }, "desktopIntegrationVerificationText": { - "message": "Please verify that the desktop application shows this fingerprint: " + "message": "โปรดยืนยันว่าแอปพลิเคชันเดสก์ท็อปแสดงลายนิ้วมือนี้: " }, "desktopIntegrationDisabledTitle": { - "message": "Browser integration is not set up" + "message": "ยังไม่ได้ตั้งค่าการรวมเบราว์เซอร์" }, "desktopIntegrationDisabledDesc": { - "message": "Browser integration is not set up in the Bitwarden desktop application. Please set it up in the settings within the desktop application." + "message": "ยังไม่ได้ตั้งค่าการรวมเบราว์เซอร์ในแอปพลิเคชัน Bitwarden บนเดสก์ท็อป โปรดตั้งค่าในการตั้งค่าภายในแอปพลิเคชันเดสก์ท็อป" }, "startDesktopTitle": { - "message": "Start the Bitwarden desktop application" + "message": "เริ่มแอปพลิเคชัน Bitwarden บนเดสก์ท็อป" }, "startDesktopDesc": { - "message": "The Bitwarden desktop application needs to be started before unlock with biometrics can be used." + "message": "จำเป็นต้องเปิดแอปพลิเคชัน Bitwarden บนเดสก์ท็อปก่อนจึงจะสามารถใช้การปลดล็อกด้วยไบโอเมตริกได้" }, "errorEnableBiometricTitle": { - "message": "Unable to set up biometrics" + "message": "ไม่สามารถตั้งค่าไบโอเมตริกได้" }, "errorEnableBiometricDesc": { - "message": "Action was canceled by the desktop application" + "message": "การดำเนินการถูกยกเลิกโดยแอปพลิเคชันเดสก์ท็อป" }, "nativeMessagingInvalidEncryptionDesc": { - "message": "Desktop application invalidated the secure communication channel. Please retry this operation" + "message": "แอปพลิเคชันเดสก์ท็อปทำให้ช่องทางการสื่อสารที่ปลอดภัยเป็นโมฆะ โปรดลองดำเนินการนี้อีกครั้ง" }, "nativeMessagingInvalidEncryptionTitle": { - "message": "Desktop communication interrupted" + "message": "การสื่อสารกับเดสก์ท็อปถูกขัดจังหวะ" }, "nativeMessagingWrongUserDesc": { - "message": "The desktop application is logged into a different account. Please ensure both applications are logged into the same account." + "message": "แอปพลิเคชันเดสก์ท็อปเข้าสู่ระบบด้วยบัญชีอื่น โปรดตรวจสอบให้แน่ใจว่าทั้งสองแอปพลิเคชันเข้าสู่ระบบด้วยบัญชีเดียวกัน" }, "nativeMessagingWrongUserTitle": { - "message": "Account missmatch" + "message": "บัญชีไม่ตรงกัน" }, "nativeMessagingWrongUserKeyTitle": { - "message": "Biometric key missmatch" + "message": "คีย์ไบโอเมตริกไม่ตรงกัน" }, "nativeMessagingWrongUserKeyDesc": { - "message": "Biometric unlock failed. The biometric secret key failed to unlock the vault. Please try to set up biometrics again." + "message": "การปลดล็อกด้วยไบโอเมตริกล้มเหลว คีย์ลับไบโอเมตริกไม่สามารถปลดล็อกตู้นิรภัยได้ โปรดลองตั้งค่าไบโอเมตริกใหม่อีกครั้ง" }, "biometricsNotEnabledTitle": { - "message": "Biometrics not set up" + "message": "ยังไม่ได้ตั้งค่าไบโอเมตริก" }, "biometricsNotEnabledDesc": { - "message": "Browser biometrics requires desktop biometric to be set up in the settings first." + "message": "ไบโอเมตริกสำหรับเบราว์เซอร์จำเป็นต้องตั้งค่าไบโอเมตริกในแอปเดสก์ท็อปก่อน" }, "biometricsNotSupportedTitle": { - "message": "Biometrics not supported" + "message": "ไม่รองรับไบโอเมตริก" }, "biometricsNotSupportedDesc": { - "message": "Browser biometrics is not supported on this device." + "message": "อุปกรณ์นี้ไม่รองรับไบโอเมตริกสำหรับเบราว์เซอร์" }, "biometricsNotUnlockedTitle": { - "message": "User locked or logged out" + "message": "ผู้ใช้ถูกล็อกหรือออกจากระบบ" }, "biometricsNotUnlockedDesc": { - "message": "Please unlock this user in the desktop application and try again." + "message": "โปรดปลดล็อกผู้ใช้นี้ในแอปพลิเคชันเดสก์ท็อปแล้วลองอีกครั้ง" }, "biometricsNotAvailableTitle": { - "message": "Biometric unlock unavailable" + "message": "การปลดล็อกด้วยไบโอเมตริกไม่พร้อมใช้งาน" }, "biometricsNotAvailableDesc": { - "message": "Biometric unlock is currently unavailable. Please try again later." + "message": "การปลดล็อกด้วยไบโอเมตริกไม่พร้อมใช้งานในขณะนี้ โปรดลองใหม่อีกครั้งในภายหลัง" }, "biometricsFailedTitle": { - "message": "Biometrics failed" + "message": "ไบโอเมตริกล้มเหลว" }, "biometricsFailedDesc": { - "message": "Biometrics cannot be completed, consider using a master password or logging out. If this persists, please contact Bitwarden support." + "message": "ไม่สามารถดำเนินการไบโอเมตริกให้เสร็จสิ้นได้ โปรดพิจารณาใช้รหัสผ่านหลักหรือออกจากระบบ หากปัญหายังคงอยู่ โปรดติดต่อฝ่ายสนับสนุน Bitwarden" }, "nativeMessaginPermissionErrorTitle": { - "message": "Permission not provided" + "message": "ไม่ได้รับอนุญาต" }, "nativeMessaginPermissionErrorDesc": { - "message": "Without permission to communicate with the Bitwarden Desktop Application we cannot provide biometrics in the browser extension. Please try again." + "message": "เราไม่สามารถให้บริการไบโอเมตริกในส่วนขยายเบราว์เซอร์ได้หากไม่ได้รับอนุญาตให้สื่อสารกับแอปพลิเคชัน Bitwarden บนเดสก์ท็อป โปรดลองอีกครั้ง" }, "nativeMessaginPermissionSidebarTitle": { - "message": "Permission request error" + "message": "ข้อผิดพลาดในการขอสิทธิ์" }, "nativeMessaginPermissionSidebarDesc": { - "message": "This action cannot be done in the sidebar, please retry the action in the popup or popout." + "message": "ไม่สามารถดำเนินการนี้ในแถบด้านข้างได้ โปรดลองดำเนินการอีกครั้งในป๊อปอัปหรือหน้าต่างแยก" }, "personalOwnershipSubmitError": { - "message": "Due to an Enterprise Policy, you are restricted from saving items to your personal vault. Change the Ownership option to an organization and choose from available collections." + "message": "เนื่องจากนโยบายองค์กร คุณถูกจำกัดไม่ให้บันทึกรายการลงในตู้นิรภัยส่วนตัว เปลี่ยนตัวเลือกความเป็นเจ้าของเป็นองค์กรและเลือกคอลเลกชันที่มีอยู่" }, "personalOwnershipPolicyInEffect": { - "message": "An organization policy is affecting your ownership options." + "message": "นโยบายองค์กรมีผลต่อตัวเลือกความเป็นเจ้าของของคุณ" }, "personalOwnershipPolicyInEffectImports": { - "message": "An organization policy has blocked importing items into your individual vault." + "message": "นโยบายองค์กรระงับการนำเข้ารายการไปยังตู้นิรภัยส่วนตัวของคุณ" }, "restrictCardTypeImport": { - "message": "Cannot import card item types" + "message": "ไม่สามารถนำเข้ารายการประเภทบัตรได้" }, "restrictCardTypeImportDesc": { - "message": "A policy set by 1 or more organizations prevents you from importing cards to your vaults." + "message": "นโยบายที่กำหนดโดยองค์กรอย่างน้อย 1 แห่งป้องกันไม่ให้คุณนำเข้าบัตรไปยังตู้นิรภัย" }, "domainsTitle": { - "message": "Domains", + "message": "โดเมน", "description": "A category title describing the concept of web domains" }, "blockedDomains": { - "message": "Blocked domains" + "message": "โดเมนที่ถูกบล็อก" }, "learnMoreAboutBlockedDomains": { - "message": "Learn more about blocked domains" + "message": "เรียนรู้เพิ่มเติมเกี่ยวกับโดเมนที่ถูกบล็อก" }, "excludedDomains": { - "message": "Excluded domains" + "message": "โดเมนที่ยกเว้น" }, "excludedDomainsDesc": { - "message": "Bitwarden will not ask to save login details for these domains. You must refresh the page for changes to take effect." + "message": "Bitwarden จะไม่ถามให้บันทึกรายละเอียดการเข้าสู่ระบบสำหรับโดเมนเหล่านี้ คุณต้องรีเฟรชหน้าเว็บเพื่อให้การเปลี่ยนแปลงมีผล" }, "excludedDomainsDescAlt": { - "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." + "message": "Bitwarden จะไม่ถามให้บันทึกรายละเอียดการเข้าสู่ระบบสำหรับโดเมนเหล่านี้สำหรับทุกบัญชีที่เข้าสู่ระบบ คุณต้องรีเฟรชหน้าเว็บเพื่อให้การเปลี่ยนแปลงมีผล" }, "blockedDomainsDesc": { - "message": "Autofill and other related features will not be offered for these websites. You must refresh the page for changes to take effect." + "message": "การป้อนอัตโนมัติและฟีเจอร์อื่น ๆ ที่เกี่ยวข้องจะไม่พร้อมใช้งานสำหรับเว็บไซต์เหล่านี้ คุณต้องรีเฟรชหน้าเว็บเพื่อให้การเปลี่ยนแปลงมีผล" }, "autofillBlockedNoticeV2": { - "message": "Autofill is blocked for this website." + "message": "การป้อนอัตโนมัติถูกบล็อกสำหรับเว็บไซต์นี้" }, "autofillBlockedNoticeGuidance": { - "message": "Change this in settings" + "message": "เปลี่ยนค่านี้ในการตั้งค่า" }, "change": { - "message": "Change" + "message": "เปลี่ยน" }, "changePassword": { - "message": "Change password", + "message": "เปลี่ยนรหัสผ่าน", "description": "Change password button for browser at risk notification on login." }, "changeButtonTitle": { - "message": "Change password - $ITEMNAME$", + "message": "เปลี่ยนรหัสผ่าน - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -2688,13 +2740,13 @@ } }, "atRiskPassword": { - "message": "At-risk password" + "message": "รหัสผ่านที่มีความเสี่ยง" }, "atRiskPasswords": { - "message": "At-risk passwords" + "message": "รหัสผ่านที่มีความเสี่ยง" }, "atRiskPasswordDescSingleOrg": { - "message": "$ORGANIZATION$ is requesting you change one password because it is at-risk.", + "message": "$ORGANIZATION$ ร้องขอให้คุณเปลี่ยนรหัสผ่าน 1 รายการเนื่องจากมีความเสี่ยง", "placeholders": { "organization": { "content": "$1", @@ -2703,7 +2755,7 @@ } }, "atRiskPasswordsDescSingleOrgPlural": { - "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at-risk.", + "message": "$ORGANIZATION$ ร้องขอให้คุณเปลี่ยนรหัสผ่าน $COUNT$ รายการเนื่องจากมีความเสี่ยง", "placeholders": { "organization": { "content": "$1", @@ -2716,7 +2768,7 @@ } }, "atRiskPasswordsDescMultiOrgPlural": { - "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at-risk.", + "message": "องค์กรของคุณร้องขอให้คุณเปลี่ยนรหัสผ่าน $COUNT$ รายการเนื่องจากมีความเสี่ยง", "placeholders": { "count": { "content": "$1", @@ -2725,7 +2777,7 @@ } }, "atRiskChangePrompt": { - "message": "Your password for this site is at-risk. $ORGANIZATION$ has requested that you change it.", + "message": "รหัสผ่านของคุณสำหรับเว็บไซต์นี้มีความเสี่ยง $ORGANIZATION$ ได้ร้องขอให้คุณเปลี่ยนรหัสผ่าน", "placeholders": { "organization": { "content": "$1", @@ -2735,7 +2787,7 @@ "description": "Notification body when a login triggers an at-risk password change request and the change password domain is known." }, "atRiskNavigatePrompt": { - "message": "$ORGANIZATION$ wants you to change this password because it is at-risk. Navigate to your account settings to change the password.", + "message": "$ORGANIZATION$ ต้องการให้คุณเปลี่ยนรหัสผ่านนี้เนื่องจากมีความเสี่ยง ไปที่การตั้งค่าบัญชีของคุณเพื่อเปลี่ยนรหัสผ่าน", "placeholders": { "organization": { "content": "$1", @@ -2745,10 +2797,10 @@ "description": "Notification body when a login triggers an at-risk password change request and no change password domain is provided." }, "reviewAndChangeAtRiskPassword": { - "message": "Review and change one at-risk password" + "message": "ตรวจสอบและเปลี่ยนรหัสผ่านที่มีความเสี่ยง 1 รายการ" }, "reviewAndChangeAtRiskPasswordsPlural": { - "message": "Review and change $COUNT$ at-risk passwords", + "message": "ตรวจสอบและเปลี่ยนรหัสผ่านที่มีความเสี่ยง $COUNT$ รายการ", "placeholders": { "count": { "content": "$1", @@ -2757,52 +2809,52 @@ } }, "changeAtRiskPasswordsFaster": { - "message": "Change at-risk passwords faster" + "message": "เปลี่ยนรหัสผ่านที่มีความเสี่ยงได้เร็วยิ่งขึ้น" }, "changeAtRiskPasswordsFasterDesc": { - "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + "message": "อัปเดตการตั้งค่าของคุณเพื่อให้สามารถป้อนรหัสผ่านอัตโนมัติและสร้างรหัสผ่านใหม่ได้อย่างรวดเร็ว" }, "reviewAtRiskLogins": { - "message": "Review at-risk logins" + "message": "ตรวจสอบข้อมูลเข้าสู่ระบบที่มีความเสี่ยง" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords" + "message": "ตรวจสอบรหัสผ่านที่มีความเสี่ยง" }, "reviewAtRiskLoginsSlideDesc": { - "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", + "message": "รหัสผ่านองค์กรของคุณมีความเสี่ยงเนื่องจากไม่ปลอดภัย ใช้ซ้ำ และ/หรือรั่วไหล", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, "reviewAtRiskLoginSlideImgAltPeriod": { - "message": "Illustration of a list of logins that are at-risk." + "message": "ภาพประกอบรายการข้อมูลเข้าสู่ระบบที่มีความเสี่ยง" }, "generatePasswordSlideDesc": { - "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", + "message": "สร้างรหัสผ่านที่รัดกุมและไม่ซ้ำกันอย่างรวดเร็วด้วยเมนูป้อนอัตโนมัติของ Bitwarden บนเว็บไซต์ที่มีความเสี่ยง", "description": "Description of the generate password slide on the at-risk password page carousel" }, "generatePasswordSlideImgAltPeriod": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password." + "message": "ภาพประกอบเมนูป้อนอัตโนมัติของ Bitwarden แสดงรหัสผ่านที่ถูกสร้าง" }, "updateInBitwarden": { - "message": "Update in Bitwarden" + "message": "อัปเดตใน Bitwarden" }, "updateInBitwardenSlideDesc": { - "message": "Bitwarden will then prompt you to update the password in the password manager.", + "message": "จากนั้น Bitwarden จะแจ้งให้คุณอัปเดตรหัสผ่านในตัวจัดการรหัสผ่าน", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, "updateInBitwardenSlideImgAltPeriod": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." + "message": "ภาพประกอบการแจ้งเตือนของ Bitwarden ที่ให้ผู้ใช้อัปเดตข้อมูลเข้าสู่ระบบ" }, "turnOnAutofill": { - "message": "Turn on autofill" + "message": "เปิดการป้อนอัตโนมัติ" }, "turnedOnAutofill": { - "message": "Turned on autofill" + "message": "เปิดการป้อนอัตโนมัติแล้ว" }, "dismiss": { - "message": "Dismiss" + "message": "ปิด" }, "websiteItemLabel": { - "message": "Website $number$ (URI)", + "message": "เว็บไซต์ $number$ (URI)", "placeholders": { "number": { "content": "$1", @@ -2811,7 +2863,7 @@ } }, "excludedDomainsInvalidDomain": { - "message": "$DOMAIN$ is not a valid domain", + "message": "$DOMAIN$ ไม่ใช่โดเมนที่ถูกต้อง", "placeholders": { "domain": { "content": "$1", @@ -2820,20 +2872,20 @@ } }, "blockedDomainsSavedSuccess": { - "message": "Blocked domain changes saved" + "message": "บันทึกการเปลี่ยนแปลงโดเมนที่ถูกบล็อกแล้ว" }, "excludedDomainsSavedSuccess": { - "message": "Excluded domain changes saved" + "message": "บันทึกการเปลี่ยนแปลงโดเมนที่ยกเว้นแล้ว" }, "limitSendViews": { - "message": "Limit views" + "message": "จำกัดจำนวนการดู" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached.", + "message": "จะไม่มีใครสามารถดู Send นี้ได้หลังจากครบกำหนด", "description": "Displayed under the limit views field on Send" }, "limitSendViewsCount": { - "message": "$ACCESSCOUNT$ views left", + "message": "ดูได้อีก $ACCESSCOUNT$ ครั้ง", "description": "Displayed under the limit views field on Send", "placeholders": { "accessCount": { @@ -2847,14 +2899,14 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDetails": { - "message": "Send details", + "message": "รายละเอียด Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendTypeText": { "message": "ข้อความ" }, "sendTypeTextToShare": { - "message": "Text to share" + "message": "ข้อความที่จะแชร์" }, "sendTypeFile": { "message": "ไฟล์" @@ -2864,36 +2916,36 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "maxAccessCountReached": { - "message": "Max access count reached", + "message": "ถึงจำนวนการเข้าถึงสูงสุดแล้ว", "description": "This text will be displayed after a Send has been accessed the maximum amount of times." }, "hideTextByDefault": { - "message": "Hide text by default" + "message": "ซ่อนข้อความโดยค่าเริ่มต้น" }, "expired": { - "message": "Expired" + "message": "หมดอายุ" }, "passwordProtected": { - "message": "Password protected" + "message": "มีการป้องกันด้วยรหัสผ่าน" }, "copyLink": { - "message": "Copy link" + "message": "คัดลอกลิงก์" }, "copySendLink": { - "message": "Copy Send link", + "message": "คัดลอกลิงก์ Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "removePassword": { - "message": "ลบรหัสผ่าน" + "message": "เอารหัสผ่านออก" }, "delete": { "message": "ลบ" }, "removedPassword": { - "message": "รหัสผ่านถูกลบแล้ว" + "message": "เอารหัสผ่านออกแล้ว" }, "deletedSend": { - "message": "Send ถูกลบแล้ว", + "message": "ลบ Send แล้ว", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLink": { @@ -2901,21 +2953,21 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "disabled": { - "message": "Disabled" + "message": "ปิดใช้งาน" }, "removePasswordConfirmation": { - "message": "คุณต้องการลบรหัสผ่านนี้ใช่หรือไม่" + "message": "ยืนยันที่จะเอารหัสผ่านออกหรือไม่" }, "deleteSend": { "message": "ลบ Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deleteSendConfirmation": { - "message": "คุณต้องการลบ Send นี้ใช่หรือไม่?", + "message": "ยืนยันที่จะลบ Send นี้หรือไม่", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deleteSendPermanentConfirmation": { - "message": "Are you sure you want to permanently delete this Send?", + "message": "ยืนยันที่จะลบ Send นี้ถาวรหรือไม่", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editSend": { @@ -2923,14 +2975,14 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deletionDate": { - "message": "Deletion date" + "message": "วันที่ลบ" }, "deletionDateDescV2": { - "message": "The Send will be permanently deleted on this date.", + "message": "Send จะถูกลบถาวรในวันนี้", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { - "message": "Expiration date" + "message": "วันที่หมดอายุ" }, "oneDay": { "message": "1 วัน" @@ -2945,41 +2997,41 @@ } }, "custom": { - "message": "Custom" + "message": "กำหนดเอง" }, "sendPasswordDescV3": { - "message": "Add an optional password for recipients to access this Send.", + "message": "เพิ่มรหัสผ่าน (ไม่บังคับ) เพื่อให้ผู้รับใช้เข้าถึง Send นี้", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createSend": { - "message": "New Send", + "message": "Send ใหม่", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "newPassword": { - "message": "New password" + "message": "รหัสผ่านใหม่" }, "sendDisabled": { - "message": "Send removed", + "message": "เอา Send ออกแล้ว", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisabledWarning": { - "message": "Due to an enterprise policy, you are only able to delete an existing Send.", + "message": "เนื่องจากนโยบายองค์กร คุณสามารถลบ Send ที่มีอยู่ได้เท่านั้น", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createdSend": { - "message": "Send created", + "message": "สร้าง Send แล้ว", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createdSendSuccessfully": { - "message": "Send created successfully!", + "message": "สร้าง Send สำเร็จแล้ว!", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendExpiresInHoursSingle": { - "message": "The Send will be available to anyone with the link for the next 1 hour.", + "message": "Send จะพร้อมใช้งานสำหรับทุกคนที่มีลิงก์ในอีก 1 ชั่วโมงข้างหน้า", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendExpiresInHours": { - "message": "The Send will be available to anyone with the link for the next $HOURS$ hours.", + "message": "Send จะพร้อมใช้งานสำหรับทุกคนที่มีลิงก์ในอีก $HOURS$ ชั่วโมงข้างหน้า", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.", "placeholders": { "hours": { @@ -2989,11 +3041,11 @@ } }, "sendExpiresInDaysSingle": { - "message": "The Send will be available to anyone with the link for the next 1 day.", + "message": "Send จะพร้อมใช้งานสำหรับทุกคนที่มีลิงก์ในอีก 1 วันข้างหน้า", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendExpiresInDays": { - "message": "The Send will be available to anyone with the link for the next $DAYS$ days.", + "message": "Send จะพร้อมใช้งานสำหรับทุกคนที่มีลิงก์ในอีก $DAYS$ วันข้างหน้า", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.", "placeholders": { "days": { @@ -3003,113 +3055,113 @@ } }, "sendLinkCopied": { - "message": "Send link copied", + "message": "คัดลอกลิงก์ Send แล้ว", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { - "message": "Send saved", + "message": "บันทึก Send แล้ว", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendFilePopoutDialogText": { - "message": "Pop out extension?", + "message": "แยกหน้าต่างส่วนขยายหรือไม่", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendFilePopoutDialogDesc": { - "message": "To create a file Send, you need to pop out the extension to a new window.", + "message": "หากต้องการสร้างไฟล์ Send คุณต้องแยกส่วนขยายออกมาเป็นหน้าต่างใหม่", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { - "message": "In order to choose a file, open the extension in the sidebar (if possible) or pop out to a new window by clicking this banner." + "message": "หากต้องการเลือกไฟล์ ให้เปิดส่วนขยายในแถบด้านข้าง (ถ้าทำได้) หรือแยกเป็นหน้าต่างใหม่โดยคลิกที่แบนเนอร์นี้" }, "sendFirefoxFileWarning": { - "message": "In order to choose a file using Firefox, open the extension in the sidebar or pop out to a new window by clicking this banner." + "message": "หากต้องการเลือกไฟล์โดยใช้ Firefox ให้เปิดส่วนขยายในแถบด้านข้างหรือแยกเป็นหน้าต่างใหม่โดยคลิกที่แบนเนอร์นี้" }, "sendSafariFileWarning": { - "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." + "message": "หากต้องการเลือกไฟล์โดยใช้ Safari ให้แยกเป็นหน้าต่างใหม่โดยคลิกที่แบนเนอร์นี้" }, "popOut": { - "message": "Pop out" + "message": "แยกหน้าต่าง" }, "sendFileCalloutHeader": { - "message": "Before you start" + "message": "ก่อนที่คุณจะเริ่ม" }, "expirationDateIsInvalid": { - "message": "The expiration date provided is not valid." + "message": "วันที่หมดอายุที่ระบุไม่ถูกต้อง" }, "deletionDateIsInvalid": { - "message": "The deletion date provided is not valid." + "message": "วันที่ลบที่ระบุไม่ถูกต้อง" }, "expirationDateAndTimeRequired": { - "message": "An expiration date and time are required." + "message": "จำเป็นต้องระบุวันที่และเวลาหมดอายุ" }, "deletionDateAndTimeRequired": { - "message": "A deletion date and time are required." + "message": "จำเป็นต้องระบุวันที่และเวลาที่จะลบ" }, "dateParsingError": { - "message": "There was an error saving your deletion and expiration dates." + "message": "เกิดข้อผิดพลาดในการบันทึกวันที่ลบและวันที่หมดอายุ" }, "hideYourEmail": { - "message": "Hide your email address from viewers." + "message": "ซ่อนที่อยู่อีเมลของคุณจากผู้ชม" }, "passwordPrompt": { - "message": "การยืนยันให้ป้อนรหัสผ่านหลักอีกครั้ง" + "message": "แจ้งเตือนให้ป้อนรหัสผ่านหลักซ้ำ" }, "passwordConfirmation": { - "message": "Master password confirmation" + "message": "การยืนยันรหัสผ่านหลัก" }, "passwordConfirmationDesc": { - "message": "This action is protected. To continue, please re-enter your master password to verify your identity." + "message": "การดำเนินการนี้ได้รับการป้องกัน หากต้องการดำเนินการต่อ โปรดป้อนรหัสผ่านหลักอีกครั้งเพื่อยืนยันตัวตน" }, "emailVerificationRequired": { - "message": "Email verification required" + "message": "จำเป็นต้องยืนยันอีเมล" }, "emailVerifiedV2": { - "message": "Email verified" + "message": "ยืนยันอีเมลแล้ว" }, "emailVerificationRequiredDesc": { - "message": "You must verify your email to use this feature. You can verify your email in the web vault." + "message": "คุณต้องยืนยันอีเมลเพื่อใช้งานฟีเจอร์นี้ คุณสามารถยืนยันอีเมลได้ในเว็บตู้นิรภัย" }, "masterPasswordSuccessfullySet": { - "message": "Master password successfully set" + "message": "ตั้งรหัสผ่านหลักสำเร็จแล้ว" }, "updatedMasterPassword": { - "message": "Updated master password" + "message": "อัปเดตรหัสผ่านหลักแล้ว" }, "updateMasterPassword": { - "message": "Update master password" + "message": "อัปเดตรหัสผ่านหลัก" }, "updateMasterPasswordWarning": { - "message": "Your master password was recently changed by an administrator in your organization. In order to access the vault, you must update it now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "รหัสผ่านหลักของคุณเพิ่งถูกเปลี่ยนโดยผู้ดูแลระบบในองค์กร หากต้องการเข้าถึงตู้นิรภัย คุณต้องอัปเดตรหัสผ่านทันที การดำเนินการนี้จะทำให้คุณออกจากระบบเซสชันปัจจุบัน และต้องเข้าสู่ระบบใหม่ เซสชันที่ใช้งานอยู่บนอุปกรณ์อื่นอาจยังคงใช้งานได้นานสูงสุด 1 ชั่วโมง" }, "updateWeakMasterPasswordWarning": { - "message": "Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "รหัสผ่านหลักของคุณไม่ตรงตามนโยบายองค์กรอย่างน้อยหนึ่งข้อ หากต้องการเข้าถึงตู้นิรภัย คุณต้องอัปเดตรหัสผ่านหลักทันที การดำเนินการนี้จะทำให้คุณออกจากระบบเซสชันปัจจุบัน และต้องเข้าสู่ระบบใหม่ เซสชันที่ใช้งานอยู่บนอุปกรณ์อื่นอาจยังคงใช้งานได้นานสูงสุด 1 ชั่วโมง" }, "tdeDisabledMasterPasswordRequired": { - "message": "Your organization has disabled trusted device encryption. Please set a master password to access your vault." + "message": "องค์กรของคุณปิดใช้งานการเข้ารหัสอุปกรณ์ที่เชื่อถือได้ โปรดตั้งรหัสผ่านหลักเพื่อเข้าถึงตู้นิรภัยของคุณ" }, "resetPasswordPolicyAutoEnroll": { - "message": "Automatic enrollment" + "message": "การลงทะเบียนอัตโนมัติ" }, "resetPasswordAutoEnrollInviteWarning": { - "message": "This organization has an enterprise policy that will automatically enroll you in password reset. Enrollment will allow organization administrators to change your master password." + "message": "องค์กรนี้มีนโยบายองค์กรที่จะลงทะเบียนคุณในการรีเซ็ตรหัสผ่านโดยอัตโนมัติ การลงทะเบียนจะอนุญาตให้ผู้ดูแลระบบขององค์กรเปลี่ยนรหัสผ่านหลักของคุณได้" }, "selectFolder": { - "message": "Select folder..." + "message": "เลือกโฟลเดอร์..." }, "noFoldersFound": { - "message": "No folders found", + "message": "ไม่พบโฟลเดอร์", "description": "Used as a message within the notification bar when no folders are found" }, "orgPermissionsUpdatedMustSetPassword": { - "message": "Your organization permissions were updated, requiring you to set a master password.", + "message": "สิทธิ์ในองค์กรของคุณได้รับการอัปเดต ซึ่งกำหนดให้คุณต้องตั้งรหัสผ่านหลัก", "description": "Used as a card title description on the set password page to explain why the user is there" }, "orgRequiresYouToSetPassword": { - "message": "Your organization requires you to set a master password.", + "message": "องค์กรของคุณกำหนดให้คุณต้องตั้งรหัสผ่านหลัก", "description": "Used as a card title description on the set password page to explain why the user is there" }, "cardMetrics": { - "message": "out of $TOTAL$", + "message": "จาก $TOTAL$", "placeholders": { "total": { "content": "$1", @@ -3118,20 +3170,20 @@ } }, "verificationRequired": { - "message": "Verification required", + "message": "จำเป็นต้องยืนยันตัวตน", "description": "Default title for the user verification dialog." }, "hours": { - "message": "Hours" + "message": "ชั่วโมง" }, "minutes": { - "message": "Minutes" + "message": "นาที" }, "vaultTimeoutPolicyAffectingOptions": { - "message": "Enterprise policy requirements have been applied to your timeout options" + "message": "ข้อกำหนดนโยบายองค์กรถูกนำไปใช้กับตัวเลือกเวลาหมดเวลาของคุณแล้ว" }, "vaultTimeoutPolicyInEffect": { - "message": "Your organization policies have set your maximum allowed vault timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "message": "นโยบายองค์กรกำหนดระยะเวลาหมดเวลาของตู้นิรภัยสูงสุดไว้ที่ $HOURS$ ชั่วโมง $MINUTES$ นาที", "placeholders": { "hours": { "content": "$1", @@ -3144,7 +3196,7 @@ } }, "vaultTimeoutPolicyInEffect1": { - "message": "$HOURS$ hour(s) and $MINUTES$ minute(s) maximum.", + "message": "สูงสุด $HOURS$ ชั่วโมง $MINUTES$ นาที", "placeholders": { "hours": { "content": "$1", @@ -3157,7 +3209,7 @@ } }, "vaultTimeoutPolicyMaximumError": { - "message": "Timeout exceeds the restriction set by your organization: $HOURS$ hour(s) and $MINUTES$ minute(s) maximum", + "message": "เวลาหมดเวลาเกินข้อจำกัดที่องค์กรกำหนด: สูงสุด $HOURS$ ชั่วโมง $MINUTES$ นาที", "placeholders": { "hours": { "content": "$1", @@ -3170,7 +3222,7 @@ } }, "vaultTimeoutPolicyWithActionInEffect": { - "message": "Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is $HOURS$ hour(s) and $MINUTES$ minute(s). Your vault timeout action is set to $ACTION$.", + "message": "นโยบายองค์กรมีผลต่อเวลาหมดเวลาของตู้นิรภัย อนุญาตให้หมดเวลาสูงสุด $HOURS$ ชั่วโมง $MINUTES$ นาที การดำเนินการเมื่อตู้นิรภัยหมดเวลาตั้งค่าไว้ที่ $ACTION$", "placeholders": { "hours": { "content": "$1", @@ -3187,7 +3239,7 @@ } }, "vaultTimeoutActionPolicyInEffect": { - "message": "Your organization policies have set your vault timeout action to $ACTION$.", + "message": "นโยบายองค์กรกำหนดการดำเนินการเมื่อตู้นิรภัยหมดเวลาเป็น $ACTION$", "placeholders": { "action": { "content": "$1", @@ -3196,55 +3248,52 @@ } }, "vaultTimeoutTooLarge": { - "message": "Your vault timeout exceeds the restrictions set by your organization." + "message": "เวลาหมดเวลาของตู้นิรภัยเกินข้อจำกัดที่องค์กรกำหนด" }, "vaultExportDisabled": { - "message": "Vault export unavailable" + "message": "ไม่สามารถส่งออกตู้นิรภัยได้" }, "personalVaultExportPolicyInEffect": { - "message": "One or more organization policies prevents you from exporting your individual vault." + "message": "นโยบายองค์กรอย่างน้อยหนึ่งรายการป้องกันไม่ให้คุณส่งออกตู้นิรภัยส่วนตัว" }, "copyCustomFieldNameInvalidElement": { - "message": "Unable to identify a valid form element. Try inspecting the HTML instead." + "message": "ไม่สามารถระบุองค์ประกอบแบบฟอร์มที่ถูกต้องได้ ลองตรวจสอบ HTML แทน" }, "copyCustomFieldNameNotUnique": { - "message": "No unique identifier found." - }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + "message": "ไม่พบตัวระบุที่ไม่ซ้ำกัน" }, "organizationName": { - "message": "Organization name" + "message": "ชื่อองค์กร" }, "keyConnectorDomain": { - "message": "Key Connector domain" + "message": "โดเมน Key Connector" }, "leaveOrganization": { - "message": "Leave organization" + "message": "ออกจากองค์กร" }, "removeMasterPassword": { - "message": "Remove master password" + "message": "เอารหัสผ่านหลักออก" }, "removedMasterPassword": { - "message": "Master password removed" + "message": "เอารหัสผ่านหลักออกแล้ว" }, "leaveOrganizationConfirmation": { - "message": "Are you sure you want to leave this organization?" + "message": "ยืนยันที่จะออกจากองค์กรนี้หรือไม่" }, "leftOrganization": { - "message": "You have left the organization." + "message": "คุณออกจากองค์กรแล้ว" }, "toggleCharacterCount": { - "message": "Toggle character count" + "message": "สลับการนับตัวอักษร" }, "sessionTimeout": { - "message": "Your session has timed out. Please go back and try logging in again." + "message": "เซสชันของคุณหมดเวลาแล้ว โปรดย้อนกลับและลองเข้าสู่ระบบอีกครั้ง" }, "exportingPersonalVaultTitle": { - "message": "Exporting individual vault" + "message": "กำลังส่งออกตู้นิรภัยส่วนตัว" }, "exportingIndividualVaultDescription": { - "message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.", + "message": "เฉพาะรายการในตู้นิรภัยส่วนตัวที่เชื่อมโยงกับ $EMAIL$ เท่านั้นที่จะถูกส่งออก รายการในตู้นิรภัยองค์กรจะไม่รวมอยู่ด้วย ระบบจะส่งออกเฉพาะข้อมูลรายการในตู้นิรภัยและไม่รวมไฟล์แนบที่เกี่ยวข้อง", "placeholders": { "email": { "content": "$1", @@ -3253,7 +3302,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "เฉพาะรายการในตู้นิรภัยส่วนตัวและไฟล์แนบที่เชื่อมโยงกับ $EMAIL$ เท่านั้นที่จะถูกส่งออก รายการในตู้นิรภัยองค์กรจะไม่รวมอยู่ด้วย", "placeholders": { "email": { "content": "$1", @@ -3262,10 +3311,10 @@ } }, "exportingOrganizationVaultTitle": { - "message": "Exporting organization vault" + "message": "กำลังส่งออกตู้นิรภัยองค์กร" }, "exportingOrganizationVaultDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", + "message": "เฉพาะตู้นิรภัยองค์กรที่เชื่อมโยงกับ $ORGANIZATION$ เท่านั้นที่จะถูกส่งออก รายการในตู้นิรภัยส่วนตัวหรือองค์กรอื่นจะไม่รวมอยู่ด้วย", "placeholders": { "organization": { "content": "$1", @@ -3274,7 +3323,7 @@ } }, "exportingOrganizationVaultFromPasswordManagerWithDataOwnershipDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported.", + "message": "เฉพาะตู้นิรภัยองค์กรที่เชื่อมโยงกับ $ORGANIZATION$ เท่านั้นที่จะถูกส่งออก", "placeholders": { "organization": { "content": "$1", @@ -3283,7 +3332,7 @@ } }, "exportingOrganizationVaultFromAdminConsoleWithDataOwnershipDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. My items collections will not be included.", + "message": "เฉพาะตู้นิรภัยองค์กรที่เชื่อมโยงกับ $ORGANIZATION$ เท่านั้นที่จะถูกส่งออก คอลเลกชันรายการของฉันจะไม่รวมอยู่ด้วย", "placeholders": { "organization": { "content": "$1", @@ -3292,33 +3341,33 @@ } }, "error": { - "message": "Error" + "message": "ข้อผิดพลาด" }, "decryptionError": { - "message": "Decryption error" + "message": "ข้อผิดพลาดในการถอดรหัส" }, "errorGettingAutoFillData": { - "message": "Error getting autofill data" + "message": "เกิดข้อผิดพลาดในการดึงข้อมูลป้อนอัตโนมัติ" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "Bitwarden ไม่สามารถถอดรหัสรายการตู้นิรภัยที่ระบุไว้ด้านล่าง" }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "ติดต่อทีม Customer Success", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "contactCSToAvoidDataLossPart2": { - "message": "to avoid additional data loss.", + "message": "เพื่อหลีกเลี่ยงการสูญหายของข้อมูลเพิ่มเติม", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "generateUsername": { - "message": "Generate username" + "message": "สร้างชื่อผู้ใช้" }, "generateEmail": { - "message": "Generate email" + "message": "สร้างอีเมล" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "ค่าต้องอยู่ระหว่าง $MIN$ ถึง $MAX$", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -3332,7 +3381,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " ใช้ $RECOMMENDED$ ตัวอักษรขึ้นไปเพื่อสร้างรหัสผ่านที่รัดกุม", "description": "Appended to `spinboxBoundariesHint` to recommend a length to the user. This must include any language-specific 'sentence' separator characters (e.g. a space in english).", "placeholders": { "recommended": { @@ -3342,7 +3391,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " ใช้ $RECOMMENDED$ คำขึ้นไปเพื่อสร้างวลีรหัสผ่านที่รัดกุม", "description": "Appended to `spinboxBoundariesHint` to recommend a number of words to the user. This must include any language-specific 'sentence' separator characters (e.g. a space in english).", "placeholders": { "recommended": { @@ -3352,46 +3401,46 @@ } }, "plusAddressedEmail": { - "message": "Plus addressed email", + "message": "อีเมลแบบ Plus addressing", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { - "message": "Use your email provider's sub-addressing capabilities." + "message": "ใช้ความสามารถ sub-addressing ของผู้ให้บริการอีเมลของคุณ" }, "catchallEmail": { - "message": "Catch-all email" + "message": "อีเมลแบบ Catch-all" }, "catchallEmailDesc": { - "message": "Use your domain's configured catch-all inbox." + "message": "ใช้อินบ็อกซ์แบบ Catch-all ที่กำหนดค่าไว้สำหรับโดเมนของคุณ" }, "random": { - "message": "Random" + "message": "สุ่ม" }, "randomWord": { - "message": "Random word" + "message": "คำสุ่ม" }, "websiteName": { - "message": "Website name" + "message": "ชื่อเว็บไซต์" }, "service": { - "message": "Service" + "message": "บริการ" }, "forwardedEmail": { - "message": "Forwarded email alias" + "message": "นามแฝงอีเมลแบบส่งต่อ" }, "forwardedEmailDesc": { - "message": "Generate an email alias with an external forwarding service." + "message": "สร้างนามแฝงอีเมลด้วยบริการส่งต่อภายนอก" }, "forwarderDomainName": { - "message": "Email domain", + "message": "โดเมนอีเมล", "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { - "message": "Choose a domain that is supported by the selected service", + "message": "เลือกโดเมนที่บริการที่เลือกไว้รองรับ", "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { - "message": "$SERVICENAME$ error: $ERRORMESSAGE$", + "message": "ข้อผิดพลาด $SERVICENAME$: $ERRORMESSAGE$", "description": "Reports an error returned by a forwarding service to the user.", "placeholders": { "servicename": { @@ -3405,11 +3454,11 @@ } }, "forwarderGeneratedBy": { - "message": "Generated by Bitwarden.", + "message": "สร้างโดย Bitwarden", "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { - "message": "Website: $WEBSITE$. Generated by Bitwarden.", + "message": "เว็บไซต์: $WEBSITE$ สร้างโดย Bitwarden", "description": "Displayed with the address on the forwarding service's configuration screen.", "placeholders": { "WEBSITE": { @@ -3419,7 +3468,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "โทเค็น API ของ $SERVICENAME$ ไม่ถูกต้อง", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -3429,7 +3478,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "โทเค็น API ของ $SERVICENAME$ ไม่ถูกต้อง: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -3443,7 +3492,7 @@ } }, "forwaderInvalidOperation": { - "message": "$SERVICENAME$ refused your request. Please contact your service provider for assistance.", + "message": "$SERVICENAME$ ปฏิเสธคำขอของคุณ โปรดติดต่อผู้ให้บริการเพื่อขอความช่วยเหลือ", "description": "Displayed when the user is forbidden from using the API by the forwarding service.", "placeholders": { "servicename": { @@ -3453,7 +3502,7 @@ } }, "forwaderInvalidOperationWithMessage": { - "message": "$SERVICENAME$ refused your request: $ERRORMESSAGE$", + "message": "$SERVICENAME$ ปฏิเสธคำขอของคุณ: $ERRORMESSAGE$", "description": "Displayed when the user is forbidden from using the API by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -3467,7 +3516,7 @@ } }, "forwarderNoAccountId": { - "message": "Unable to obtain $SERVICENAME$ masked email account ID.", + "message": "ไม่สามารถรับ ID บัญชีอีเมลแบบปิดบังตัวตนของ $SERVICENAME$", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -3477,7 +3526,7 @@ } }, "forwarderNoDomain": { - "message": "Invalid $SERVICENAME$ domain.", + "message": "โดเมน $SERVICENAME$ ไม่ถูกต้อง", "description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.", "placeholders": { "servicename": { @@ -3487,7 +3536,7 @@ } }, "forwarderNoUrl": { - "message": "Invalid $SERVICENAME$ url.", + "message": "URL ของ $SERVICENAME$ ไม่ถูกต้อง", "description": "Displayed when the url of the forwarding service wasn't supplied.", "placeholders": { "servicename": { @@ -3497,7 +3546,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "เกิดข้อผิดพลาด $SERVICENAME$ ที่ไม่รู้จัก", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -3507,7 +3556,7 @@ } }, "forwarderUnknownForwarder": { - "message": "Unknown forwarder: '$SERVICENAME$'.", + "message": "ไม่รู้จักบริการส่งต่อ: '$SERVICENAME$'", "description": "Displayed when the forwarding service is not supported.", "placeholders": { "servicename": { @@ -3517,29 +3566,29 @@ } }, "hostname": { - "message": "Hostname", + "message": "ชื่อโฮสต์", "description": "Part of a URL." }, "apiAccessToken": { - "message": "API Access Token" + "message": "โทเค็นการเข้าถึง API" }, "apiKey": { - "message": "API Key" + "message": "คีย์ API" }, "ssoKeyConnectorError": { - "message": "Key connector error: make sure key connector is available and working correctly." + "message": "ข้อผิดพลาด Key Connector: ตรวจสอบให้แน่ใจว่า Key Connector พร้อมใช้งานและทำงานอย่างถูกต้อง" }, "premiumSubcriptionRequired": { - "message": "Premium subscription required" + "message": "จำเป็นต้องสมัครสมาชิกพรีเมียม" }, "organizationIsDisabled": { - "message": "Organization suspended." + "message": "องค์กรถูกระงับ" }, "disabledOrganizationFilterError": { - "message": "Items in suspended Organizations cannot be accessed. Contact your Organization owner for assistance." + "message": "ไม่สามารถเข้าถึงรายการในองค์กรที่ถูกระงับได้ ติดต่อเจ้าขององค์กรเพื่อขอความช่วยเหลือ" }, "loggingInTo": { - "message": "Logging in to $DOMAIN$", + "message": "กำลังเข้าสู่ระบบ $DOMAIN$", "placeholders": { "domain": { "content": "$1", @@ -3548,16 +3597,16 @@ } }, "serverVersion": { - "message": "Server version" + "message": "เวอร์ชันเซิร์ฟเวอร์" }, "selfHostedServer": { - "message": "self-hosted" + "message": "โฮสต์เอง" }, "thirdParty": { - "message": "Third-party" + "message": "บุคคลที่สาม" }, "thirdPartyServerMessage": { - "message": "Connected to third-party server implementation, $SERVERNAME$. Please verify bugs using the official server, or report them to the third-party server.", + "message": "เชื่อมต่อกับเซิร์ฟเวอร์บุคคลที่สาม $SERVERNAME$ แล้ว โปรดตรวจสอบข้อผิดพลาดโดยใช้เซิร์ฟเวอร์อย่างเป็นทางการ หรือรายงานข้อผิดพลาดไปยังเซิร์ฟเวอร์บุคคลที่สาม", "placeholders": { "servername": { "content": "$1", @@ -3566,7 +3615,7 @@ } }, "lastSeenOn": { - "message": "last seen on: $DATE$", + "message": "ใช้งานล่าสุดเมื่อ: $DATE$", "placeholders": { "date": { "content": "$1", @@ -3575,58 +3624,58 @@ } }, "loginWithMasterPassword": { - "message": "Log in with master password" + "message": "เข้าสู่ระบบด้วยรหัสผ่านหลัก" }, "newAroundHere": { - "message": "New around here?" + "message": "เพิ่งเคยใช้งานใช่หรือไม่" }, "rememberEmail": { - "message": "Remember email" + "message": "จดจำอีเมล" }, "loginWithDevice": { - "message": "Log in with device" + "message": "เข้าสู่ระบบด้วยอุปกรณ์" }, "fingerprintPhraseHeader": { - "message": "Fingerprint phrase" + "message": "วลีลายนิ้วมือ" }, "fingerprintMatchInfo": { - "message": "โปรดตรวจสอบให้แน่ใจว่าห้องนิรภัยของคุณปลดล็อกอยู่ และลายนิ้วมือตรงกันบนอุปกรณ์อื่น" + "message": "โปรดตรวจสอบให้แน่ใจว่าตู้นิรภัยปลดล็อกอยู่ และวลีลายนิ้วมือตรงกับอุปกรณ์อีกเครื่อง" }, "resendNotification": { - "message": "Resend notification" + "message": "ส่งการแจ้งเตือนอีกครั้ง" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "ดูตัวเลือกการเข้าสู่ระบบทั้งหมด" }, "notificationSentDevice": { - "message": "A notification has been sent to your device." + "message": "ส่งการแจ้งเตือนไปยังอุปกรณ์ของคุณแล้ว" }, "notificationSentDevicePart1": { - "message": "Unlock Bitwarden on your device or on the" + "message": "ปลดล็อก Bitwarden บนอุปกรณ์ของคุณหรือบน" }, "notificationSentDeviceAnchor": { - "message": "web app" + "message": "เว็บแอป" }, "notificationSentDevicePart2": { - "message": "Make sure the Fingerprint phrase matches the one below before approving." + "message": "ตรวจสอบให้แน่ใจว่าวลีลายนิ้วมือตรงกับด้านล่างก่อนอนุมัติ" }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "ส่งการแจ้งเตือนไปยังอุปกรณ์ของคุณแล้ว" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "คุณจะได้รับแจ้งเมื่อคำขอได้รับการอนุมัติ" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "ต้องการตัวเลือกอื่นหรือไม่" }, "loginInitiated": { - "message": "Login initiated" + "message": "เริ่มการเข้าสู่ระบบแล้ว" }, "logInRequestSent": { - "message": "Request sent" + "message": "ส่งคำขอแล้ว" }, "loginRequestApprovedForEmailOnDevice": { - "message": "Login request approved for $EMAIL$ on $DEVICE$", + "message": "อนุมัติคำขอเข้าสู่ระบบสำหรับ $EMAIL$ บน $DEVICE$ แล้ว", "placeholders": { "email": { "content": "$1", @@ -3639,40 +3688,40 @@ } }, "youDeniedLoginAttemptFromAnotherDevice": { - "message": "You denied a login attempt from another device. If this was you, try to log in with the device again." + "message": "คุณปฏิเสธความพยายามเข้าสู่ระบบจากอุปกรณ์อื่น หากนี่คือคุณ ให้ลองเข้าสู่ระบบด้วยอุปกรณ์อีกครั้ง" }, "device": { - "message": "Device" + "message": "อุปกรณ์" }, "loginStatus": { - "message": "Login status" + "message": "สถานะการเข้าสู่ระบบ" }, "masterPasswordChanged": { - "message": "Master password saved" + "message": "บันทึกรหัสผ่านหลักแล้ว" }, "exposedMasterPassword": { - "message": "Exposed Master Password" + "message": "รหัสผ่านหลักรั่วไหล" }, "exposedMasterPasswordDesc": { - "message": "Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?" + "message": "พบรหัสผ่านในเหตุการณ์ข้อมูลรั่วไหล ใช้รหัสผ่านที่ไม่ซ้ำกันเพื่อปกป้องบัญชีของคุณ ยืนยันที่จะใช้รหัสผ่านที่รั่วไหลหรือไม่" }, "weakAndExposedMasterPassword": { - "message": "Weak and Exposed Master Password" + "message": "รหัสผ่านหลักไม่ปลอดภัยและรั่วไหล" }, "weakAndBreachedMasterPasswordDesc": { - "message": "Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?" + "message": "พบรหัสผ่านที่ไม่ปลอดภัยและอยู่ในเหตุการณ์ข้อมูลรั่วไหล ใช้รหัสผ่านที่รัดกุมและไม่ซ้ำกันเพื่อปกป้องบัญชีของคุณ ยืนยันที่จะใช้รหัสผ่านนี้หรือไม่" }, "checkForBreaches": { - "message": "Check known data breaches for this password" + "message": "ตรวจสอบเหตุการณ์ข้อมูลรั่วไหลสำหรับรหัสผ่านนี้" }, "important": { - "message": "Important:" + "message": "สำคัญ:" }, "masterPasswordHint": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "รหัสผ่านหลักไม่สามารถกู้คืนได้หากคุณลืม!" }, "characterMinimum": { - "message": "$LENGTH$ character minimum", + "message": "ขั้นต่ำ $LENGTH$ ตัวอักษร", "placeholders": { "length": { "content": "$1", @@ -3681,10 +3730,10 @@ } }, "autofillPageLoadPolicyActivated": { - "message": "Your organization policies have turned on autofill on page load." + "message": "นโยบายองค์กรของคุณเปิดใช้งานการป้อนอัตโนมัติเมื่อโหลดหน้าเว็บ" }, "autofillSelectInfoWithCommand": { - "message": "Select an item from this screen, use the shortcut $COMMAND$, or explore other options in settings.", + "message": "เลือกรายการจากหน้านี้ ใช้ทางลัด $COMMAND$ หรือสำรวจตัวเลือกอื่น ๆ ในการตั้งค่า", "placeholders": { "command": { "content": "$1", @@ -3693,31 +3742,31 @@ } }, "autofillSelectInfoWithoutCommand": { - "message": "Select an item from this screen, or explore other options in settings." + "message": "เลือกรายการจากหน้านี้ หรือสำรวจตัวเลือกอื่น ๆ ในการตั้งค่า" }, "gotIt": { - "message": "Got it" + "message": "เข้าใจแล้ว" }, "autofillSettings": { - "message": "Autofill settings" + "message": "การตั้งค่าการป้อนอัตโนมัติ" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "ทางลัดการป้อนอัตโนมัติ" }, "autofillKeyboardShortcutUpdateLabel": { - "message": "Change shortcut" + "message": "เปลี่ยนทางลัด" }, "autofillKeyboardManagerShortcutsLabel": { - "message": "Manage shortcuts" + "message": "จัดการทางลัด" }, "autofillShortcut": { - "message": "Autofill keyboard shortcut" + "message": "คีย์ลัดการป้อนอัตโนมัติ" }, "autofillLoginShortcutNotSet": { - "message": "The autofill login shortcut is not set. Change this in the browser's settings." + "message": "ยังไม่ได้ตั้งค่าทางลัดการป้อนข้อมูลเข้าสู่ระบบ เปลี่ยนค่านี้ได้ในการตั้งค่าของเบราว์เซอร์" }, "autofillLoginShortcutText": { - "message": "The autofill login shortcut is $COMMAND$. Manage all shortcuts in the browser's settings.", + "message": "ทางลัดการป้อนข้อมูลเข้าสู่ระบบคือ $COMMAND$ จัดการทางลัดทั้งหมดได้ในการตั้งค่าของเบราว์เซอร์", "placeholders": { "command": { "content": "$1", @@ -3726,7 +3775,7 @@ } }, "autofillShortcutTextSafari": { - "message": "Default autofill shortcut: $COMMAND$.", + "message": "ทางลัดการป้อนอัตโนมัติเริ่มต้น: $COMMAND$", "placeholders": { "command": { "content": "$1", @@ -3735,34 +3784,34 @@ } }, "opensInANewWindow": { - "message": "Opens in a new window" + "message": "เปิดในหน้าต่างใหม่" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "จดจำอุปกรณ์นี้เพื่อให้การเข้าสู่ระบบในอนาคตราบรื่นยิ่งขึ้น" }, "manageDevices": { - "message": "Manage devices" + "message": "จัดการอุปกรณ์" }, "currentSession": { - "message": "Current session" + "message": "เซสชันปัจจุบัน" }, "mobile": { - "message": "Mobile", + "message": "มือถือ", "description": "Mobile app" }, "extension": { - "message": "Extension", + "message": "ส่วนขยาย", "description": "Browser extension/addon" }, "desktop": { - "message": "Desktop", + "message": "เดสก์ท็อป", "description": "Desktop app" }, "webVault": { - "message": "Web vault" + "message": "เว็บตู้นิรภัย" }, "webApp": { - "message": "Web app" + "message": "เว็บแอป" }, "cli": { "message": "CLI" @@ -3772,22 +3821,22 @@ "description": "Software Development Kit" }, "requestPending": { - "message": "Request pending" + "message": "คำขอรอดำเนินการ" }, "firstLogin": { - "message": "First login" + "message": "เข้าสู่ระบบครั้งแรก" }, "trusted": { - "message": "Trusted" + "message": "เชื่อถือได้" }, "needsApproval": { - "message": "Needs approval" + "message": "รอการอนุมัติ" }, "devices": { - "message": "Devices" + "message": "อุปกรณ์" }, "accessAttemptBy": { - "message": "Access attempt by $EMAIL$", + "message": "ความพยายามเข้าถึงโดย $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -3796,31 +3845,31 @@ } }, "confirmAccess": { - "message": "Confirm access" + "message": "ยืนยันการเข้าถึง" }, "denyAccess": { - "message": "Deny access" + "message": "ปฏิเสธการเข้าถึง" }, "time": { - "message": "Time" + "message": "เวลา" }, "deviceType": { - "message": "Device Type" + "message": "ประเภทอุปกรณ์" }, "loginRequest": { - "message": "Login request" + "message": "คำขอเข้าสู่ระบบ" }, "thisRequestIsNoLongerValid": { - "message": "This request is no longer valid." + "message": "คำขอนี้ใช้ไม่ได้อีกต่อไป" }, "loginRequestHasAlreadyExpired": { - "message": "Login request has already expired." + "message": "คำขอเข้าสู่ระบบหมดอายุแล้ว" }, "justNow": { - "message": "Just now" + "message": "เมื่อสักครู่" }, "requestedXMinutesAgo": { - "message": "Requested $MINUTES$ minutes ago", + "message": "ร้องขอเมื่อ $MINUTES$ นาทีที่แล้ว", "placeholders": { "minutes": { "content": "$1", @@ -3829,136 +3878,136 @@ } }, "deviceApprovalRequired": { - "message": "Device approval required. Select an approval option below:" + "message": "จำเป็นต้องอนุมัติอุปกรณ์ เลือกตัวเลือกการอนุมัติด้านล่าง:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "จำเป็นต้องอนุมัติอุปกรณ์" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "เลือกตัวเลือกการอนุมัติด้านล่าง" }, "rememberThisDevice": { - "message": "Remember this device" + "message": "จดจำอุปกรณ์นี้" }, "uncheckIfPublicDevice": { - "message": "Uncheck if using a public device" + "message": "ไม่ต้องเลือกหากใช้อุปกรณ์สาธารณะ" }, "approveFromYourOtherDevice": { - "message": "Approve from your other device" + "message": "อนุมัติจากอุปกรณ์อื่นของคุณ" }, "requestAdminApproval": { - "message": "Request admin approval" + "message": "ขอการอนุมัติจากผู้ดูแลระบบ" }, "unableToCompleteLogin": { - "message": "Unable to complete login" + "message": "ไม่สามารถเข้าสู่ระบบให้เสร็จสมบูรณ์ได้" }, "loginOnTrustedDeviceOrAskAdminToAssignPassword": { - "message": "You need to log in on a trusted device or ask your administrator to assign you a password." + "message": "คุณต้องเข้าสู่ระบบบนอุปกรณ์ที่เชื่อถือได้ หรือขอให้ผู้ดูแลระบบกำหนดรหัสผ่านให้คุณ" }, "ssoIdentifierRequired": { - "message": "Organization SSO identifier is required." + "message": "จำเป็นต้องระบุตัวระบุ SSO ขององค์กร" }, "creatingAccountOn": { - "message": "Creating account on" + "message": "กำลังสร้างบัญชีบน" }, "checkYourEmail": { - "message": "Check your email" + "message": "ตรวจสอบอีเมลของคุณ" }, "followTheLinkInTheEmailSentTo": { - "message": "Follow the link in the email sent to" + "message": "คลิกลิงก์ในอีเมลที่ส่งไปที่" }, "andContinueCreatingYourAccount": { - "message": "and continue creating your account." + "message": "และดำเนินการสร้างบัญชีต่อ" }, "noEmail": { - "message": "No email?" + "message": "ไม่ได้รับอีเมลใช่ไหม" }, "goBack": { - "message": "Go back" + "message": "ย้อนกลับ" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "เพื่อแก้ไขที่อยู่อีเมลของคุณ" }, "eu": { "message": "EU", "description": "European Union" }, "accessDenied": { - "message": "Access denied. You do not have permission to view this page." + "message": "การเข้าถึงถูกปฏิเสธ คุณไม่มีสิทธิ์ดูหน้านี้" }, "general": { - "message": "General" + "message": "ทั่วไป" }, "display": { - "message": "Display" + "message": "การแสดงผล" }, "accountSuccessfullyCreated": { - "message": "Account successfully created!" + "message": "สร้างบัญชีสำเร็จแล้ว!" }, "adminApprovalRequested": { - "message": "Admin approval requested" + "message": "ส่งคำขออนุมัติจากผู้ดูแลระบบแล้ว" }, "adminApprovalRequestSentToAdmins": { - "message": "Your request has been sent to your admin." + "message": "ส่งคำขอของคุณไปยังผู้ดูแลระบบแล้ว" }, "troubleLoggingIn": { - "message": "Trouble logging in?" + "message": "มีปัญหาในการเข้าสู่ระบบใช่หรือไม่" }, "loginApproved": { - "message": "Login approved" + "message": "อนุมัติการเข้าสู่ระบบแล้ว" }, "userEmailMissing": { - "message": "User email missing" + "message": "ไม่พบอีเมลผู้ใช้" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "ไม่พบอีเมลผู้ใช้ที่ใช้งานอยู่ กำลังออกจากระบบ" }, "deviceTrusted": { - "message": "Device trusted" + "message": "อุปกรณ์ที่เชื่อถือได้" }, "trustOrganization": { - "message": "Trust organization" + "message": "เชื่อถือองค์กร" }, "trust": { - "message": "Trust" + "message": "เชื่อถือ" }, "doNotTrust": { - "message": "Do not trust" + "message": "ไม่เชื่อถือ" }, "organizationNotTrusted": { - "message": "Organization is not trusted" + "message": "องค์กรไม่น่าเชื่อถือ" }, "emergencyAccessTrustWarning": { - "message": "เพื่อความปลอดภัยของบัญชีของคุณ โปรดยืนยันว่าคุณได้ให้สิทธิ์การเข้าถึงในกรณีฉุกเฉินแก่ผู้ใช้นี้ และลายนิ้วมือของผู้ใช้ตรงกับที่แสดงในบัญชีของพวกเขาเท่านั้น" + "message": "เพื่อความปลอดภัยของบัญชี โปรดยืนยันเฉพาะเมื่อคุณได้ให้สิทธิ์การเข้าถึงฉุกเฉินแก่ผู้ใช้นี้ และลายนิ้วมือของพวกเขาตรงกับที่แสดงในบัญชีของพวกเขา" }, "orgTrustWarning": { - "message": "เพื่อความปลอดภัยของบัญชีของคุณ ให้ดำเนินการต่อเมื่อคุณเป็นสมาชิกขององค์กรนี้, ได้เปิดใช้งานการกู้คืนบัญชี, และลายนิ้วมือที่แสดงด้านล่างตรงกับลายนิ้วมือขององค์กรเท่านั้น" + "message": "เพื่อความปลอดภัยของบัญชี โปรดดำเนินการต่อเฉพาะเมื่อคุณเป็นสมาชิกขององค์กรนี้ เปิดใช้งานการกู้คืนบัญชี และลายนิ้วมือที่แสดงด้านล่างตรงกับลายนิ้วมือขององค์กร" }, "orgTrustWarning1": { - "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + "message": "องค์กรนี้มีนโยบายองค์กรที่จะลงทะเบียนคุณในการกู้คืนบัญชี การลงทะเบียนจะอนุญาตให้ผู้ดูแลระบบองค์กรเปลี่ยนรหัสผ่านของคุณได้ โปรดดำเนินการต่อเฉพาะเมื่อคุณรู้จักองค์กรนี้ และวลีลายนิ้วมือที่แสดงด้านล่างตรงกับลายนิ้วมือขององค์กร" }, "trustUser": { - "message": "Trust user" + "message": "เชื่อถือผู้ใช้" }, "sendsTitleNoItems": { - "message": "Send sensitive information safely", + "message": "ส่งข้อมูลสำคัญอย่างปลอดภัยด้วย Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendsBodyNoItems": { - "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "message": "แชร์ไฟล์และข้อมูลอย่างปลอดภัยกับทุกคน บนทุกแพลตฟอร์ม ข้อมูลของคุณจะได้รับการเข้ารหัสแบบ End-to-end และจำกัดการเข้าถึง", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "inputRequired": { - "message": "Input is required." + "message": "จำเป็นต้องระบุข้อมูล" }, "required": { - "message": "required" + "message": "จำเป็น" }, "search": { - "message": "Search" + "message": "ค้นหา" }, "inputMinLength": { - "message": "Input must be at least $COUNT$ characters long.", + "message": "ข้อมูลต้องมีความยาวอย่างน้อย $COUNT$ ตัวอักษร", "placeholders": { "count": { "content": "$1", @@ -3967,7 +4016,7 @@ } }, "inputMaxLength": { - "message": "Input must not exceed $COUNT$ characters in length.", + "message": "ข้อมูลต้องมีความยาวไม่เกิน $COUNT$ ตัวอักษร", "placeholders": { "count": { "content": "$1", @@ -3976,7 +4025,7 @@ } }, "inputForbiddenCharacters": { - "message": "The following characters are not allowed: $CHARACTERS$", + "message": "ไม่อนุญาตให้ใช้อักขระต่อไปนี้: $CHARACTERS$", "placeholders": { "characters": { "content": "$1", @@ -3985,7 +4034,7 @@ } }, "inputMinValue": { - "message": "Input value must be at least $MIN$.", + "message": "ค่าที่ป้อนต้องมีค่าอย่างน้อย $MIN$", "placeholders": { "min": { "content": "$1", @@ -3994,7 +4043,7 @@ } }, "inputMaxValue": { - "message": "Input value must not exceed $MAX$.", + "message": "ค่าที่ป้อนต้องมีค่าไม่เกิน $MAX$", "placeholders": { "max": { "content": "$1", @@ -4003,17 +4052,17 @@ } }, "multipleInputEmails": { - "message": "1 or more emails are invalid" + "message": "อีเมลอย่างน้อย 1 รายการไม่ถูกต้อง" }, "inputTrimValidator": { - "message": "Input must not contain only whitespace.", + "message": "ข้อมูลต้องไม่ประกอบด้วยช่องว่างเพียงอย่างเดียว", "description": "Notification to inform the user that a form's input can't contain only whitespace." }, "inputEmail": { - "message": "Input is not an email address." + "message": "ข้อมูลไม่ใช่ที่อยู่อีเมล" }, "fieldsNeedAttention": { - "message": "$COUNT$ field(s) above need your attention.", + "message": "ฟิลด์ด้านบน $COUNT$ รายการต้องการการตรวจสอบ", "placeholders": { "count": { "content": "$1", @@ -4022,10 +4071,10 @@ } }, "singleFieldNeedsAttention": { - "message": "1 field needs your attention." + "message": "1 ฟิลด์ต้องการการตรวจสอบ" }, "multipleFieldsNeedAttention": { - "message": "$COUNT$ fields need your attention.", + "message": "$COUNT$ ฟิลด์ต้องการการตรวจสอบ", "placeholders": { "count": { "content": "$1", @@ -4034,22 +4083,22 @@ } }, "selectPlaceholder": { - "message": "-- Select --" + "message": "-- เลือก --" }, "multiSelectPlaceholder": { - "message": "-- Type to filter --" + "message": "-- พิมพ์เพื่อกรอง --" }, "multiSelectLoading": { - "message": "Retrieving options..." + "message": "กำลังดึงตัวเลือก..." }, "multiSelectNotFound": { - "message": "No items found" + "message": "ไม่พบรายการ" }, "multiSelectClearAll": { - "message": "Clear all" + "message": "ล้างทั้งหมด" }, "plusNMore": { - "message": "+ $QUANTITY$ more", + "message": "+ อีก $QUANTITY$ รายการ", "placeholders": { "quantity": { "content": "$1", @@ -4058,145 +4107,141 @@ } }, "submenu": { - "message": "Submenu" + "message": "เมนูย่อย" }, "toggleCollapse": { - "message": "Toggle collapse", + "message": "ย่อ/ขยาย", "description": "Toggling an expand/collapse state." }, "aliasDomain": { - "message": "Alias domain" + "message": "โดเมนนามแฝง" }, "autofillOnPageLoadSetToDefault": { - "message": "Autofill on page load set to use default setting.", + "message": "ตั้งค่าการป้อนอัตโนมัติเมื่อโหลดหน้าเว็บเป็นค่าเริ่มต้นแล้ว", "description": "Toast message for informing the user that autofill on page load has been set to the default setting." }, "cannotAutofill": { - "message": "Cannot autofill" + "message": "ไม่สามารถป้อนอัตโนมัติได้" }, "cannotAutofillExactMatch": { - "message": "Default matching is set to 'Exact Match'. The current website does not exactly match the saved login details for this item." + "message": "การจับคู่เริ่มต้นตั้งค่าไว้ที่ 'ตรงกันทุกตัวอักษร' เว็บไซต์ปัจจุบันไม่ตรงกับรายละเอียดข้อมูลเข้าสู่ระบบที่บันทึกไว้สำหรับรายการนี้อย่างถูกต้อง" }, "okay": { - "message": "Okay" + "message": "ตกลง" }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "สลับแถบนำทางด้านข้าง" }, "skipToContent": { - "message": "Skip to content" + "message": "ข้ามไปที่เนื้อหา" }, "bitwardenOverlayButton": { - "message": "Bitwarden autofill menu button", + "message": "ปุ่มเมนูป้อนอัตโนมัติ Bitwarden", "description": "Page title for the iframe containing the overlay button" }, "toggleBitwardenVaultOverlay": { - "message": "Toggle Bitwarden autofill menu", + "message": "สลับเมนูป้อนอัตโนมัติ Bitwarden", "description": "Screen reader and tool tip label for the overlay button" }, "bitwardenVault": { - "message": "Bitwarden autofill menu", + "message": "เมนูป้อนอัตโนมัติ Bitwarden", "description": "Page title in overlay" }, "unlockYourAccountToViewMatchingLogins": { - "message": "Unlock your account to view matching logins", + "message": "ปลดล็อกบัญชีเพื่อดูข้อมูลเข้าสู่ระบบที่ตรงกัน", "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "ปลดล็อกบัญชีเพื่อดูคำแนะนำการป้อนอัตโนมัติ", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { - "message": "Unlock account", + "message": "ปลดล็อกบัญชี", "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "ปลดล็อกบัญชี เปิดในหน้าต่างใหม่", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Time-based One-Time Password Verification Code", + "message": "รหัสยืนยันรหัสผ่านใช้ครั้งเดียวตามเวลา", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { - "message": "Time remaining before current TOTP expires", + "message": "เวลาที่เหลือก่อน TOTP ปัจจุบันหมดอายุ", "description": "Aria label for the totp seconds displayed in the inline menu for autofill" }, "fillCredentialsFor": { - "message": "Fill credentials for", + "message": "ป้อนข้อมูลประจำตัวสำหรับ", "description": "Screen reader text for when overlay item is in focused" }, "partialUsername": { - "message": "Partial username", + "message": "ชื่อผู้ใช้บางส่วน", "description": "Screen reader text for when a login item is focused where a partial username is displayed. SR will announce this phrase before reading the text of the partial username" }, "noItemsToShow": { - "message": "No items to show", + "message": "ไม่มีรายการที่จะแสดง", "description": "Text to show in overlay if there are no matching items" }, "newItem": { - "message": "New item", + "message": "รายการใหม่", "description": "Button text to display in overlay when there are no matching items" }, "addNewVaultItem": { - "message": "Add new vault item", + "message": "เพิ่มรายการตู้นิรภัยใหม่", "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "ข้อมูลเข้าสู่ระบบใหม่", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "เพิ่มข้อมูลเข้าสู่ระบบตู้นิรภัยใหม่ เปิดในหน้าต่างใหม่", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "บัตรใหม่", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "เพิ่มรายการบัตรตู้นิรภัยใหม่ เปิดในหน้าต่างใหม่", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "ข้อมูลระบุตัวตนใหม่", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "เพิ่มข้อมูลระบุตัวตนตู้นิรภัยใหม่ เปิดในหน้าต่างใหม่", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { - "message": "Bitwarden autofill menu available. Press the down arrow key to select.", + "message": "เมนูป้อนอัตโนมัติ Bitwarden พร้อมใช้งาน กดปุ่มลูกศรลงเพื่อเลือก", "description": "Screen reader text for announcing when the overlay opens on the page" }, "turnOn": { - "message": "Turn on" + "message": "เปิด" }, "ignore": { - "message": "Ignore" - }, - "importData": { - "message": "Import data", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" + "message": "เพิกเฉย" }, "importError": { - "message": "Import error" + "message": "ข้อผิดพลาดในการนำเข้า" }, "importErrorDesc": { - "message": "There was a problem with the data you tried to import. Please resolve the errors listed below in your source file and try again." + "message": "เกิดปัญหากับข้อมูลที่คุณพยายามนำเข้า โปรดแก้ไขข้อผิดพลาดที่ระบุด้านล่างในไฟล์ต้นฉบับแล้วลองอีกครั้ง" }, "resolveTheErrorsBelowAndTryAgain": { - "message": "Resolve the errors below and try again." + "message": "แก้ไขข้อผิดพลาดด้านล่างแล้วลองอีกครั้ง" }, "description": { - "message": "Description" + "message": "คำอธิบาย" }, "importSuccess": { - "message": "Data successfully imported" + "message": "นำเข้าข้อมูลสำเร็จแล้ว" }, "importSuccessNumberOfItems": { - "message": "A total of $AMOUNT$ items were imported.", + "message": "นำเข้าข้อมูลทั้งหมด $AMOUNT$ รายการ", "placeholders": { "amount": { "content": "$1", @@ -4205,46 +4250,46 @@ } }, "tryAgain": { - "message": "Try again" + "message": "ลองอีกครั้ง" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "จำเป็นต้องยืนยันตัวตนสำหรับการดำเนินการนี้ ตั้งค่า PIN เพื่อดำเนินการต่อ" }, "setPin": { - "message": "ตั้ง PIN" + "message": "ตั้งค่า PIN" }, "verifyWithBiometrics": { - "message": "Verify with biometrics" + "message": "ยืนยันด้วยไบโอเมตริก" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "รอการยืนยัน" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "ไม่สามารถดำเนินการไบโอเมตริกให้เสร็จสิ้นได้" }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "ต้องการวิธีอื่นหรือไม่" }, "useMasterPassword": { - "message": "Use master password" + "message": "ใช้รหัสผ่านหลัก" }, "usePin": { - "message": "Use PIN" + "message": "ใช้ PIN" }, "useBiometrics": { - "message": "Use biometrics" + "message": "ใช้ไบโอเมตริก" }, "enterVerificationCodeSentToEmail": { - "message": "Enter the verification code that was sent to your email." + "message": "ป้อนรหัสยืนยันที่ส่งไปที่อีเมลของคุณ" }, "resendCode": { - "message": "Resend code" + "message": "ส่งรหัสอีกครั้ง" }, "total": { - "message": "Total" + "message": "รวม" }, "importWarning": { - "message": "You are importing data to $ORGANIZATION$. Your data may be shared with members of this organization. Do you want to proceed?", + "message": "คุณกำลังนำเข้าข้อมูลไปยัง $ORGANIZATION$ ข้อมูลของคุณอาจถูกแชร์กับสมาชิกขององค์กรนี้ ต้องการดำเนินการต่อหรือไม่", "placeholders": { "organization": { "content": "$1", @@ -4253,67 +4298,67 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "เกิดข้อผิดพลาดในการเชื่อมต่อกับบริการ Duo ใช้วิธีการเข้าสู่ระบบ 2 ขั้นตอนอื่น หรือติดต่อ Duo เพื่อขอความช่วยเหลือ" }, "duoRequiredForAccount": { - "message": "Duo two-step login is required for your account." + "message": "บัญชีของคุณจำเป็นต้องใช้การเข้าสู่ระบบ 2 ขั้นตอนผ่าน Duo" }, "popoutExtension": { - "message": "Popout extension" + "message": "แยกหน้าต่างส่วนขยาย" }, "launchDuo": { - "message": "Launch Duo" + "message": "เปิดใช้งาน Duo" }, "importFormatError": { - "message": "Data is not formatted correctly. Please check your import file and try again." + "message": "รูปแบบข้อมูลไม่ถูกต้อง โปรดตรวจสอบไฟล์นำเข้าแล้วลองอีกครั้ง" }, "importNothingError": { - "message": "Nothing was imported." + "message": "ไม่มีการนำเข้าข้อมูล" }, "importEncKeyError": { - "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." + "message": "เกิดข้อผิดพลาดในการถอดรหัสไฟล์ที่ส่งออก กุญแจเข้ารหัสของคุณไม่ตรงกับกุญแจเข้ารหัสที่ใช้ส่งออกข้อมูล" }, "invalidFilePassword": { - "message": "Invalid file password, please use the password you entered when you created the export file." + "message": "รหัสผ่านไฟล์ไม่ถูกต้อง โปรดใช้รหัสผ่านที่คุณป้อนตอนสร้างไฟล์ส่งออก" }, "destination": { - "message": "Destination" + "message": "ปลายทาง" }, "learnAboutImportOptions": { - "message": "Learn about your import options" + "message": "เรียนรู้เกี่ยวกับตัวเลือกการนำเข้า" }, "selectImportFolder": { - "message": "Select a folder" + "message": "เลือกโฟลเดอร์" }, "selectImportCollection": { - "message": "Select a collection" + "message": "เลือกคอลเลกชัน" }, "importTargetHintCollection": { - "message": "Select this option if you want the imported file contents moved to a collection" + "message": "เลือกตัวเลือกนี้หากต้องการย้ายเนื้อหาไฟล์ที่นำเข้าไปยังคอลเลกชัน" }, "importTargetHintFolder": { - "message": "Select this option if you want the imported file contents moved to a folder" + "message": "เลือกตัวเลือกนี้หากต้องการย้ายเนื้อหาไฟล์ที่นำเข้าไปยังโฟลเดอร์" }, "importUnassignedItemsError": { - "message": "File contains unassigned items." + "message": "ไฟล์มีรายการที่ไม่ได้มอบหมาย" }, "selectFormat": { - "message": "Select the format of the import file" + "message": "เลือกรูปแบบของไฟล์นำเข้า" }, "selectImportFile": { - "message": "Select the import file" + "message": "เลือกไฟล์นำเข้า" }, "chooseFile": { "message": "เลือกไฟล์" }, "noFileChosen": { - "message": "ไม่มีไฟล์ที่เลือก" + "message": "ไม่ได้เลือกไฟล์" }, "orCopyPasteFileContents": { - "message": "or copy/paste the import file contents" + "message": "หรือคัดลอก/วางเนื้อหาไฟล์นำเข้า" }, "instructionsFor": { - "message": "$NAME$ Instructions", + "message": "คำแนะนำสำหรับ $NAME$", "description": "The title for the import tool instructions.", "placeholders": { "name": { @@ -4323,200 +4368,200 @@ } }, "confirmVaultImport": { - "message": "Confirm vault import" + "message": "ยืนยันการนำเข้าตู้นิรภัย" }, "confirmVaultImportDesc": { - "message": "This file is password-protected. Please enter the file password to import data." + "message": "ไฟล์นี้มีการป้องกันด้วยรหัสผ่าน โปรดป้อนรหัสผ่านไฟล์เพื่อนำเข้าข้อมูล" }, "confirmFilePassword": { - "message": "Confirm file password" + "message": "ยืนยันรหัสผ่านไฟล์" }, "exportSuccess": { - "message": "Vault data exported" + "message": "ส่งออกข้อมูลตู้นิรภัยแล้ว" }, "typePasskey": { - "message": "Passkey" + "message": "พาสคีย์" }, "accessing": { "message": "กำลังเข้าถึง" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "เข้าสู่ระบบแล้ว!" }, "passkeyNotCopied": { - "message": "Passkey will not be copied" + "message": "จะไม่คัดลอกพาสคีย์" }, "passkeyNotCopiedAlert": { - "message": "The passkey will not be copied to the cloned item. Do you want to continue cloning this item?" + "message": "พาสคีย์จะไม่ถูกคัดลอกไปยังรายการที่โคลน ต้องการโคลนรายการนี้ต่อหรือไม่" }, "logInWithPasskeyQuestion": { - "message": "Log in with passkey?" + "message": "เข้าสู่ระบบด้วยพาสคีย์หรือไม่" }, "passkeyAlreadyExists": { - "message": "A passkey already exists for this application." + "message": "มีพาสคีย์สำหรับแอปพลิเคชันนี้อยู่แล้ว" }, "noPasskeysFoundForThisApplication": { - "message": "No passkeys found for this application." + "message": "ไม่พบพาสคีย์สำหรับแอปพลิเคชันนี้" }, "noMatchingPasskeyLogin": { - "message": "You do not have a matching login for this site." + "message": "คุณไม่มีข้อมูลเข้าสู่ระบบที่ตรงกันสำหรับไซต์นี้" }, "noMatchingLoginsForSite": { - "message": "No matching logins for this site" + "message": "ไม่มีข้อมูลเข้าสู่ระบบที่ตรงกันสำหรับไซต์นี้" }, "searchSavePasskeyNewLogin": { - "message": "Search or save passkey as new login" + "message": "ค้นหาหรือบันทึกพาสคีย์เป็นข้อมูลเข้าสู่ระบบใหม่" }, "confirm": { - "message": "Confirm" + "message": "ยืนยัน" }, "savePasskey": { - "message": "Save passkey" + "message": "บันทึกพาสคีย์" }, "savePasskeyNewLogin": { - "message": "Save passkey as new login" + "message": "บันทึกพาสคีย์เป็นข้อมูลเข้าสู่ระบบใหม่" }, "chooseCipherForPasskeySave": { - "message": "Choose a login to save this passkey to" + "message": "เลือกข้อมูลเข้าสู่ระบบเพื่อบันทึกพาสคีย์นี้" }, "chooseCipherForPasskeyAuth": { - "message": "Choose a passkey to log in with" + "message": "เลือกพาสคีย์เพื่อเข้าสู่ระบบ" }, "passkeyItem": { - "message": "Passkey Item" + "message": "รายการพาสคีย์" }, "overwritePasskey": { - "message": "Overwrite passkey?" + "message": "เขียนทับพาสคีย์หรือไม่" }, "overwritePasskeyAlert": { - "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + "message": "รายการนี้มีพาสคีย์อยู่แล้ว ยืนยันที่จะเขียนทับพาสคีย์ปัจจุบันหรือไม่" }, "featureNotSupported": { - "message": "Feature not yet supported" + "message": "ยังไม่รองรับฟีเจอร์นี้" }, "yourPasskeyIsLocked": { - "message": "Authentication required to use passkey. Verify your identity to continue." + "message": "จำเป็นต้องยืนยันตัวตนเพื่อใช้พาสคีย์ ยืนยันตัวตนของคุณเพื่อดำเนินการต่อ" }, "multifactorAuthenticationCancelled": { - "message": "Multifactor authentication cancelled" + "message": "ยกเลิกการยืนยันตัวตนแบบหลายปัจจัยแล้ว" }, "noLastPassDataFound": { - "message": "No LastPass data found" + "message": "ไม่พบข้อมูล LastPass" }, "incorrectUsernameOrPassword": { - "message": "Incorrect username or password" + "message": "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง" }, "incorrectPassword": { - "message": "Incorrect password" + "message": "รหัสผ่านไม่ถูกต้อง" }, "incorrectCode": { - "message": "Incorrect code" + "message": "รหัสไม่ถูกต้อง" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "รหัส PIN ไม่ถูกต้อง" }, "multifactorAuthenticationFailed": { - "message": "Multifactor authentication failed" + "message": "การยืนยันตัวตนแบบหลายปัจจัยล้มเหลว" }, "includeSharedFolders": { - "message": "Include shared folders" + "message": "รวมโฟลเดอร์ที่แชร์" }, "lastPassEmail": { - "message": "LastPass Email" + "message": "อีเมล LastPass" }, "importingYourAccount": { - "message": "Importing your account..." + "message": "กำลังนำเข้าบัญชีของคุณ..." }, "lastPassMFARequired": { - "message": "LastPass multifactor authentication required" + "message": "จำเป็นต้องยืนยันตัวตนแบบหลายปัจจัยของ LastPass" }, "lastPassMFADesc": { - "message": "Enter your one-time passcode from your authentication app" + "message": "ป้อนรหัสผ่านใช้ครั้งเดียวจากแอปยืนยันตัวตนของคุณ" }, "lastPassOOBDesc": { - "message": "Approve the login request in your authentication app or enter a one-time passcode." + "message": "อนุมัติคำขอเข้าสู่ระบบในแอปยืนยันตัวตนของคุณ หรือป้อนรหัสผ่านใช้ครั้งเดียว" }, "passcode": { - "message": "Passcode" + "message": "รหัสผ่าน" }, "lastPassMasterPassword": { - "message": "LastPass master password" + "message": "รหัสผ่านหลัก LastPass" }, "lastPassAuthRequired": { - "message": "LastPass authentication required" + "message": "จำเป็นต้องยืนยันตัวตน LastPass" }, "awaitingSSO": { - "message": "Awaiting SSO authentication" + "message": "กำลังรอการยืนยันตัวตน SSO" }, "awaitingSSODesc": { - "message": "Please continue to log in using your company credentials." + "message": "โปรดดำเนินการเข้าสู่ระบบโดยใช้ข้อมูลประจำตัวของบริษัทของคุณ" }, "seeDetailedInstructions": { - "message": "See detailed instructions on our help site at", + "message": "ดูคำแนะนำโดยละเอียดบนเว็บไซต์ช่วยเหลือของเราที่", "description": "This is followed a by a hyperlink to the help website." }, "importDirectlyFromLastPass": { - "message": "Import directly from LastPass" + "message": "นำเข้าจาก LastPass โดยตรง" }, "importFromCSV": { - "message": "Import from CSV" + "message": "นำเข้าจาก CSV" }, "lastPassTryAgainCheckEmail": { - "message": "Try again or look for an email from LastPass to verify it's you." + "message": "ลองอีกครั้งหรือตรวจสอบอีเมลจาก LastPass เพื่อยืนยันว่าเป็นคุณ" }, "collection": { - "message": "Collection" + "message": "คอลเลกชัน" }, "lastPassYubikeyDesc": { - "message": "Insert the YubiKey associated with your LastPass account into your computer's USB port, then touch its button." + "message": "เสียบ YubiKey ที่เชื่อมโยงกับบัญชี LastPass เข้ากับพอร์ต USB ของคอมพิวเตอร์ แล้วแตะที่ปุ่ม" }, "switchAccount": { - "message": "Switch account" + "message": "สลับบัญชี" }, "switchAccounts": { - "message": "Switch accounts" + "message": "สลับบัญชี" }, "switchToAccount": { - "message": "Switch to account" + "message": "สลับไปที่บัญชี" }, "activeAccount": { - "message": "Active account" + "message": "บัญชีที่ใช้งานอยู่" }, "bitwardenAccount": { - "message": "Bitwarden account" + "message": "บัญชี Bitwarden" }, "availableAccounts": { - "message": "Available accounts" + "message": "บัญชีที่มีอยู่" }, "accountLimitReached": { - "message": "ถึงขีดจำกัดของบัญชีแล้ว กรุณาออกจากระบบบัญชีอื่นเพื่อเพิ่มบัญชีใหม่" + "message": "ถึงขีดจำกัดจำนวนบัญชีแล้ว ออกจากระบบบัญชีหนึ่งเพื่อเพิ่มบัญชีอื่น" }, "active": { - "message": "active" + "message": "ใช้งานอยู่" }, "locked": { - "message": "locked" + "message": "ล็อกอยู่" }, "unlocked": { - "message": "unlocked" + "message": "ปลดล็อกแล้ว" }, "server": { - "message": "server" + "message": "เซิร์ฟเวอร์" }, "hostedAt": { - "message": "hosted at" + "message": "โฮสต์ที่" }, "useDeviceOrHardwareKey": { - "message": "Use your device or hardware key" + "message": "ใช้อุปกรณ์หรือคีย์ฮาร์ดแวร์ของคุณ" }, "justOnce": { - "message": "Just once" + "message": "เพียงครั้งเดียว" }, "alwaysForThisSite": { - "message": "Always for this site" + "message": "เสมอสำหรับไซต์นี้" }, "domainAddedToExcludedDomains": { - "message": "$DOMAIN$ added to excluded domains.", + "message": "เพิ่ม $DOMAIN$ ในโดเมนที่ยกเว้นแล้ว", "placeholders": { "domain": { "content": "$1", @@ -4525,126 +4570,126 @@ } }, "commonImportFormats": { - "message": "Common formats", + "message": "รูปแบบทั่วไป", "description": "Label indicating the most common import formats" }, "uriMatchDefaultStrategyHint": { - "message": "URI match detection is how Bitwarden identifies autofill suggestions.", + "message": "การตรวจสอบการจับคู่ URI คือวิธีที่ Bitwarden ระบุคำแนะนำการป้อนอัตโนมัติ", "description": "Explains to the user that URI match detection determines how Bitwarden suggests autofill options, and clarifies that this default strategy applies when no specific match detection is set for a login item." }, "regExAdvancedOptionWarning": { - "message": "\"Regular expression\" is an advanced option with increased risk of exposing credentials.", + "message": "\"Regular expression\" เป็นตัวเลือกขั้นสูงที่มีความเสี่ยงสูงในการเปิดเผยข้อมูลเข้าสู่ระบบ", "description": "Content for dialog which warns a user when selecting 'regular expression' matching strategy as a cipher match strategy" }, "startsWithAdvancedOptionWarning": { - "message": "\"Starts with\" is an advanced option with increased risk of exposing credentials.", + "message": "\"ขึ้นต้นด้วย\" เป็นตัวเลือกขั้นสูงที่มีความเสี่ยงสูงในการเปิดเผยข้อมูลเข้าสู่ระบบ", "description": "Content for dialog which warns a user when selecting 'starts with' matching strategy as a cipher match strategy" }, "uriMatchWarningDialogLink": { - "message": "More about match detection", + "message": "เพิ่มเติมเกี่ยวกับการตรวจสอบการจับคู่", "description": "Link to match detection docs on warning dialog for advance match strategy" }, "uriAdvancedOption": { - "message": "Advanced options", + "message": "ตัวเลือกขั้นสูง", "description": "Advanced option placeholder for uri option component" }, "confirmContinueToBrowserSettingsTitle": { - "message": "Continue to browser settings?", + "message": "ไปที่การตั้งค่าเบราว์เซอร์หรือไม่", "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" }, "confirmContinueToHelpCenter": { - "message": "Continue to Help Center?", + "message": "ไปที่ศูนย์ช่วยเหลือหรือไม่", "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { - "message": "Change your browser's autofill and password management settings.", + "message": "เปลี่ยนการตั้งค่าการป้อนอัตโนมัติและการจัดการรหัสผ่านของเบราว์เซอร์", "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser password management settings" }, "confirmContinueToHelpCenterKeyboardShortcutsContent": { - "message": "You can view and set extension shortcuts in your browser's settings.", + "message": "คุณสามารถดูและตั้งค่าทางลัดส่วนขยายได้ในการตั้งค่าของเบราว์เซอร์", "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser keyboard shortcut settings" }, "confirmContinueToBrowserPasswordManagementSettingsContent": { - "message": "Change your browser's autofill and password management settings.", + "message": "เปลี่ยนการตั้งค่าการป้อนอัตโนมัติและการจัดการรหัสผ่านของเบราว์เซอร์", "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" }, "confirmContinueToBrowserKeyboardShortcutSettingsContent": { - "message": "You can view and set extension shortcuts in your browser's settings.", + "message": "คุณสามารถดูและตั้งค่าทางลัดส่วนขยายได้ในการตั้งค่าของเบราว์เซอร์", "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" }, "overrideDefaultBrowserAutofillTitle": { - "message": "Make Bitwarden your default password manager?", + "message": "ตั้งให้ Bitwarden เป็นตัวจัดการรหัสผ่านเริ่มต้นหรือไม่", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", + "message": "การเพิกเฉยตัวเลือกนี้อาจทำให้เกิดความขัดแย้งระหว่างคำแนะนำการป้อนอัตโนมัติของ Bitwarden กับของเบราว์เซอร์", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { - "message": "Make Bitwarden your default password manager", + "message": "ตั้งให้ Bitwarden เป็นตัวจัดการรหัสผ่านเริ่มต้น", "description": "Label for the setting that allows overriding the default browser autofill settings" }, "privacyPermissionAdditionNotGrantedTitle": { - "message": "Unable to set Bitwarden as the default password manager", + "message": "ไม่สามารถตั้งค่า Bitwarden เป็นตัวจัดการรหัสผ่านเริ่มต้นได้", "description": "Title for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "privacyPermissionAdditionNotGrantedDescription": { - "message": "You must grant browser privacy permissions to Bitwarden to set it as the default password manager.", + "message": "คุณต้องอนุญาตสิทธิ์ความเป็นส่วนตัวของเบราว์เซอร์ให้ Bitwarden เพื่อตั้งค่าเป็นตัวจัดการรหัสผ่านเริ่มต้น", "description": "Description for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "makeDefault": { - "message": "Make default", + "message": "ตั้งเป็นค่าเริ่มต้น", "description": "Button text for the setting that allows overriding the default browser autofill settings" }, "saveCipherAttemptSuccess": { - "message": "Credentials saved successfully!", + "message": "บันทึกข้อมูลเข้าสู่ระบบสำเร็จแล้ว!", "description": "Notification message for when saving credentials has succeeded." }, "passwordSaved": { - "message": "Password saved!", + "message": "บันทึกรหัสผ่านแล้ว!", "description": "Notification message for when saving credentials has succeeded." }, "updateCipherAttemptSuccess": { - "message": "Credentials updated successfully!", + "message": "อัปเดตข้อมูลเข้าสู่ระบบสำเร็จแล้ว!", "description": "Notification message for when updating credentials has succeeded." }, "passwordUpdated": { - "message": "Password updated!", + "message": "อัปเดตรหัสผ่านแล้ว!", "description": "Notification message for when updating credentials has succeeded." }, "saveCipherAttemptFailed": { - "message": "Error saving credentials. Check console for details.", + "message": "เกิดข้อผิดพลาดในการบันทึกข้อมูลเข้าสู่ระบบ ตรวจสอบรายละเอียดในคอนโซล", "description": "Notification message for when saving credentials has failed." }, "success": { - "message": "Success" + "message": "สำเร็จ" }, "removePasskey": { - "message": "Remove passkey" + "message": "เอาพาสคีย์ออก" }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "เอาพาสคีย์ออกแล้ว" }, "autofillSuggestions": { - "message": "Autofill suggestions" + "message": "คำแนะนำการป้อนอัตโนมัติ" }, "itemSuggestions": { - "message": "Suggested items" + "message": "รายการที่แนะนำ" }, "autofillSuggestionsTip": { - "message": "Save a login item for this site to autofill" + "message": "บันทึกข้อมูลเข้าสู่ระบบสำหรับไซต์นี้เพื่อป้อนอัตโนมัติ" }, "yourVaultIsEmpty": { - "message": "Your vault is empty" + "message": "ตู้นิรภัยของคุณว่างเปล่า" }, "noItemsMatchSearch": { - "message": "No items match your search" + "message": "ไม่พบรายการที่ตรงกับการค้นหา" }, "clearFiltersOrTryAnother": { - "message": "Clear filters or try another search term" + "message": "ล้างตัวกรองหรือลองค้นหาด้วยคำอื่น" }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "คัดลอกข้อมูล - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -4654,7 +4699,7 @@ } }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "คัดลอกโน้ต - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -4664,7 +4709,7 @@ } }, "moreOptionsLabel": { - "message": "More options, $ITEMNAME$", + "message": "ตัวเลือกเพิ่มเติม $ITEMNAME$", "description": "Aria label for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -4674,7 +4719,7 @@ } }, "moreOptionsTitle": { - "message": "More options - $ITEMNAME$", + "message": "ตัวเลือกเพิ่มเติม - $ITEMNAME$", "description": "Title for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -4684,7 +4729,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "ดูรายการ - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4694,7 +4739,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "ดูรายการ - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4708,7 +4753,7 @@ } }, "autofillTitle": { - "message": "Autofill - $ITEMNAME$", + "message": "ป้อนอัตโนมัติ - $ITEMNAME$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4718,7 +4763,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "ป้อนอัตโนมัติ - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4732,7 +4777,7 @@ } }, "copyFieldCipherName": { - "message": "Copy $FIELD$, $CIPHERNAME$", + "message": "คัดลอก $FIELD$, $CIPHERNAME$", "description": "Title for a button that copies a field value to the clipboard.", "placeholders": { "field": { @@ -4746,40 +4791,49 @@ } }, "noValuesToCopy": { - "message": "No values to copy" + "message": "ไม่มีค่าให้คัดลอก" }, "assignToCollections": { - "message": "Assign to collections" + "message": "มอบหมายให้คอลเลกชัน" }, "copyEmail": { - "message": "Copy email" + "message": "คัดลอกอีเมล" }, "copyPhone": { - "message": "Copy phone" + "message": "คัดลอกเบอร์โทรศัพท์" }, "copyAddress": { - "message": "Copy address" + "message": "คัดลอกที่อยู่" }, "adminConsole": { - "message": "Admin Console" + "message": "คอนโซลผู้ดูแลระบบ" }, "accountSecurity": { "message": "ความปลอดภัยของบัญชี" }, + "phishingBlocker": { + "message": "ตัวบล็อกฟิชชิง" + }, + "enablePhishingDetection": { + "message": "การตรวจจับฟิชชิง" + }, + "enablePhishingDetectionDesc": { + "message": "แสดงคำเตือนก่อนเข้าถึงไซต์ที่ต้องสงสัยว่าเป็นฟิชชิง" + }, "notifications": { - "message": "Notifications" + "message": "การแจ้งเตือน" }, "appearance": { - "message": "Appearance" + "message": "รูปลักษณ์" }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "เกิดข้อผิดพลาดในการมอบหมายคอลเลกชันปลายทาง" }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "เกิดข้อผิดพลาดในการมอบหมายโฟลเดอร์ปลายทาง" }, "viewItemsIn": { - "message": "View items in $NAME$", + "message": "ดูรายการใน $NAME$", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { @@ -4789,7 +4843,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "กลับไปที่ $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -4799,10 +4853,10 @@ } }, "new": { - "message": "New" + "message": "ใหม่" }, "removeItem": { - "message": "Remove $NAME$", + "message": "เอา $NAME$ ออก", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -4812,44 +4866,44 @@ } }, "itemsWithNoFolder": { - "message": "Items with no folder" + "message": "รายการที่ไม่มีโฟลเดอร์" }, "itemDetails": { - "message": "Item details" + "message": "รายละเอียดรายการ" }, "itemName": { - "message": "Item name" + "message": "ชื่อรายการ" }, "organizationIsDeactivated": { - "message": "Organization is deactivated" + "message": "องค์กรถูกปิดใช้งาน" }, "owner": { - "message": "Owner" + "message": "เจ้าของ" }, "selfOwnershipLabel": { - "message": "You", + "message": "คุณ", "description": "Used as a label to indicate that the user is the owner of an item." }, "contactYourOrgAdmin": { - "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." + "message": "ไม่สามารถเข้าถึงรายการในองค์กรที่ถูกปิดใช้งาน ติดต่อเจ้าขององค์กรเพื่อขอความช่วยเหลือ" }, "additionalInformation": { - "message": "Additional information" + "message": "ข้อมูลเพิ่มเติม" }, "itemHistory": { - "message": "ประวัติการแก้ไขรายการ" + "message": "ประวัติรายการ" }, "lastEdited": { - "message": "แก้ไขล่าสุดเมื่อ" + "message": "แก้ไขล่าสุด" }, "ownerYou": { - "message": "Owner: You" + "message": "เจ้าของ: คุณ" }, "linked": { - "message": "Linked" + "message": "เชื่อมโยง" }, "copySuccessful": { - "message": "Copy Successful" + "message": "คัดลอกสำเร็จ" }, "upload": { "message": "อัปโหลด" @@ -4858,10 +4912,10 @@ "message": "เพิ่มไฟล์แนบ" }, "maxFileSizeSansPunctuation": { - "message": "ขนาดไฟล์สูงสุด คือ 500 MB" + "message": "ขนาดไฟล์สูงสุดคือ 500 MB" }, "deleteAttachmentName": { - "message": "Delete attachment $NAME$", + "message": "ลบไฟล์แนบ $NAME$", "placeholders": { "name": { "content": "$1", @@ -4870,7 +4924,7 @@ } }, "downloadAttachmentName": { - "message": "Download $NAME$", + "message": "ดาวน์โหลด $NAME$", "placeholders": { "name": { "content": "$1", @@ -4879,55 +4933,55 @@ } }, "downloadBitwarden": { - "message": "Download Bitwarden" + "message": "ดาวน์โหลด Bitwarden" }, "downloadBitwardenOnAllDevices": { - "message": "Download Bitwarden on all devices" + "message": "ดาวน์โหลด Bitwarden บนทุกอุปกรณ์" }, "getTheMobileApp": { - "message": "Get the mobile app" + "message": "รับแอปมือถือ" }, "getTheMobileAppDesc": { - "message": "Access your passwords on the go with the Bitwarden mobile app." + "message": "เข้าถึงรหัสผ่านของคุณได้ทุกที่ด้วยแอปมือถือ Bitwarden" }, "getTheDesktopApp": { - "message": "Get the desktop app" + "message": "รับแอปเดสก์ท็อป" }, "getTheDesktopAppDesc": { - "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + "message": "เข้าถึงตู้นิรภัยโดยไม่ต้องใช้เบราว์เซอร์ จากนั้นตั้งค่าการปลดล็อกด้วยไบโอเมตริกเพื่อเร่งการปลดล็อกทั้งในแอปเดสก์ท็อปและส่วนขยายเบราว์เซอร์" }, "downloadFromBitwardenNow": { - "message": "Download from bitwarden.com now" + "message": "ดาวน์โหลดจาก bitwarden.com เลย" }, "getItOnGooglePlay": { - "message": "Get it on Google Play" + "message": "ดาวน์โหลดได้จาก Google Play" }, "downloadOnTheAppStore": { - "message": "Download on the App Store" + "message": "ดาวน์โหลดได้จาก App Store" }, "permanentlyDeleteAttachmentConfirmation": { - "message": "Are you sure you want to permanently delete this attachment?" + "message": "ยืนยันที่จะลบไฟล์แนบนี้ถาวรหรือไม่" }, "premium": { - "message": "Premium" + "message": "พรีเมียม" }, "unlockFeaturesWithPremium": { - "message": "Unlock reporting, emergency access, and more security features with Premium." + "message": "ปลดล็อกการรายงาน การเข้าถึงฉุกเฉิน และฟีเจอร์ความปลอดภัยเพิ่มเติมด้วยพรีเมียม" }, "freeOrgsCannotUseAttachments": { - "message": "Free organizations cannot use attachments" + "message": "องค์กรฟรีไม่สามารถใช้ไฟล์แนบได้" }, "filters": { - "message": "Filters" + "message": "ตัวกรอง" }, "filterVault": { - "message": "Filter vault" + "message": "กรองตู้นิรภัย" }, "filterApplied": { - "message": "One filter applied" + "message": "ใช้ตัวกรอง 1 รายการ" }, "filterAppliedPlural": { - "message": "$COUNT$ filters applied", + "message": "ใช้ตัวกรอง $COUNT$ รายการ", "placeholders": { "count": { "content": "$1", @@ -4936,16 +4990,16 @@ } }, "personalDetails": { - "message": "Personal details" + "message": "ข้อมูลส่วนตัว" }, "identification": { - "message": "Identification" + "message": "เอกสารระบุตัวตน" }, "contactInfo": { - "message": "Contact info" + "message": "ข้อมูลติดต่อ" }, "downloadAttachment": { - "message": "Download - $ITEMNAME$", + "message": "ดาวน์โหลด - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -4954,23 +5008,23 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "หมายเลขบัตรลงท้ายด้วย", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { - "message": "Login credentials" + "message": "ข้อมูลเข้าสู่ระบบ" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "คีย์ยืนยันตัวตน" }, "autofillOptions": { - "message": "ตัวเลือกในการป้อนอัตโนมัติ" + "message": "ตัวเลือกการป้อนอัตโนมัติ" }, "websiteUri": { - "message": "Website (URI)" + "message": "เว็บไซต์ (URI)" }, "websiteUriCount": { - "message": "Website (URI) $COUNT$", + "message": "เว็บไซต์ (URI) $COUNT$", "description": "Label for an input field that contains a website URI. The input field is part of a list of fields, and the count indicates the position of the field in the list.", "placeholders": { "count": { @@ -4980,16 +5034,16 @@ } }, "websiteAdded": { - "message": "Website added" + "message": "เพิ่มเว็บไซต์แล้ว" }, "addWebsite": { - "message": "Add website" + "message": "เพิ่มเว็บไซต์" }, "deleteWebsite": { - "message": "Delete website" + "message": "ลบเว็บไซต์" }, "defaultLabel": { - "message": "Default ($VALUE$)", + "message": "ค่าเริ่มต้น ($VALUE$)", "description": "A label that indicates the default value for a field with the current default value in parentheses.", "placeholders": { "value": { @@ -4999,7 +5053,7 @@ } }, "defaultLabelWithValue": { - "message": "Default ( $VALUE$ )", + "message": "ค่าเริ่มต้น ( $VALUE$ )", "description": "A label that indicates the default value for a field with the current default value in parentheses.", "placeholders": { "value": { @@ -5009,7 +5063,7 @@ } }, "showMatchDetection": { - "message": "Show match detection $WEBSITE$", + "message": "แสดงการตรวจสอบการจับคู่ $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -5018,7 +5072,7 @@ } }, "hideMatchDetection": { - "message": "Hide match detection $WEBSITE$", + "message": "ซ่อนการตรวจสอบการจับคู่ $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -5027,19 +5081,19 @@ } }, "autoFillOnPageLoad": { - "message": "Autofill on page load?" + "message": "ป้อนอัตโนมัติเมื่อโหลดหน้าเว็บหรือไม่" }, "cardExpiredTitle": { - "message": "Expired card" + "message": "บัตรหมดอายุ" }, "cardExpiredMessage": { - "message": "If you've renewed it, update the card's information" + "message": "หากคุณต่ออายุแล้ว ให้อัปเดตข้อมูลบัตร" }, "cardDetails": { - "message": "Card details" + "message": "รายละเอียดบัตร" }, "cardBrandDetails": { - "message": "$BRAND$ details", + "message": "รายละเอียด $BRAND$", "placeholders": { "brand": { "content": "$1", @@ -5048,40 +5102,40 @@ } }, "showAnimations": { - "message": "Show animations" + "message": "แสดงภาพเคลื่อนไหว" }, "addAccount": { "message": "เพิ่มบัญชี" }, "loading": { - "message": "Loading" + "message": "กำลังโหลด" }, "data": { - "message": "Data" + "message": "ข้อมูล" }, "passkeys": { - "message": "Passkeys", + "message": "พาสคีย์", "description": "A section header for a list of passkeys." }, "passwords": { - "message": "Passwords", + "message": "รหัสผ่าน", "description": "A section header for a list of passwords." }, "logInWithPasskeyAriaLabel": { - "message": "Log in with passkey", + "message": "เข้าสู่ระบบด้วยพาสคีย์", "description": "ARIA label for the inline menu button that logs in with a passkey." }, "assign": { - "message": "Assign" + "message": "มอบหมาย" }, "bulkCollectionAssignmentDialogDescriptionSingular": { - "message": "Only organization members with access to these collections will be able to see the item." + "message": "เฉพาะสมาชิกองค์กรที่มีสิทธิ์เข้าถึงคอลเลกชันเหล่านี้เท่านั้นที่จะเห็นรายการนี้" }, "bulkCollectionAssignmentDialogDescriptionPlural": { - "message": "Only organization members with access to these collections will be able to see the items." + "message": "เฉพาะสมาชิกองค์กรที่มีสิทธิ์เข้าถึงคอลเลกชันเหล่านี้เท่านั้นที่จะเห็นรายการเหล่านี้" }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "คุณเลือก $TOTAL_COUNT$ รายการ คุณไม่สามารถอัปเดต $READONLY_COUNT$ รายการได้เนื่องจากคุณไม่มีสิทธิ์แก้ไข", "placeholders": { "total_count": { "content": "$1", @@ -5096,34 +5150,34 @@ "message": "เพิ่มฟิลด์" }, "add": { - "message": "Add" + "message": "เพิ่ม" }, "fieldType": { - "message": "Field type" + "message": "ประเภทฟิลด์" }, "fieldLabel": { - "message": "Field label" + "message": "ป้ายกำกับฟิลด์" }, "textHelpText": { - "message": "ใช้ช่องข้อความสำหรับเก็บข้อมูล เช่น คำถามเพื่อความปลอดภัย" + "message": "ใช้ฟิลด์ข้อความสำหรับข้อมูลเช่นคำถามความปลอดภัย" }, "hiddenHelpText": { - "message": "Use hidden fields for sensitive data like a password" + "message": "ใช้ฟิลด์ซ่อนสำหรับข้อมูลที่ละเอียดอ่อนเช่นรหัสผ่าน" }, "checkBoxHelpText": { - "message": "Use checkboxes if you'd like to autofill a form's checkbox, like a remember email" + "message": "ใช้ช่องทำเครื่องหมายหากคุณต้องการป้อนข้อมูลลงในช่องทำเครื่องหมายของแบบฟอร์มโดยอัตโนมัติ เช่น การจดจำอีเมล" }, "linkedHelpText": { - "message": "Use a linked field when you are experiencing autofill issues for a specific website." + "message": "ใช้ฟิลด์เชื่อมโยงเมื่อคุณประสบปัญหาการป้อนอัตโนมัติสำหรับเว็บไซต์ใดเว็บไซต์หนึ่งโดยเฉพาะ" }, "linkedLabelHelpText": { - "message": "Enter the the field's html id, name, aria-label, or placeholder." + "message": "ป้อน html id, name, aria-label หรือ placeholder ของฟิลด์" }, "editField": { - "message": "Edit field" + "message": "แก้ไขฟิลด์" }, "editFieldLabel": { - "message": "Edit $LABEL$", + "message": "แก้ไข $LABEL$", "placeholders": { "label": { "content": "$1", @@ -5132,7 +5186,7 @@ } }, "deleteCustomField": { - "message": "Delete $LABEL$", + "message": "ลบ $LABEL$", "placeholders": { "label": { "content": "$1", @@ -5150,7 +5204,7 @@ } }, "reorderToggleButton": { - "message": "Reorder $LABEL$. Use arrow key to move item up or down.", + "message": "จัดลำดับ $LABEL$ ใหม่ ใช้ปุ่มลูกศรเพื่อเลื่อนรายการขึ้นหรือลง", "placeholders": { "label": { "content": "$1", @@ -5159,10 +5213,10 @@ } }, "reorderWebsiteUriButton": { - "message": "Reorder website URI. Use arrow key to move item up or down." + "message": "จัดลำดับ URI เว็บไซต์ใหม่ ใช้ปุ่มลูกศรเพื่อเลื่อนรายการขึ้นหรือลง" }, "reorderFieldUp": { - "message": "$LABEL$ moved up, position $INDEX$ of $LENGTH$", + "message": "เลื่อน $LABEL$ ขึ้น ตำแหน่งที่ $INDEX$ จาก $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -5179,13 +5233,13 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "เลือกคอลเลกชันที่จะมอบหมาย" }, "personalItemTransferWarningSingular": { - "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + "message": "1 รายการจะถูกโอนย้ายไปยังองค์กรที่เลือกอย่างถาวร คุณจะไม่ได้เป็นเจ้าของรายการนี้อีกต่อไป" }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ รายการจะถูกโอนย้ายไปยังองค์กรที่เลือกอย่างถาวร คุณจะไม่ได้เป็นเจ้าของรายการเหล่านี้อีกต่อไป", "placeholders": { "personal_items_count": { "content": "$1", @@ -5194,7 +5248,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "1 รายการจะถูกโอนย้ายไปยัง $ORG$ อย่างถาวร คุณจะไม่ได้เป็นเจ้าของรายการนี้อีกต่อไป", "placeholders": { "org": { "content": "$1", @@ -5203,7 +5257,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ รายการจะถูกโอนย้ายไปยัง $ORG$ อย่างถาวร คุณจะไม่ได้เป็นเจ้าของรายการเหล่านี้อีกต่อไป", "placeholders": { "personal_items_count": { "content": "$1", @@ -5216,13 +5270,13 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "มอบหมายคอลเลกชันสำเร็จแล้ว" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "คุณไม่ได้เลือกสิ่งใดเลย" }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "ย้ายรายการไปที่ $ORGNAME$ แล้ว", "placeholders": { "orgname": { "content": "$1", @@ -5231,7 +5285,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "ย้ายรายการไปที่ $ORGNAME$ แล้ว", "placeholders": { "orgname": { "content": "$1", @@ -5240,7 +5294,7 @@ } }, "reorderFieldDown": { - "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", + "message": "เลื่อน $LABEL$ ลง ตำแหน่งที่ $INDEX$ จาก $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -5257,25 +5311,25 @@ } }, "itemLocation": { - "message": "Item Location" + "message": "ตำแหน่งรายการ" }, "fileSends": { - "message": "File Sends" + "message": "ไฟล์ Send" }, "textSends": { - "message": "Text Sends" + "message": "ข้อความ Send" }, "accountActions": { - "message": "การจัดการบัญชี" + "message": "การดำเนินการกับบัญชี" }, "showNumberOfAutofillSuggestions": { - "message": "Show number of login autofill suggestions on extension icon" + "message": "แสดงจำนวนคำแนะนำการป้อนข้อมูลเข้าสู่ระบบอัตโนมัติบนไอคอนส่วนขยาย" }, "accountAccessRequested": { - "message": "Account access requested" + "message": "ร้องขอการเข้าถึงบัญชีแล้ว" }, "confirmAccessAttempt": { - "message": "Confirm access attempt for $EMAIL$", + "message": "ยืนยันความพยายามเข้าถึงสำหรับ $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -5284,25 +5338,25 @@ } }, "showQuickCopyActions": { - "message": "Show quick copy actions on Vault" + "message": "แสดงการดำเนินการคัดลอกด่วนบนตู้นิรภัย" }, "systemDefault": { - "message": "System default" + "message": "ค่าเริ่มต้นของระบบ" }, "enterprisePolicyRequirementsApplied": { - "message": "Enterprise policy requirements have been applied to this setting" + "message": "ข้อกำหนดนโยบายองค์กรถูกนำมาใช้กับการตั้งค่านี้นี้" }, "sshPrivateKey": { - "message": "Private key" + "message": "กุญแจส่วนตัว" }, "sshPublicKey": { - "message": "Public key" + "message": "กุญแจสาธารณะ" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "ลายนิ้วมือ" }, "sshKeyAlgorithm": { - "message": "Key type" + "message": "ประเภทคีย์" }, "sshKeyAlgorithmED25519": { "message": "ED25519" @@ -5317,58 +5371,58 @@ "message": "RSA 4096-Bit" }, "retry": { - "message": "Retry" + "message": "ลองใหม่" }, "vaultCustomTimeoutMinimum": { - "message": "Minimum custom timeout is 1 minute." + "message": "เวลาหมดเวลาที่กำหนดเองขั้นต่ำคือ 1 นาที" }, "fileSavedToDevice": { - "message": "File saved to device. Manage from your device downloads." + "message": "บันทึกไฟล์ลงในอุปกรณ์แล้ว จัดการได้จากการดาวน์โหลดของอุปกรณ์" }, "showCharacterCount": { - "message": "Show character count" + "message": "แสดงจำนวนตัวอักษร" }, "hideCharacterCount": { - "message": "Hide character count" + "message": "ซ่อนจำนวนตัวอักษร" }, "itemsInTrash": { - "message": "Items in trash" + "message": "รายการในถังขยะ" }, "noItemsInTrash": { - "message": "No items in trash" + "message": "ไม่มีรายการในถังขยะ" }, "noItemsInTrashDesc": { - "message": "Items you delete will appear here and be permanently deleted after 30 days" + "message": "รายการที่คุณลบจะปรากฏที่นี่และจะถูกลบถาวรหลังจาก 30 วัน" }, "trashWarning": { - "message": "Items that have been in trash more than 30 days will automatically be deleted" + "message": "รายการที่อยู่ในถังขยะนานกว่า 30 วันจะถูกลบโดยอัตโนมัติ" }, "restore": { - "message": "Restore" + "message": "กู้คืน" }, "deleteForever": { - "message": "Delete forever" + "message": "ลบถาวร" }, "noEditPermissions": { - "message": "You don't have permission to edit this item" + "message": "คุณไม่มีสิทธิ์แก้ไขรายการนี้" }, "biometricsStatusHelptextUnlockNeeded": { - "message": "Biometric unlock is unavailable because PIN or password unlock is required first." + "message": "การปลดล็อกด้วยไบโอเมตริกไม่พร้อมใช้งาน เนื่องจากต้องปลดล็อกด้วย PIN หรือรหัสผ่านก่อน" }, "biometricsStatusHelptextHardwareUnavailable": { - "message": "Biometric unlock is currently unavailable." + "message": "การปลดล็อกด้วยไบโอเมตริกไม่พร้อมใช้งานในขณะนี้" }, "biometricsStatusHelptextAutoSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "การปลดล็อกด้วยไบโอเมตริกไม่พร้อมใช้งานเนื่องจากการกำหนดค่าไฟล์ระบบไม่ถูกต้อง" }, "biometricsStatusHelptextManualSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "การปลดล็อกด้วยไบโอเมตริกไม่พร้อมใช้งานเนื่องจากการกำหนดค่าไฟล์ระบบไม่ถูกต้อง" }, "biometricsStatusHelptextDesktopDisconnected": { - "message": "Biometric unlock is unavailable because the Bitwarden desktop app is closed." + "message": "การปลดล็อกด้วยไบโอเมตริกไม่พร้อมใช้งาน เนื่องจากแอป Bitwarden บนเดสก์ท็อปปิดอยู่" }, "biometricsStatusHelptextNotEnabledInDesktop": { - "message": "Biometric unlock is unavailable because it is not enabled for $EMAIL$ in the Bitwarden desktop app.", + "message": "การปลดล็อกด้วยไบโอเมตริกไม่พร้อมใช้งาน เนื่องจากยังไม่ได้เปิดใช้งานสำหรับ $EMAIL$ ในแอป Bitwarden บนเดสก์ท็อป", "placeholders": { "email": { "content": "$1", @@ -5377,41 +5431,41 @@ } }, "biometricsStatusHelptextUnavailableReasonUnknown": { - "message": "Biometric unlock is currently unavailable for an unknown reason." + "message": "การปลดล็อกด้วยไบโอเมตริกไม่พร้อมใช้งานในขณะนี้โดยไม่ทราบสาเหตุ" }, "unlockVault": { - "message": "Unlock your vault in seconds" + "message": "ปลดล็อกตู้นิรภัยของคุณในไม่กี่วินาที" }, "unlockVaultDesc": { - "message": "You can customize your unlock and timeout settings to more quickly access your vault." + "message": "คุณสามารถปรับแต่งการตั้งค่าการปลดล็อกและเวลาหมดเวลาเพื่อเข้าถึงตู้นิรภัยได้รวดเร็วยิ่งขึ้น" }, "unlockPinSet": { - "message": "ตั้งค่า PIN สำหรับปลดล็อกแล้ว" + "message": "ตั้งค่า PIN ปลดล็อกแล้ว" }, "unlockWithBiometricSet": { - "message": "Unlock with biometrics set" + "message": "ตั้งค่าการปลดล็อกด้วยไบโอเมตริกแล้ว" }, "authenticating": { - "message": "Authenticating" + "message": "กำลังยืนยันตัวตน" }, "fillGeneratedPassword": { - "message": "Fill generated password", + "message": "ป้อนรหัสผ่านที่สร้างขึ้น", "description": "Heading for the password generator within the inline menu" }, "passwordRegenerated": { - "message": "Password regenerated", + "message": "สร้างรหัสผ่านใหม่แล้ว", "description": "Notification message for when a password has been regenerated" }, "saveToBitwarden": { - "message": "Save to Bitwarden", + "message": "บันทึกลง Bitwarden", "description": "Confirmation message for saving a login to Bitwarden" }, "spaceCharacterDescriptor": { - "message": "Space", + "message": "เว้นวรรค", "description": "Represents the space key in screen reader content as a readable word" }, "tildeCharacterDescriptor": { - "message": "Tilde", + "message": "ตัวหนอน", "description": "Represents the ~ key in screen reader content as a readable word" }, "backtickCharacterDescriptor": { @@ -5419,23 +5473,23 @@ "description": "Represents the ` key in screen reader content as a readable word" }, "exclamationCharacterDescriptor": { - "message": "Exclamation mark", + "message": "เครื่องหมายตกใจ", "description": "Represents the ! key in screen reader content as a readable word" }, "atSignCharacterDescriptor": { - "message": "At sign", + "message": "เครื่องหมาย @", "description": "Represents the @ key in screen reader content as a readable word" }, "hashSignCharacterDescriptor": { - "message": "Hash sign", + "message": "เครื่องหมาย #", "description": "Represents the # key in screen reader content as a readable word" }, "dollarSignCharacterDescriptor": { - "message": "Dollar sign", + "message": "เครื่องหมาย $", "description": "Represents the $ key in screen reader content as a readable word" }, "percentSignCharacterDescriptor": { - "message": "Percent sign", + "message": "เครื่องหมาย %", "description": "Represents the % key in screen reader content as a readable word" }, "caretCharacterDescriptor": { @@ -5443,154 +5497,154 @@ "description": "Represents the ^ key in screen reader content as a readable word" }, "ampersandCharacterDescriptor": { - "message": "Ampersand", + "message": "เครื่องหมาย &", "description": "Represents the & key in screen reader content as a readable word" }, "asteriskCharacterDescriptor": { - "message": "Asterisk", + "message": "ดอกจัน", "description": "Represents the * key in screen reader content as a readable word" }, "parenLeftCharacterDescriptor": { - "message": "Left parenthesis", + "message": "วงเล็บเปิด", "description": "Represents the ( key in screen reader content as a readable word" }, "parenRightCharacterDescriptor": { - "message": "Right parenthesis", + "message": "วงเล็บปิด", "description": "Represents the ) key in screen reader content as a readable word" }, "hyphenCharacterDescriptor": { - "message": "Underscore", + "message": "ขีดล่าง", "description": "Represents the _ key in screen reader content as a readable word" }, "underscoreCharacterDescriptor": { - "message": "Hyphen", + "message": "ขีดกลาง", "description": "Represents the - key in screen reader content as a readable word" }, "plusCharacterDescriptor": { - "message": "Plus", + "message": "เครื่องหมาย +", "description": "Represents the + key in screen reader content as a readable word" }, "equalsCharacterDescriptor": { - "message": "Equals", + "message": "เครื่องหมาย =", "description": "Represents the = key in screen reader content as a readable word" }, "braceLeftCharacterDescriptor": { - "message": "Left brace", + "message": "ปีกกาเปิด", "description": "Represents the { key in screen reader content as a readable word" }, "braceRightCharacterDescriptor": { - "message": "Right brace", + "message": "ปีกกาปิด", "description": "Represents the } key in screen reader content as a readable word" }, "bracketLeftCharacterDescriptor": { - "message": "Left bracket", + "message": "วงเล็บเหลี่ยมเปิด", "description": "Represents the [ key in screen reader content as a readable word" }, "bracketRightCharacterDescriptor": { - "message": "Right bracket", + "message": "วงเล็บเหลี่ยมปิด", "description": "Represents the ] key in screen reader content as a readable word" }, "pipeCharacterDescriptor": { - "message": "Pipe", + "message": "ขีดตั้ง", "description": "Represents the | key in screen reader content as a readable word" }, "backSlashCharacterDescriptor": { - "message": "Back slash", + "message": "แบคสแลช", "description": "Represents the back slash key in screen reader content as a readable word" }, "colonCharacterDescriptor": { - "message": "Colon", + "message": "โคลอน", "description": "Represents the : key in screen reader content as a readable word" }, "semicolonCharacterDescriptor": { - "message": "Semicolon", + "message": "เซมิโคลอน", "description": "Represents the ; key in screen reader content as a readable word" }, "doubleQuoteCharacterDescriptor": { - "message": "Double quote", + "message": "ฟันหนู", "description": "Represents the double quote key in screen reader content as a readable word" }, "singleQuoteCharacterDescriptor": { - "message": "Single quote", + "message": "ฝนทอง", "description": "Represents the ' key in screen reader content as a readable word" }, "lessThanCharacterDescriptor": { - "message": "Less than", + "message": "น้อยกว่า", "description": "Represents the < key in screen reader content as a readable word" }, "greaterThanCharacterDescriptor": { - "message": "Greater than", + "message": "มากกว่า", "description": "Represents the > key in screen reader content as a readable word" }, "commaCharacterDescriptor": { - "message": "Comma", + "message": "จุลภาค", "description": "Represents the , key in screen reader content as a readable word" }, "periodCharacterDescriptor": { - "message": "Period", + "message": "จุด", "description": "Represents the . key in screen reader content as a readable word" }, "questionCharacterDescriptor": { - "message": "Question mark", + "message": "เครื่องหมายคำถาม", "description": "Represents the ? key in screen reader content as a readable word" }, "forwardSlashCharacterDescriptor": { - "message": "Forward slash", + "message": "ทับ", "description": "Represents the / key in screen reader content as a readable word" }, "lowercaseAriaLabel": { - "message": "Lowercase" + "message": "ตัวพิมพ์เล็ก" }, "uppercaseAriaLabel": { - "message": "Uppercase" + "message": "ตัวพิมพ์ใหญ่" }, "generatedPassword": { - "message": "Generated password" + "message": "รหัสผ่านที่สร้างขึ้น" }, "compactMode": { - "message": "Compact mode" + "message": "โหมดกะทัดรัด" }, "beta": { - "message": "Beta" + "message": "เบต้า" }, "extensionWidth": { - "message": "Extension width" + "message": "ความกว้างส่วนขยาย" }, "wide": { - "message": "Wide" + "message": "กว้าง" }, "extraWide": { - "message": "Extra wide" + "message": "กว้างพิเศษ" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "รหัสผ่านที่คุณป้อนไม่ถูกต้อง" }, "importSshKey": { - "message": "Import" + "message": "นำเข้า" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "ยืนยันรหัสผ่าน" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "ป้อนรหัสผ่านสำหรับคีย์ SSH" }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "ป้อนรหัสผ่าน" }, "invalidSshKey": { - "message": "The SSH key is invalid" + "message": "คีย์ SSH ไม่ถูกต้อง" }, "sshKeyTypeUnsupported": { - "message": "The SSH key type is not supported" + "message": "ไม่รองรับประเภทคีย์ SSH" }, "importSshKeyFromClipboard": { - "message": "Import key from clipboard" + "message": "นำเข้าคีย์จากคลิปบอร์ด" }, "sshKeyImported": { - "message": "SSH key imported successfully" + "message": "นำเข้าคีย์ SSH สำเร็จแล้ว" }, "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "message": "คุณไม่สามารถลบคอลเลกชันที่มีสิทธิ์ดูอย่างเดียวได้: $COLLECTIONS$", "placeholders": { "collections": { "content": "$1", @@ -5599,93 +5653,93 @@ } }, "updateDesktopAppOrDisableFingerprintDialogTitle": { - "message": "Please update your desktop application" + "message": "โปรดอัปเดตแอปพลิเคชันเดสก์ท็อปของคุณ" }, "updateDesktopAppOrDisableFingerprintDialogMessage": { - "message": "To use biometric unlock, please update your desktop application, or disable fingerprint unlock in the desktop settings." + "message": "หากต้องการใช้การปลดล็อกด้วยไบโอเมตริก โปรดอัปเดตแอปพลิเคชันเดสก์ท็อป หรือปิดใช้งานการปลดล็อกด้วยลายนิ้วมือในการตั้งค่าเดสก์ท็อป" }, "changeAtRiskPassword": { - "message": "Change at-risk password" + "message": "เปลี่ยนรหัสผ่านที่มีความเสี่ยง" }, "changeAtRiskPasswordAndAddWebsite": { - "message": "This login is at-risk and missing a website. Add a website and change the password for stronger security." + "message": "ข้อมูลเข้าสู่ระบบนี้มีความเสี่ยงและไม่มีเว็บไซต์ เพิ่มเว็บไซต์และเปลี่ยนรหัสผ่านเพื่อความปลอดภัยที่รัดกุมยิ่งขึ้น" }, "missingWebsite": { - "message": "Missing website" + "message": "ไม่มีเว็บไซต์" }, "settingsVaultOptions": { - "message": "Vault options" + "message": "ตัวเลือกตู้นิรภัย" }, "emptyVaultDescription": { - "message": "The vault protects more than just your passwords. Store secure logins, IDs, cards and notes securely here." + "message": "ตู้นิรภัยปกป้องมากกว่าแค่รหัสผ่าน จัดเก็บข้อมูลเข้าสู่ระบบ เอกสารระบุตัวตน บัตร และโน้ตอย่างปลอดภัยที่นี่" }, "introCarouselLabel": { - "message": "Welcome to Bitwarden" + "message": "ยินดีต้อนรับสู่ Bitwarden" }, "securityPrioritized": { - "message": "Security, prioritized" + "message": "ให้ความสำคัญกับความปลอดภัย" }, "securityPrioritizedBody": { - "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + "message": "บันทึกข้อมูลเข้าสู่ระบบ บัตร และข้อมูลระบุตัวตนลงในตู้นิรภัยที่ปลอดภัย Bitwarden ใช้การเข้ารหัสแบบ End-to-end แบบ Zero-knowledge เพื่อปกป้องสิ่งที่สำคัญสำหรับคุณ" }, "quickLogin": { - "message": "Quick and easy login" + "message": "เข้าสู่ระบบที่รวดเร็วและง่ายดาย" }, "quickLoginBody": { - "message": "ตั้งค่าการปลดล็อกด้วยไบโอเมตริกซ์และการกรอกข้อมูลอัตโนมัติ เพื่อลงชื่อเข้าใช้บัญชีของคุณโดยไม่ต้องพิมพ์แม้แต่ตัวอักษรเดียว" + "message": "ตั้งค่าการปลดล็อกด้วยไบโอเมตริกและการป้อนอัตโนมัติเพื่อเข้าสู่ระบบบัญชีโดยไม่ต้องพิมพ์แม้แต่ตัวอักษรเดียว" }, "secureUser": { - "message": "Level up your logins" + "message": "ยกระดับการเข้าสู่ระบบของคุณ" }, "secureUserBody": { - "message": "Use the generator to create and save strong, unique passwords for all your accounts." + "message": "ใช้ตัวสร้างเพื่อสร้างและบันทึกรหัสผ่านที่รัดกุมและไม่ซ้ำกันสำหรับทุกบัญชีของคุณ" }, "secureDevices": { - "message": "Your data, when and where you need it" + "message": "ข้อมูลของคุณ ทุกที่ทุกเวลาที่คุณต้องการ" }, "secureDevicesBody": { - "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." + "message": "บันทึกรหัสผ่านได้ไม่จำกัดบนอุปกรณ์ไม่จำกัดด้วยแอป Bitwarden บนมือถือ เบราว์เซอร์ และเดสก์ท็อป" }, "nudgeBadgeAria": { - "message": "1 notification" + "message": "1 การแจ้งเตือน" }, "emptyVaultNudgeTitle": { - "message": "Import existing passwords" + "message": "นำเข้ารหัสผ่านที่มีอยู่" }, "emptyVaultNudgeBody": { - "message": "Use the importer to quickly transfer logins to Bitwarden without manually adding them." + "message": "ใช้ตัวนำเข้าเพื่อโอนย้ายข้อมูลเข้าสู่ระบบไปยัง Bitwarden อย่างรวดเร็วโดยไม่ต้องเพิ่มด้วยตนเอง" }, "emptyVaultNudgeButton": { - "message": "Import now" + "message": "นำเข้าเลย" }, "hasItemsVaultNudgeTitle": { - "message": "Welcome to your vault!" + "message": "ยินดีต้อนรับสู่ตู้นิรภัยของคุณ!" }, "phishingPageTitleV2": { - "message": "Phishing attempt detected" + "message": "ตรวจพบความพยายามฟิชชิง" }, "phishingPageSummary": { - "message": "The site you are attempting to visit is a known malicious site and a security risk." + "message": "ไซต์ที่คุณพยายามเข้าชมเป็นไซต์อันตรายที่รู้จักและมีความเสี่ยงด้านความปลอดภัย" }, "phishingPageCloseTabV2": { - "message": "Close this tab" + "message": "ปิดแท็บนี้" }, "phishingPageContinueV2": { - "message": "Continue to this site (not recommended)" + "message": "ไปที่ไซต์นี้ต่อ (ไม่แนะนำ)" }, "phishingPageExplanation1": { - "message": "This site was found in ", + "message": "พบไซต์นี้ใน ", "description": "This is in multiple parts to allow for bold text in the middle of the sentence. A proper name follows this." }, "phishingPageExplanation2": { - "message": ", an open-source list of known phishing sites used for stealing personal and sensitive information.", + "message": " ซึ่งเป็นรายการโอเพนซอร์สของไซต์ฟิชชิงที่รู้จักที่ใช้ขโมยข้อมูลส่วนบุคคลและข้อมูลสำคัญ", "description": "This is in multiple parts to allow for bold text in the middle of the sentence. A proper name precedes this." }, "phishingPageLearnMore": { - "message": "Learn more about phishing detection" + "message": "เรียนรู้เพิ่มเติมเกี่ยวกับการตรวจจับฟิชชิง" }, "protectedBy": { - "message": "Protected by $PRODUCT$", + "message": "ปกป้องโดย $PRODUCT$", "placeholders": { "product": { "content": "$1", @@ -5694,162 +5748,296 @@ } }, "hasItemsVaultNudgeBodyOne": { - "message": "Autofill items for the current page" + "message": "ป้อนข้อมูลรายการอัตโนมัติสำหรับหน้าปัจจุบัน" }, "hasItemsVaultNudgeBodyTwo": { - "message": "Favorite items for easy access" + "message": "ตั้งรายการโปรดเพื่อการเข้าถึงที่ง่ายดาย" }, "hasItemsVaultNudgeBodyThree": { - "message": "Search your vault for something else" + "message": "ค้นหาสิ่งอื่นในตู้นิรภัยของคุณ" }, "newLoginNudgeTitle": { - "message": "Save time with autofill" + "message": "ประหยัดเวลาด้วยการป้อนอัตโนมัติ" }, "newLoginNudgeBodyOne": { - "message": "Include a", + "message": "ระบุ", "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", "example": "Include a Website so this login appears as an autofill suggestion." }, "newLoginNudgeBodyBold": { - "message": "Website", + "message": "เว็บไซต์", "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", "example": "Include a Website so this login appears as an autofill suggestion." }, "newLoginNudgeBodyTwo": { - "message": "so this login appears as an autofill suggestion.", + "message": "เพื่อให้ข้อมูลเข้าสู่ระบบนี้ปรากฏเป็นคำแนะนำการป้อนอัตโนมัติ", "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { - "message": "Seamless online checkout" + "message": "ชำระเงินออนไลน์ได้อย่างราบรื่น" }, "newCardNudgeBody": { - "message": "With cards, easily autofill payment forms securely and accurately." + "message": "ด้วยบัตร คุณสามารถป้อนแบบฟอร์มการชำระเงินอัตโนมัติได้อย่างปลอดภัยและแม่นยำ" }, "newIdentityNudgeTitle": { - "message": "Simplify creating accounts" + "message": "สร้างบัญชีได้ง่ายขึ้น" }, "newIdentityNudgeBody": { - "message": "With identities, quickly autofill long registration or contact forms." + "message": "ด้วยข้อมูลระบุตัวตน คุณสามารถป้อนแบบฟอร์มลงทะเบียนหรือข้อมูลติดต่อยาว ๆ ได้อย่างรวดเร็ว" }, "newNoteNudgeTitle": { - "message": "Keep your sensitive data safe" + "message": "เก็บรักษาข้อมูลสำคัญของคุณให้ปลอดภัย" }, "newNoteNudgeBody": { - "message": "With notes, securely store sensitive data like banking or insurance details." + "message": "ด้วยโน้ต คุณสามารถจัดเก็บข้อมูลสำคัญ เช่น รายละเอียดธนาคารหรือประกันภัยได้อย่างปลอดภัย" }, "newSshNudgeTitle": { - "message": "Developer-friendly SSH access" + "message": "การเข้าถึง SSH ที่เป็นมิตรกับนักพัฒนา" }, "newSshNudgeBodyOne": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "message": "จัดเก็บคีย์ของคุณและเชื่อมต่อกับ SSH Agent เพื่อการยืนยันตัวตนที่รวดเร็วและเข้ารหัส", "description": "Two part message", "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" }, "newSshNudgeBodyTwo": { - "message": "Learn more about SSH agent", + "message": "เรียนรู้เพิ่มเติมเกี่ยวกับ SSH Agent", "description": "Two part message", "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" }, "generatorNudgeTitle": { - "message": "Quickly create passwords" + "message": "สร้างรหัสผ่านอย่างรวดเร็ว" }, "generatorNudgeBodyOne": { - "message": "Easily create strong and unique passwords by clicking on", + "message": "สร้างรหัสผ่านที่รัดกุมและไม่ซ้ำกันได้ง่าย ๆ โดยคลิกที่", "description": "Two part message", "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." }, "generatorNudgeBodyTwo": { - "message": "to help you keep your logins secure.", + "message": "เพื่อช่วยรักษาความปลอดภัยข้อมูลเข้าสู่ระบบของคุณ", "description": "Two part message", "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." }, "generatorNudgeBodyAria": { - "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "message": "สร้างรหัสผ่านที่รัดกุมและไม่ซ้ำกันได้ง่าย ๆ โดยคลิกที่ปุ่มสร้างรหัสผ่าน เพื่อช่วยรักษาความปลอดภัยข้อมูลเข้าสู่ระบบของคุณ", "description": "Aria label for the body content of the generator nudge" }, "aboutThisSetting": { - "message": "About this setting" + "message": "เกี่ยวกับการตั้งค่านี้" }, "permitCipherDetailsDescription": { - "message": "Bitwarden will use saved login URIs to identify which icon or change password URL should be used to improve your experience. No information is collected or saved when you use this service." + "message": "Bitwarden จะใช้ URI ข้อมูลเข้าสู่ระบบที่บันทึกไว้เพื่อระบุว่าควรใช้ไอคอนหรือ URL เปลี่ยนรหัสผ่านใดเพื่อปรับปรุงประสบการณ์ของคุณ ไม่มีการรวบรวมหรือบันทึกข้อมูลเมื่อคุณใช้บริการนี้" }, "noPermissionsViewPage": { - "message": "You do not have permissions to view this page. Try logging in with a different account." + "message": "คุณไม่มีสิทธิ์ดูหน้านี้ ลองเข้าสู่ระบบด้วยบัญชีอื่น" }, "wasmNotSupported": { - "message": "WebAssembly is not supported on your browser or is not enabled. WebAssembly is required to use the Bitwarden app.", + "message": "เบราว์เซอร์ของคุณไม่รองรับ WebAssembly หรือไม่ได้เปิดใช้งาน จำเป็นต้องมี WebAssembly เพื่อใช้งานแอป Bitwarden", "description": "'WebAssembly' is a technical term and should not be translated." }, "showMore": { - "message": "Show more" + "message": "แสดงเพิ่มเติม" }, "showLess": { - "message": "Show less" + "message": "แสดงน้อยลง" }, "next": { - "message": "Next" + "message": "ถัดไป" }, "moreBreadcrumbs": { - "message": "More breadcrumbs", + "message": "Breadcrumbs เพิ่มเติม", "description": "This is used in the context of a breadcrumb navigation, indicating that there are more items in the breadcrumb trail that are not currently displayed." }, "confirmKeyConnectorDomain": { - "message": "Confirm Key Connector domain" + "message": "ยืนยันโดเมน Key Connector" }, "atRiskLoginsSecured": { - "message": "Great job securing your at-risk logins!" + "message": "เยี่ยมมาก คุณจัดการความปลอดภัยข้อมูลเข้าสู่ระบบที่มีความเสี่ยงแล้ว!" }, "upgradeNow": { - "message": "Upgrade now" + "message": "อัปเกรดตอนนี้" }, "builtInAuthenticator": { - "message": "Built-in authenticator" + "message": "ตัวยืนยันตัวตนในตัว" }, "secureFileStorage": { - "message": "Secure file storage" + "message": "พื้นที่จัดเก็บไฟล์ที่ปลอดภัย" }, "emergencyAccess": { - "message": "Emergency access" + "message": "การเข้าถึงฉุกเฉิน" }, "breachMonitoring": { - "message": "Breach monitoring" + "message": "การตรวจสอบข้อมูลรั่วไหล" }, "andMoreFeatures": { - "message": "And more!" + "message": "และอื่น ๆ!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "ความปลอดภัยออนไลน์ขั้นสูง" }, "upgradeToPremium": { - "message": "Upgrade to Premium" + "message": "อัปเกรดเป็นพรีเมียม" }, "unlockAdvancedSecurity": { - "message": "Unlock advanced security features" + "message": "ปลดล็อกฟีเจอร์ความปลอดภัยขั้นสูง" }, "unlockAdvancedSecurityDesc": { - "message": "A Premium subscription gives you more tools to stay secure and in control" + "message": "การสมัครสมาชิกพรีเมียมมอบเครื่องมือเพิ่มเติมเพื่อให้คุณปลอดภัยและควบคุมได้" }, "explorePremium": { - "message": "Explore Premium" + "message": "สำรวจพรีเมียม" }, "loadingVault": { - "message": "Loading vault" + "message": "กำลังโหลดตู้นิรภัย" }, "vaultLoaded": { - "message": "Vault loaded" + "message": "โหลดตู้นิรภัยแล้ว" }, "settingDisabledByPolicy": { - "message": "This setting is disabled by your organization's policy.", + "message": "การตั้งค่านี้ถูกปิดใช้งานโดยนโยบายองค์กรของคุณ", "description": "This hint text is displayed when a user setting is disabled due to an organization policy." }, "zipPostalCodeLabel": { - "message": "ZIP / Postal code" + "message": "รหัสไปรษณีย์" }, "cardNumberLabel": { - "message": "Card number" + "message": "หมายเลขบัตร" + }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "องค์กรของคุณไม่ใช้รหัสผ่านหลักในการเข้าสู่ระบบ Bitwarden อีกต่อไป หากต้องการดำเนินการต่อ ให้ยืนยันองค์กรและโดเมน" + }, + "continueWithLogIn": { + "message": "ดำเนินการเข้าสู่ระบบต่อ" + }, + "doNotContinue": { + "message": "ไม่ดำเนินการต่อ" + }, + "domain": { + "message": "โดเมน" + }, + "keyConnectorDomainTooltip": { + "message": "โดเมนนี้จะจัดเก็บกุญแจเข้ารหัสบัญชีของคุณ ดังนั้นโปรดตรวจสอบให้แน่ใจว่าคุณเชื่อถือ หากไม่แน่ใจ ให้ตรวจสอบกับผู้ดูแลระบบ" + }, + "verifyYourOrganization": { + "message": "ยืนยันองค์กรของคุณเพื่อเข้าสู่ระบบ" + }, + "organizationVerified": { + "message": "ยืนยันองค์กรแล้ว" + }, + "domainVerified": { + "message": "ยืนยันโดเมนแล้ว" + }, + "leaveOrganizationContent": { + "message": "หากคุณไม่ยืนยันองค์กร สิทธิ์การเข้าถึงองค์กรของคุณจะถูกเพิกถอน" + }, + "leaveNow": { + "message": "ออกตอนนี้" + }, + "verifyYourDomainToLogin": { + "message": "ยืนยันโดเมนของคุณเพื่อเข้าสู่ระบบ" + }, + "verifyYourDomainDescription": { + "message": "หากต้องการดำเนินการเข้าสู่ระบบต่อ ให้ยืนยันโดเมนนี้" + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "หากต้องการดำเนินการเข้าสู่ระบบต่อ ให้ยืนยันองค์กรและโดเมน" }, "sessionTimeoutSettingsAction": { - "message": "Timeout action" + "message": "การดำเนินการเมื่อหมดเวลา" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "การตั้งค่านี้ได้รับการจัดการโดยองค์กรของคุณ" + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "องค์กรของคุณกำหนดเวลาหมดเวลาเซสชันสูงสุดไว้ที่ $HOURS$ ชั่วโมง $MINUTES$ นาที", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "องค์กรของคุณกำหนดเวลาหมดเวลาเซสชันเริ่มต้นเป็น ทันที" + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "องค์กรของคุณกำหนดเวลาหมดเวลาเซสชันเริ่มต้นเป็น เมื่อล็อกระบบ" + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "องค์กรของคุณกำหนดเวลาหมดเวลาเซสชันเริ่มต้นเป็น เมื่อรีสตาร์ตเบราว์เซอร์" + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "เวลาหมดเวลาสูงสุดต้องไม่เกิน $HOURS$ ชั่วโมง $MINUTES$ นาที", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "เมื่อรีสตาร์ตเบราว์เซอร์" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "ตั้งค่าวิธีการปลดล็อกเพื่อเปลี่ยนการดำเนินการเมื่อหมดเวลา" + }, + "upgrade": { + "message": "อัปเกรด" + }, + "leaveConfirmationDialogTitle": { + "message": "ยืนยันที่จะออกหรือไม่" + }, + "leaveConfirmationDialogContentOne": { + "message": "หากปฏิเสธ รายการส่วนตัวจะยังคงอยู่ในบัญชีของคุณ แต่คุณจะเสียสิทธิ์เข้าถึงรายการที่แชร์และฟีเจอร์ขององค์กร" + }, + "leaveConfirmationDialogContentTwo": { + "message": "ติดต่อผู้ดูแลระบบเพื่อขอรับสิทธิ์เข้าถึงอีกครั้ง" + }, + "leaveConfirmationDialogConfirmButton": { + "message": "ออกจาก $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "ฉันจะจัดการตู้นิรภัยได้อย่างไร" + }, + "transferItemsToOrganizationTitle": { + "message": "โอนย้ายรายการไปยัง $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ กำหนดให้รายการทั้งหมดต้องเป็นขององค์กรเพื่อความปลอดภัยและการปฏิบัติตามข้อกำหนด คลิกยอมรับเพื่อโอนกรรมสิทธิ์รายการของคุณ", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "ยอมรับการโอนย้าย" + }, + "declineAndLeave": { + "message": "ปฏิเสธและออก" + }, + "whyAmISeeingThis": { + "message": "ทำไมฉันจึงเห็นสิ่งนี้" } } diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index e6004ef387f..e6a787716a4 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Eşitle" }, - "syncVaultNow": { - "message": "Kasayı şimdi eşitle" + "syncNow": { + "message": "Şimdi eşitle" }, "lastSync": { "message": "Son eşitleme:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden web uygulaması" }, - "importItems": { - "message": "Hesapları içe aktar" - }, "select": { "message": "Seç" }, @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Dışa aktarılacak konum" }, - "exportVault": { - "message": "Kasayı dışa aktar" + "exportVerb": { + "message": "Dışa aktar", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Dışa aktar", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "İçe aktar", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "İçe aktar", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Dosya biçimi" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Daha fazla bilgi al" }, + "migrationsFailed": { + "message": "Şifreleme ayarları güncellenirken bir hata oluştu." + }, + "updateEncryptionSettingsTitle": { + "message": "Şifreleme ayarlarınızı güncelleyin" + }, + "updateEncryptionSettingsDesc": { + "message": "Önerilen yeni şifreleme ayarları hesap güvenliğinizi artıracaktır. Şimdi güncellemek için ana parolanızı girin." + }, + "confirmIdentityToContinue": { + "message": "Devam etmek için kimliğinizi doğrulayın" + }, + "enterYourMasterPassword": { + "message": "Ana parolanızı girin" + }, + "updateSettings": { + "message": "Ayarları güncelle" + }, + "later": { + "message": "Daha sonra" + }, "authenticatorKeyTotp": { "message": "Kimlik doğrulama anahtarı (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Dosya kaydedildi" }, + "fixEncryption": { + "message": "Şifrelemeyi düzelt" + }, + "fixEncryptionTooltip": { + "message": "Bu dosya eski bir şifreleme yöntemi kullanıyor." + }, + "attachmentUpdated": { + "message": "Ek güncellendi" + }, "file": { "message": "Dosya" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Bir dosya seçin" }, + "itemsTransferred": { + "message": "Kayıtlar aktarıldı" + }, "maxFileSize": { "message": "Maksimum dosya boyutu 500 MB'dir." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "Dosya ekleri için 1 GB şifrelenmiş depolama." }, + "premiumSignUpStorageV2": { + "message": "Dosya ekleri için $SIZE$ şifrelenmiş depolama.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Acil durum erişimi." }, @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Benzersiz tanımlayıcı bulunamadı." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Aşağıdaki organizasyonun üyeleri için artık ana parola gerekmemektedir. Lütfen alan adını organizasyon yöneticinizle doğrulayın." - }, "organizationName": { "message": "Kuruluş adı" }, @@ -4075,7 +4124,7 @@ "message": "Otomatik doldurulamıyor" }, "cannotAutofillExactMatch": { - "message": "Default matching is set to 'Exact Match'. The current website does not exactly match the saved login details for this item." + "message": "Varsayılan eşleştirme \"Tam eşleşme\" olarak ayarlı. Geçerli web sitesi, bu kayıt için kaydedilen hesap bilgileriyle tam olarak eşleşmiyor." }, "okay": { "message": "Tamam" @@ -4176,10 +4225,6 @@ "ignore": { "message": "Yok say" }, - "importData": { - "message": "Verileri içe aktar", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "İçe aktarma hatası" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Hesap güvenliği" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Bildirimler" }, @@ -4912,7 +4966,7 @@ "message": "Premium" }, "unlockFeaturesWithPremium": { - "message": "Unlock reporting, emergency access, and more security features with Premium." + "message": "Raporlama, acil erişim ve daha fazla güvenlik özelliğinin kilidini Premium ile açın." }, "freeOrgsCannotUseAttachments": { "message": "Ücretsiz kuruluşlar dosya eklerini kullanamaz" @@ -5674,18 +5728,18 @@ "message": "Siteye devam et (önerilmez)" }, "phishingPageExplanation1": { - "message": "This site was found in ", + "message": "Bu site şurada bulundu ", "description": "This is in multiple parts to allow for bold text in the middle of the sentence. A proper name follows this." }, "phishingPageExplanation2": { - "message": ", an open-source list of known phishing sites used for stealing personal and sensitive information.", + "message": ", kişisel ve hassas bilgileri çalmak için kullanılan bilinen oltalama sitelerini içeren açık kaynaklı bir liste.", "description": "This is in multiple parts to allow for bold text in the middle of the sentence. A proper name precedes this." }, "phishingPageLearnMore": { - "message": "Learn more about phishing detection" + "message": "Oltalama tespiti hakkında daha fazla bilgi edinin" }, "protectedBy": { - "message": "Protected by $PRODUCT$", + "message": "$PRODUCT$ tarafından korunuyor", "placeholders": { "product": { "content": "$1", @@ -5798,7 +5852,7 @@ "message": "Key Connector alan adını doğrulayın" }, "atRiskLoginsSecured": { - "message": "Great job securing your at-risk logins!" + "message": "Risk altındaki hesaplarınızı güvene alarak harika bir iş çıkardınız!" }, "upgradeNow": { "message": "Şimdi yükselt" @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "Ve daha fazlası!" }, - "planDescPremium": { - "message": "Eksiksiz çevrimiçi güvenlik" + "advancedOnlineSecurity": { + "message": "Gelişmiş çevrimiçi güvenlik" }, "upgradeToPremium": { "message": "Premium'a yükselt" @@ -5831,7 +5885,7 @@ "message": "Premium abonelik size daha fazla güvenlik ve kontrol olanağı sunan ek araçlara erişmenizi sağlar" }, "explorePremium": { - "message": "Explore Premium" + "message": "Premium’u keşfet" }, "loadingVault": { "message": "Kasa yükleniyor" @@ -5840,7 +5894,7 @@ "message": "Kasa yüklendi" }, "settingDisabledByPolicy": { - "message": "This setting is disabled by your organization's policy.", + "message": "Bu ayar, kuruluşunuzun ilkesi tarafından devre dışı bırakıldı.", "description": "This hint text is displayed when a user setting is disabled due to an organization policy." }, "zipPostalCodeLabel": { @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Kart numarası" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Zaman aşımı eylemi" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Bu ayar kuruluşunuz tarafından yönetiliyor." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Kuruluşunuz maksimum kasa zaman aşımını $HOURS$ saat $MINUTES$ dakika olarak belirlemiş.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Kuruluşunuz varsayılan oturum zaman aşımını “Hemen” olarak ayarlamış." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Kuruluşunuz varsayılan oturum zaman aşımını “Sistem kilitlenince” olarak ayarlamış." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Kuruluşunuz varsayılan oturum zaman aşımını “Tarayıcı yeniden başlatılınca” olarak ayarlamış." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maksimum zaman aşımı en fazla $HOURS$ saat $MINUTES$ dakika olabilir", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Tarayıcı yeniden başlatılınca" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Zaman aşımı eyleminizi değiştirmek için kilit açma yönteminizi ayarlayın" + }, + "upgrade": { + "message": "Yükselt" + }, + "leaveConfirmationDialogTitle": { + "message": "Ayrılmak istediğinizden emin misiniz?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Reddederseniz kişisel kayıtlarınız hesabınızda kalır, ancak paylaşılan kayıtlara ve kuruluş özelliklerine erişiminizi kaybedersiniz." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Erişiminizi yeniden kazanmak için yöneticinizle iletişime geçin." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "$ORGANIZATION$ kuruluşundan ayrıl", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Kasamı nasıl yönetebilirim?" + }, + "transferItemsToOrganizationTitle": { + "message": "Kayıtları $ORGANIZATION$ kuruluşuna aktar", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$, güvenlik ve mevzuata uyum amacıyla tüm kayıtların kuruluşa ait olmasını zorunlu kılıyor. Kayıtlarınızın sahipliğini devretmek için \"Kabul et\"e tıklayın.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Aktarımı kabul et" + }, + "declineAndLeave": { + "message": "Reddet ve ayrıl" + }, + "whyAmISeeingThis": { + "message": "Bunu neden görüyorum?" } } diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index a1922a5abd8..d777dee1472 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Синхронізація" }, - "syncVaultNow": { - "message": "Синхронізувати зараз" + "syncNow": { + "message": "Синхронізувати" }, "lastSync": { "message": "Остання синхронізація:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Вебпрограма Bitwarden" }, - "importItems": { - "message": "Імпортувати записи" - }, "select": { "message": "Обрати" }, @@ -586,7 +583,7 @@ "message": "Архівовані записи виключаються з результатів звичайного пошуку та пропозицій автозаповнення. Ви дійсно хочете архівувати цей запис?" }, "upgradeToUseArchive": { - "message": "A premium membership is required to use Archive." + "message": "Для використання архіву необхідна передплата Premium." }, "edit": { "message": "Змінити" @@ -598,10 +595,10 @@ "message": "Переглянути все" }, "showAll": { - "message": "Show all" + "message": "Показати все" }, "viewLess": { - "message": "View less" + "message": "Показати менше" }, "viewLogin": { "message": "Переглянути запис" @@ -806,10 +803,10 @@ "message": "З блокуванням системи" }, "onIdle": { - "message": "On system idle" + "message": "Бездіяльність системи" }, "onSleep": { - "message": "On system sleep" + "message": "Режим сну" }, "onRestart": { "message": "З перезапуском браузера" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Експортувати з" }, - "exportVault": { - "message": "Експортувати сховище" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Формат файлу" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Докладніше" }, + "migrationsFailed": { + "message": "Сталася помилка під час оновлення налаштувань шифрування." + }, + "updateEncryptionSettingsTitle": { + "message": "Оновіть свої налаштування шифрування" + }, + "updateEncryptionSettingsDesc": { + "message": "Нові рекомендовані налаштування шифрування покращать безпеку вашого облікового запису. Щоб оновити їх, введіть свій головний пароль." + }, + "confirmIdentityToContinue": { + "message": "Щоб продовжити, підтвердьте свої облікові дані" + }, + "enterYourMasterPassword": { + "message": "Введіть головний пароль" + }, + "updateSettings": { + "message": "Оновити налаштування" + }, + "later": { + "message": "Пізніше" + }, "authenticatorKeyTotp": { "message": "Ключ автентифікації (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Вкладення збережено" }, + "fixEncryption": { + "message": "Виправити шифрування" + }, + "fixEncryptionTooltip": { + "message": "Для цього файлу використовується застарілий метод шифрування." + }, + "attachmentUpdated": { + "message": "Вкладення оновлено" + }, "file": { "message": "Файл" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Оберіть файл" }, + "itemsTransferred": { + "message": "Записи переміщено" + }, "maxFileSize": { "message": "Максимальний розмір файлу 500 МБ." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1 ГБ зашифрованого сховища для файлів." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ зашифрованого сховища для вкладених файлів.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Екстрений доступ." }, @@ -1874,7 +1926,7 @@ "message": "Рік завершення" }, "monthly": { - "message": "month" + "message": "місяць" }, "expiration": { "message": "Термін дії" @@ -2446,7 +2498,7 @@ } }, "topLayerHijackWarning": { - "message": "This page is interfering with the Bitwarden experience. The Bitwarden inline menu has been temporarily disabled as a safety measure." + "message": "Ця сторінка заважає роботі Bitwarden. Задля безпеки вбудоване меню Bitwarden тимчасово вимкнено." }, "setMasterPassword": { "message": "Встановити головний пароль" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Не знайдено унікальний ідентифікатор." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Головний пароль більше не є обов'язковим для учасників зазначеної організації. Підтвердьте вказаний нижче домен з адміністратором вашої організації." - }, "organizationName": { "message": "Назва організації" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Ігнорувати" }, - "importData": { - "message": "Імпортувати дані", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Помилка імпорту" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Безпека облікового запису" }, + "phishingBlocker": { + "message": "Блокувальник шахрайства" + }, + "enablePhishingDetection": { + "message": "Виявлення шахрайства" + }, + "enablePhishingDetectionDesc": { + "message": "Показувати попередження перед відвідуванням підозрюваних шахрайських сайтів" + }, "notifications": { "message": "Сповіщення" }, @@ -4912,7 +4966,7 @@ "message": "Premium" }, "unlockFeaturesWithPremium": { - "message": "Unlock reporting, emergency access, and more security features with Premium." + "message": "Розблокуйте звіти, екстрений доступ та інші функції безпеки, передплативши Premium." }, "freeOrgsCannotUseAttachments": { "message": "Організації без передплати не можуть використовувати вкладення" @@ -4999,7 +5053,7 @@ } }, "defaultLabelWithValue": { - "message": "Default ( $VALUE$ )", + "message": "Типово ( $VALUE$ )", "description": "A label that indicates the default value for a field with the current default value in parentheses.", "placeholders": { "value": { @@ -5818,26 +5872,26 @@ "andMoreFeatures": { "message": "Інші можливості!" }, - "planDescPremium": { - "message": "Повна онлайн-безпека" + "advancedOnlineSecurity": { + "message": "Розширена онлайн-безпека" }, "upgradeToPremium": { "message": "Покращити до Premium" }, "unlockAdvancedSecurity": { - "message": "Unlock advanced security features" + "message": "Розблокуйте розширені функції безпеки" }, "unlockAdvancedSecurityDesc": { - "message": "A Premium subscription gives you more tools to stay secure and in control" + "message": "З передплатою Premium ви матимете більше інструментів безпеки та контролю" }, "explorePremium": { - "message": "Explore Premium" + "message": "Ознайомитися з Premium" }, "loadingVault": { - "message": "Loading vault" + "message": "Завантаження сховища" }, "vaultLoaded": { - "message": "Vault loaded" + "message": "Сховище завантажено" }, "settingDisabledByPolicy": { "message": "Цей параметр вимкнено політикою вашої організації.", @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Номер картки" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Ваша організація більше не використовує головні паролі для входу в Bitwarden. Щоб продовжити, підтвердіть організацію та домен." + }, + "continueWithLogIn": { + "message": "Перейти до входу" + }, + "doNotContinue": { + "message": "Не продовжувати" + }, + "domain": { + "message": "Домен" + }, + "keyConnectorDomainTooltip": { + "message": "Цей домен зберігатиме ключі шифрування вашого облікового запису, тому переконайтеся в його надійності. Якщо ви не впевнені, зверніться до свого адміністратора." + }, + "verifyYourOrganization": { + "message": "Підтвердьте свою організацію, щоб увійти" + }, + "organizationVerified": { + "message": "Організацію підтверджено" + }, + "domainVerified": { + "message": "Домен підтверджено" + }, + "leaveOrganizationContent": { + "message": "Якщо ви не підтвердите свою організацію, ваш доступ до неї буде відкликаний." + }, + "leaveNow": { + "message": "Покинути" + }, + "verifyYourDomainToLogin": { + "message": "Підтвердьте свій домен, щоб увійти" + }, + "verifyYourDomainDescription": { + "message": "Щоб перейти до входу, підтвердьте цей домен." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Щоб перейти до входу, підтвердьте організацію і домен." + }, "sessionTimeoutSettingsAction": { - "message": "Timeout action" + "message": "Дія після часу очікування" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Цим параметром керує ваша організація." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Ваша організація встановила максимальний час очікування сеансу $HOURS$ год і $MINUTES$ хв.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Ваша організація встановила максимальний час очікування сеансу \"Негайно\"." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Ваша організація встановила максимальний час очікування сеансу \"Блокування системи\"." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Ваша організація встановила максимальний час очікування сеансу \"З перезапуском браузера\"." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Максимальний час очікування не може перевищувати $HOURS$ год і $MINUTES$ хв", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "З перезапуском браузера" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Встановіть спосіб розблокування, щоб змінити дію під час очікування" + }, + "upgrade": { + "message": "Оновити" + }, + "leaveConfirmationDialogTitle": { + "message": "Ви дійсно хочете покинути?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Відхиливши, ваші особисті записи залишаться у вашому обліковому записі, але ви втратите доступ до спільних записів та функцій організації." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Зверніться до свого адміністратора, щоб відновити доступ." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Покинути $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Як керувати своїм сховищем?" + }, + "transferItemsToOrganizationTitle": { + "message": "Перемістити записи до $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "З міркувань безпеки та для забезпечення відповідності $ORGANIZATION$ вимагає, щоб власником всіх елементів була організація. Натисніть кнопку \"прийняти\", щоб передати права власності на ваші елементи.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Схвалити переміщення" + }, + "declineAndLeave": { + "message": "Відхилити і покинути" + }, + "whyAmISeeingThis": { + "message": "Чому я це бачу?" } } diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index 415cf474af0..cd8ad7cbc91 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "Đồng bộ" }, - "syncVaultNow": { - "message": "Đồng bộ kho lưu trữ ngay" + "syncNow": { + "message": "Sync now" }, "lastSync": { "message": "Đồng bộ lần cuối:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Ứng dụng web Bitwarden" }, - "importItems": { - "message": "Nhập vào kho" - }, "select": { "message": "Chọn" }, @@ -586,7 +583,7 @@ "message": "Các mục đã lưu trữ sẽ bị loại khỏi kết quả tìm kiếm chung và gợi ý tự động điền. Bạn có chắc chắn muốn lưu trữ mục này không?" }, "upgradeToUseArchive": { - "message": "A premium membership is required to use Archive." + "message": "Cần là thành viên cao cấp để sử dụng tính năng Lưu trữ." }, "edit": { "message": "Sửa" @@ -598,10 +595,10 @@ "message": "Xem tất cả" }, "showAll": { - "message": "Show all" + "message": "Hiện tất cả" }, "viewLess": { - "message": "View less" + "message": "Ẩn bớt" }, "viewLogin": { "message": "Xem đăng nhập" @@ -806,10 +803,10 @@ "message": "Mỗi khi khóa máy" }, "onIdle": { - "message": "On system idle" + "message": "Khi hệ thống nhàn rỗi" }, "onSleep": { - "message": "On system sleep" + "message": "Khi hệ thống ngủ" }, "onRestart": { "message": "Mỗi khi khởi động lại trình duyệt" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "Xuất từ" }, - "exportVault": { - "message": "Xuất kho" + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Định dạng tập tin" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "Tìm hiểu thêm" }, + "migrationsFailed": { + "message": "Đã xảy ra lỗi khi cập nhật cài đặt mã hóa." + }, + "updateEncryptionSettingsTitle": { + "message": "Cập nhật cài đặt mã hóa của bạn" + }, + "updateEncryptionSettingsDesc": { + "message": "Cài đặt mã hóa được khuyến nghị sẽ cải thiện bảo mật cho tài khoản của bạn. Nhập mật khẩu chính để cập nhật ngay." + }, + "confirmIdentityToContinue": { + "message": "Xác minh danh tính để tiếp tục" + }, + "enterYourMasterPassword": { + "message": "Nhập mật khẩu chính của bạn" + }, + "updateSettings": { + "message": "Cập nhật cài đặt" + }, + "later": { + "message": "Để sau" + }, "authenticatorKeyTotp": { "message": "Khóa xác thực (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "Đã lưu tệp đính kèm" }, + "fixEncryption": { + "message": "Sửa mã hóa" + }, + "fixEncryptionTooltip": { + "message": "Tệp này đang sử dụng phương pháp mã hóa lỗi thời." + }, + "attachmentUpdated": { + "message": "Tệp đính kèm đã được cập nhật" + }, "file": { "message": "Tập tin" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "Chọn tập tin" }, + "itemsTransferred": { + "message": "Các mục đã chuyển" + }, "maxFileSize": { "message": "Kích thước tối đa của tập tin là 500MB." }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "1GB bộ nhớ lưu trữ được mã hóa cho các tệp đính kèm." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ bộ nhớ lưu trữ được mã hóa cho các tệp đính kèm.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "Truy cập khẩn cấp." }, @@ -1874,7 +1926,7 @@ "message": "Năm hết hạn" }, "monthly": { - "message": "month" + "message": "tháng" }, "expiration": { "message": "Hết hạn" @@ -2446,7 +2498,7 @@ } }, "topLayerHijackWarning": { - "message": "This page is interfering with the Bitwarden experience. The Bitwarden inline menu has been temporarily disabled as a safety measure." + "message": "Trang này đang làm gián đoạn trải nghiệm Bitwarden. Menu nội tuyến của Bitwarden đã tạm thời bị tắt để đảm bảo an toàn." }, "setMasterPassword": { "message": "Đặt mật khẩu chính" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "Không tìm thấy danh tính duy nhất." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Mật khẩu chính không còn được yêu cầu đối với các thành viên của tổ chức sau đây. Vui lòng xác nhận tên miền bên dưới với quản trị viên của tổ chức." - }, "organizationName": { "message": "Tên tổ chức" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "Bỏ qua" }, - "importData": { - "message": "Nhập dữ liệu", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "Lỗi khi nhập" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "Bảo mật tài khoản" }, + "phishingBlocker": { + "message": "Phishing Blocker" + }, + "enablePhishingDetection": { + "message": "Phishing detection" + }, + "enablePhishingDetectionDesc": { + "message": "Display warning before accessing suspected phishing sites" + }, "notifications": { "message": "Thông báo" }, @@ -4912,7 +4966,7 @@ "message": "Cao cấp" }, "unlockFeaturesWithPremium": { - "message": "Unlock reporting, emergency access, and more security features with Premium." + "message": "Mở khóa tính năng báo cáo, quyền truy cập khẩn cấp và nhiều tính năng bảo mật khác với gói Cao cấp." }, "freeOrgsCannotUseAttachments": { "message": "Các tổ chức miễn phí không thể sử dụng tệp đính kèm" @@ -4999,7 +5053,7 @@ } }, "defaultLabelWithValue": { - "message": "Default ( $VALUE$ )", + "message": "Mặc định ( $VALUE$ )", "description": "A label that indicates the default value for a field with the current default value in parentheses.", "placeholders": { "value": { @@ -5818,26 +5872,26 @@ "andMoreFeatures": { "message": "Và nhiều hơn nữa!" }, - "planDescPremium": { - "message": "Bảo mật trực tuyến toàn diện" + "advancedOnlineSecurity": { + "message": "Bảo mật trực tuyến nâng cao" }, "upgradeToPremium": { "message": "Nâng cấp lên gói Cao cấp" }, "unlockAdvancedSecurity": { - "message": "Unlock advanced security features" + "message": "Mở khóa các tính năng bảo mật nâng cao" }, "unlockAdvancedSecurityDesc": { - "message": "A Premium subscription gives you more tools to stay secure and in control" + "message": "Đăng ký gói Cao cấp cung cấp nhiều công cụ để bạn luôn an toàn và kiểm soát tốt hơn" }, "explorePremium": { - "message": "Explore Premium" + "message": "Khám phá gói Cao cấp" }, "loadingVault": { - "message": "Loading vault" + "message": "Đang tải kho" }, "vaultLoaded": { - "message": "Vault loaded" + "message": "Đã tải kho" }, "settingDisabledByPolicy": { "message": "Cài đặt này bị vô hiệu hóa bởi chính sách tổ chức của bạn.", @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "Số thẻ" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { - "message": "Timeout action" + "message": "Hành động sau khi đóng kho" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Cài đặt này do tổ chức của bạn quản lý." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Tổ chức của bạn đã đặt thời gian chờ phiên tối đa là $HOURS$ giờ và $MINUTES$ phút.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "Tổ chức của bạn đã đặt thời gian chờ phiên mặc định là Ngay lập tức." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Tổ chức của bạn đã đặt thời gian chờ phiên mặc định là Mỗi khi khóa máy." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Tổ chức của bạn đã đặt thời gian chờ phiên mặc định là Mỗi khi khởi động lại trình duyệt." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Thời gian chờ tối đa không thể vượt quá $HOURS$ giờ và $MINUTES$ phút", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Mỗi khi khởi động lại trình duyệt" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Đặt phương thức mở khóa để thay đổi hành động khi hết thời gian chờ" + }, + "upgrade": { + "message": "Nâng cấp" + }, + "leaveConfirmationDialogTitle": { + "message": "Bạn có chắc chắn muốn rời đi không?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Bằng việc từ chối, các mục cá nhân sẽ vẫn nằm trong tài khoản của bạn, nhưng bạn sẽ mất quyền truy cập vào các mục được chia sẻ và tính năng tổ chức." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Liên hệ quản trị viên của bạn để lấy lại quyền truy cập." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Rời khỏi $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Tôi quản lý kho của mình như thế nào?" + }, + "transferItemsToOrganizationTitle": { + "message": "Chuyển các mục đến $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ yêu cầu tất cả các mục phải thuộc sở hữu của tổ chức để đảm bảo an ninh và tuân thủ. Nhấp chấp nhận để chuyển quyền sở hữu các mục của bạn.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Chấp nhận chuyển" + }, + "declineAndLeave": { + "message": "Từ chối và rời đi" + }, + "whyAmISeeingThis": { + "message": "Tại sao tôi thấy điều này?" } } diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 7a0662fb9f8..a699be016eb 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "同步" }, - "syncVaultNow": { - "message": "立即同步密码库" + "syncNow": { + "message": "立即同步" }, "lastSync": { "message": "上次同步:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden 网页 App" }, - "importItems": { - "message": "导入项目" - }, "select": { "message": "选择" }, @@ -601,7 +598,7 @@ "message": "显示全部" }, "viewLess": { - "message": "查看更少" + "message": "显示更少" }, "viewLogin": { "message": "查看登录" @@ -991,7 +988,7 @@ "message": "文件夹已添加" }, "twoStepLoginConfirmation": { - "message": "两步登录要求您从其他设备(例如安全密钥、验证器 App、短信、电话或者电子邮件)来验证您的登录,这能使您的账户更加安全。两步登录需要在 bitwarden.com 网页版密码库中设置。现在访问此网站吗?" + "message": "两步登录要求您从其他设备(例如安全密钥、验证器 App、短信、电话或者电子邮件)来验证您的登录,这能使您的账户更加安全。两步登录需要在 bitwarden.com 网页版密码库中设置。现在要访问此网站吗?" }, "twoStepLoginConfirmationContent": { "message": "在 Bitwarden 网页 App 中设置两步登录,让您的账户更加安全。" @@ -1275,7 +1272,7 @@ "message": "询问保存新的通行密钥或使用存储在密码库中的通行密钥登录。适用于所有已登录的账户。" }, "notificationChangeDesc": { - "message": "是否要在 Bitwarden 中更新此密码?" + "message": "要在 Bitwarden 中更新此密码吗?" }, "notificationChangeSave": { "message": "更新" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "导出自" }, - "exportVault": { - "message": "导出密码库" + "exportVerb": { + "message": "导出", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "导出", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "导入", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "导入", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "文件格式" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "进一步了解" }, + "migrationsFailed": { + "message": "更新加密设置时发生错误。" + }, + "updateEncryptionSettingsTitle": { + "message": "更新您的加密设置" + }, + "updateEncryptionSettingsDesc": { + "message": "新推荐的加密设置将提高您的账户安全性。输入您的主密码以立即更新。" + }, + "confirmIdentityToContinue": { + "message": "确认您的身份以继续" + }, + "enterYourMasterPassword": { + "message": "输入您的主密码" + }, + "updateSettings": { + "message": "更新设置" + }, + "later": { + "message": "稍后" + }, "authenticatorKeyTotp": { "message": "验证器密钥 (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "附件已保存" }, + "fixEncryption": { + "message": "修复加密" + }, + "fixEncryptionTooltip": { + "message": "此文件正在使用过时的加密方式。" + }, + "attachmentUpdated": { + "message": "附件已更新" + }, "file": { "message": "文件" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "选择一个文件" }, + "itemsTransferred": { + "message": "项目已传输" + }, "maxFileSize": { "message": "文件最大为 500 MB。" }, @@ -1461,7 +1504,7 @@ "message": "管理会员资格" }, "premiumManageAlert": { - "message": "您可以在 bitwarden.com 网页版密码库管理您的会员资格。现在要访问吗?" + "message": "您可以在 bitwarden.com 网页版密码库管理您的会员资格。现在要访问此网站吗?" }, "premiumRefresh": { "message": "刷新会员资格" @@ -1473,7 +1516,16 @@ "message": "注册高级会员将获得:" }, "ppremiumSignUpStorage": { - "message": "1 GB 文件附件加密存储。" + "message": "1 GB 文件附件加密存储空间。" + }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ 文件附件加密存储空间。", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } }, "premiumSignUpEmergency": { "message": "紧急访问。" @@ -2313,7 +2365,7 @@ "message": "无效 PIN 码。" }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "无效的 PIN 输入尝试次数过多,正在注销。" + "message": "无效的 PIN 输入尝试次数过多。正在注销。" }, "unlockWithBiometrics": { "message": "使用生物识别解锁" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "未找到唯一的标识符。" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "以下组织的成员不再需要主密码。请与您的组织管理员确认下面的域名。" - }, "organizationName": { "message": "组织名称" }, @@ -3865,10 +3914,10 @@ "message": "检查您的电子邮箱" }, "followTheLinkInTheEmailSentTo": { - "message": "点击发送到电子邮件中的链接" + "message": "点击发送到" }, "andContinueCreatingYourAccount": { - "message": "然后继续创建您的账户。" + "message": "的电子邮件中的链接,然后继续创建您的账户。" }, "noEmail": { "message": "没收到电子邮件吗?" @@ -4176,10 +4225,6 @@ "ignore": { "message": "忽略" }, - "importData": { - "message": "导入数据", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "导入出错" }, @@ -4365,7 +4410,7 @@ "message": "此站点没有匹配的登录" }, "searchSavePasskeyNewLogin": { - "message": "搜索或将通行密钥保存为一个新的登录" + "message": "搜索或将通行密钥保存为新的登录" }, "confirm": { "message": "确认" @@ -4374,7 +4419,7 @@ "message": "保存通行密钥" }, "savePasskeyNewLogin": { - "message": "作为新的登录项目保存通行密钥" + "message": "将通行密钥保存为新的登录" }, "chooseCipherForPasskeySave": { "message": "选择一个用于保存此通行密钥的登录项目" @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "账户安全" }, + "phishingBlocker": { + "message": "网络钓鱼拦截器" + }, + "enablePhishingDetection": { + "message": "网络钓鱼检测" + }, + "enablePhishingDetectionDesc": { + "message": "在访问疑似钓鱼网站前显示警告" + }, "notifications": { "message": "通知" }, @@ -5682,7 +5736,7 @@ "description": "This is in multiple parts to allow for bold text in the middle of the sentence. A proper name precedes this." }, "phishingPageLearnMore": { - "message": "进一步了解钓鱼检测" + "message": "进一步了解网络钓鱼检测" }, "protectedBy": { "message": "受 $PRODUCT$ 保护", @@ -5818,8 +5872,8 @@ "andMoreFeatures": { "message": "以及更多!" }, - "planDescPremium": { - "message": "全面的在线安全防护" + "advancedOnlineSecurity": { + "message": "高级在线安全防护" }, "upgradeToPremium": { "message": "升级为高级版" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "卡号" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "您的组织已不再使用主密码登录 Bitwarden。要继续,请验证组织和域名。" + }, + "continueWithLogIn": { + "message": "继续登录" + }, + "doNotContinue": { + "message": "不要继续" + }, + "domain": { + "message": "域名" + }, + "keyConnectorDomainTooltip": { + "message": "此域名将存储您的账户加密密钥,所以请确保您信任它。如果您不确定,请与您的管理员联系。" + }, + "verifyYourOrganization": { + "message": "验证您的组织以登录" + }, + "organizationVerified": { + "message": "组织已验证" + }, + "domainVerified": { + "message": "域名已验证" + }, + "leaveOrganizationContent": { + "message": "如果不验证您的组织,您对组织的访问权限将被撤销。" + }, + "leaveNow": { + "message": "立即退出" + }, + "verifyYourDomainToLogin": { + "message": "验证您的域名以登录" + }, + "verifyYourDomainDescription": { + "message": "要继续登录,请验证此域名。" + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "要继续登录,请验证组织和域名。" + }, "sessionTimeoutSettingsAction": { "message": "超时动作" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "此设置由您的组织管理。" + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "您的组织已将最大会话超时设置为 $HOURS$ 小时 $MINUTES$ 分钟。", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "您的组织已将默认会话超时设置为「立即」。" + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "您的组织已将默认会话超时设置为「系统锁定时」。" + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "您的组织已将默认会话超时设置为「浏览器重启时」。" + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "最大超时不能超过 $HOURS$ 小时 $MINUTES$ 分钟", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "浏览器重启时" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "设置一个解锁方式以更改您的超时动作" + }, + "upgrade": { + "message": "升级" + }, + "leaveConfirmationDialogTitle": { + "message": "确定要退出吗?" + }, + "leaveConfirmationDialogContentOne": { + "message": "拒绝后,您的个人项目将保留在您的账户中,但您将失去对共享项目和组织功能的访问权限。" + }, + "leaveConfirmationDialogContentTwo": { + "message": "联系您的管理员以重新获取访问权限。" + }, + "leaveConfirmationDialogConfirmButton": { + "message": "退出 $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "我该如何管理我的密码库?" + }, + "transferItemsToOrganizationTitle": { + "message": "传输项目到 $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "出于安全和合规考虑,$ORGANIZATION$ 要求所有项目归组织所有。点击「接受」以传输您的项目的所有权。", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "接受传输" + }, + "declineAndLeave": { + "message": "拒绝并退出" + }, + "whyAmISeeingThis": { + "message": "为什么我会看到这个?" } } diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index 38fb50d6c8b..abb25c48b43 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -436,8 +436,8 @@ "sync": { "message": "同步" }, - "syncVaultNow": { - "message": "立即同步密碼庫" + "syncNow": { + "message": "立即同步" }, "lastSync": { "message": "上次同步於:" @@ -455,9 +455,6 @@ "bitWebVaultApp": { "message": "Bitwarden 網頁應用程式" }, - "importItems": { - "message": "匯入項目" - }, "select": { "message": "選擇" }, @@ -586,7 +583,7 @@ "message": "封存的項目將不會出現在一般搜尋結果或自動填入建議中。確定要封存此項目嗎?" }, "upgradeToUseArchive": { - "message": "A premium membership is required to use Archive." + "message": "需要進階版會員才能使用封存功能。" }, "edit": { "message": "編輯" @@ -598,7 +595,7 @@ "message": "檢視全部" }, "showAll": { - "message": "Show all" + "message": "顯示全部" }, "viewLess": { "message": "顯示較少" @@ -1325,8 +1322,21 @@ "exportFrom": { "message": "匯出自" }, - "exportVault": { - "message": "匯出密碼庫" + "exportVerb": { + "message": "匯出", + "description": "The verb form of the word Export" + }, + "exportNoun": { + "message": "匯出", + "description": "The noun form of the word Export" + }, + "importNoun": { + "message": "匯入", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "匯入", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "檔案格式" @@ -1406,6 +1416,27 @@ "learnMore": { "message": "深入了解" }, + "migrationsFailed": { + "message": "更新加密設定時發生錯誤。" + }, + "updateEncryptionSettingsTitle": { + "message": "更新您的加密設定" + }, + "updateEncryptionSettingsDesc": { + "message": "新的建議加密設定將提升您的帳戶安全性。請輸入主密碼以立即更新。" + }, + "confirmIdentityToContinue": { + "message": "請先確認身分後再繼續" + }, + "enterYourMasterPassword": { + "message": "輸入您的主密碼" + }, + "updateSettings": { + "message": "更新設定" + }, + "later": { + "message": "以後再說" + }, "authenticatorKeyTotp": { "message": "驗證器金鑰 (TOTP)" }, @@ -1436,6 +1467,15 @@ "attachmentSaved": { "message": "附件已儲存" }, + "fixEncryption": { + "message": "修正加密" + }, + "fixEncryptionTooltip": { + "message": "此檔案使用了過時的加密方式。" + }, + "attachmentUpdated": { + "message": "附件已更新" + }, "file": { "message": "檔案" }, @@ -1445,6 +1485,9 @@ "selectFile": { "message": "選取檔案" }, + "itemsTransferred": { + "message": "項目已轉移" + }, "maxFileSize": { "message": "檔案最大為 500MB。" }, @@ -1475,6 +1518,15 @@ "ppremiumSignUpStorage": { "message": "用於檔案附件的 1 GB 加密儲存空間。" }, + "premiumSignUpStorageV2": { + "message": "用於檔案附件的 $SIZE$ 加密儲存空間。", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpEmergency": { "message": "緊急存取" }, @@ -1874,7 +1926,7 @@ "message": "逾期年份" }, "monthly": { - "message": "month" + "message": "月" }, "expiration": { "message": "逾期" @@ -3210,9 +3262,6 @@ "copyCustomFieldNameNotUnique": { "message": "找不到唯一識別碼。" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "以下組織的成員已不再需要主密碼。請與你的組織管理員確認下方的網域。" - }, "organizationName": { "message": "組織名稱" }, @@ -4176,10 +4225,6 @@ "ignore": { "message": "忽略" }, - "importData": { - "message": "匯入資料", - "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" - }, "importError": { "message": "匯入時發生錯誤" }, @@ -4766,6 +4811,15 @@ "accountSecurity": { "message": "帳戶安全性" }, + "phishingBlocker": { + "message": "釣魚封鎖器" + }, + "enablePhishingDetection": { + "message": "釣魚偵測" + }, + "enablePhishingDetectionDesc": { + "message": "在存取疑似釣魚網站前顯示警告" + }, "notifications": { "message": "通知" }, @@ -4912,7 +4966,7 @@ "message": "進階版" }, "unlockFeaturesWithPremium": { - "message": "Unlock reporting, emergency access, and more security features with Premium." + "message": "使用進階版解鎖報告、緊急存取及更多安全功能。" }, "freeOrgsCannotUseAttachments": { "message": "免費組織無法使用附檔" @@ -5818,17 +5872,17 @@ "andMoreFeatures": { "message": "以及其他功能功能!" }, - "planDescPremium": { - "message": "完整的線上安全" + "advancedOnlineSecurity": { + "message": "進階線上安全防護" }, "upgradeToPremium": { "message": "升級到 Premium" }, "unlockAdvancedSecurity": { - "message": "Unlock advanced security features" + "message": "解鎖進階安全功能" }, "unlockAdvancedSecurityDesc": { - "message": "A Premium subscription gives you more tools to stay secure and in control" + "message": "進階版訂閱可為您提供更多工具,協助維持安全並掌握主控權" }, "explorePremium": { "message": "探索進階版" @@ -5849,7 +5903,141 @@ "cardNumberLabel": { "message": "支付卡號碼" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "您的組織已不再使用主密碼登入 Bitwarden。若要繼續,請驗證組織與網域。" + }, + "continueWithLogIn": { + "message": "繼續登入" + }, + "doNotContinue": { + "message": "不要繼續" + }, + "domain": { + "message": "網域" + }, + "keyConnectorDomainTooltip": { + "message": "此網域將儲存您帳號的加密金鑰,請確認您信任它。若不確定,請洽詢您的管理員。" + }, + "verifyYourOrganization": { + "message": "驗證您的組織以登入" + }, + "organizationVerified": { + "message": "組織已驗證" + }, + "domainVerified": { + "message": "已驗證網域" + }, + "leaveOrganizationContent": { + "message": "若您未驗證組織,將會被撤銷對該組織的存取權限。" + }, + "leaveNow": { + "message": "立即離開" + }, + "verifyYourDomainToLogin": { + "message": "驗證您的網域以登入" + }, + "verifyYourDomainDescription": { + "message": "若要繼續登入,請驗證此網域。" + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "若要繼續登入,請驗證組織與網域。" + }, "sessionTimeoutSettingsAction": { "message": "逾時後動作" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "此設定由您的組織管理。" + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "您的組織已將最長工作階段逾時設為 $HOURS$ 小時與 $MINUTES$ 分鐘。", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToImmediately": { + "message": "您的組織已將預設工作階段逾時設定為「立即」。" + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "您的組織已將預設工作階段逾時設定為「在系統鎖定時」。" + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "您的組織已將預設工作階段逾時設定為「在瀏覽器重新啟動時」。" + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "最長逾時時間不可超過 $HOURS$ 小時 $MINUTES$ 分鐘", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "於瀏覽器重新啟動時" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "設定一個解鎖方式來變更您的密碼庫逾時動作。" + }, + "upgrade": { + "message": "升級" + }, + "leaveConfirmationDialogTitle": { + "message": "確定要離開嗎?" + }, + "leaveConfirmationDialogContentOne": { + "message": "若選擇拒絕,您的個人項目將保留在帳號中,但您將失去對共用項目與組織功能的存取權。" + }, + "leaveConfirmationDialogContentTwo": { + "message": "請聯絡您的管理員以重新取得存取權限。" + }, + "leaveConfirmationDialogConfirmButton": { + "message": "離開 $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "我要如何管理我的密碼庫?" + }, + "transferItemsToOrganizationTitle": { + "message": "將項目轉移至 $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ 為了安全性與合規性,要求所有項目皆由組織擁有。點擊接受即可轉移您項目的擁有權。", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "同意轉移" + }, + "declineAndLeave": { + "message": "拒絕並離開" + }, + "whyAmISeeingThis": { + "message": "為什麼我會看到此訊息?" } } diff --git a/apps/browser/src/auth/popup/account-switching/current-account.component.html b/apps/browser/src/auth/popup/account-switching/current-account.component.html index 2e2440f6258..7ab55f36753 100644 --- a/apps/browser/src/auth/popup/account-switching/current-account.component.html +++ b/apps/browser/src/auth/popup/account-switching/current-account.component.html @@ -2,7 +2,7 @@
`; - const shadowRoot = document.getElementById("shadow-root").attachShadow({ mode: "open" }); + const shadowRoot = document.getElementById("shadow-root")!.attachShadow({ mode: "open" }); shadowRoot.innerHTML = ` `; @@ -1668,7 +1668,7 @@ describe("AutofillOverlayContentService", () => { pageDetailsMock, ); await flushPromises(); - buttonElement.dispatchEvent(new KeyboardEvent("keyup", { code: "Enter" })); + buttonElement?.dispatchEvent(new KeyboardEvent("keyup", { code: "Enter" })); expect(sendExtensionMessageSpy).toHaveBeenCalledWith( "formFieldSubmitted", @@ -1716,6 +1716,85 @@ describe("AutofillOverlayContentService", () => { }); }); + describe("refreshMenuLayerPosition", () => { + it("calls refreshTopLayerPosition on the inline menu content service", () => { + autofillOverlayContentService.refreshMenuLayerPosition(); + + expect(inlineMenuContentService.refreshTopLayerPosition).toHaveBeenCalled(); + }); + + it("does not throw if inline menu content service is not available", () => { + const serviceWithoutInlineMenu = new AutofillOverlayContentService( + domQueryService, + domElementVisibilityService, + inlineMenuFieldQualificationService, + ); + + expect(() => serviceWithoutInlineMenu.refreshMenuLayerPosition()).not.toThrow(); + }); + }); + + describe("getOwnedInlineMenuTagNames", () => { + it("returns tag names from the inline menu content service", () => { + inlineMenuContentService.getOwnedTagNames.mockReturnValue(["div", "span"]); + + const result = autofillOverlayContentService.getOwnedInlineMenuTagNames(); + + expect(result).toEqual(["div", "span"]); + }); + + it("returns an empty array if inline menu content service is not available", () => { + const serviceWithoutInlineMenu = new AutofillOverlayContentService( + domQueryService, + domElementVisibilityService, + inlineMenuFieldQualificationService, + ); + + const result = serviceWithoutInlineMenu.getOwnedInlineMenuTagNames(); + + expect(result).toEqual([]); + }); + }); + + describe("getUnownedTopLayerItems", () => { + it("returns unowned top layer items from the inline menu content service", () => { + const mockElements = document.querySelectorAll("div"); + inlineMenuContentService.getUnownedTopLayerItems.mockReturnValue(mockElements); + + const result = autofillOverlayContentService.getUnownedTopLayerItems(true); + + expect(result).toEqual(mockElements); + expect(inlineMenuContentService.getUnownedTopLayerItems).toHaveBeenCalledWith(true); + }); + + it("returns undefined if inline menu content service is not available", () => { + const serviceWithoutInlineMenu = new AutofillOverlayContentService( + domQueryService, + domElementVisibilityService, + inlineMenuFieldQualificationService, + ); + + const result = serviceWithoutInlineMenu.getUnownedTopLayerItems(); + + expect(result).toBeUndefined(); + }); + }); + + describe("clearUserFilledFields", () => { + it("deletes all user filled fields", () => { + const mockElement1 = document.createElement("input") as FillableFormFieldElement; + const mockElement2 = document.createElement("input") as FillableFormFieldElement; + autofillOverlayContentService["userFilledFields"] = { + username: mockElement1, + password: mockElement2, + }; + + autofillOverlayContentService.clearUserFilledFields(); + + expect(autofillOverlayContentService["userFilledFields"]).toEqual({}); + }); + }); + describe("handleOverlayRepositionEvent", () => { const repositionEvents = [EVENTS.SCROLL, EVENTS.RESIZE]; repositionEvents.forEach((repositionEvent) => { @@ -2049,7 +2128,7 @@ describe("AutofillOverlayContentService", () => { }); it("skips focusing an element if no recently focused field exists", async () => { - autofillOverlayContentService["mostRecentlyFocusedField"] = undefined; + (autofillOverlayContentService as any)["mostRecentlyFocusedField"] = null; sendMockExtensionMessage({ command: "redirectAutofillInlineMenuFocusOut", @@ -2149,7 +2228,6 @@ describe("AutofillOverlayContentService", () => { }); it("returns null if the sub frame URL cannot be parsed correctly", async () => { - delete globalThis.location; globalThis.location = { href: "invalid-base" } as Location; sendMockExtensionMessage( { diff --git a/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts b/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts index f7c46a9fa77..65f9eee1ecb 100644 --- a/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts +++ b/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts @@ -16,9 +16,7 @@ import { } from "./autofill-constants"; import AutofillService from "./autofill.service"; -export class InlineMenuFieldQualificationService - implements InlineMenuFieldQualificationServiceInterface -{ +export class InlineMenuFieldQualificationService implements InlineMenuFieldQualificationServiceInterface { private searchFieldNamesSet = new Set(AutoFillConstants.SearchFieldNames); private excludedAutofillFieldTypesSet = new Set(AutoFillConstants.ExcludedAutofillLoginTypes); private usernameFieldTypes = new Set(["text", "email", "number", "tel"]); @@ -945,7 +943,8 @@ export class InlineMenuFieldQualificationService !fieldType || !this.usernameFieldTypes.has(fieldType) || this.isExcludedFieldType(field, this.excludedAutofillFieldTypesSet) || - this.fieldHasDisqualifyingAttributeValue(field) + this.fieldHasDisqualifyingAttributeValue(field) || + this.isTotpField(field) ) { return false; } diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 143f5d1f6b3..2d1da8510c1 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -82,9 +82,13 @@ import { import { isUrlInList } from "@bitwarden/common/autofill/utils"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service"; +import { PhishingDetectionSettingsServiceAbstraction } from "@bitwarden/common/dirt/services/abstractions/phishing-detection-settings.service.abstraction"; import { HibpApiService } from "@bitwarden/common/dirt/services/hibp-api.service"; +import { PhishingDetectionSettingsService } from "@bitwarden/common/dirt/services/phishing-detection/phishing-detection-settings.service"; import { ClientType } from "@bitwarden/common/enums"; import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service"; +import { AccountCryptographicStateService } from "@bitwarden/common/key-management/account-cryptography/account-cryptographic-state.service"; +import { DefaultAccountCryptographicStateService } from "@bitwarden/common/key-management/account-cryptography/default-account-cryptographic-state.service"; import { DefaultKeyGenerationService, KeyGenerationService, @@ -297,6 +301,7 @@ import { SafariApp } from "../browser/safariApp"; import { PhishingDataService } from "../dirt/phishing-detection/services/phishing-data.service"; import { PhishingDetectionService } from "../dirt/phishing-detection/services/phishing-detection.service"; import { BackgroundBrowserBiometricsService } from "../key-management/biometrics/background-browser-biometrics.service"; +import { BrowserSessionTimeoutTypeService } from "../key-management/session-timeout/services/browser-session-timeout-type.service"; import VaultTimeoutService from "../key-management/vault-timeout/vault-timeout.service"; import { BrowserActionsService } from "../platform/actions/browser-actions.service"; import { DefaultBadgeBrowserApi } from "../platform/badge/badge-browser-api"; @@ -452,6 +457,7 @@ export default class MainBackground { syncServiceListener: SyncServiceListener; browserInitialInstallService: BrowserInitialInstallService; backgroundSyncService: BackgroundSyncService; + accountCryptographicStateService: AccountCryptographicStateService; webPushConnectionService: WorkerWebPushConnectionService | UnsupportedWebPushConnectionService; themeStateService: DefaultThemeStateService; @@ -496,6 +502,7 @@ export default class MainBackground { // DIRT private phishingDataService: PhishingDataService; + private phishingDetectionSettingsService: PhishingDetectionSettingsServiceAbstraction; constructor() { const logoutCallback = async (logoutReason: LogoutReason, userId?: UserId) => @@ -738,6 +745,10 @@ export default class MainBackground { this.accountService, ); + const sessionTimeoutTypeService = new BrowserSessionTimeoutTypeService( + this.platformUtilsService, + ); + this.vaultTimeoutSettingsService = new DefaultVaultTimeoutSettingsService( this.accountService, pinStateService, @@ -749,6 +760,7 @@ export default class MainBackground { this.stateProvider, this.logService, VaultTimeoutStringType.OnRestart, // default vault timeout + sessionTimeoutTypeService, ); this.apiService = new ApiService( @@ -835,10 +847,7 @@ export default class MainBackground { ); this.pinService = new PinService( - this.accountService, this.encryptService, - this.kdfConfigService, - this.keyGenerationService, this.logService, this.keyService, this.sdkService, @@ -1004,6 +1013,9 @@ export default class MainBackground { this.avatarService = new AvatarService(this.apiService, this.stateProvider); this.providerService = new ProviderService(this.stateProvider); + this.accountCryptographicStateService = new DefaultAccountCryptographicStateService( + this.stateProvider, + ); this.syncService = new DefaultSyncService( this.masterPasswordService, this.accountService, @@ -1031,6 +1043,7 @@ export default class MainBackground { this.stateProvider, this.securityStateService, this.kdfConfigService, + this.accountCryptographicStateService, ); this.syncServiceListener = new SyncServiceListener( @@ -1106,7 +1119,7 @@ export default class MainBackground { this.collectionService, this.keyService, this.encryptService, - this.pinService, + this.keyGenerationService, this.accountService, this.restrictedItemTypesService, ); @@ -1114,7 +1127,7 @@ export default class MainBackground { this.individualVaultExportService = new IndividualVaultExportService( this.folderService, this.cipherService, - this.pinService, + this.keyGenerationService, this.keyService, this.encryptService, this.cryptoFunctionService, @@ -1128,7 +1141,7 @@ export default class MainBackground { this.organizationVaultExportService = new OrganizationVaultExportService( this.cipherService, this.exportApiService, - this.pinService, + this.keyGenerationService, this.keyService, this.encryptService, this.cryptoFunctionService, @@ -1472,12 +1485,19 @@ export default class MainBackground { this.platformUtilsService, ); - PhishingDetectionService.initialize( + this.phishingDetectionSettingsService = new PhishingDetectionSettingsService( this.accountService, this.billingAccountProfileStateService, this.configService, + this.organizationService, + this.platformUtilsService, + this.stateProvider, + ); + + PhishingDetectionService.initialize( this.logService, this.phishingDataService, + this.phishingDetectionSettingsService, messageListener, ); diff --git a/apps/browser/src/background/runtime.background.ts b/apps/browser/src/background/runtime.background.ts index 597babdc777..eba6b01fe90 100644 --- a/apps/browser/src/background/runtime.background.ts +++ b/apps/browser/src/background/runtime.background.ts @@ -294,19 +294,11 @@ export default class RuntimeBackground { await this.openPopup(); break; case VaultMessages.OpenAtRiskPasswords: { - if (await this.shouldRejectManyOriginMessage(msg)) { - return; - } - await this.main.openAtRisksPasswordsPage(); this.announcePopupOpen(); break; } case VaultMessages.OpenBrowserExtensionToUrl: { - if (await this.shouldRejectManyOriginMessage(msg)) { - return; - } - await this.main.openTheExtensionToPage(msg.url); this.announcePopupOpen(); break; diff --git a/apps/browser/src/dirt/phishing-detection/services/phishing-detection.service.spec.ts b/apps/browser/src/dirt/phishing-detection/services/phishing-detection.service.spec.ts index e33b4b1b4f1..06a37f12faa 100644 --- a/apps/browser/src/dirt/phishing-detection/services/phishing-detection.service.spec.ts +++ b/apps/browser/src/dirt/phishing-detection/services/phishing-detection.service.spec.ts @@ -1,9 +1,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { Observable, of } from "rxjs"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; +import { PhishingDetectionSettingsServiceAbstraction } from "@bitwarden/common/dirt/services/abstractions/phishing-detection-settings.service.abstraction"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessageListener } from "@bitwarden/messaging"; @@ -11,17 +9,12 @@ import { PhishingDataService } from "./phishing-data.service"; import { PhishingDetectionService } from "./phishing-detection.service"; describe("PhishingDetectionService", () => { - let accountService: AccountService; - let billingAccountProfileStateService: BillingAccountProfileStateService; - let configService: ConfigService; let logService: LogService; let phishingDataService: MockProxy; let messageListener: MockProxy; + let phishingDetectionSettingsService: MockProxy; beforeEach(() => { - accountService = { getAccount$: jest.fn(() => of(null)) } as any; - billingAccountProfileStateService = {} as any; - configService = { getFeatureFlag$: jest.fn(() => of(false)) } as any; logService = { info: jest.fn(), debug: jest.fn(), warning: jest.fn(), error: jest.fn() } as any; phishingDataService = mock(); messageListener = mock({ @@ -29,16 +22,17 @@ describe("PhishingDetectionService", () => { return new Observable(); }, }); + phishingDetectionSettingsService = mock({ + on$: of(true), + }); }); it("should initialize without errors", () => { expect(() => { PhishingDetectionService.initialize( - accountService, - billingAccountProfileStateService, - configService, logService, phishingDataService, + phishingDetectionSettingsService, messageListener, ); }).not.toThrow(); @@ -61,6 +55,7 @@ describe("PhishingDetectionService", () => { // logService, // phishingDataService, // messageListener, + // phishingDetectionSettingsService, // ); // }); @@ -81,6 +76,12 @@ describe("PhishingDetectionService", () => { // logService, // phishingDataService, // messageListener, + // phishingDetectionSettingsService, // ); // }); + + // TODO + // it("should not enable phishing detection for safari", () => { + // + // }); }); diff --git a/apps/browser/src/dirt/phishing-detection/services/phishing-detection.service.ts b/apps/browser/src/dirt/phishing-detection/services/phishing-detection.service.ts index 4917e740be8..e04d08559ab 100644 --- a/apps/browser/src/dirt/phishing-detection/services/phishing-detection.service.ts +++ b/apps/browser/src/dirt/phishing-detection/services/phishing-detection.service.ts @@ -1,21 +1,16 @@ import { - combineLatest, concatMap, distinctUntilChanged, EMPTY, filter, map, merge, - of, Subject, switchMap, tap, } from "rxjs"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; +import { PhishingDetectionSettingsServiceAbstraction } from "@bitwarden/common/dirt/services/abstractions/phishing-detection-settings.service.abstraction"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { CommandDefinition, MessageListener } from "@bitwarden/messaging"; @@ -50,11 +45,9 @@ export class PhishingDetectionService { private static _didInit = false; static initialize( - accountService: AccountService, - billingAccountProfileStateService: BillingAccountProfileStateService, - configService: ConfigService, logService: LogService, phishingDataService: PhishingDataService, + phishingDetectionSettingsService: PhishingDetectionSettingsServiceAbstraction, messageListener: MessageListener, ) { if (this._didInit) { @@ -118,22 +111,9 @@ export class PhishingDetectionService { .messages$(PHISHING_DETECTION_CANCEL_COMMAND) .pipe(switchMap((message) => BrowserApi.closeTab(message.tabId))); - const activeAccountHasAccess$ = combineLatest([ - accountService.activeAccount$, - configService.getFeatureFlag$(FeatureFlag.PhishingDetection), - ]).pipe( - switchMap(([account, featureEnabled]) => { - if (!account) { - logService.debug("[PhishingDetectionService] No active account."); - return of(false); - } - return billingAccountProfileStateService - .hasPremiumFromAnySource$(account.id) - .pipe(map((hasPremium) => hasPremium && featureEnabled)); - }), - ); + const phishingDetectionActive$ = phishingDetectionSettingsService.on$; - const initSub = activeAccountHasAccess$ + const initSub = phishingDetectionActive$ .pipe( distinctUntilChanged(), switchMap((activeUserHasAccess) => { diff --git a/apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts b/apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts index b6e84fee31a..d803a457a81 100644 --- a/apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts +++ b/apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts @@ -48,7 +48,11 @@ export class ForegroundBrowserBiometricsService extends BiometricsService { result: BiometricsStatus; error: string; }>(BiometricsCommands.GetBiometricsStatusForUser, { userId: id }); - return response.result; + if (response != null) { + return response.result; + } else { + return BiometricsStatus.DesktopDisconnected; + } } async getShouldAutopromptNow(): Promise { diff --git a/apps/browser/src/key-management/key-connector/remove-password.component.html b/apps/browser/src/key-management/key-connector/remove-password.component.html deleted file mode 100644 index 427065e83f3..00000000000 --- a/apps/browser/src/key-management/key-connector/remove-password.component.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - @if (loading) { -
- - {{ "loading" | i18n }} -
- } @else { -

{{ "removeMasterPasswordForOrganizationUserKeyConnector" | i18n }}

-

{{ "organizationName" | i18n }}:

-

{{ organization.name }}

-

{{ "keyConnectorDomain" | i18n }}:

-

{{ organization.keyConnectorUrl }}

- - - - } -
diff --git a/apps/browser/src/key-management/key-connector/remove-password.component.ts b/apps/browser/src/key-management/key-connector/remove-password.component.ts deleted file mode 100644 index c4077a1eca9..00000000000 --- a/apps/browser/src/key-management/key-connector/remove-password.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -// FIXME (PM-22628): angular imports are forbidden in background -// eslint-disable-next-line no-restricted-imports -import { Component } from "@angular/core"; - -import { RemovePasswordComponent as BaseRemovePasswordComponent } from "@bitwarden/key-management-ui"; - -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -@Component({ - selector: "app-remove-password", - templateUrl: "remove-password.component.html", - standalone: false, -}) -export class RemovePasswordComponent extends BaseRemovePasswordComponent {} diff --git a/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-settings-component.service.spec.ts b/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-settings-component.service.spec.ts new file mode 100644 index 00000000000..cf5d556a553 --- /dev/null +++ b/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-settings-component.service.spec.ts @@ -0,0 +1,57 @@ +import { mock } from "jest-mock-extended"; + +import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { SessionTimeoutTypeService } from "@bitwarden/common/key-management/session-timeout"; +import { + VaultTimeoutNumberType, + VaultTimeoutStringType, +} from "@bitwarden/common/key-management/vault-timeout"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; + +import { BrowserSessionTimeoutSettingsComponentService } from "./browser-session-timeout-settings-component.service"; + +describe("BrowserSessionTimeoutSettingsComponentService", () => { + let service: BrowserSessionTimeoutSettingsComponentService; + let mockI18nService: jest.Mocked; + let mockSessionTimeoutTypeService: jest.Mocked; + let mockPolicyService: jest.Mocked; + let mockMessagingService: jest.Mocked; + + beforeEach(() => { + mockI18nService = mock(); + mockSessionTimeoutTypeService = mock(); + mockPolicyService = mock(); + mockMessagingService = mock(); + + service = new BrowserSessionTimeoutSettingsComponentService( + mockI18nService, + mockSessionTimeoutTypeService, + mockPolicyService, + mockMessagingService, + ); + }); + + describe("onTimeoutSave", () => { + it("should call messagingService.send with 'bgReseedStorage' when timeout is Never", () => { + service.onTimeoutSave(VaultTimeoutStringType.Never); + + expect(mockMessagingService.send).toHaveBeenCalledWith("bgReseedStorage"); + }); + + it.each([ + VaultTimeoutNumberType.Immediately, + VaultTimeoutNumberType.OnMinute, + VaultTimeoutNumberType.EightHours, + VaultTimeoutStringType.OnIdle, + VaultTimeoutStringType.OnSleep, + VaultTimeoutStringType.OnLocked, + VaultTimeoutStringType.OnRestart, + VaultTimeoutStringType.Custom, + ])("should not call messagingService.send when timeout is %s", (timeoutValue) => { + service.onTimeoutSave(timeoutValue); + + expect(mockMessagingService.send).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-settings-component.service.ts b/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-settings-component.service.ts index 297718687eb..24925e25e24 100644 --- a/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-settings-component.service.ts +++ b/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-settings-component.service.ts @@ -1,56 +1,24 @@ -import { defer, Observable, of } from "rxjs"; - +import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { SessionTimeoutTypeService } from "@bitwarden/common/key-management/session-timeout"; import { VaultTimeout, - VaultTimeoutOption, VaultTimeoutStringType, } from "@bitwarden/common/key-management/vault-timeout"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SessionTimeoutSettingsComponentService } from "@bitwarden/key-management-ui"; -export class BrowserSessionTimeoutSettingsComponentService - implements SessionTimeoutSettingsComponentService -{ - availableTimeoutOptions$: Observable = defer(() => { - const options: VaultTimeoutOption[] = [ - { name: this.i18nService.t("immediately"), value: 0 }, - { name: this.i18nService.t("oneMinute"), value: 1 }, - { name: this.i18nService.t("fiveMinutes"), value: 5 }, - { name: this.i18nService.t("fifteenMinutes"), value: 15 }, - { name: this.i18nService.t("thirtyMinutes"), value: 30 }, - { name: this.i18nService.t("oneHour"), value: 60 }, - { name: this.i18nService.t("fourHours"), value: 240 }, - ]; - - const showOnLocked = - !this.platformUtilsService.isFirefox() && - !this.platformUtilsService.isSafari() && - !(this.platformUtilsService.isOpera() && navigator.platform === "MacIntel"); - - if (showOnLocked) { - options.push({ - name: this.i18nService.t("onLocked"), - value: VaultTimeoutStringType.OnLocked, - }); - } - - options.push( - { name: this.i18nService.t("onRestart"), value: VaultTimeoutStringType.OnRestart }, - { name: this.i18nService.t("never"), value: VaultTimeoutStringType.Never }, - ); - - return of(options); - }); - +export class BrowserSessionTimeoutSettingsComponentService extends SessionTimeoutSettingsComponentService { constructor( - private readonly i18nService: I18nService, - private readonly platformUtilsService: PlatformUtilsService, + i18nService: I18nService, + sessionTimeoutTypeService: SessionTimeoutTypeService, + policyService: PolicyService, private readonly messagingService: MessagingService, - ) {} + ) { + super(i18nService, sessionTimeoutTypeService, policyService); + } - onTimeoutSave(timeout: VaultTimeout): void { + override onTimeoutSave(timeout: VaultTimeout): void { if (timeout === VaultTimeoutStringType.Never) { this.messagingService.send("bgReseedStorage"); } diff --git a/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-type.service.spec.ts b/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-type.service.spec.ts new file mode 100644 index 00000000000..83de5c51a4a --- /dev/null +++ b/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-type.service.spec.ts @@ -0,0 +1,139 @@ +import { mock } from "jest-mock-extended"; + +import { + VaultTimeoutNumberType, + VaultTimeoutStringType, +} from "@bitwarden/common/key-management/vault-timeout"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; + +import { BrowserSessionTimeoutTypeService } from "./browser-session-timeout-type.service"; + +describe("BrowserSessionTimeoutTypeService", () => { + let service: BrowserSessionTimeoutTypeService; + let mockPlatformUtilsService: jest.Mocked; + + beforeEach(() => { + mockPlatformUtilsService = mock(); + service = new BrowserSessionTimeoutTypeService(mockPlatformUtilsService); + }); + + describe("isAvailable", () => { + it.each([ + VaultTimeoutNumberType.Immediately, + VaultTimeoutStringType.OnRestart, + VaultTimeoutStringType.Never, + VaultTimeoutStringType.Custom, + ])("should return true for always available type: %s", async (timeoutType) => { + const result = await service.isAvailable(timeoutType); + + expect(result).toBe(true); + }); + + it.each([VaultTimeoutNumberType.OnMinute, VaultTimeoutNumberType.EightHours])( + "should return true for numeric timeout type: %s", + async (timeoutType) => { + const result = await service.isAvailable(timeoutType); + + expect(result).toBe(true); + }, + ); + + describe("OnLocked availability", () => { + const mockNavigatorPlatform = (platform: string) => { + Object.defineProperty(navigator, "platform", { + value: platform, + writable: true, + configurable: true, + }); + }; + + beforeEach(() => { + mockNavigatorPlatform("Linux x86_64"); + mockPlatformUtilsService.isFirefox.mockReturnValue(false); + mockPlatformUtilsService.isSafari.mockReturnValue(false); + mockPlatformUtilsService.isOpera.mockReturnValue(false); + }); + + it("should return true when not Firefox, Safari, or Opera on Mac", async () => { + const result = await service.isAvailable(VaultTimeoutStringType.OnLocked); + + expect(result).toBe(true); + }); + + it("should return true when Opera on non-Mac platform", async () => { + mockNavigatorPlatform("Win32"); + mockPlatformUtilsService.isOpera.mockReturnValue(true); + + const result = await service.isAvailable(VaultTimeoutStringType.OnLocked); + + expect(result).toBe(true); + }); + + it("should return false when Opera on Mac", async () => { + mockNavigatorPlatform("MacIntel"); + mockPlatformUtilsService.isOpera.mockReturnValue(true); + + const result = await service.isAvailable(VaultTimeoutStringType.OnLocked); + + expect(result).toBe(false); + }); + + it("should return false when Firefox", async () => { + mockPlatformUtilsService.isFirefox.mockReturnValue(true); + + const result = await service.isAvailable(VaultTimeoutStringType.OnLocked); + + expect(result).toBe(false); + }); + + it("should return false when Safari", async () => { + mockPlatformUtilsService.isSafari.mockReturnValue(true); + + const result = await service.isAvailable(VaultTimeoutStringType.OnLocked); + + expect(result).toBe(false); + }); + }); + + it.each([VaultTimeoutStringType.OnIdle, VaultTimeoutStringType.OnSleep])( + "should return false for unavailable timeout type: %s", + async (timeoutType) => { + const result = await service.isAvailable(timeoutType); + + expect(result).toBe(false); + }, + ); + }); + + describe("getOrPromoteToAvailable", () => { + it.each([ + VaultTimeoutNumberType.Immediately, + VaultTimeoutNumberType.OnMinute, + VaultTimeoutStringType.Never, + VaultTimeoutStringType.OnRestart, + VaultTimeoutStringType.OnLocked, + VaultTimeoutStringType.Custom, + ])("should return the original type when it is available: %s", async (timeoutType) => { + jest.spyOn(service, "isAvailable").mockResolvedValue(true); + + const result = await service.getOrPromoteToAvailable(timeoutType); + + expect(result).toBe(timeoutType); + expect(service.isAvailable).toHaveBeenCalledWith(timeoutType); + }); + + it.each([ + VaultTimeoutStringType.OnIdle, + VaultTimeoutStringType.OnSleep, + VaultTimeoutStringType.OnLocked, + 5, + ])("should return OnRestart when type is not available: %s", async (timeoutType) => { + jest.spyOn(service, "isAvailable").mockResolvedValue(false); + + const result = await service.getOrPromoteToAvailable(timeoutType); + + expect(result).toBe(VaultTimeoutStringType.OnRestart); + expect(service.isAvailable).toHaveBeenCalledWith(timeoutType); + }); + }); +}); diff --git a/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-type.service.ts b/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-type.service.ts new file mode 100644 index 00000000000..33ac3e356d4 --- /dev/null +++ b/apps/browser/src/key-management/session-timeout/services/browser-session-timeout-type.service.ts @@ -0,0 +1,43 @@ +import { SessionTimeoutTypeService } from "@bitwarden/common/key-management/session-timeout"; +import { + isVaultTimeoutTypeNumeric, + VaultTimeout, + VaultTimeoutNumberType, + VaultTimeoutStringType, +} from "@bitwarden/common/key-management/vault-timeout"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; + +export class BrowserSessionTimeoutTypeService implements SessionTimeoutTypeService { + constructor(private readonly platformUtilsService: PlatformUtilsService) {} + + async isAvailable(type: VaultTimeout): Promise { + switch (type) { + case VaultTimeoutNumberType.Immediately: + case VaultTimeoutStringType.OnRestart: + case VaultTimeoutStringType.Never: + case VaultTimeoutStringType.Custom: + return true; + case VaultTimeoutStringType.OnLocked: + return ( + !this.platformUtilsService.isFirefox() && + !this.platformUtilsService.isSafari() && + !(this.platformUtilsService.isOpera() && navigator.platform === "MacIntel") + ); + default: + if (isVaultTimeoutTypeNumeric(type)) { + return true; + } + break; + } + + return false; + } + + async getOrPromoteToAvailable(type: VaultTimeout): Promise { + const available = await this.isAvailable(type); + if (!available) { + return VaultTimeoutStringType.OnRestart; + } + return type; + } +} diff --git a/apps/browser/src/models/browserComponentState.ts b/apps/browser/src/models/browserComponentState.ts deleted file mode 100644 index 50ee9fe34d4..00000000000 --- a/apps/browser/src/models/browserComponentState.ts +++ /dev/null @@ -1,16 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Jsonify } from "type-fest"; - -export class BrowserComponentState { - scrollY: number; - searchText: string; - - static fromJSON(json: Jsonify) { - if (json == null) { - return null; - } - - return Object.assign(new BrowserComponentState(), json); - } -} diff --git a/apps/browser/src/models/browserGroupingsComponentState.ts b/apps/browser/src/models/browserGroupingsComponentState.ts deleted file mode 100644 index 364f4beb6bf..00000000000 --- a/apps/browser/src/models/browserGroupingsComponentState.ts +++ /dev/null @@ -1,46 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { CollectionView } from "@bitwarden/admin-console/common"; -import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { DeepJsonify } from "@bitwarden/common/types/deep-jsonify"; -import { CipherType } from "@bitwarden/common/vault/enums"; -import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; - -import { BrowserComponentState } from "./browserComponentState"; - -export class BrowserGroupingsComponentState extends BrowserComponentState { - favoriteCiphers: CipherView[]; - noFolderCiphers: CipherView[]; - ciphers: CipherView[]; - collectionCounts: Map; - folderCounts: Map; - typeCounts: Map; - folders: FolderView[]; - collections: CollectionView[]; - deletedCount: number; - - toJSON() { - return Utils.merge(this, { - collectionCounts: Utils.mapToRecord(this.collectionCounts), - folderCounts: Utils.mapToRecord(this.folderCounts), - typeCounts: Utils.mapToRecord(this.typeCounts), - }); - } - - static fromJSON(json: DeepJsonify) { - if (json == null) { - return null; - } - - return Object.assign(new BrowserGroupingsComponentState(), json, { - favoriteCiphers: json.favoriteCiphers?.map((c) => CipherView.fromJSON(c)), - noFolderCiphers: json.noFolderCiphers?.map((c) => CipherView.fromJSON(c)), - ciphers: json.ciphers?.map((c) => CipherView.fromJSON(c)), - collectionCounts: Utils.recordToMap(json.collectionCounts), - folderCounts: Utils.recordToMap(json.folderCounts), - typeCounts: Utils.recordToMap(json.typeCounts), - folders: json.folders?.map((f) => FolderView.fromJSON(f)), - }); - } -} diff --git a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts index 4abd9cd4803..26138d57954 100644 --- a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts +++ b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts @@ -22,7 +22,7 @@ export type NavButton = { templateUrl: "popup-tab-navigation.component.html", imports: [CommonModule, LinkModule, RouterModule, JslibModule, IconModule], host: { - class: "tw-block tw-h-full tw-w-full tw-flex tw-flex-col", + class: "tw-block tw-size-full tw-flex tw-flex-col", }, }) export class PopupTabNavigationComponent { diff --git a/apps/browser/src/platform/popup/view-cache/popup-router-cache.service.ts b/apps/browser/src/platform/popup/view-cache/popup-router-cache.service.ts index abb7c6405c2..6e5218c9f27 100644 --- a/apps/browser/src/platform/popup/view-cache/popup-router-cache.service.ts +++ b/apps/browser/src/platform/popup/view-cache/popup-router-cache.service.ts @@ -120,8 +120,8 @@ export class PopupRouterCacheService { /** * Navigate back in history */ - async back() { - if (!BrowserPopupUtils.inPopup(window)) { + async back(updateCache = false) { + if (!updateCache && !BrowserPopupUtils.inPopup(window)) { this.location.back(); return; } diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index a36396afa1a..12e1288e806 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -43,11 +43,16 @@ import { TwoFactorAuthGuard, } from "@bitwarden/auth/angular"; import { AnonLayoutWrapperComponent, AnonLayoutWrapperData } from "@bitwarden/components"; -import { LockComponent, ConfirmKeyConnectorDomainComponent } from "@bitwarden/key-management-ui"; +import { + LockComponent, + ConfirmKeyConnectorDomainComponent, + RemovePasswordComponent, +} from "@bitwarden/key-management-ui"; import { AccountSwitcherComponent } from "../auth/popup/account-switching/account-switcher.component"; import { AuthExtensionRoute } from "../auth/popup/constants/auth-extension-route.constant"; import { fido2AuthGuard } from "../auth/popup/guards/fido2-auth.guard"; +import { platformPopoutGuard } from "../auth/popup/guards/platform-popout.guard"; import { AccountSecurityComponent } from "../auth/popup/settings/account-security.component"; import { ExtensionDeviceManagementComponent } from "../auth/popup/settings/extension-device-management.component"; import { Fido2Component } from "../autofill/popup/fido2/fido2.component"; @@ -58,12 +63,12 @@ import { NotificationsSettingsComponent } from "../autofill/popup/settings/notif import { PremiumV2Component } from "../billing/popup/settings/premium-v2.component"; import { PhishingWarning } from "../dirt/phishing-detection/popup/phishing-warning.component"; import { ProtectedByComponent } from "../dirt/phishing-detection/popup/protected-by-component"; -import { RemovePasswordComponent } from "../key-management/key-connector/remove-password.component"; import BrowserPopupUtils from "../platform/browser/browser-popup-utils"; import { popupRouterCacheGuard } from "../platform/popup/view-cache/popup-router-cache.service"; import { RouteCacheOptions } from "../platform/services/popup-view-cache-background.service"; import { CredentialGeneratorHistoryComponent } from "../tools/popup/generator/credential-generator-history.component"; import { CredentialGeneratorComponent } from "../tools/popup/generator/credential-generator.component"; +import { firefoxPopoutGuard } from "../tools/popup/guards/firefox-popout.guard"; import { SendAddEditComponent as SendAddEditV2Component } from "../tools/popup/send-v2/add-edit/send-add-edit.component"; import { SendCreatedComponent } from "../tools/popup/send-v2/send-created/send-created.component"; import { SendV2Component } from "../tools/popup/send-v2/send-v2.component"; @@ -187,9 +192,22 @@ const routes: Routes = [ }, { path: "remove-password", - component: RemovePasswordComponent, + component: ExtensionAnonLayoutWrapperComponent, canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, + children: [ + { + path: "", + component: RemovePasswordComponent, + data: { + pageTitle: { + key: "verifyYourOrganization", + }, + showBackButton: false, + pageIcon: LockIcon, + } satisfies ExtensionAnonLayoutWrapperData, + }, + ], }, { path: "view-cipher", @@ -245,7 +263,7 @@ const routes: Routes = [ { path: "import", component: ImportBrowserV2Component, - canActivate: [authGuard], + canActivate: [authGuard, firefoxPopoutGuard()], data: { elevation: 1 } satisfies RouteDataProperties, }, { @@ -323,13 +341,13 @@ const routes: Routes = [ { path: "add-send", component: SendAddEditV2Component, - canActivate: [authGuard], + canActivate: [authGuard, firefoxPopoutGuard()], data: { elevation: 1 } satisfies RouteDataProperties, }, { path: "edit-send", component: SendAddEditV2Component, - canActivate: [authGuard], + canActivate: [authGuard, firefoxPopoutGuard()], data: { elevation: 1 } satisfies RouteDataProperties, }, { @@ -414,7 +432,7 @@ const routes: Routes = [ }, { path: AuthRoute.LoginWithPasskey, - canActivate: [unauthGuardFn(unauthRouteOverrides)], + canActivate: [unauthGuardFn(unauthRouteOverrides), platformPopoutGuard(["linux"])], data: { pageIcon: TwoFactorAuthSecurityKeyIcon, pageTitle: { @@ -645,7 +663,7 @@ const routes: Routes = [ component: ConfirmKeyConnectorDomainComponent, data: { pageTitle: { - key: "confirmKeyConnectorDomain", + key: "verifyYourOrganization", }, showBackButton: true, pageIcon: DomainIcon, diff --git a/apps/browser/src/popup/app.component.html b/apps/browser/src/popup/app.component.html index 3d81354ca35..3a5c8021e17 100644 --- a/apps/browser/src/popup/app.component.html +++ b/apps/browser/src/popup/app.component.html @@ -13,8 +13,11 @@ } @else { -
- + +
+
+ +
+
- } diff --git a/apps/browser/src/popup/app.module.ts b/apps/browser/src/popup/app.module.ts index 71846cc6444..d178cee2fc3 100644 --- a/apps/browser/src/popup/app.module.ts +++ b/apps/browser/src/popup/app.module.ts @@ -28,7 +28,6 @@ import { CurrentAccountComponent } from "../auth/popup/account-switching/current import { AccountSecurityComponent } from "../auth/popup/settings/account-security.component"; import { AutofillComponent } from "../autofill/popup/settings/autofill.component"; import { NotificationsSettingsComponent } from "../autofill/popup/settings/notifications.component"; -import { RemovePasswordComponent } from "../key-management/key-connector/remove-password.component"; import { PopOutComponent } from "../platform/popup/components/pop-out.component"; import { PopupFooterComponent } from "../platform/popup/layout/popup-footer.component"; import { PopupHeaderComponent } from "../platform/popup/layout/popup-header.component"; @@ -85,13 +84,7 @@ import "../platform/popup/locales"; CalloutModule, LinkModule, ], - declarations: [ - AppComponent, - ColorPasswordPipe, - ColorPasswordCountPipe, - TabsV2Component, - RemovePasswordComponent, - ], + declarations: [AppComponent, ColorPasswordPipe, ColorPasswordCountPipe, TabsV2Component], exports: [CalloutModule], providers: [CurrencyPipe, DatePipe], bootstrap: [AppComponent], diff --git a/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html b/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html index dcd0496ed30..484f9680519 100644 --- a/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html +++ b/apps/browser/src/popup/components/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html @@ -14,7 +14,6 @@ - div { - height: 100%; - width: 100%; -} - -main::-webkit-scrollbar, -cdk-virtual-scroll-viewport::-webkit-scrollbar, -.vault-select::-webkit-scrollbar { - width: 10px; - height: 10px; -} - -main::-webkit-scrollbar-track, -.vault-select::-webkit-scrollbar-track { - background-color: transparent; -} - -cdk-virtual-scroll-viewport::-webkit-scrollbar-track { - @include themify($themes) { - background-color: themed("backgroundColor"); - } -} - -main::-webkit-scrollbar-thumb, -cdk-virtual-scroll-viewport::-webkit-scrollbar-thumb, -.vault-select::-webkit-scrollbar-thumb { - border-radius: 10px; - margin-right: 1px; - - @include themify($themes) { - background-color: themed("scrollbarColor"); - } - - &:hover { - @include themify($themes) { - background-color: themed("scrollbarHoverColor"); - } - } -} - -header:not(bit-callout header, bit-dialog header, popup-page header) { - height: 44px; - display: flex; - - &:not(.no-theme) { - border-bottom: 1px solid #000000; - - @include themify($themes) { - color: themed("headerColor"); - background-color: themed("headerBackgroundColor"); - border-bottom-color: themed("headerBorderColor"); - } - } - - .header-content { - display: flex; - flex: 1 1 auto; - } - - .header-content > .right, - .header-content > .right > .right { - height: 100%; - } - - .left, - .right { - flex: 1; - display: flex; - min-width: -webkit-min-content; /* Workaround to Chrome bug */ - .header-icon { - margin-right: 5px; - } - } - - .right { - justify-content: flex-end; - align-items: center; - app-avatar { - max-height: 30px; - margin-right: 5px; - } - } - - .center { - display: flex; - align-items: center; - text-align: center; - min-width: 0; - } - - .login-center { - margin: auto; - } - - app-pop-out > button, - div > button:not(app-current-account button):not(.home-acc-switcher-btn), - div > a { - border: none; - padding: 0 10px; - text-decoration: none; - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - height: 100%; - white-space: pre; - - &:not(.home-acc-switcher-btn):hover, - &:not(.home-acc-switcher-btn):focus { - @include themify($themes) { - background-color: themed("headerBackgroundHoverColor"); - color: themed("headerColor"); - } - } - - &[disabled] { - opacity: 0.65; - cursor: default !important; - background-color: inherit !important; - } - - i + span { - margin-left: 5px; - } - } - - app-pop-out { - display: flex; - padding-right: 0.5em; - } - - .title { - font-weight: bold; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .search { - padding: 7px 10px; - width: 100%; - text-align: left; - position: relative; - display: flex; - - .bwi { - position: absolute; - top: 15px; - left: 20px; - - @include themify($themes) { - color: themed("headerInputPlaceholderColor"); - } - } - - input:not(bit-form-field input) { - width: 100%; - margin: 0; - border: none; - padding: 5px 10px 5px 30px; - border-radius: $border-radius; - - @include themify($themes) { - background-color: themed("headerInputBackgroundColor"); - color: themed("headerInputColor"); - } - - &::selection { - @include themify($themes) { - // explicitly set text selection to invert foreground/background - background-color: themed("headerInputColor"); - color: themed("headerInputBackgroundColor"); - } - } - - &:focus { - border-radius: $border-radius; - outline: none; - - @include themify($themes) { - background-color: themed("headerInputBackgroundFocusColor"); - } - } - - &::-webkit-input-placeholder { - @include themify($themes) { - color: themed("headerInputPlaceholderColor"); - } - } - /** make the cancel button visible in both dark/light themes **/ - &[type="search"]::-webkit-search-cancel-button { - -webkit-appearance: none; - appearance: none; - height: 15px; - width: 15px; - background-repeat: no-repeat; - mask-image: url("../images/close-button-white.svg"); - -webkit-mask-image: url("../images/close-button-white.svg"); - @include themify($themes) { - background-color: themed("headerInputColor"); - } - } - } - } - - .left + .search, - .left + .sr-only + .search { - padding-left: 0; - - .bwi { - left: 10px; - } - } - - .search + .right { - margin-left: -10px; - } -} - -.content { - padding: 15px 5px; -} - -app-root { - width: 100%; - height: 100vh; - display: flex; - - @include themify($themes) { - background-color: themed("backgroundColor"); - } -} - -main:not(popup-page main):not(auth-anon-layout main) { - position: absolute; - top: 44px; - bottom: 0; - left: 0; - right: 0; - overflow-y: auto; - overflow-x: hidden; - - @include themify($themes) { - background-color: themed("backgroundColor"); - } - - &.no-header { - top: 0; - } - - &.flex { - display: flex; - flex-flow: column; - height: calc(100% - 44px); - } -} - -.center-content, -.no-items, -.full-loading-spinner { - display: flex; - justify-content: center; - align-items: center; - height: 100%; - flex-direction: column; - flex-grow: 1; -} - -.no-items, -.full-loading-spinner { - text-align: center; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - - .no-items-image { - @include themify($themes) { - content: url("../images/search-desktop" + themed("svgSuffix")); - } - } - - .bwi { - margin-bottom: 10px; - - @include themify($themes) { - color: themed("disabledIconColor"); - } - } -} - -// cdk-virtual-scroll -.cdk-virtual-scroll-viewport { - width: 100%; - height: 100%; - overflow-y: auto; - overflow-x: hidden; -} - -.cdk-virtual-scroll-content-wrapper { - width: 100%; -} diff --git a/apps/browser/src/popup/scss/box.scss b/apps/browser/src/popup/scss/box.scss deleted file mode 100644 index 763f73a15cb..00000000000 --- a/apps/browser/src/popup/scss/box.scss +++ /dev/null @@ -1,620 +0,0 @@ -@import "variables.scss"; - -.box { - position: relative; - width: 100%; - - &.first { - margin-top: 0; - } - - .box-header { - margin: 0 10px 5px 10px; - text-transform: uppercase; - display: flex; - - @include themify($themes) { - color: themed("headingColor"); - } - } - - .box-content { - @include themify($themes) { - background-color: themed("backgroundColor"); - border-color: themed("borderColor"); - } - - &.box-content-padded { - padding: 10px 15px; - } - - &.condensed .box-content-row, - .box-content-row.condensed { - padding-top: 5px; - padding-bottom: 5px; - } - - &.no-hover .box-content-row, - .box-content-row.no-hover { - &:hover, - &:focus { - @include themify($themes) { - background-color: themed("boxBackgroundColor") !important; - } - } - } - - &.single-line .box-content-row, - .box-content-row.single-line { - padding-top: 10px; - padding-bottom: 10px; - margin: 5px; - } - - &.row-top-padding { - padding-top: 10px; - } - } - - .box-footer { - margin: 0 5px 5px 5px; - padding: 0 10px 5px 10px; - font-size: $font-size-small; - - button.btn { - font-size: $font-size-small; - padding: 0; - } - - button.btn.primary { - font-size: $font-size-base; - padding: 7px 15px; - width: 100%; - - &:hover { - @include themify($themes) { - border-color: themed("borderHoverColor") !important; - } - } - } - - @include themify($themes) { - color: themed("mutedColor"); - } - } - - &.list { - margin: 10px 0 20px 0; - .box-content { - .virtual-scroll-item { - display: inline-block; - width: 100%; - } - - .box-content-row { - text-decoration: none; - border-radius: $border-radius; - // background-color: $background-color; - - @include themify($themes) { - color: themed("textColor"); - background-color: themed("boxBackgroundColor"); - } - - &.padded { - padding-top: 10px; - padding-bottom: 10px; - } - - &.no-hover { - &:hover { - @include themify($themes) { - background-color: themed("boxBackgroundColor") !important; - } - } - } - - &:hover, - &:focus, - &.active { - @include themify($themes) { - background-color: themed("listItemBackgroundHoverColor"); - } - } - - &:focus { - border-left: 5px solid #000000; - padding-left: 5px; - - @include themify($themes) { - border-left-color: themed("mutedColor"); - } - } - - .action-buttons { - .row-btn { - padding-left: 5px; - padding-right: 5px; - } - } - - .text:not(.no-ellipsis), - .detail { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .row-main { - display: flex; - min-width: 0; - align-items: normal; - - .row-main-content { - min-width: 0; - } - } - } - - &.single-line { - .box-content-row { - display: flex; - padding-top: 10px; - padding-bottom: 10px; - margin: 5px; - border-radius: $border-radius; - } - } - } - } -} - -.box-content-row { - display: block; - padding: 5px 10px; - position: relative; - z-index: 1; - border-radius: $border-radius; - margin: 3px 5px; - - @include themify($themes) { - background-color: themed("boxBackgroundColor"); - } - - &:last-child { - &:before { - border: none; - height: 0; - } - } - - &.override-last:last-child:before { - border-bottom: 1px solid #000000; - @include themify($themes) { - border-bottom-color: themed("boxBorderColor"); - } - } - - &.last:last-child:before { - border-bottom: 1px solid #000000; - @include themify($themes) { - border-bottom-color: themed("boxBorderColor"); - } - } - - &:after { - content: ""; - display: table; - clear: both; - } - - &:hover, - &:focus, - &.active { - @include themify($themes) { - background-color: themed("boxBackgroundHoverColor"); - } - } - - &.pre { - white-space: pre; - overflow-x: auto; - } - - &.pre-wrap { - white-space: pre-wrap; - overflow-x: auto; - } - - .row-label, - label { - font-size: $font-size-small; - display: block; - width: 100%; - margin-bottom: 5px; - - @include themify($themes) { - color: themed("mutedColor"); - } - - .sub-label { - margin-left: 10px; - } - } - - .flex-label { - font-size: $font-size-small; - display: flex; - flex-grow: 1; - margin-bottom: 5px; - - @include themify($themes) { - color: themed("mutedColor"); - } - - > a { - flex-grow: 0; - } - } - - .text, - .detail { - display: block; - text-align: left; - - @include themify($themes) { - color: themed("textColor"); - } - } - - .detail { - font-size: $font-size-small; - - @include themify($themes) { - color: themed("mutedColor"); - } - } - - .img-right, - .txt-right { - float: right; - margin-left: 10px; - } - - .row-main { - flex-grow: 1; - min-width: 0; - } - - &.box-content-row-flex, - .box-content-row-flex, - &.box-content-row-checkbox, - &.box-content-row-link, - &.box-content-row-input, - &.box-content-row-slider, - &.box-content-row-multi { - display: flex; - align-items: center; - word-break: break-all; - - &.box-content-row-word-break { - word-break: normal; - } - } - - &.box-content-row-multi { - input:not([type="checkbox"]) { - width: 100%; - } - - input + label.sr-only + select { - margin-top: 5px; - } - - > a, - > button { - padding: 8px 8px 8px 4px; - margin: 0; - - @include themify($themes) { - color: themed("dangerColor"); - } - } - } - - &.box-content-row-multi, - &.box-content-row-newmulti { - padding-left: 10px; - } - - &.box-content-row-newmulti { - @include themify($themes) { - color: themed("primaryColor"); - } - } - - &.box-content-row-checkbox, - &.box-content-row-link, - &.box-content-row-input, - &.box-content-row-slider { - padding-top: 10px; - padding-bottom: 10px; - margin: 5px; - - label, - .row-label { - font-size: $font-size-base; - display: block; - width: initial; - margin-bottom: 0; - - @include themify($themes) { - color: themed("textColor"); - } - } - - > span { - @include themify($themes) { - color: themed("mutedColor"); - } - } - - > input { - margin: 0 0 0 auto; - padding: 0; - } - - > * { - margin-right: 15px; - - &:last-child { - margin-right: 0; - } - } - } - - &.box-content-row-checkbox-left { - justify-content: flex-start; - - > input { - margin: 0 15px 0 0; - } - } - - &.box-content-row-input { - label { - white-space: nowrap; - } - - input { - text-align: right; - - &[type="number"] { - max-width: 50px; - } - } - } - - &.box-content-row-slider { - input[type="range"] { - height: 10px; - } - - input[type="number"] { - width: 45px; - } - - label { - white-space: nowrap; - } - } - - input:not([type="checkbox"]):not([type="radio"]), - textarea { - border: none; - width: 100%; - background-color: transparent !important; - - &::-webkit-input-placeholder { - @include themify($themes) { - color: themed("inputPlaceholderColor"); - } - } - - &:not([type="file"]):focus { - outline: none; - } - } - - select { - width: 100%; - border: 1px solid #000000; - border-radius: $border-radius; - padding: 7px 4px; - - @include themify($themes) { - border-color: themed("inputBorderColor"); - } - } - - .action-buttons { - display: flex; - margin-left: 5px; - - &.action-buttons-fixed { - align-self: start; - margin-top: 2px; - } - - .row-btn { - cursor: pointer; - padding: 10px 8px; - background: none; - border: none; - - @include themify($themes) { - color: themed("boxRowButtonColor"); - } - - &:hover, - &:focus { - @include themify($themes) { - color: themed("boxRowButtonHoverColor"); - } - } - - &.disabled, - &[disabled] { - @include themify($themes) { - color: themed("disabledIconColor"); - opacity: themed("disabledBoxOpacity"); - } - - &:hover { - @include themify($themes) { - color: themed("disabledIconColor"); - opacity: themed("disabledBoxOpacity"); - } - } - cursor: default !important; - } - } - - &.no-pad .row-btn { - padding-top: 0; - padding-bottom: 0; - } - } - - &:not(.box-draggable-row) { - .action-buttons .row-btn:last-child { - margin-right: -3px; - } - } - - &.box-draggable-row { - &.box-content-row-checkbox { - input[type="checkbox"] + .drag-handle { - margin-left: 10px; - } - } - } - - .drag-handle { - cursor: move; - padding: 10px 2px 10px 8px; - user-select: none; - - @include themify($themes) { - color: themed("mutedColor"); - } - } - - &.cdk-drag-preview { - position: relative; - display: flex; - align-items: center; - opacity: 0.8; - - @include themify($themes) { - background-color: themed("boxBackgroundColor"); - } - } - - select.field-type { - margin: 5px 0 0 25px; - width: calc(100% - 25px); - } - - .icon { - display: flex; - justify-content: center; - align-items: center; - min-width: 34px; - margin-left: -5px; - - @include themify($themes) { - color: themed("mutedColor"); - } - - &.icon-small { - min-width: 25px; - } - - img { - border-radius: $border-radius; - max-height: 20px; - max-width: 20px; - } - } - - .progress { - display: flex; - height: 5px; - overflow: hidden; - margin: 5px -15px -10px; - - .progress-bar { - display: flex; - flex-direction: column; - justify-content: center; - white-space: nowrap; - background-color: $brand-primary; - } - } - - .radio-group { - display: flex; - justify-content: flex-start; - align-items: center; - margin-bottom: 5px; - - input { - flex-grow: 0; - } - - label { - margin: 0 0 0 5px; - flex-grow: 1; - font-size: $font-size-base; - display: block; - width: 100%; - - @include themify($themes) { - color: themed("textColor"); - } - } - - &.align-start { - align-items: start; - margin-top: 10px; - - label { - margin-top: -4px; - } - } - } -} - -.truncate { - display: inline-block; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -form { - .box { - .box-content { - .box-content-row { - &.no-hover { - &:hover { - @include themify($themes) { - background-color: themed("transparentColor") !important; - } - } - } - } - } - } -} diff --git a/apps/browser/src/popup/scss/buttons.scss b/apps/browser/src/popup/scss/buttons.scss deleted file mode 100644 index e9af536dc3d..00000000000 --- a/apps/browser/src/popup/scss/buttons.scss +++ /dev/null @@ -1,118 +0,0 @@ -@import "variables.scss"; - -.btn { - border-radius: $border-radius; - padding: 7px 15px; - border: 1px solid #000000; - font-size: $font-size-base; - text-align: center; - cursor: pointer; - - @include themify($themes) { - background-color: themed("buttonBackgroundColor"); - border-color: themed("buttonBorderColor"); - color: themed("buttonColor"); - } - - &.primary { - @include themify($themes) { - color: themed("buttonPrimaryColor"); - } - } - - &.danger { - @include themify($themes) { - color: themed("buttonDangerColor"); - } - } - - &.callout-half { - font-weight: bold; - max-width: 50%; - } - - &:hover:not([disabled]) { - cursor: pointer; - - @include themify($themes) { - background-color: darken(themed("buttonBackgroundColor"), 1.5%); - border-color: darken(themed("buttonBorderColor"), 17%); - color: darken(themed("buttonColor"), 10%); - } - - &.primary { - @include themify($themes) { - color: darken(themed("buttonPrimaryColor"), 6%); - } - } - - &.danger { - @include themify($themes) { - color: darken(themed("buttonDangerColor"), 6%); - } - } - } - - &:focus:not([disabled]) { - cursor: pointer; - outline: 0; - - @include themify($themes) { - background-color: darken(themed("buttonBackgroundColor"), 6%); - border-color: darken(themed("buttonBorderColor"), 25%); - } - } - - &[disabled] { - opacity: 0.65; - cursor: default !important; - } - - &.block { - display: block; - width: calc(100% - 10px); - margin: 0 auto; - } - - &.link, - &.neutral { - border: none !important; - background: none !important; - - &:focus { - text-decoration: underline; - } - } -} - -.action-buttons { - .btn { - &:focus { - outline: auto; - } - } -} - -button.box-content-row { - display: block; - width: calc(100% - 10px); - text-align: left; - border-color: none; - - @include themify($themes) { - background-color: themed("boxBackgroundColor"); - } -} - -button { - border: none; - background: transparent; - color: inherit; -} - -.login-buttons { - .btn.block { - width: 100%; - margin-bottom: 10px; - } -} diff --git a/apps/browser/src/popup/scss/environment.scss b/apps/browser/src/popup/scss/environment.scss deleted file mode 100644 index cd8f6379e2c..00000000000 --- a/apps/browser/src/popup/scss/environment.scss +++ /dev/null @@ -1,43 +0,0 @@ -@import "variables.scss"; - -html.browser_safari { - &.safari_height_fix { - body { - height: 360px !important; - - &.body-xs { - height: 300px !important; - } - - &.body-full { - height: 100% !important; - } - } - } - - header { - .search .bwi { - left: 20px; - } - - .left + .search .bwi { - left: 10px; - } - } - - .content { - &.login-page { - padding-top: 100px; - } - } - - app-root { - border-width: 1px; - border-style: solid; - border-color: #000000; - } - - &.theme_light app-root { - border-color: #777777; - } -} diff --git a/apps/browser/src/popup/scss/grid.scss b/apps/browser/src/popup/scss/grid.scss deleted file mode 100644 index 8cdb29bb52c..00000000000 --- a/apps/browser/src/popup/scss/grid.scss +++ /dev/null @@ -1,11 +0,0 @@ -.row { - display: flex; - margin: 0 -15px; - width: 100%; -} - -.col { - flex-basis: 0; - flex-grow: 1; - padding: 0 15px; -} diff --git a/apps/browser/src/popup/scss/misc.scss b/apps/browser/src/popup/scss/misc.scss deleted file mode 100644 index 006e1d35f6a..00000000000 --- a/apps/browser/src/popup/scss/misc.scss +++ /dev/null @@ -1,348 +0,0 @@ -@import "variables.scss"; - -small, -.small { - font-size: $font-size-small; -} - -.bg-primary { - @include themify($themes) { - background-color: themed("primaryColor") !important; - } -} - -.bg-success { - @include themify($themes) { - background-color: themed("successColor") !important; - } -} - -.bg-danger { - @include themify($themes) { - background-color: themed("dangerColor") !important; - } -} - -.bg-info { - @include themify($themes) { - background-color: themed("infoColor") !important; - } -} - -.bg-warning { - @include themify($themes) { - background-color: themed("warningColor") !important; - } -} - -.text-primary { - @include themify($themes) { - color: themed("primaryColor") !important; - } -} - -.text-success { - @include themify($themes) { - color: themed("successColor") !important; - } -} - -.text-muted { - @include themify($themes) { - color: themed("mutedColor") !important; - } -} - -.text-default { - @include themify($themes) { - color: themed("textColor") !important; - } -} - -.text-danger { - @include themify($themes) { - color: themed("dangerColor") !important; - } -} - -.text-info { - @include themify($themes) { - color: themed("infoColor") !important; - } -} - -.text-warning { - @include themify($themes) { - color: themed("warningColor") !important; - } -} - -.text-center { - text-align: center; -} - -.font-weight-semibold { - font-weight: 600; -} - -p.lead { - font-size: $font-size-large; - margin-bottom: 20px; - font-weight: normal; -} - -.flex-right { - margin-left: auto; -} - -.flex-bottom { - margin-top: auto; -} - -.no-margin { - margin: 0 !important; -} - -.display-block { - display: block !important; -} - -.monospaced { - font-family: $font-family-monospace; -} - -.show-whitespace { - white-space: pre-wrap; -} - -.img-responsive { - display: block; - max-width: 100%; - height: auto; -} - -.img-rounded { - border-radius: $border-radius; -} - -.select-index-top { - position: relative; - z-index: 100; -} - -.sr-only { - position: absolute !important; - width: 1px !important; - height: 1px !important; - padding: 0 !important; - margin: -1px !important; - overflow: hidden !important; - clip: rect(0, 0, 0, 0) !important; - border: 0 !important; -} - -:not(:focus) > .exists-only-on-parent-focus { - display: none; -} - -.password-wrapper { - overflow-wrap: break-word; - white-space: pre-wrap; - min-width: 0; -} - -.password-number { - @include themify($themes) { - color: themed("passwordNumberColor"); - } -} - -.password-special { - @include themify($themes) { - color: themed("passwordSpecialColor"); - } -} - -.password-character { - display: inline-flex; - flex-direction: column; - align-items: center; - width: 30px; - height: 36px; - font-weight: 600; - - &:nth-child(odd) { - @include themify($themes) { - background-color: themed("backgroundColor"); - } - } -} - -.password-count { - white-space: nowrap; - font-size: 8px; - - @include themify($themes) { - color: themed("passwordCountText") !important; - } -} - -#duo-frame { - background: url("../images/loading.svg") 0 0 no-repeat; - width: 100%; - height: 470px; - margin-bottom: -10px; - - iframe { - width: 100%; - height: 100%; - border: none; - } -} - -#web-authn-frame { - width: 100%; - height: 40px; - - iframe { - border: none; - height: 100%; - width: 100%; - } -} - -body.linux-webauthn { - width: 485px !important; - #web-authn-frame { - iframe { - width: 375px; - margin: 0 55px; - } - } -} - -app-root > #loading { - display: flex; - text-align: center; - justify-content: center; - align-items: center; - height: 100%; - width: 100%; - color: $text-muted; - - @include themify($themes) { - color: themed("mutedColor"); - } -} - -app-vault-icon, -.app-vault-icon { - display: flex; -} - -.logo-image { - margin: 0 auto; - width: 142px; - height: 21px; - background-size: 142px 21px; - background-repeat: no-repeat; - @include themify($themes) { - background-image: url("../images/logo-" + themed("logoSuffix") + "@2x.png"); - } - @media (min-width: 219px) { - width: 189px; - height: 28px; - background-size: 189px 28px; - } - @media (min-width: 314px) { - width: 284px; - height: 43px; - background-size: 284px 43px; - } -} - -[hidden] { - display: none !important; -} - -.draggable { - cursor: move; -} - -input[type="password"]::-ms-reveal { - display: none; -} - -.flex { - display: flex; - - &.flex-grow { - > * { - flex: 1; - } - } -} - -// Text selection styles -// Set explicit selection styles (assumes primary accent color has sufficient -// contrast against the background, so its inversion is also still readable) -// and suppress user selection for most elements (to make it more app-like) - -:not(bit-form-field input)::selection { - @include themify($themes) { - color: themed("backgroundColor"); - background-color: themed("primaryAccentColor"); - } -} - -h1, -h2, -h3, -label, -a, -button, -p, -img, -.box-header, -.box-footer, -.callout, -.row-label, -.modal-title, -.overlay-container { - user-select: none; - - &.user-select { - user-select: auto; - } -} - -/* tweak for inconsistent line heights in cipher view */ -.box-footer button, -.box-footer a { - line-height: 1; -} - -// Workaround for slow performance on external monitors on Chrome + MacOS -// See: https://bugs.chromium.org/p/chromium/issues/detail?id=971701#c64 -@keyframes redraw { - 0% { - opacity: 0.99; - } - 100% { - opacity: 1; - } -} -html.force_redraw { - animation: redraw 1s linear infinite; -} - -/* override for vault icon in browser (pre extension refresh) */ -app-vault-icon:not(app-vault-list-items-container app-vault-icon) > div { - display: flex; - justify-content: center; - align-items: center; - float: left; - height: 36px; - width: 34px; - margin-left: -5px; -} diff --git a/apps/browser/src/popup/scss/pages.scss b/apps/browser/src/popup/scss/pages.scss deleted file mode 100644 index 56c5f80c86c..00000000000 --- a/apps/browser/src/popup/scss/pages.scss +++ /dev/null @@ -1,144 +0,0 @@ -@import "variables.scss"; - -app-home { - position: fixed; - height: 100%; - width: 100%; - - .center-content { - margin-top: -50px; - height: calc(100% + 50px); - } - - img { - width: 284px; - margin: 0 auto; - } - - p.lead { - margin: 30px 0; - } - - .btn + .btn { - margin-top: 10px; - } - - button.settings-icon { - position: absolute; - top: 10px; - left: 10px; - - @include themify($themes) { - color: themed("mutedColor"); - } - - &:not(:hover):not(:focus) { - span { - clip: rect(0 0 0 0); - clip-path: inset(50%); - height: 1px; - overflow: hidden; - position: absolute; - white-space: nowrap; - width: 1px; - } - } - - &:hover, - &:focus { - text-decoration: none; - - @include themify($themes) { - color: themed("primaryColor"); - } - } - } -} - -body.body-sm, -body.body-xs { - app-home { - .center-content { - margin-top: 0; - height: 100%; - } - - p.lead { - margin: 15px 0; - } - } -} - -body.body-full { - app-home { - .center-content { - margin-top: -80px; - height: calc(100% + 80px); - } - } -} - -.createAccountLink { - padding: 30px 10px 0 10px; -} - -.remember-email-check { - padding-top: 18px; - padding-left: 10px; - padding-bottom: 18px; -} - -.login-buttons > button { - margin: 15px 0 15px 0; -} - -.useBrowserlink { - margin-left: 5px; - margin-top: 20px; - - span { - font-weight: 700; - font-size: $font-size-small; - } -} - -.fido2-browser-selector-dropdown { - @include themify($themes) { - background-color: themed("boxBackgroundColor"); - } - padding: 8px; - width: 100%; - box-shadow: - 0 2px 2px 0 rgba(0, 0, 0, 0.14), - 0 3px 1px -2px rgba(0, 0, 0, 0.12), - 0 1px 5px 0 rgba(0, 0, 0, 0.2); - border-radius: $border-radius; -} - -.fido2-browser-selector-dropdown-item { - @include themify($themes) { - color: themed("textColor") !important; - } - width: 100%; - text-align: left; - padding: 0px 15px 0px 5px; - margin-bottom: 5px; - border-radius: 3px; - border: 1px solid transparent; - transition: all 0.2s ease-in-out; - - &:hover { - @include themify($themes) { - background-color: themed("listItemBackgroundHoverColor") !important; - } - } - - &:last-child { - margin-bottom: 0; - } -} - -/** Temporary fix for avatar, will not be required once we migrate to tailwind preflight **/ -bit-avatar svg { - display: block; -} diff --git a/apps/browser/src/popup/scss/plugins.scss b/apps/browser/src/popup/scss/plugins.scss deleted file mode 100644 index 591e8a1bd0c..00000000000 --- a/apps/browser/src/popup/scss/plugins.scss +++ /dev/null @@ -1,23 +0,0 @@ -@import "variables.scss"; - -@each $mfaType in $mfaTypes { - .mfaType#{$mfaType} { - content: url("../images/two-factor/" + $mfaType + ".png"); - max-width: 100px; - } -} - -.mfaType1 { - @include themify($themes) { - content: url("../images/two-factor/1" + themed("mfaLogoSuffix")); - max-width: 100px; - max-height: 45px; - } -} - -.mfaType7 { - @include themify($themes) { - content: url("../images/two-factor/7" + themed("mfaLogoSuffix")); - max-width: 100px; - } -} diff --git a/apps/browser/src/popup/scss/popup.scss b/apps/browser/src/popup/scss/popup.scss index b150de2c75d..59b4d472f23 100644 --- a/apps/browser/src/popup/scss/popup.scss +++ b/apps/browser/src/popup/scss/popup.scss @@ -1,13 +1,50 @@ @import "../../../../../libs/angular/src/scss/bwicons/styles/style.scss"; @import "variables.scss"; @import "../../../../../libs/angular/src/scss/icons.scss"; -@import "base.scss"; -@import "grid.scss"; -@import "box.scss"; -@import "buttons.scss"; -@import "misc.scss"; -@import "environment.scss"; -@import "pages.scss"; -@import "plugins.scss"; @import "@angular/cdk/overlay-prebuilt.css"; @import "../../../../../libs/components/src/multi-select/scss/bw.theme"; + +.cdk-virtual-scroll-content-wrapper { + width: 100%; +} + +// MFA Types for logo styling with no dark theme alternative +$mfaTypes: 0, 2, 3, 4, 6; + +@each $mfaType in $mfaTypes { + .mfaType#{$mfaType} { + content: url("../images/two-factor/" + $mfaType + ".png"); + max-width: 100px; + } +} + +.mfaType0 { + content: url("../images/two-factor/0.png"); + max-width: 100px; + max-height: 45px; +} + +.mfaType1 { + max-width: 100px; + max-height: 45px; + + &:is(.theme_light *) { + content: url("../images/two-factor/1.png"); + } + + &:is(.theme_dark *) { + content: url("../images/two-factor/1-w.png"); + } +} + +.mfaType7 { + max-width: 100px; + + &:is(.theme_light *) { + content: url("../images/two-factor/7.png"); + } + + &:is(.theme_dark *) { + content: url("../images/two-factor/7-w.png"); + } +} diff --git a/apps/browser/src/popup/scss/tailwind.css b/apps/browser/src/popup/scss/tailwind.css index 54139990356..f58950cc86a 100644 --- a/apps/browser/src/popup/scss/tailwind.css +++ b/apps/browser/src/popup/scss/tailwind.css @@ -1,4 +1,104 @@ -@import "../../../../../libs/components/src/tw-theme.css"; +@import "../../../../../libs/components/src/tw-theme-preflight.css"; + +@layer base { + html { + overflow: hidden; + min-height: 600px; + height: 100%; + + &.body-sm { + min-height: 500px; + } + + &.body-xs { + min-height: 400px; + } + + &.body-xxs { + min-height: 300px; + } + + &.body-3xs { + min-height: 240px; + } + + &.body-full { + min-height: unset; + width: 100%; + height: 100%; + + & body { + width: 100%; + } + } + } + + html.browser_safari { + &.safari_height_fix { + body { + height: 360px !important; + + &.body-xs { + height: 300px !important; + } + + &.body-full { + height: 100% !important; + } + } + } + + app-root { + border-width: 1px; + border-style: solid; + border-color: #000000; + } + + &.theme_light app-root { + border-color: #777777; + } + } + + body { + width: 380px; + height: 100%; + position: relative; + min-height: inherit; + overflow: hidden; + @apply tw-bg-background-alt; + } + + /** + * Workaround for slow performance on external monitors on Chrome + MacOS + * See: https://bugs.chromium.org/p/chromium/issues/detail?id=971701#c64 + */ + @keyframes redraw { + 0% { + opacity: 0.99; + } + 100% { + opacity: 1; + } + } + html.force_redraw { + animation: redraw 1s linear infinite; + } + + /** + * Text selection style: + * suppress user selection for most elements (to make it more app-like) + */ + h1, + h2, + h3, + label, + a, + button, + p, + img { + user-select: none; + } +} @layer components { /** Safari Support */ @@ -19,4 +119,59 @@ html:not(.browser_safari) .tw-styled-scrollbar { scrollbar-color: rgb(var(--color-secondary-500)) rgb(var(--color-background-alt)); } + + #duo-frame { + background: url("../images/loading.svg") 0 0 no-repeat; + width: 100%; + height: 470px; + margin-bottom: -10px; + + iframe { + width: 100%; + height: 100%; + border: none; + } + } + + #web-authn-frame { + width: 100%; + height: 40px; + + iframe { + border: none; + height: 100%; + width: 100%; + } + } + + body.linux-webauthn { + width: 485px !important; + #web-authn-frame { + iframe { + width: 375px; + margin: 0 55px; + } + } + } + + app-root > #loading { + display: flex; + text-align: center; + justify-content: center; + align-items: center; + height: 100%; + width: 100%; + + @apply tw-text-muted; + } + + /** + * Text selection style: + * Set explicit selection styles (assumes primary accent color has sufficient + * contrast against the background, so its inversion is also still readable) + */ + :not(bit-form-field input)::selection { + @apply tw-text-contrast; + @apply tw-bg-primary-700; + } } diff --git a/apps/browser/src/popup/scss/variables.scss b/apps/browser/src/popup/scss/variables.scss index e57e98fd0cc..02a10521bca 100644 --- a/apps/browser/src/popup/scss/variables.scss +++ b/apps/browser/src/popup/scss/variables.scss @@ -1,178 +1,42 @@ -$dark-icon-themes: "theme_dark"; +/** + * DEPRECATED: DO NOT MODIFY OR USE! + */ + +$dark-icon-themes: "theme_dark"; $font-family-sans-serif: Inter, "Helvetica Neue", Helvetica, Arial, sans-serif; $font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace; -$font-size-base: 16px; -$font-size-large: 18px; -$font-size-xlarge: 22px; -$font-size-xxlarge: 28px; -$font-size-small: 12px; $text-color: #000000; -$border-color: #f0f0f0; $border-color-dark: #ddd; -$list-item-hover: #fbfbfb; -$list-icon-color: #767679; -$disabled-box-opacity: 1; -$border-radius: 6px; -$line-height-base: 1.42857143; -$icon-hover-color: lighten($text-color, 50%); - -$mfaTypes: 0, 2, 3, 4, 6; - -$gray: #555; -$gray-light: #777; -$text-muted: $gray-light; - $brand-primary: #175ddc; -$brand-danger: #c83522; $brand-success: #017e45; -$brand-info: #555555; -$brand-warning: #8b6609; -$brand-primary-accent: #1252a3; - $background-color: #f0f0f0; - -$box-background-color: white; -$box-background-hover-color: $list-item-hover; -$box-border-color: $border-color; -$border-color-alt: #c3c5c7; - -$button-border-color: darken($border-color-dark, 12%); -$button-background-color: white; -$button-color: lighten($text-color, 40%); $button-color-primary: darken($brand-primary, 8%); -$button-color-danger: darken($brand-danger, 10%); - -$code-color: #c01176; -$code-color-dark: #f08dc7; $themes: ( light: ( textColor: $text-color, - hoverColorTransparent: rgba($text-color, 0.15), borderColor: $border-color-dark, backgroundColor: $background-color, - borderColorAlt: $border-color-alt, - backgroundColorAlt: #ffffff, - scrollbarColor: rgba(100, 100, 100, 0.2), - scrollbarHoverColor: rgba(100, 100, 100, 0.4), - boxBackgroundColor: $box-background-color, - boxBackgroundHoverColor: $box-background-hover-color, - boxBorderColor: $box-border-color, - tabBackgroundColor: #ffffff, - tabBackgroundHoverColor: $list-item-hover, - headerColor: #ffffff, - headerBackgroundColor: $brand-primary, - headerBackgroundHoverColor: rgba(255, 255, 255, 0.1), - headerBorderColor: $brand-primary, - headerInputBackgroundColor: darken($brand-primary, 8%), - headerInputBackgroundFocusColor: darken($brand-primary, 10%), - headerInputColor: #ffffff, - headerInputPlaceholderColor: lighten($brand-primary, 35%), - listItemBackgroundHoverColor: $list-item-hover, - disabledIconColor: $list-icon-color, - disabledBoxOpacity: $disabled-box-opacity, - headingColor: $gray-light, - labelColor: $gray-light, - mutedColor: $text-muted, - totpStrokeColor: $brand-primary, - boxRowButtonColor: $brand-primary, - boxRowButtonHoverColor: darken($brand-primary, 10%), inputBorderColor: darken($border-color-dark, 7%), inputBackgroundColor: #ffffff, - inputPlaceholderColor: lighten($gray-light, 35%), - buttonBackgroundColor: $button-background-color, - buttonBorderColor: $button-border-color, - buttonColor: $button-color, buttonPrimaryColor: $button-color-primary, - buttonDangerColor: $button-color-danger, primaryColor: $brand-primary, - primaryAccentColor: $brand-primary-accent, - dangerColor: $brand-danger, successColor: $brand-success, - infoColor: $brand-info, - warningColor: $brand-warning, - logoSuffix: "dark", - mfaLogoSuffix: ".png", passwordNumberColor: #007fde, passwordSpecialColor: #c40800, - passwordCountText: #212529, - calloutBorderColor: $border-color-dark, - calloutBackgroundColor: $box-background-color, - toastTextColor: #ffffff, - svgSuffix: "-light.svg", - transparentColor: rgba(0, 0, 0, 0), - dateInputColorScheme: light, - // https://stackoverflow.com/a/53336754 - webkitCalendarPickerFilter: invert(46%) sepia(69%) saturate(6397%) hue-rotate(211deg) - brightness(85%) contrast(103%), - // light has no hover so use same color - webkitCalendarPickerHoverFilter: invert(46%) sepia(69%) saturate(6397%) hue-rotate(211deg) - brightness(85%) contrast(103%), - codeColor: $code-color, ), dark: ( textColor: #ffffff, - hoverColorTransparent: rgba($text-color, 0.15), borderColor: #161c26, backgroundColor: #161c26, - borderColorAlt: #6e788a, - backgroundColorAlt: #2f343d, - scrollbarColor: #6e788a, - scrollbarHoverColor: #8d94a5, - boxBackgroundColor: #2f343d, - boxBackgroundHoverColor: #3c424e, - boxBorderColor: #4c525f, - tabBackgroundColor: #2f343d, - tabBackgroundHoverColor: #3c424e, - headerColor: #ffffff, - headerBackgroundColor: #2f343d, - headerBackgroundHoverColor: #3c424e, - headerBorderColor: #161c26, - headerInputBackgroundColor: #3c424e, - headerInputBackgroundFocusColor: #4c525f, - headerInputColor: #ffffff, - headerInputPlaceholderColor: #bac0ce, - listItemBackgroundHoverColor: #3c424e, - disabledIconColor: #bac0ce, - disabledBoxOpacity: 0.5, - headingColor: #bac0ce, - labelColor: #bac0ce, - mutedColor: #bac0ce, - totpStrokeColor: #4c525f, - boxRowButtonColor: #bac0ce, - boxRowButtonHoverColor: #ffffff, inputBorderColor: #4c525f, inputBackgroundColor: #2f343d, - inputPlaceholderColor: #bac0ce, - buttonBackgroundColor: #3c424e, - buttonBorderColor: #4c525f, - buttonColor: #bac0ce, buttonPrimaryColor: #6f9df1, - buttonDangerColor: #ff8d85, primaryColor: #6f9df1, - primaryAccentColor: #6f9df1, - dangerColor: #ff8d85, successColor: #52e07c, - infoColor: #a4b0c6, - warningColor: #ffeb66, - logoSuffix: "white", - mfaLogoSuffix: "-w.png", passwordNumberColor: #6f9df1, passwordSpecialColor: #ff8d85, - passwordCountText: #ffffff, - calloutBorderColor: #4c525f, - calloutBackgroundColor: #3c424e, - toastTextColor: #1f242e, - svgSuffix: "-dark.svg", - transparentColor: rgba(0, 0, 0, 0), - dateInputColorScheme: dark, - // https://stackoverflow.com/a/53336754 - must prepend brightness(0) saturate(100%) to dark themed date inputs - webkitCalendarPickerFilter: brightness(0) saturate(100%) invert(86%) sepia(19%) saturate(152%) - hue-rotate(184deg) brightness(87%) contrast(93%), - webkitCalendarPickerHoverFilter: brightness(0) saturate(100%) invert(100%) sepia(0%) - saturate(0%) hue-rotate(93deg) brightness(103%) contrast(103%), - codeColor: $code-color-dark, ), ); diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index c462319dc2e..739166ff6f8 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -41,6 +41,7 @@ import { import { ExtensionNewDeviceVerificationComponentService } from "@bitwarden/browser/auth/services/new-device-verification/extension-new-device-verification-component.service"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { EventCollectionService as EventCollectionServiceAbstraction } from "@bitwarden/common/abstractions/event/event-collection.service"; +import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService, @@ -67,6 +68,8 @@ import { UserNotificationSettingsServiceAbstraction, } from "@bitwarden/common/autofill/services/user-notification-settings.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; +import { PhishingDetectionSettingsServiceAbstraction } from "@bitwarden/common/dirt/services/abstractions/phishing-detection-settings.service.abstraction"; +import { PhishingDetectionSettingsService } from "@bitwarden/common/dirt/services/phishing-detection/phishing-detection-settings.service"; import { ClientType } from "@bitwarden/common/enums"; import { KeyGenerationService } from "@bitwarden/common/key-management/crypto"; import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; @@ -76,6 +79,7 @@ import { InternalMasterPasswordServiceAbstraction, MasterPasswordServiceAbstraction, } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; +import { SessionTimeoutTypeService } from "@bitwarden/common/key-management/session-timeout"; import { VaultTimeoutService, VaultTimeoutStringType, @@ -135,6 +139,7 @@ import { DialogService, ToastService, } from "@bitwarden/components"; +import { GeneratorServicesModule } from "@bitwarden/generator-components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { BiometricsService, @@ -170,6 +175,7 @@ import { InlineMenuFieldQualificationService } from "../../autofill/services/inl import { ForegroundBrowserBiometricsService } from "../../key-management/biometrics/foreground-browser-biometrics"; import { ExtensionLockComponentService } from "../../key-management/lock/services/extension-lock-component.service"; import { BrowserSessionTimeoutSettingsComponentService } from "../../key-management/session-timeout/services/browser-session-timeout-settings-component.service"; +import { BrowserSessionTimeoutTypeService } from "../../key-management/session-timeout/services/browser-session-timeout-type.service"; import { ForegroundVaultTimeoutService } from "../../key-management/vault-timeout/foreground-vault-timeout.service"; import { BrowserActionsService } from "../../platform/actions/browser-actions.service"; import { BrowserApi } from "../../platform/browser/browser-api"; @@ -509,6 +515,18 @@ const safeProviders: SafeProvider[] = [ useClass: UserNotificationSettingsService, deps: [StateProvider], }), + safeProvider({ + provide: PhishingDetectionSettingsServiceAbstraction, + useClass: PhishingDetectionSettingsService, + deps: [ + AccountService, + BillingAccountProfileStateService, + ConfigService, + OrganizationService, + PlatformUtilsService, + StateProvider, + ], + }), safeProvider({ provide: MessageListener, useFactory: (subject: Subject>>, ngZone: NgZone) => @@ -723,15 +741,25 @@ const safeProviders: SafeProvider[] = [ useClass: ExtensionNewDeviceVerificationComponentService, deps: [], }), + safeProvider({ + provide: SessionTimeoutTypeService, + useClass: BrowserSessionTimeoutTypeService, + deps: [PlatformUtilsService], + }), safeProvider({ provide: SessionTimeoutSettingsComponentService, useClass: BrowserSessionTimeoutSettingsComponentService, - deps: [I18nServiceAbstraction, PlatformUtilsService, MessagingServiceAbstraction], + deps: [ + I18nServiceAbstraction, + SessionTimeoutTypeService, + PolicyService, + MessagingServiceAbstraction, + ], }), ]; @NgModule({ - imports: [JslibServicesModule], + imports: [JslibServicesModule, GeneratorServicesModule], declarations: [], // Do not register your dependency here! Add it to the typesafeProviders array using the helper function providers: safeProviders, diff --git a/apps/browser/src/tools/popup/guards/firefox-popout.guard.spec.ts b/apps/browser/src/tools/popup/guards/firefox-popout.guard.spec.ts new file mode 100644 index 00000000000..df04b965d4c --- /dev/null +++ b/apps/browser/src/tools/popup/guards/firefox-popout.guard.spec.ts @@ -0,0 +1,194 @@ +import { TestBed } from "@angular/core/testing"; +import { ActivatedRouteSnapshot, RouterStateSnapshot } from "@angular/router"; + +import { DeviceType } from "@bitwarden/common/enums"; + +import { BrowserApi } from "../../../platform/browser/browser-api"; +import BrowserPopupUtils from "../../../platform/browser/browser-popup-utils"; +import { BrowserPlatformUtilsService } from "../../../platform/services/platform-utils/browser-platform-utils.service"; + +import { firefoxPopoutGuard } from "./firefox-popout.guard"; + +describe("firefoxPopoutGuard", () => { + let getDeviceSpy: jest.SpyInstance; + let inPopoutSpy: jest.SpyInstance; + let inSidebarSpy: jest.SpyInstance; + let openPopoutSpy: jest.SpyInstance; + let closePopupSpy: jest.SpyInstance; + + const mockRoute = {} as ActivatedRouteSnapshot; + const mockState: RouterStateSnapshot = { + url: "/import?param=value", + } as RouterStateSnapshot; + + beforeEach(() => { + getDeviceSpy = jest.spyOn(BrowserPlatformUtilsService, "getDevice"); + inPopoutSpy = jest.spyOn(BrowserPopupUtils, "inPopout"); + inSidebarSpy = jest.spyOn(BrowserPopupUtils, "inSidebar"); + openPopoutSpy = jest.spyOn(BrowserPopupUtils, "openPopout").mockImplementation(); + closePopupSpy = jest.spyOn(BrowserApi, "closePopup").mockImplementation(); + + TestBed.configureTestingModule({}); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe("when browser is Firefox", () => { + beforeEach(() => { + getDeviceSpy.mockReturnValue(DeviceType.FirefoxExtension); + inPopoutSpy.mockReturnValue(false); + inSidebarSpy.mockReturnValue(false); + }); + + it("should open popout and block navigation when not already in popout or sidebar", async () => { + const guard = firefoxPopoutGuard(); + const result = await TestBed.runInInjectionContext(() => guard(mockRoute, mockState)); + + expect(getDeviceSpy).toHaveBeenCalledWith(window); + expect(inPopoutSpy).toHaveBeenCalledWith(window); + expect(inSidebarSpy).toHaveBeenCalledWith(window); + expect(openPopoutSpy).toHaveBeenCalledWith("popup/index.html#/import?param=value"); + expect(closePopupSpy).toHaveBeenCalledWith(window); + expect(result).toBe(false); + }); + + it("should not add autoClosePopout parameter to the url", async () => { + const guard = firefoxPopoutGuard(); + await TestBed.runInInjectionContext(() => guard(mockRoute, mockState)); + + expect(openPopoutSpy).toHaveBeenCalledWith("popup/index.html#/import?param=value"); + expect(openPopoutSpy).not.toHaveBeenCalledWith(expect.stringContaining("autoClosePopout")); + }); + + it("should allow navigation when already in popout", async () => { + inPopoutSpy.mockReturnValue(true); + + const guard = firefoxPopoutGuard(); + const result = await TestBed.runInInjectionContext(() => guard(mockRoute, mockState)); + + expect(openPopoutSpy).not.toHaveBeenCalled(); + expect(closePopupSpy).not.toHaveBeenCalled(); + expect(result).toBe(true); + }); + + it("should allow navigation when already in sidebar", async () => { + inSidebarSpy.mockReturnValue(true); + + const guard = firefoxPopoutGuard(); + const result = await TestBed.runInInjectionContext(() => guard(mockRoute, mockState)); + + expect(openPopoutSpy).not.toHaveBeenCalled(); + expect(closePopupSpy).not.toHaveBeenCalled(); + expect(result).toBe(true); + }); + }); + + describe("when browser is not Firefox", () => { + beforeEach(() => { + inPopoutSpy.mockReturnValue(false); + inSidebarSpy.mockReturnValue(false); + }); + + it.each([ + { deviceType: DeviceType.ChromeExtension, name: "ChromeExtension" }, + { deviceType: DeviceType.EdgeExtension, name: "EdgeExtension" }, + { deviceType: DeviceType.OperaExtension, name: "OperaExtension" }, + { deviceType: DeviceType.SafariExtension, name: "SafariExtension" }, + { deviceType: DeviceType.VivaldiExtension, name: "VivaldiExtension" }, + ])( + "should allow navigation without opening popout when device is $name", + async ({ deviceType }) => { + getDeviceSpy.mockReturnValue(deviceType); + + const guard = firefoxPopoutGuard(); + const result = await TestBed.runInInjectionContext(() => guard(mockRoute, mockState)); + + expect(getDeviceSpy).toHaveBeenCalledWith(window); + expect(openPopoutSpy).not.toHaveBeenCalled(); + expect(closePopupSpy).not.toHaveBeenCalled(); + expect(result).toBe(true); + }, + ); + }); + + describe("file picker routes", () => { + beforeEach(() => { + getDeviceSpy.mockReturnValue(DeviceType.FirefoxExtension); + inPopoutSpy.mockReturnValue(false); + inSidebarSpy.mockReturnValue(false); + }); + + it("should open popout for /import route", async () => { + const importState: RouterStateSnapshot = { + url: "/import", + } as RouterStateSnapshot; + + const guard = firefoxPopoutGuard(); + const result = await TestBed.runInInjectionContext(() => guard(mockRoute, importState)); + + expect(openPopoutSpy).toHaveBeenCalledWith("popup/index.html#/import"); + expect(closePopupSpy).toHaveBeenCalledWith(window); + expect(result).toBe(false); + }); + + it("should open popout for /add-send route", async () => { + const addSendState: RouterStateSnapshot = { + url: "/add-send", + } as RouterStateSnapshot; + + const guard = firefoxPopoutGuard(); + const result = await TestBed.runInInjectionContext(() => guard(mockRoute, addSendState)); + + expect(openPopoutSpy).toHaveBeenCalledWith("popup/index.html#/add-send"); + expect(closePopupSpy).toHaveBeenCalledWith(window); + expect(result).toBe(false); + }); + + it("should open popout for /edit-send route", async () => { + const editSendState: RouterStateSnapshot = { + url: "/edit-send", + } as RouterStateSnapshot; + + const guard = firefoxPopoutGuard(); + const result = await TestBed.runInInjectionContext(() => guard(mockRoute, editSendState)); + + expect(openPopoutSpy).toHaveBeenCalledWith("popup/index.html#/edit-send"); + expect(closePopupSpy).toHaveBeenCalledWith(window); + expect(result).toBe(false); + }); + }); + + describe("url handling", () => { + beforeEach(() => { + getDeviceSpy.mockReturnValue(DeviceType.FirefoxExtension); + inPopoutSpy.mockReturnValue(false); + inSidebarSpy.mockReturnValue(false); + }); + + it("should preserve query parameters in the popout url", async () => { + const stateWithQuery: RouterStateSnapshot = { + url: "/import?foo=bar&baz=qux", + } as RouterStateSnapshot; + + const guard = firefoxPopoutGuard(); + await TestBed.runInInjectionContext(() => guard(mockRoute, stateWithQuery)); + + expect(openPopoutSpy).toHaveBeenCalledWith("popup/index.html#/import?foo=bar&baz=qux"); + expect(closePopupSpy).toHaveBeenCalledWith(window); + }); + + it("should handle urls without query parameters", async () => { + const stateWithoutQuery: RouterStateSnapshot = { + url: "/simple-path", + } as RouterStateSnapshot; + + const guard = firefoxPopoutGuard(); + await TestBed.runInInjectionContext(() => guard(mockRoute, stateWithoutQuery)); + + expect(openPopoutSpy).toHaveBeenCalledWith("popup/index.html#/simple-path"); + expect(closePopupSpy).toHaveBeenCalledWith(window); + }); + }); +}); diff --git a/apps/browser/src/tools/popup/guards/firefox-popout.guard.ts b/apps/browser/src/tools/popup/guards/firefox-popout.guard.ts new file mode 100644 index 00000000000..821f1b7a5bc --- /dev/null +++ b/apps/browser/src/tools/popup/guards/firefox-popout.guard.ts @@ -0,0 +1,38 @@ +import { ActivatedRouteSnapshot, CanActivateFn, RouterStateSnapshot } from "@angular/router"; + +import { BrowserApi } from "@bitwarden/browser/platform/browser/browser-api"; +import BrowserPopupUtils from "@bitwarden/browser/platform/browser/browser-popup-utils"; +import { BrowserPlatformUtilsService } from "@bitwarden/browser/platform/services/platform-utils/browser-platform-utils.service"; +import { DeviceType } from "@bitwarden/common/enums"; + +/** + * Guard that forces a popout window on Firefox browser when a file picker could be exposed. + * Necessary to avoid a crash: https://bugzilla.mozilla.org/show_bug.cgi?id=1292701 + * Also disallows the user from closing a popout and re-opening the view exposing the file picker. + * + * @returns CanActivateFn that opens popout and blocks navigation on Firefox + */ +export function firefoxPopoutGuard(): CanActivateFn { + return async (_route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + // Check if browser is Firefox using the platform utils service + const deviceType = BrowserPlatformUtilsService.getDevice(window); + const isFirefox = deviceType === DeviceType.FirefoxExtension; + + // Check if already in popout/sidebar + const inPopout = BrowserPopupUtils.inPopout(window); + const inSidebar = BrowserPopupUtils.inSidebar(window); + + // Open popout if on Firefox and not already in popout/sidebar + if (isFirefox && !inPopout && !inSidebar) { + // Don't add autoClosePopout for file picker scenarios - user should manually close + await BrowserPopupUtils.openPopout(`popup/index.html#${state.url}`); + + // Close the original popup window + BrowserApi.closePopup(window); + + return false; // Block navigation - popout will reload + } + + return true; // Allow navigation + }; +} diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts b/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts index 6d79f430a37..6e73d9811f2 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts @@ -16,6 +16,7 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { mockAccountInfoWith } from "@bitwarden/common/spec"; import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; import { SendView } from "@bitwarden/common/tools/send/models/view/send.view"; import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; @@ -96,9 +97,10 @@ describe("SendV2Component", () => { useValue: { activeAccount$: of({ id: "123", - email: "test@email.com", - emailVerified: true, - name: "Test User", + ...mockAccountInfoWith({ + email: "test@email.com", + name: "Test User", + }), }), }, }, diff --git a/apps/browser/src/tools/popup/settings/export/export-browser-v2.component.html b/apps/browser/src/tools/popup/settings/export/export-browser-v2.component.html index d6bf3a3a253..36c84d9b788 100644 --- a/apps/browser/src/tools/popup/settings/export/export-browser-v2.component.html +++ b/apps/browser/src/tools/popup/settings/export/export-browser-v2.component.html @@ -1,5 +1,5 @@ - + @@ -21,7 +21,7 @@ bitFormButton buttonType="primary" > - {{ "exportVault" | i18n }} + {{ "exportVerb" | i18n }} diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts index 871163ac80b..1da2d352c14 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts @@ -1,4 +1,4 @@ -import { Component, Input } from "@angular/core"; +import { Component, input, ChangeDetectionStrategy } from "@angular/core"; import { ComponentFixture, TestBed, fakeAsync, tick } from "@angular/core/testing"; import { By } from "@angular/platform-browser"; import { ActivatedRoute, Router } from "@angular/router"; @@ -25,31 +25,23 @@ import { PopupRouterCacheService } from "../../../../../platform/popup/view-cach import { AttachmentsV2Component } from "./attachments-v2.component"; -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "popup-header", template: ``, + changeDetection: ChangeDetectionStrategy.OnPush, }) class MockPopupHeaderComponent { - // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals - // eslint-disable-next-line @angular-eslint/prefer-signals - @Input() pageTitle: string; - // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals - // eslint-disable-next-line @angular-eslint/prefer-signals - @Input() backAction: () => void; + readonly pageTitle = input(); + readonly backAction = input<() => void>(); } -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "popup-footer", template: ``, + changeDetection: ChangeDetectionStrategy.OnPush, }) class MockPopupFooterComponent { - // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals - // eslint-disable-next-line @angular-eslint/prefer-signals - @Input() pageTitle: string; + readonly pageTitle = input(); } describe("AttachmentsV2Component", () => { @@ -120,7 +112,7 @@ describe("AttachmentsV2Component", () => { const submitBtn = fixture.debugElement.queryAll(By.directive(ButtonComponent))[1] .componentInstance; - expect(cipherAttachment.submitBtn).toEqual(submitBtn); + expect(cipherAttachment.submitBtn()).toEqual(submitBtn); }); it("navigates the user to the edit view `onUploadSuccess`", fakeAsync(() => { diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts index 295496c701f..29282d293de 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts @@ -51,6 +51,6 @@ export class AttachmentsV2Component { /** Navigate the user back to the edit screen after uploading an attachment */ async navigateBack() { - await this.popupRouterCacheService.back(); + await this.popupRouterCacheService.back(true); } } diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts index 459b328c44e..e9636e09873 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts @@ -11,6 +11,7 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs import { ProductTierType } from "@bitwarden/common/billing/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { mockAccountInfoWith } from "@bitwarden/common/spec"; import { CipherId, OrganizationId, UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service"; @@ -60,9 +61,10 @@ describe("OpenAttachmentsComponent", () => { const accountService = { activeAccount$: of({ id: mockUserId, - email: "test@email.com", - emailVerified: true, - name: "Test User", + ...mockAccountInfoWith({ + email: "test@email.com", + name: "Test User", + }), }), }; const formStatusChange$ = new BehaviorSubject<"enabled" | "disabled">("enabled"); diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.spec.ts index 577b7d96771..b9f48b7407b 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.spec.ts @@ -108,7 +108,7 @@ describe("ItemMoreOptionsComponent", () => { { provide: RestrictedItemTypesService, useValue: { restricted$: of([]) } }, { provide: CipherArchiveService, - useValue: { userCanArchive$: () => of(true), hasArchiveFlagEnabled$: () => of(true) }, + useValue: { userCanArchive$: () => of(true), hasArchiveFlagEnabled$: of(true) }, }, { provide: ToastService, useValue: { showToast: () => {} } }, { provide: Router, useValue: { navigate: () => Promise.resolve(true) } }, diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts index 4dfaf7bc66f..b65acc6ca8e 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts @@ -141,7 +141,7 @@ export class ItemMoreOptionsComponent { }), ); - protected showArchive$: Observable = this.cipherArchiveService.hasArchiveFlagEnabled$(); + protected showArchive$: Observable = this.cipherArchiveService.hasArchiveFlagEnabled$; protected canArchive$: Observable = this.accountService.activeAccount$.pipe( getUserId, diff --git a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html index 7dd0a5a3bc7..fa8683c12dc 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html @@ -1,5 +1,5 @@ - diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html index 347c5fe6286..6382b5fee0e 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html @@ -108,7 +108,7 @@
- + { const nudgesSvc = { showNudgeSpotlight$: jest.fn().mockImplementation((_type: NudgeType) => of(false)), dismissNudge: jest.fn().mockResolvedValue(undefined), - } as Partial; + }; const dialogSvc = {} as Partial; @@ -193,6 +197,11 @@ describe("VaultV2Component", () => { stop: jest.fn(), } as Partial; + const vaultItemsTransferSvc = { + transferInProgress$: new BehaviorSubject(false), + enforceOrganizationDataOwnership: jest.fn().mockResolvedValue(undefined), + } as Partial; + function getObs(cmp: any, key: string): Observable { return cmp[key] as Observable; } @@ -209,6 +218,10 @@ describe("VaultV2Component", () => { .mockResolvedValue(new Date(Date.now() - 8 * 24 * 60 * 60 * 1000)), // 8 days ago }; + const configSvc = { + getFeatureFlag$: jest.fn().mockImplementation((_flag: string) => of(false)), + }; + beforeEach(async () => { jest.clearAllMocks(); await TestBed.configureTestingModule({ @@ -256,9 +269,7 @@ describe("VaultV2Component", () => { { provide: StateProvider, useValue: mock() }, { provide: ConfigService, - useValue: { - getFeatureFlag$: (_: string) => of(false), - }, + useValue: configSvc, }, { provide: SearchService, @@ -281,6 +292,9 @@ describe("VaultV2Component", () => { AutofillVaultListItemsComponent, VaultListItemsContainerComponent, ], + providers: [ + { provide: VaultItemsTransferService, useValue: DefaultVaultItemsTransferService }, + ], }, add: { imports: [ @@ -294,6 +308,7 @@ describe("VaultV2Component", () => { AutofillVaultListItemsStubComponent, VaultListItemsContainerStubComponent, ], + providers: [{ provide: VaultItemsTransferService, useValue: vaultItemsTransferSvc }], }, }); @@ -342,6 +357,7 @@ describe("VaultV2Component", () => { it("loading$ is true when items loading or filters missing; false when both ready", () => { const itemsLoading$ = itemsSvc.loading$ as unknown as BehaviorSubject; const allFilters$ = filtersSvc.allFilters$ as unknown as Subject; + const readySubject$ = component["readySubject"] as unknown as BehaviorSubject; const values: boolean[] = []; getObs(component, "loading$").subscribe((v) => values.push(!!v)); @@ -352,6 +368,8 @@ describe("VaultV2Component", () => { itemsLoading$.next(false); + readySubject$.next(true); + expect(values[values.length - 1]).toBe(false); }); @@ -453,7 +471,9 @@ describe("VaultV2Component", () => { hasPremiumFromAnySource$.next(false); - (nudgesSvc.showNudgeSpotlight$ as jest.Mock).mockImplementation((type: NudgeType) => + configSvc.getFeatureFlag$.mockImplementation((_flag: string) => of(true)); + + nudgesSvc.showNudgeSpotlight$.mockImplementation((type: NudgeType) => of(type === NudgeType.PremiumUpgrade), ); @@ -482,9 +502,11 @@ describe("VaultV2Component", () => { })); it("renders Empty-Vault spotlight when vaultState is Empty and nudge is on", fakeAsync(() => { + configSvc.getFeatureFlag$.mockImplementation((_flag: string) => of(false)); + itemsSvc.emptyVault$.next(true); - (nudgesSvc.showNudgeSpotlight$ as jest.Mock).mockImplementation((type: NudgeType) => { + nudgesSvc.showNudgeSpotlight$.mockImplementation((type: NudgeType) => { return of(type === NudgeType.EmptyVaultNudge); }); diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts index 9cee4f66b67..30d1d21abfb 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts @@ -16,6 +16,7 @@ import { switchMap, take, tap, + BehaviorSubject, } from "rxjs"; import { PremiumUpgradeDialogComponent } from "@bitwarden/angular/billing/components"; @@ -42,7 +43,11 @@ import { NoItemsModule, TypographyModule, } from "@bitwarden/components"; -import { DecryptionFailureDialogComponent } from "@bitwarden/vault"; +import { + DecryptionFailureDialogComponent, + VaultItemsTransferService, + DefaultVaultItemsTransferService, +} from "@bitwarden/vault"; import { CurrentAccountComponent } from "../../../../auth/popup/account-switching/current-account.component"; import { BrowserApi } from "../../../../platform/browser/browser-api"; @@ -105,6 +110,7 @@ type VaultState = UnionOfValues; VaultFadeInOutSkeletonComponent, VaultFadeInOutComponent, ], + providers: [{ provide: VaultItemsTransferService, useClass: DefaultVaultItemsTransferService }], }) export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals @@ -125,7 +131,22 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { activeUserId: UserId | null = null; - private loading$ = this.vaultPopupLoadingService.loading$.pipe( + /** + * Subject that indicates whether the vault is ready to render + * and that all initialization tasks have been completed (ngOnInit). + * @private + */ + private readySubject = new BehaviorSubject(false); + + /** + * Indicates whether the vault is loading and not yet ready to be displayed. + * @protected + */ + protected loading$ = combineLatest([ + this.vaultPopupLoadingService.loading$, + this.readySubject.asObservable(), + ]).pipe( + map(([loading, ready]) => loading || !ready), distinctUntilChanged(), tap((loading) => { const key = loading ? "loadingVault" : "vaultLoaded"; @@ -137,6 +158,10 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { FeatureFlag.VaultLoadingSkeletons, ); + protected premiumSpotlightFeatureFlag$ = this.configService.getFeatureFlag$( + FeatureFlag.BrowserPremiumSpotlight, + ); + private showPremiumNudgeSpotlight$ = this.activeUserId$.pipe( switchMap((userId) => this.nudgesService.showNudgeSpotlight$(NudgeType.PremiumUpgrade, userId)), ); @@ -164,6 +189,7 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { ); protected showPremiumSpotlight$ = combineLatest([ + this.premiumSpotlightFeatureFlag$, this.showPremiumNudgeSpotlight$, this.showHasItemsVaultSpotlight$, this.hasPremium$, @@ -171,8 +197,13 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { this.accountAgeInDays$, ]).pipe( map( - ([showPremiumNudge, showHasItemsNudge, hasPremium, count, age]) => - showPremiumNudge && !showHasItemsNudge && !hasPremium && count >= 5 && age >= 7, + ([featureFlagEnabled, showPremiumNudge, showHasItemsNudge, hasPremium, count, age]) => + featureFlagEnabled && + showPremiumNudge && + !showHasItemsNudge && + !hasPremium && + count >= 5 && + age >= 7, ), shareReplay({ bufferSize: 1, refCount: true }), ); @@ -190,14 +221,15 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { protected showSkeletonsLoaders$ = combineLatest([ this.loading$, this.searchService.isCipherSearching$, + this.vaultItemsTransferService.transferInProgress$, this.skeletonFeatureFlag$, ]).pipe( - map( - ([loading, cipherSearching, skeletonsEnabled]) => - (loading || cipherSearching) && skeletonsEnabled, - ), + map(([loading, cipherSearching, transferInProgress, skeletonsEnabled]) => { + return (loading || cipherSearching || transferInProgress) && skeletonsEnabled; + }), distinctUntilChanged(), skeletonLoadingDelay(), + shareReplay({ bufferSize: 1, refCount: true }), ); protected newItemItemValues$: Observable = @@ -241,6 +273,7 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { private i18nService: I18nService, private configService: ConfigService, private searchService: SearchService, + private vaultItemsTransferService: VaultItemsTransferService, ) { combineLatest([ this.vaultPopupItemsService.emptyVault$, @@ -295,6 +328,10 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { cipherIds: ciphers.map((c) => c.id as CipherId), }); }); + + await this.vaultItemsTransferService.enforceOrganizationDataOwnership(this.activeUserId); + + this.readySubject.next(true); } ngOnDestroy() { diff --git a/apps/browser/src/vault/popup/settings/vault-settings-v2.component.html b/apps/browser/src/vault/popup/settings/vault-settings-v2.component.html index 225640137e8..d5b94df5008 100644 --- a/apps/browser/src/vault/popup/settings/vault-settings-v2.component.html +++ b/apps/browser/src/vault/popup/settings/vault-settings-v2.component.html @@ -15,7 +15,7 @@ diff --git a/apps/browser/src/vault/popup/settings/vault-settings-v2.component.spec.ts b/apps/browser/src/vault/popup/settings/vault-settings-v2.component.spec.ts new file mode 100644 index 00000000000..15ddb7507fd --- /dev/null +++ b/apps/browser/src/vault/popup/settings/vault-settings-v2.component.spec.ts @@ -0,0 +1,205 @@ +import { ChangeDetectionStrategy, Component, DebugElement, input } from "@angular/core"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { provideRouter, Router } from "@angular/router"; +import { mock } from "jest-mock-extended"; +import { BehaviorSubject } from "rxjs"; + +import { NudgesService } from "@bitwarden/angular/vault"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { CipherArchiveService } from "@bitwarden/common/vault/abstractions/cipher-archive.service"; +import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { DialogService, ToastService } from "@bitwarden/components"; + +import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; +import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; +import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; + +import { VaultSettingsV2Component } from "./vault-settings-v2.component"; + +@Component({ + selector: "popup-header", + template: ``, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +class MockPopupHeaderComponent { + readonly pageTitle = input(); + readonly showBackButton = input(); +} + +@Component({ + selector: "popup-page", + template: ``, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +class MockPopupPageComponent {} + +@Component({ + selector: "app-pop-out", + template: ``, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +class MockPopOutComponent { + readonly show = input(true); +} + +describe("VaultSettingsV2Component", () => { + let component: VaultSettingsV2Component; + let fixture: ComponentFixture; + let router: Router; + let mockCipherArchiveService: jest.Mocked; + + const mockActiveAccount$ = new BehaviorSubject<{ id: string }>({ + id: "user-id", + }); + const mockUserCanArchive$ = new BehaviorSubject(false); + const mockHasArchiveFlagEnabled$ = new BehaviorSubject(true); + const mockArchivedCiphers$ = new BehaviorSubject([]); + const mockShowNudgeBadge$ = new BehaviorSubject(false); + + const queryByTestId = (testId: string): DebugElement | null => { + return fixture.debugElement.query(By.css(`[data-test-id="${testId}"]`)); + }; + + const setArchiveState = ( + canArchive: boolean, + archivedItems: CipherView[] = [], + flagEnabled = true, + ) => { + mockUserCanArchive$.next(canArchive); + mockArchivedCiphers$.next(archivedItems); + mockHasArchiveFlagEnabled$.next(flagEnabled); + fixture.detectChanges(); + }; + + beforeEach(async () => { + // Reset BehaviorSubjects to initial values + mockUserCanArchive$.next(false); + mockHasArchiveFlagEnabled$.next(true); + mockArchivedCiphers$.next([]); + mockShowNudgeBadge$.next(false); + + mockCipherArchiveService = mock({ + userCanArchive$: jest.fn().mockReturnValue(mockUserCanArchive$), + archivedCiphers$: jest.fn().mockReturnValue(mockArchivedCiphers$), + }); + mockCipherArchiveService.hasArchiveFlagEnabled$ = mockHasArchiveFlagEnabled$.asObservable(); + + await TestBed.configureTestingModule({ + imports: [VaultSettingsV2Component], + providers: [ + provideRouter([ + { path: "archive", component: VaultSettingsV2Component }, + { path: "premium", component: VaultSettingsV2Component }, + ]), + { provide: SyncService, useValue: mock() }, + { provide: ToastService, useValue: mock() }, + { provide: ConfigService, useValue: mock() }, + { provide: DialogService, useValue: mock() }, + { provide: I18nService, useValue: { t: (key: string) => key } }, + { provide: CipherArchiveService, useValue: mockCipherArchiveService }, + { + provide: NudgesService, + useValue: { showNudgeBadge$: jest.fn().mockReturnValue(mockShowNudgeBadge$) }, + }, + + { + provide: BillingAccountProfileStateService, + useValue: mock(), + }, + { + provide: AccountService, + useValue: { activeAccount$: mockActiveAccount$ }, + }, + ], + }) + .overrideComponent(VaultSettingsV2Component, { + remove: { + imports: [PopupHeaderComponent, PopupPageComponent, PopOutComponent], + }, + add: { + imports: [MockPopupHeaderComponent, MockPopupPageComponent, MockPopOutComponent], + }, + }) + .compileComponents(); + + fixture = TestBed.createComponent(VaultSettingsV2Component); + component = fixture.componentInstance; + router = TestBed.inject(Router); + jest.spyOn(router, "navigate"); + }); + + describe("archive link", () => { + it("shows direct archive link when user can archive", () => { + setArchiveState(true); + + const archiveLink = queryByTestId("archive-link"); + + expect(archiveLink?.nativeElement.getAttribute("routerLink")).toBe("/archive"); + }); + + it("routes to archive when user has archived items but cannot archive", async () => { + setArchiveState(false, [{ id: "cipher1" } as CipherView]); + + const premiumArchiveLink = queryByTestId("premium-archive-link"); + + premiumArchiveLink?.nativeElement.click(); + await fixture.whenStable(); + + expect(router.navigate).toHaveBeenCalledWith(["/archive"]); + }); + + it("prompts for premium when user cannot archive and has no archived items", async () => { + setArchiveState(false, []); + const badge = component["premiumBadgeComponent"](); + jest.spyOn(badge!, "promptForPremium"); + + const premiumArchiveLink = queryByTestId("premium-archive-link"); + + premiumArchiveLink?.nativeElement.click(); + await fixture.whenStable(); + + expect(badge!.promptForPremium).toHaveBeenCalled(); + }); + }); + + describe("archive visibility", () => { + it("displays archive link when user can archive", () => { + setArchiveState(true); + + const archiveLink = queryByTestId("archive-link"); + + expect(archiveLink).toBeTruthy(); + expect(component["userCanArchive"]()).toBe(true); + }); + + it("hides archive link when feature flag is disabled", () => { + setArchiveState(false, [], false); + + const archiveLink = queryByTestId("archive-link"); + const premiumArchiveLink = queryByTestId("premium-archive-link"); + + expect(archiveLink).toBeNull(); + expect(premiumArchiveLink).toBeNull(); + expect(component["showArchiveItem"]()).toBe(false); + }); + + it("shows premium badge when user has no archived items and cannot archive", () => { + setArchiveState(false, []); + + expect(component["premiumBadgeComponent"]()).toBeTruthy(); + expect(component["userHasArchivedItems"]()).toBe(false); + }); + + it("hides premium badge when user has archived items", () => { + setArchiveState(false, [{ id: "cipher1" } as CipherView]); + + expect(component["premiumBadgeComponent"]()).toBeUndefined(); + expect(component["userHasArchivedItems"]()).toBe(true); + }); + }); +}); diff --git a/apps/browser/src/vault/popup/settings/vault-settings-v2.component.ts b/apps/browser/src/vault/popup/settings/vault-settings-v2.component.ts index c6db820c232..c1d90d678cb 100644 --- a/apps/browser/src/vault/popup/settings/vault-settings-v2.component.ts +++ b/apps/browser/src/vault/popup/settings/vault-settings-v2.component.ts @@ -1,5 +1,5 @@ import { CommonModule } from "@angular/common"; -import { Component, OnDestroy, OnInit } from "@angular/core"; +import { Component, OnDestroy, OnInit, viewChild } from "@angular/core"; import { toSignal } from "@angular/core/rxjs-interop"; import { Router, RouterModule } from "@angular/router"; import { firstValueFrom, map, switchMap } from "rxjs"; @@ -42,6 +42,8 @@ import { BrowserPremiumUpgradePromptService } from "../services/browser-premium- ], }) export class VaultSettingsV2Component implements OnInit, OnDestroy { + private readonly premiumBadgeComponent = viewChild(PremiumBadgeComponent); + lastSync = "--"; private userId$ = this.accountService.activeAccount$.pipe(getUserId); @@ -49,7 +51,7 @@ export class VaultSettingsV2Component implements OnInit, OnDestroy { this.userId$.pipe(switchMap((userId) => this.cipherArchiveService.userCanArchive$(userId))), ); - protected readonly showArchiveItem = toSignal(this.cipherArchiveService.hasArchiveFlagEnabled$()); + protected readonly showArchiveItem = toSignal(this.cipherArchiveService.hasArchiveFlagEnabled$); protected readonly userHasArchivedItems = toSignal( this.userId$.pipe( @@ -117,4 +119,18 @@ export class VaultSettingsV2Component implements OnInit, OnDestroy { this.lastSync = this.i18nService.t("never"); } } + + /** + * When a user can archive or has previously archived items, route them to + * the archive page. Otherwise, prompt them to upgrade to premium. + */ + async conditionallyRouteToArchive(event: Event) { + event.preventDefault(); + const premiumBadge = this.premiumBadgeComponent(); + if (this.userCanArchive() || this.userHasArchivedItems()) { + await this.router.navigate(["/archive"]); + } else if (premiumBadge) { + await premiumBadge.promptForPremium(event); + } + } } diff --git a/apps/browser/store/locales/th/copy.resx b/apps/browser/store/locales/th/copy.resx index 1473e24d92e..5ffab9e41fe 100644 --- a/apps/browser/store/locales/th/copy.resx +++ b/apps/browser/store/locales/th/copy.resx @@ -118,58 +118,57 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden - จัดการรหัสผ่าน + Bitwarden Password Manager - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + ไม่ว่าจะที่บ้าน ที่ทำงาน หรือระหว่างเดินทาง Bitwarden ช่วยปกป้องรหัสผ่าน พาสคีย์ และข้อมูลสำคัญของคุณได้อย่างง่ายดาย - Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! + ได้รับการยอมรับว่าเป็นตัวจัดการรหัสผ่านที่ดีที่สุดโดย PCMag, WIRED, The Verge, CNET, G2 และอีกมากมาย! -SECURE YOUR DIGITAL LIFE -Secure your digital life and protect against data breaches by generating and saving unique, strong passwords for every account. Maintain everything in an end-to-end encrypted password vault that only you can access. +ปกป้องชีวิตดิจิทัลของคุณ +ปกป้องชีวิตดิจิทัลและป้องกันข้อมูลรั่วไหลโดยการสร้างและบันทึกรหัสผ่านที่รัดกุมและไม่ซ้ำกันสำหรับทุกบัญชี ดูแลจัดการทุกอย่างในตู้นิรภัยรหัสผ่านที่เข้ารหัสแบบต้นทางถึงปลายทาง ซึ่งมีเพียงคุณเท่านั้นที่เข้าถึงได้ -ACCESS YOUR DATA, ANYWHERE, ANYTIME, ON ANY DEVICE -Easily manage, store, secure, and share unlimited passwords across unlimited devices without restrictions. +เข้าถึงข้อมูลของคุณได้ทุกที่ ทุกเวลา บนทุกอุปกรณ์ +จัดการ จัดเก็บ ปกป้อง และแชร์รหัสผ่านได้ไม่จำกัดบนอุปกรณ์ไม่จำกัดจำนวนได้อย่างง่ายดายโดยไม่มีข้อจำกัด -EVERYONE SHOULD HAVE THE TOOLS TO STAY SAFE ONLINE -Utilize Bitwarden for free with no ads or selling data. Bitwarden believes everyone should have the ability to stay safe online. Premium plans offer access to advanced features. +ทุกคนควรมีเครื่องมือเพื่อความปลอดภัยบนโลกออนไลน์ +ใช้งาน Bitwarden ได้ฟรีโดยไม่มีโฆษณาหรือการขายข้อมูล Bitwarden เชื่อว่าทุกคนควรมีความสามารถในการอยู่อย่างปลอดภัยบนโลกออนไลน์ แผนพรีเมียมจะมอบการเข้าถึงฟีเจอร์ขั้นสูง -EMPOWER YOUR TEAMS WITH BITWARDEN -Plans for Teams and Enterprise come with professional business features. Some examples include SSO integration, self-hosting, directory integration and SCIM provisioning, global policies, API access, event logs, and more. +เสริมศักยภาพทีมของคุณด้วย BITWARDEN +แผนสำหรับ Teams และ Enterprise มาพร้อมกับฟีเจอร์ทางธุรกิจระดับมืออาชีพ ตัวอย่างเช่น การรวม SSO, การโฮสต์เอง (Self-hosting), การรวมไดเรกทอรีและการจัดเตรียม SCIM, นโยบายระดับองค์กร, การเข้าถึง API, บันทึกเหตุการณ์ และอื่น ๆ -Use Bitwarden to secure your workforce and share sensitive information with colleagues. +ใช้ Bitwarden เพื่อปกป้องบุคลากรของคุณและแชร์ข้อมูลสำคัญกับเพื่อนร่วมงาน +เหตุผลเพิ่มเติมที่ควรเลือก Bitwarden: -More reasons to choose Bitwarden: +การเข้ารหัสระดับโลก +รหัสผ่านได้รับการปกป้องด้วยการเข้ารหัสแบบต้นทางถึงปลายทาง ขั้นสูง (AES-256 bit, salted hashing และ PBKDF2 SHA-256) ข้อมูลของคุณจึงปลอดภัยและเป็นส่วนตัว -World-Class Encryption -Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashing, and PBKDF2 SHA-256) so your data stays secure and private. +การตรวจสอบโดยบุคคลที่สาม +Bitwarden ดำเนินการตรวจสอบความปลอดภัยโดยบุคคลที่สามอย่างครอบคลุมกับบริษัทความปลอดภัยที่มีชื่อเสียงอย่างสม่ำเสมอ การตรวจสอบประจำปีเหล่านี้รวมถึงการประเมินซอร์สโค้ดและการทดสอบเจาะระบบครอบคลุมทั้ง IP, เซิร์ฟเวอร์ และเว็บแอปพลิเคชันของ Bitwarden -3rd-party Audits -Bitwarden regularly conducts comprehensive third-party security audits with notable security firms. These annual audits include source code assessments and penetration testing across Bitwarden IPs, servers, and web applications. - -Advanced 2FA -Secure your login with a third-party authenticator, emailed codes, or FIDO2 WebAuthn credentials such as a hardware security key or passkey. +2FA ขั้นสูง +ปกป้องการเข้าสู่ระบบของคุณด้วยแอปยืนยันตัวตนของบุคคลที่สาม, รหัสทางอีเมล หรือข้อมูลประจำตัว FIDO2 WebAuthn เช่น คีย์ความปลอดภัยฮาร์ดแวร์หรือพาสคีย์ Bitwarden Send -Transmit data directly to others while maintaining end-to-end encrypted security and limiting exposure. +ส่งข้อมูลโดยตรงถึงผู้อื่นในขณะที่ยังคงรักษาความปลอดภัยด้วยการเข้ารหัสแบบต้นทางถึงปลายทาง และจำกัดการเปิดเผยข้อมูล -Built-in Generator -Create long, complex, and distinct passwords and unique usernames for every site you visit. Integrate with email alias providers for additional privacy. +ตัวสร้างในตัว +สร้างรหัสผ่านที่ยาว ซับซ้อน และแตกต่างกัน รวมถึงชื่อผู้ใช้ที่ไม่ซ้ำกันสำหรับทุกเว็บไซต์ที่คุณเยี่ยมชม ผสานรวมกับผู้ให้บริการนามแฝงอีเมลเพื่อความเป็นส่วนตัวเพิ่มเติม -Global Translations -Bitwarden translations exist for more than 60 languages, translated by the global community though Crowdin. +การแปลภาษาทั่วโลก +Bitwarden มีการแปลภาษามากกว่า 60 ภาษา โดยชุมชนทั่วโลกผ่าน Crowdin -Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. +แอปพลิเคชันข้ามแพลตฟอร์ม +ปกป้องและแชร์ข้อมูลสำคัญภายในตู้นิรภัย Bitwarden ของคุณจากเบราว์เซอร์ อุปกรณ์มือถือ หรือระบบปฏิบัติการเดสก์ท็อปใดก็ได้ และอื่น ๆ -Bitwarden secures more than just passwords -End-to-end encrypted credential management solutions from Bitwarden empower organizations to secure everything, including developer secrets and passkey experiences. Visit Bitwarden.com to learn more about Bitwarden Secrets Manager and Bitwarden Passwordless.dev! +Bitwarden ปกป้องมากกว่าแค่รหัสผ่าน +โซลูชันการจัดการข้อมูลประจำตัวที่เข้ารหัสแบบ End-to-end จาก Bitwarden ช่วยให้องค์กรปกป้องทุกสิ่ง รวมถึงความลับของนักพัฒนาและประสบการณ์พาสคีย์ เยี่ยมชม Bitwarden.com เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับ Bitwarden Secrets Manager และ Bitwarden Passwordless.dev! - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + ไม่ว่าจะที่บ้าน ที่ทำงาน หรือระหว่างเดินทาง Bitwarden ช่วยปกป้องรหัสผ่าน พาสคีย์ และข้อมูลสำคัญของคุณได้อย่างง่ายดาย ซิงค์และเข้าถึงตู้นิรภัยของคุณจากหลายอุปกรณ์ @@ -178,15 +177,15 @@ End-to-end encrypted credential management solutions from Bitwarden empower orga จัดการล็อกอินและรหัสผ่านทั้งหมดของคุณจากตู้นิรภัยที่ปลอดภัย - กรอกข้อมูลล็อกอินโดยอัตโนมัติบนทุกเว็บไซต์ที่คุณใช้งานได้อย่างรวดเร็ว + ป้อนข้อมูลเข้าสู่ระบบของคุณลงในเว็บไซต์ที่คุณเยี่ยมชมอย่างรวดเร็วโดยอัตโนมัติ - ตู้เซฟของคุณยังสามารถเข้าถึงได้โดยสะดวกผ่านเมนูคลิกขวา + เข้าถึงตู้นิรภัยของคุณได้อย่างสะดวกจากเมนูคลิกขวา - ส่มสร้างรหัสผ่านที่แข็งแกร่งและปลอดภัยโดยอัตโนมัติ + สร้างรหัสผ่านที่รัดกุม แบบสุ่ม และปลอดภัยโดยอัตโนมัติ - ข้อมูลของคุณได้รับการจัดการอย่างปลอดภัยโดยใช้การเข้ารหัส AES 256 บิต + ข้อมูลของคุณได้รับการจัดการอย่างปลอดภัยโดยใช้การเข้ารหัส AES-256 bit diff --git a/apps/browser/tailwind.config.js b/apps/browser/tailwind.config.js index 134001bbf13..faaa7fa4128 100644 --- a/apps/browser/tailwind.config.js +++ b/apps/browser/tailwind.config.js @@ -12,5 +12,6 @@ config.content = [ "../../libs/vault/src/**/*.{html,ts}", "../../libs/pricing/src/**/*.{html,ts}", ]; +config.corePlugins.preflight = true; module.exports = config; diff --git a/apps/cli/package.json b/apps/cli/package.json index d041f818c29..ff74664ac76 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -69,13 +69,13 @@ "browser-hrtime": "1.1.8", "chalk": "4.1.2", "commander": "14.0.0", - "core-js": "3.45.0", + "core-js": "3.47.0", "form-data": "4.0.4", "https-proxy-agent": "7.0.6", "inquirer": "8.2.6", "jsdom": "26.1.0", "jszip": "3.10.1", - "koa": "2.16.3", + "koa": "3.1.1", "koa-bodyparser": "4.4.1", "koa-json": "2.0.2", "lowdb": "1.0.0", @@ -83,7 +83,7 @@ "multer": "2.0.2", "node-fetch": "2.6.12", "node-forge": "1.3.2", - "open": "10.1.2", + "open": "11.0.0", "papaparse": "5.5.3", "proper-lockfile": "4.1.2", "rxjs": "7.8.1", diff --git a/apps/cli/src/auth/commands/login.command.ts b/apps/cli/src/auth/commands/login.command.ts index d0ab062d0b3..89d774b443b 100644 --- a/apps/cli/src/auth/commands/login.command.ts +++ b/apps/cli/src/auth/commands/login.command.ts @@ -13,6 +13,7 @@ import { SsoLoginCredentials, SsoUrlService, UserApiLoginCredentials, + UserDecryptionOptionsServiceAbstraction, } from "@bitwarden/auth/common"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction"; @@ -31,6 +32,7 @@ import { TwoFactorService, TwoFactorApiService } from "@bitwarden/common/auth/tw import { ClientType } from "@bitwarden/common/enums"; import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string"; +import { EncryptedMigrator } from "@bitwarden/common/key-management/encrypted-migrator/encrypted-migrator.abstraction"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; import { MasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; @@ -81,6 +83,8 @@ export class LoginCommand { protected ssoUrlService: SsoUrlService, protected i18nService: I18nService, protected masterPasswordService: MasterPasswordServiceAbstraction, + protected userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction, + protected encryptedMigrator: EncryptedMigrator, ) {} async run(email: string, password: string, options: OptionValues) { @@ -111,20 +115,14 @@ export class LoginCommand { } else if (options.sso != null && this.canInteract) { // If the optional Org SSO Identifier isn't provided, the option value is `true`. const orgSsoIdentifier = options.sso === true ? null : options.sso; - const passwordOptions: any = { - type: "password", - length: 64, - uppercase: true, - lowercase: true, - numbers: true, - special: false, - }; - const state = await this.passwordGenerationService.generatePassword(passwordOptions); - ssoCodeVerifier = await this.passwordGenerationService.generatePassword(passwordOptions); - const codeVerifierHash = await this.cryptoFunctionService.hash(ssoCodeVerifier, "sha256"); - const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash); + const ssoPromptData = await this.makeSsoPromptData(); + ssoCodeVerifier = ssoPromptData.ssoCodeVerifier; try { - const ssoParams = await this.openSsoPrompt(codeChallenge, state, orgSsoIdentifier); + const ssoParams = await this.openSsoPrompt( + ssoPromptData.codeChallenge, + ssoPromptData.state, + orgSsoIdentifier, + ); ssoCode = ssoParams.ssoCode; orgIdentifier = ssoParams.orgIdentifier; } catch { @@ -229,9 +227,43 @@ export class LoginCommand { new PasswordLoginCredentials(email, password, twoFactor), ); } + + // Begin Acting on initial AuthResult + if (response.requiresEncryptionKeyMigration) { return Response.error(this.i18nService.t("legacyEncryptionUnsupported")); } + + // Opting for not checking feature flag since the server will not respond with + // SsoOrganizationIdentifier if the feature flag is not enabled. + if (response.requiresSso && this.canInteract) { + const ssoPromptData = await this.makeSsoPromptData(); + ssoCodeVerifier = ssoPromptData.ssoCodeVerifier; + try { + const ssoParams = await this.openSsoPrompt( + ssoPromptData.codeChallenge, + ssoPromptData.state, + response.ssoOrganizationIdentifier, + ); + ssoCode = ssoParams.ssoCode; + orgIdentifier = ssoParams.orgIdentifier; + if (ssoCode != null && ssoCodeVerifier != null) { + response = await this.loginStrategyService.logIn( + new SsoLoginCredentials( + ssoCode, + ssoCodeVerifier, + this.ssoRedirectUri, + orgIdentifier, + undefined, // email to look up 2FA token not required as CLI can't remember 2FA token + twoFactor, + ), + ); + } + } catch { + return Response.badRequest("Something went wrong. Try again."); + } + } + if (response.requiresTwoFactor) { const twoFactorProviders = await this.twoFactorService.getSupportedProviders(null); if (twoFactorProviders.length === 0) { @@ -277,6 +309,10 @@ export class LoginCommand { if (twoFactorToken == null && selectedProvider.type === TwoFactorProviderType.Email) { const emailReq = new TwoFactorEmailRequest(); emailReq.email = await this.loginStrategyService.getEmail(); + // if the user was logging in with SSO, we need to include the SSO session token + if (response.ssoEmail2FaSessionToken != null) { + emailReq.ssoEmail2FaSessionToken = response.ssoEmail2FaSessionToken; + } emailReq.masterPasswordHash = await this.loginStrategyService.getMasterPasswordHash(); await this.twoFactorApiService.postTwoFactorEmail(emailReq); } @@ -322,15 +358,18 @@ export class LoginCommand { response = await this.loginStrategyService.logInNewDeviceVerification(newDeviceToken); } + // We check response two factor again here since MFA could fail based on the logic on ln 226 if (response.requiresTwoFactor) { return Response.error("Login failed."); } - if (response.resetMasterPassword) { - return Response.error( - "In order to log in with SSO from the CLI, you must first log in" + - " through the web vault to set your master password.", - ); + // If we are in the SSO flow and we got a successful login response (we are past rejection scenarios + // and should always have a userId here), validate that SSO user in MP encryption org has MP set + // This must be done here b/c we have 2 places we try to login with SSO above and neither has a + // common handleSsoAuthnResult method to consoldiate this logic into (1. the normal SSO flow and + // 2. the requiresSso automatic authentication flow) + if (ssoCode != null && ssoCodeVerifier != null && response.userId) { + await this.validateSsoUserInMpEncryptionOrgHasMp(response.userId); } // Check if Key Connector domain confirmation is required @@ -367,6 +406,8 @@ export class LoginCommand { } } + await this.encryptedMigrator.runMigrations(response.userId, password); + return await this.handleSuccessResponse(response); } catch (e) { if ( @@ -688,6 +729,27 @@ export class LoginCommand { }; } + /// Generate SSO prompt data: code verifier, code challenge, and state + private async makeSsoPromptData(): Promise<{ + ssoCodeVerifier: string; + codeChallenge: string; + state: string; + }> { + const passwordOptions: any = { + type: "password", + length: 64, + uppercase: true, + lowercase: true, + numbers: true, + special: false, + }; + const state = await this.passwordGenerationService.generatePassword(passwordOptions); + const ssoCodeVerifier = await this.passwordGenerationService.generatePassword(passwordOptions); + const codeVerifierHash = await this.cryptoFunctionService.hash(ssoCodeVerifier, "sha256"); + const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash); + return { ssoCodeVerifier, codeChallenge, state }; + } + private async openSsoPrompt( codeChallenge: string, state: string, @@ -778,4 +840,35 @@ export class LoginCommand { const checkStateSplit = checkState.split("_identifier="); return stateSplit[0] === checkStateSplit[0]; } + + /** + * Validate that a user logging in with SSO that is in an org using MP encryption + * has a MP set. If not, they cannot set a MP in the CLI and must use another client. + * @param userId + * @returns void + */ + private async validateSsoUserInMpEncryptionOrgHasMp(userId: UserId): Promise { + const userDecryptionOptions = await firstValueFrom( + this.userDecryptionOptionsService.userDecryptionOptionsById$(userId), + ); + + // device trust isn't supported in the CLI as we don't have persistent device key storage. + const notUsingTrustedDeviceEncryption = !userDecryptionOptions.trustedDeviceOption; + const notUsingKeyConnector = !userDecryptionOptions.keyConnectorOption; + + if ( + notUsingTrustedDeviceEncryption && + notUsingKeyConnector && + !userDecryptionOptions.hasMasterPassword + ) { + // If user is in an org that is using MP encryption and they JIT provisioned but + // have not yet set a MP and come to the CLI to login, they won't be able to unlock + // or set a MP in the CLI as it isn't supported. + await this.logoutCallback(); + throw Response.error( + "In order to log in with SSO from the CLI, you must first log in" + + " through the web vault, the desktop, or the extension to set your master password.", + ); + } + } } diff --git a/apps/cli/src/base-program.ts b/apps/cli/src/base-program.ts index 69a5e4e1bde..71c3830b4cc 100644 --- a/apps/cli/src/base-program.ts +++ b/apps/cli/src/base-program.ts @@ -182,6 +182,7 @@ export abstract class BaseProgram { this.serviceContainer.organizationApiService, this.serviceContainer.logout, this.serviceContainer.i18nService, + this.serviceContainer.encryptedMigrator, this.serviceContainer.masterPasswordUnlockService, this.serviceContainer.configService, ); diff --git a/apps/cli/src/commands/edit.command.ts b/apps/cli/src/commands/edit.command.ts index 14a218c7141..d95e8333dca 100644 --- a/apps/cli/src/commands/edit.command.ts +++ b/apps/cli/src/commands/edit.command.ts @@ -186,15 +186,15 @@ export class EditCommand { return Response.notFound(); } - let folderView = await folder.decrypt(); + const userKey = await firstValueFrom(this.keyService.userKey$(activeUserId)); + let folderView = await folder.decrypt(userKey); folderView = FolderExport.toView(req, folderView); - const userKey = await this.keyService.getUserKey(activeUserId); const encFolder = await this.folderService.encrypt(folderView, userKey); try { const folder = await this.folderApiService.save(encFolder, activeUserId); const updatedFolder = new Folder(folder); - const decFolder = await updatedFolder.decrypt(); + const decFolder = await updatedFolder.decrypt(userKey); const res = new FolderResponse(decFolder); return Response.success(res); } catch (e) { diff --git a/apps/cli/src/commands/get.command.ts b/apps/cli/src/commands/get.command.ts index 93e711d748f..35816b56fb2 100644 --- a/apps/cli/src/commands/get.command.ts +++ b/apps/cli/src/commands/get.command.ts @@ -417,10 +417,11 @@ export class GetCommand extends DownloadCommand { private async getFolder(id: string) { let decFolder: FolderView = null; const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + const userKey = await firstValueFrom(this.keyService.userKey$(activeUserId)); if (Utils.isGuid(id)) { const folder = await this.folderService.getFromState(id, activeUserId); if (folder != null) { - decFolder = await folder.decrypt(); + decFolder = await folder.decrypt(userKey); } } else if (id.trim() !== "") { let folders = await this.folderService.getAllDecryptedFromState(activeUserId); diff --git a/apps/cli/src/commands/status.command.ts b/apps/cli/src/commands/status.command.ts index f7fc8541a5f..7ae1e657630 100644 --- a/apps/cli/src/commands/status.command.ts +++ b/apps/cli/src/commands/status.command.ts @@ -1,12 +1,12 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { firstValueFrom, map } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; +import { UserAutoUnlockKeyService } from "@bitwarden/common/platform/services/user-auto-unlock-key.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { UserId } from "@bitwarden/user-core"; import { Response } from "../models/response"; import { TemplateResponse } from "../models/response/template.response"; @@ -17,16 +17,17 @@ export class StatusCommand { private syncService: SyncService, private accountService: AccountService, private authService: AuthService, + private userAutoUnlockKeyService: UserAutoUnlockKeyService, ) {} async run(): Promise { try { const baseUrl = await this.baseUrl(); - const status = await this.status(); const lastSync = await this.syncService.getLastSync(); const [userId, email] = await firstValueFrom( this.accountService.activeAccount$.pipe(map((a) => [a?.id, a?.email])), ); + const status = await this.status(userId); return Response.success( new TemplateResponse({ @@ -42,12 +43,18 @@ export class StatusCommand { } } - private async baseUrl(): Promise { + private async baseUrl(): Promise { const env = await firstValueFrom(this.envService.environment$); return env.getUrls().base; } - private async status(): Promise<"unauthenticated" | "locked" | "unlocked"> { + private async status( + userId: UserId | undefined, + ): Promise<"unauthenticated" | "locked" | "unlocked"> { + if (userId != null) { + await this.userAutoUnlockKeyService.setUserKeyInMemoryIfAutoUserKeySet(userId); + } + const authStatus = await this.authService.getAuthStatus(); if (authStatus === AuthenticationStatus.Unlocked) { return "unlocked"; diff --git a/apps/cli/src/key-management/commands/unlock.command.spec.ts b/apps/cli/src/key-management/commands/unlock.command.spec.ts index 928a750dca6..50ef414ec37 100644 --- a/apps/cli/src/key-management/commands/unlock.command.spec.ts +++ b/apps/cli/src/key-management/commands/unlock.command.spec.ts @@ -7,6 +7,7 @@ import { UserVerificationService } from "@bitwarden/common/auth/abstractions/use import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; import { MasterPasswordVerificationResponse } from "@bitwarden/common/auth/types/verification"; import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; +import { EncryptedMigrator } from "@bitwarden/common/key-management/encrypted-migrator/encrypted-migrator.abstraction"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; import { MasterPasswordUnlockService } from "@bitwarden/common/key-management/master-password/abstractions/master-password-unlock.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; @@ -14,6 +15,7 @@ import { ConfigService } from "@bitwarden/common/platform/abstractions/config/co import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; +import { mockAccountInfoWith } from "@bitwarden/common/spec"; import { CsprngArray } from "@bitwarden/common/types/csprng"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { KeyService } from "@bitwarden/key-management"; @@ -40,15 +42,17 @@ describe("UnlockCommand", () => { const organizationApiService = mock(); const logout = jest.fn(); const i18nService = mock(); + const encryptedMigrator = mock(); const masterPasswordUnlockService = mock(); const configService = mock(); const mockMasterPassword = "testExample"; const activeAccount: Account = { id: "user-id" as UserId, - email: "user@example.com", - emailVerified: true, - name: "User", + ...mockAccountInfoWith({ + email: "user@example.com", + name: "User", + }), }; const mockUserKey = new SymmetricCryptoKey(new Uint8Array(64)) as UserKey; const mockSessionKey = new Uint8Array(64) as CsprngArray; @@ -92,6 +96,7 @@ describe("UnlockCommand", () => { organizationApiService, logout, i18nService, + encryptedMigrator, masterPasswordUnlockService, configService, ); diff --git a/apps/cli/src/key-management/commands/unlock.command.ts b/apps/cli/src/key-management/commands/unlock.command.ts index 4ae8ce823a4..c88d9ae1cc4 100644 --- a/apps/cli/src/key-management/commands/unlock.command.ts +++ b/apps/cli/src/key-management/commands/unlock.command.ts @@ -9,6 +9,7 @@ import { VerificationType } from "@bitwarden/common/auth/enums/verification-type import { MasterPasswordVerification } from "@bitwarden/common/auth/types/verification"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; +import { EncryptedMigrator } from "@bitwarden/common/key-management/encrypted-migrator/encrypted-migrator.abstraction"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; import { MasterPasswordUnlockService } from "@bitwarden/common/key-management/master-password/abstractions/master-password-unlock.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; @@ -38,6 +39,7 @@ export class UnlockCommand { private organizationApiService: OrganizationApiServiceAbstraction, private logout: () => Promise, private i18nService: I18nService, + private encryptedMigrator: EncryptedMigrator, private masterPasswordUnlockService: MasterPasswordUnlockService, private configService: ConfigService, ) {} @@ -116,6 +118,8 @@ export class UnlockCommand { } } + await this.encryptedMigrator.runMigrations(userId, password); + return this.successResponse(); } diff --git a/apps/cli/src/key-management/session-timeout/services/cli-session-timeout-type.service.ts b/apps/cli/src/key-management/session-timeout/services/cli-session-timeout-type.service.ts new file mode 100644 index 00000000000..8143b37b8a3 --- /dev/null +++ b/apps/cli/src/key-management/session-timeout/services/cli-session-timeout-type.service.ts @@ -0,0 +1,15 @@ +import { SessionTimeoutTypeService } from "@bitwarden/common/key-management/session-timeout"; +import { + VaultTimeout, + VaultTimeoutStringType, +} from "@bitwarden/common/key-management/vault-timeout"; + +export class CliSessionTimeoutTypeService implements SessionTimeoutTypeService { + async isAvailable(timeout: VaultTimeout): Promise { + return timeout === VaultTimeoutStringType.Never; + } + + async getOrPromoteToAvailable(_: VaultTimeout): Promise { + return VaultTimeoutStringType.Never; + } +} diff --git a/apps/cli/src/oss-serve-configurator.ts b/apps/cli/src/oss-serve-configurator.ts index bd51cf4dd91..e8f5e6acd9a 100644 --- a/apps/cli/src/oss-serve-configurator.ts +++ b/apps/cli/src/oss-serve-configurator.ts @@ -122,6 +122,7 @@ export class OssServeConfigurator { this.serviceContainer.syncService, this.serviceContainer.accountService, this.serviceContainer.authService, + this.serviceContainer.userAutoUnlockKeyService, ); this.deleteCommand = new DeleteCommand( this.serviceContainer.cipherService, @@ -176,6 +177,7 @@ export class OssServeConfigurator { this.serviceContainer.organizationApiService, async () => await this.serviceContainer.logout(), this.serviceContainer.i18nService, + this.serviceContainer.encryptedMigrator, this.serviceContainer.masterPasswordUnlockService, this.serviceContainer.configService, ); diff --git a/apps/cli/src/platform/services/cli-sdk-load.service.ts b/apps/cli/src/platform/services/cli-sdk-load.service.ts index 638e64a8214..13a4c19d51d 100644 --- a/apps/cli/src/platform/services/cli-sdk-load.service.ts +++ b/apps/cli/src/platform/services/cli-sdk-load.service.ts @@ -3,6 +3,8 @@ import * as sdk from "@bitwarden/sdk-internal"; export class CliSdkLoadService extends SdkLoadService { async load(): Promise { + // CLI uses stdout for user interaction / automations so we cannot log info / debug here. + SdkLoadService.logLevel = sdk.LogLevel.Error; const module = await import("@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm"); (sdk as any).init(module); } diff --git a/apps/cli/src/program.ts b/apps/cli/src/program.ts index a47278db089..870d743095d 100644 --- a/apps/cli/src/program.ts +++ b/apps/cli/src/program.ts @@ -195,6 +195,8 @@ export class Program extends BaseProgram { this.serviceContainer.ssoUrlService, this.serviceContainer.i18nService, this.serviceContainer.masterPasswordService, + this.serviceContainer.userDecryptionOptionsService, + this.serviceContainer.encryptedMigrator, ); const response = await command.run(email, password, options); this.processResponse(response, true); @@ -311,6 +313,7 @@ export class Program extends BaseProgram { this.serviceContainer.organizationApiService, async () => await this.serviceContainer.logout(), this.serviceContainer.i18nService, + this.serviceContainer.encryptedMigrator, this.serviceContainer.masterPasswordUnlockService, this.serviceContainer.configService, ); @@ -522,6 +525,7 @@ export class Program extends BaseProgram { this.serviceContainer.syncService, this.serviceContainer.accountService, this.serviceContainer.authService, + this.serviceContainer.userAutoUnlockKeyService, ); const response = await command.run(); this.processResponse(response); diff --git a/apps/cli/src/service-container/service-container.ts b/apps/cli/src/service-container/service-container.ts index c163b7581b4..2f1e92d14fc 100644 --- a/apps/cli/src/service-container/service-container.ts +++ b/apps/cli/src/service-container/service-container.ts @@ -69,6 +69,7 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service"; import { HibpApiService } from "@bitwarden/common/dirt/services/hibp-api.service"; import { ClientType } from "@bitwarden/common/enums"; +import { DefaultAccountCryptographicStateService } from "@bitwarden/common/key-management/account-cryptography/default-account-cryptographic-state.service"; import { DefaultKeyGenerationService, KeyGenerationService, @@ -76,6 +77,10 @@ import { import { EncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/encrypt.service.implementation"; import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { DeviceTrustService } from "@bitwarden/common/key-management/device-trust/services/device-trust.service.implementation"; +import { DefaultEncryptedMigrator } from "@bitwarden/common/key-management/encrypted-migrator/default-encrypted-migrator"; +import { EncryptedMigrator } from "@bitwarden/common/key-management/encrypted-migrator/encrypted-migrator.abstraction"; +import { DefaultChangeKdfApiService } from "@bitwarden/common/key-management/kdf/change-kdf-api.service"; +import { DefaultChangeKdfService } from "@bitwarden/common/key-management/kdf/change-kdf.service"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/services/key-connector.service"; import { MasterPasswordUnlockService } from "@bitwarden/common/key-management/master-password/abstractions/master-password-unlock.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; @@ -207,6 +212,7 @@ import { import { CliBiometricsService } from "../key-management/cli-biometrics-service"; import { CliProcessReloadService } from "../key-management/cli-process-reload.service"; +import { CliSessionTimeoutTypeService } from "../key-management/session-timeout/services/cli-session-timeout-type.service"; import { flagEnabled } from "../platform/flags"; import { CliPlatformUtilsService } from "../platform/services/cli-platform-utils.service"; import { CliSdkLoadService } from "../platform/services/cli-sdk-load.service"; @@ -324,10 +330,12 @@ export class ServiceContainer { cipherEncryptionService: CipherEncryptionService; restrictedItemTypesService: RestrictedItemTypesService; cliRestrictedItemTypesService: CliRestrictedItemTypesService; + encryptedMigrator: EncryptedMigrator; securityStateService: SecurityStateService; masterPasswordUnlockService: MasterPasswordUnlockService; cipherArchiveService: CipherArchiveService; lockService: LockService; + private accountCryptographicStateService: DefaultAccountCryptographicStateService; constructor() { let p = null; @@ -486,10 +494,7 @@ export class ServiceContainer { const pinStateService = new PinStateService(this.stateProvider); this.pinService = new PinService( - this.accountService, this.encryptService, - this.kdfConfigService, - this.keyGenerationService, this.logService, this.keyService, this.sdkService, @@ -524,6 +529,8 @@ export class ServiceContainer { this.accountService, ); + const sessionTimeoutTypeService = new CliSessionTimeoutTypeService(); + this.vaultTimeoutSettingsService = new DefaultVaultTimeoutSettingsService( this.accountService, pinStateService, @@ -535,6 +542,7 @@ export class ServiceContainer { this.stateProvider, this.logService, VaultTimeoutStringType.Never, // default vault timeout + sessionTimeoutTypeService, ); const refreshAccessTokenErrorCallback = () => { @@ -711,6 +719,10 @@ export class ServiceContainer { this.accountService, ); + this.accountCryptographicStateService = new DefaultAccountCryptographicStateService( + this.stateProvider, + ); + this.loginStrategyService = new LoginStrategyService( this.accountService, this.masterPasswordService, @@ -738,6 +750,7 @@ export class ServiceContainer { this.kdfConfigService, this.taskSchedulerService, this.configService, + this.accountCryptographicStateService, ); this.restrictedItemTypesService = new RestrictedItemTypesService( @@ -873,6 +886,7 @@ export class ServiceContainer { this.stateProvider, this.securityStateService, this.kdfConfigService, + this.accountCryptographicStateService, ); this.totpService = new TotpService(this.sdkService); @@ -899,7 +913,7 @@ export class ServiceContainer { this.collectionService, this.keyService, this.encryptService, - this.pinService, + this.keyGenerationService, this.accountService, this.restrictedItemTypesService, ); @@ -907,7 +921,7 @@ export class ServiceContainer { this.individualExportService = new IndividualVaultExportService( this.folderService, this.cipherService, - this.pinService, + this.keyGenerationService, this.keyService, this.encryptService, this.cryptoFunctionService, @@ -921,7 +935,7 @@ export class ServiceContainer { this.organizationExportService = new OrganizationVaultExportService( this.cipherService, this.vaultExportApiService, - this.pinService, + this.keyGenerationService, this.keyService, this.encryptService, this.cryptoFunctionService, @@ -975,6 +989,21 @@ export class ServiceContainer { ); this.masterPasswordApiService = new MasterPasswordApiService(this.apiService, this.logService); + const changeKdfApiService = new DefaultChangeKdfApiService(this.apiService); + const changeKdfService = new DefaultChangeKdfService( + changeKdfApiService, + this.sdkService, + this.keyService, + this.masterPasswordService, + ); + this.encryptedMigrator = new DefaultEncryptedMigrator( + this.kdfConfigService, + changeKdfService, + this.logService, + this.configService, + this.masterPasswordService, + this.syncService, + ); } async logout() { diff --git a/apps/cli/src/vault/create.command.ts b/apps/cli/src/vault/create.command.ts index 5602c593942..d826766dc65 100644 --- a/apps/cli/src/vault/create.command.ts +++ b/apps/cli/src/vault/create.command.ts @@ -181,12 +181,12 @@ export class CreateCommand { private async createFolder(req: FolderExport) { const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); - const userKey = await this.keyService.getUserKey(activeUserId); + const userKey = await firstValueFrom(this.keyService.userKey$(activeUserId)); const folder = await this.folderService.encrypt(FolderExport.toView(req), userKey); try { const folderData = await this.folderApiService.save(folder, activeUserId); const newFolder = new Folder(folderData); - const decFolder = await newFolder.decrypt(); + const decFolder = await newFolder.decrypt(userKey); const res = new FolderResponse(decFolder); return Response.success(res); } catch (e) { diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 3b9b8c2db27..5978659f21e 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - [[package]] name = "aead" version = "0.5.2" @@ -114,9 +99,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arboard" @@ -138,14 +123,14 @@ dependencies = [ [[package]] name = "ashpd" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df" +checksum = "da0986d5b4f0802160191ad75f8d33ada000558757db3defb70299ca95d9fcbd" dependencies = [ "enumflags2", "futures-channel", "futures-util", - "rand 0.9.1", + "rand 0.9.2", "serde", "serde_repr", "tokio", @@ -347,23 +332,8 @@ dependencies = [ "mockall", "serial_test", "tracing", - "windows 0.61.1", - "windows-core 0.61.0", -] - -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", + "windows", + "windows-core", ] [[package]] @@ -457,7 +427,7 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", - "windows 0.61.1", + "windows", ] [[package]] @@ -501,6 +471,12 @@ dependencies = [ "cipher", ] +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + [[package]] name = "byteorder" version = "1.5.0" @@ -509,9 +485,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "camino" @@ -556,9 +532,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.46" +version = "1.2.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36" +checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" dependencies = [ "find-msvc-tools", "shlex", @@ -614,7 +590,7 @@ dependencies = [ "hex", "oo7", "pbkdf2", - "rand 0.9.1", + "rand 0.9.2", "rusqlite", "security-framework", "serde", @@ -623,7 +599,7 @@ dependencies = [ "tokio", "tracing", "verifysign", - "windows 0.61.1", + "windows", ] [[package]] @@ -709,9 +685,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "convert_case" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" dependencies = [ "unicode-segmentation", ] @@ -770,16 +746,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "ctor" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "ctor" version = "0.5.0" @@ -867,7 +833,7 @@ dependencies = [ "memsec", "oo7", "pin-project", - "rand 0.9.1", + "rand 0.9.2", "scopeguard", "secmem-proc", "security-framework", @@ -877,13 +843,13 @@ dependencies = [ "sha2", "ssh-key", "sysinfo", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", "tokio-util", "tracing", "typenum", "widestring", - "windows 0.61.1", + "windows", "windows-future", "zbus", "zbus_polkit", @@ -1409,17 +1375,11 @@ dependencies = [ "polyval", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "glob" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "goblin" @@ -1499,14 +1459,14 @@ dependencies = [ [[package]] name = "homedir" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bdbbd5bc8c5749697ccaa352fa45aff8730cf21c68029c0eef1ffed7c3d6ba2" +checksum = "68df315d2857b2d8d2898be54a85e1d001bbbe0dbb5f8ef847b48dd3a23c4527" dependencies = [ "cfg-if", - "nix 0.29.0", + "nix", "widestring", - "windows 0.57.0", + "windows", ] [[package]] @@ -1663,6 +1623,16 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "js-sys" +version = "0.3.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -1674,9 +1644,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.177" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libloading" @@ -1685,7 +1655,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-targets 0.48.5", ] [[package]] @@ -1841,15 +1811,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" -dependencies = [ - "adler2", -] - [[package]] name = "mio" version = "1.0.3" @@ -1889,32 +1850,33 @@ dependencies = [ [[package]] name = "napi" -version = "2.16.17" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3" +checksum = "f1b74e3dce5230795bb4d2821b941706dee733c7308752507254b0497f39cad7" dependencies = [ "bitflags", - "ctor 0.2.9", - "napi-derive", + "ctor", + "napi-build", "napi-sys", - "once_cell", + "nohash-hasher", + "rustc-hash", "tokio", ] [[package]] name = "napi-build" -version = "2.2.0" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03acbfa4f156a32188bfa09b86dc11a431b5725253fc1fc6f6df5bed273382c4" +checksum = "dcae8ad5609d14afb3a3b91dee88c757016261b151e9dcecabf1b2a31a6cab14" [[package]] name = "napi-derive" -version = "2.16.13" +version = "3.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cbe2585d8ac223f7d34f13701434b9d5f4eb9c332cccce8dee57ea18ab8ab0c" +checksum = "7552d5a579b834614bbd496db5109f1b9f1c758f08224b0dee1e408333adf0d0" dependencies = [ - "cfg-if", "convert_case", + "ctor", "napi-derive-backend", "proc-macro2", "quote", @@ -1923,40 +1885,26 @@ dependencies = [ [[package]] name = "napi-derive-backend" -version = "1.0.75" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1639aaa9eeb76e91c6ae66da8ce3e89e921cd3885e99ec85f4abacae72fc91bf" +checksum = "5f6a81ac7486b70f2532a289603340862c06eea5a1e650c1ffeda2ce1238516a" dependencies = [ "convert_case", - "once_cell", "proc-macro2", "quote", - "regex", "semver", "syn", ] [[package]] name = "napi-sys" -version = "2.4.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427802e8ec3a734331fec1035594a210ce1ff4dc5bc1950530920ab717964ea3" +checksum = "3e4e7135a8f97aa0f1509cce21a8a1f9dcec1b50d8dee006b48a5adb69a9d64d" dependencies = [ "libloading", ] -[[package]] -name = "nix" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" -dependencies = [ - "bitflags", - "cfg-if", - "cfg_aliases", - "libc", -] - [[package]] name = "nix" version = "0.30.1" @@ -1970,6 +1918,12 @@ dependencies = [ "memoffset", ] +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + [[package]] name = "nom" version = "7.1.3" @@ -2173,15 +2127,6 @@ dependencies = [ "objc2-core-foundation", ] -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.21.3" @@ -2190,9 +2135,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oo7" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb23d3ec3527d65a83be1c1795cb883c52cfa57147d42acc797127df56fc489" +checksum = "e3299dd401feaf1d45afd8fd1c0586f10fcfb22f244bb9afa942cec73503b89d" dependencies = [ "aes", "ashpd", @@ -2208,7 +2153,7 @@ dependencies = [ "num", "num-bigint-dig", "pbkdf2", - "rand 0.9.1", + "rand 0.9.2", "serde", "sha2", "subtle", @@ -2548,7 +2493,7 @@ dependencies = [ name = "process_isolation" version = "0.0.0" dependencies = [ - "ctor 0.5.0", + "ctor", "desktop_core", "libc", "tracing", @@ -2591,9 +2536,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", @@ -2660,19 +2605,7 @@ checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.12", -] - -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "thiserror 2.0.17", ] [[package]] @@ -2748,10 +2681,10 @@ dependencies = [ ] [[package]] -name = "rustc-demangle" -version = "0.1.24" +name = "rustc-hash" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc_version" @@ -2798,6 +2731,12 @@ dependencies = [ "rustix 1.0.7", ] +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + [[package]] name = "ryu" version = "1.0.20" @@ -2870,15 +2809,15 @@ dependencies = [ "libc", "rustix 1.0.7", "rustix-linux-procfs", - "thiserror 2.0.12", - "windows 0.61.1", + "thiserror 2.0.17", + "windows", ] [[package]] name = "security-framework" -version = "3.5.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc198e42d9b7510827939c9a15f5062a0c913f3371d765977e586d2fe6c16f4a" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ "bitflags", "core-foundation", @@ -3068,12 +3007,12 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "socket2" -version = "0.5.9" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -3188,16 +3127,16 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.35.0" +version = "0.37.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b897c8ea620e181c7955369a31be5f48d9a9121cb59fd33ecef9ff2a34323422" +checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f" dependencies = [ "libc", "memchr", "ntapi", "objc2-core-foundation", "objc2-io-kit", - "windows 0.61.1", + "windows", ] [[package]] @@ -3239,11 +3178,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.17", ] [[package]] @@ -3259,9 +3198,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -3289,11 +3228,10 @@ dependencies = [ [[package]] name = "tokio" -version = "1.45.0" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", "libc", "mio", @@ -3303,14 +3241,14 @@ dependencies = [ "socket2", "tokio-macros", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", @@ -3319,9 +3257,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.13" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" dependencies = [ "bytes", "futures-core", @@ -3680,6 +3618,17 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.1" @@ -3745,6 +3694,51 @@ dependencies = [ "wit-bindgen-rt", ] +[[package]] +name = "wasm-bindgen" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +dependencies = [ + "unicode-ident", +] + [[package]] name = "wayland-backend" version = "0.3.10" @@ -3852,16 +3846,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" -dependencies = [ - "windows-core 0.57.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows" version = "0.61.1" @@ -3869,7 +3853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" dependencies = [ "windows-collections", - "windows-core 0.61.0", + "windows-core", "windows-future", "windows-link 0.1.3", "windows-numerics", @@ -3881,19 +3865,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core 0.61.0", -] - -[[package]] -name = "windows-core" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" -dependencies = [ - "windows-implement 0.57.0", - "windows-interface 0.57.0", - "windows-result 0.1.2", - "windows-targets 0.52.6", + "windows-core", ] [[package]] @@ -3902,8 +3874,8 @@ version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ - "windows-implement 0.60.0", - "windows-interface 0.59.1", + "windows-implement", + "windows-interface", "windows-link 0.1.3", "windows-result 0.3.4", "windows-strings 0.4.2", @@ -3915,21 +3887,10 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32" dependencies = [ - "windows-core 0.61.0", + "windows-core", "windows-link 0.1.3", ] -[[package]] -name = "windows-implement" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-implement" version = "0.60.0" @@ -3941,17 +3902,6 @@ dependencies = [ "syn", ] -[[package]] -name = "windows-interface" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-interface" version = "0.59.1" @@ -3981,7 +3931,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-core 0.61.0", + "windows-core", "windows-link 0.1.3", ] @@ -3996,15 +3946,6 @@ dependencies = [ "windows-strings 0.5.1", ] -[[package]] -name = "windows-result" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-result" version = "0.3.4" @@ -4262,8 +4203,8 @@ name = "windows_plugin_authenticator" version = "0.0.0" dependencies = [ "hex", - "windows 0.61.1", - "windows-core 0.61.0", + "windows", + "windows-core", ] [[package]] @@ -4434,9 +4375,9 @@ dependencies = [ [[package]] name = "zbus" -version = "5.11.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d07e46d035fb8e375b2ce63ba4e4ff90a7f73cf2ffb0138b29e1158d2eaadf7" +checksum = "b622b18155f7a93d1cd2dc8c01d2d6a44e08fb9ebb7b3f9e6ed101488bad6c91" dependencies = [ "async-broadcast", "async-executor", @@ -4452,14 +4393,15 @@ dependencies = [ "futures-core", "futures-lite", "hex", - "nix 0.30.1", + "nix", "ordered-stream", "serde", "serde_repr", "tokio", "tracing", "uds_windows", - "windows-sys 0.60.2", + "uuid", + "windows-sys 0.61.2", "winnow", "zbus_macros", "zbus_names", @@ -4468,9 +4410,9 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.11.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e797a9c847ed3ccc5b6254e8bcce056494b375b511b3d6edcec0aeb4defaca" +checksum = "1cdb94821ca8a87ca9c298b5d1cbd80e2a8b67115d99f6e4551ac49e42b6a314" dependencies = [ "proc-macro-crate", "proc-macro2", diff --git a/apps/desktop/desktop_native/Cargo.toml b/apps/desktop/desktop_native/Cargo.toml index 0b09daa9bdd..26f791fd660 100644 --- a/apps/desktop/desktop_native/Cargo.toml +++ b/apps/desktop/desktop_native/Cargo.toml @@ -21,13 +21,13 @@ publish = false [workspace.dependencies] aes = "=0.8.4" aes-gcm = "=0.10.3" -anyhow = "=1.0.94" +anyhow = "=1.0.100" arboard = { version = "=3.6.1", default-features = false } -ashpd = "=0.11.0" +ashpd = "=0.12.0" base64 = "=0.22.1" bitwarden-russh = { git = "https://github.com/bitwarden/bitwarden-russh.git", rev = "a641316227227f8777fdf56ac9fa2d6b5f7fe662" } byteorder = "=1.5.0" -bytes = "=1.10.1" +bytes = "=1.11.0" cbc = "=0.1.2" chacha20poly1305 = "=0.10.1" core-foundation = "=0.10.1" @@ -37,33 +37,33 @@ ed25519 = "=2.2.3" embed_plist = "=1.2.2" futures = "=0.3.31" hex = "=0.4.3" -homedir = "=0.3.4" +homedir = "=0.3.6" interprocess = "=2.2.1" -libc = "=0.2.177" +libc = "=0.2.178" linux-keyutils = "=0.2.4" memsec = "=0.7.0" -napi = "=2.16.17" -napi-build = "=2.2.0" -napi-derive = "=2.16.13" -oo7 = "=0.4.3" +napi = "=3.3.0" +napi-build = "=2.2.3" +napi-derive = "=3.2.5" +oo7 = "=0.5.0" pin-project = "=1.1.10" pkcs8 = "=0.10.2" -rand = "=0.9.1" +rand = "=0.9.2" rsa = "=0.9.6" russh-cryptovec = "=0.7.3" scopeguard = "=1.2.0" secmem-proc = "=0.3.7" -security-framework = "=3.5.0" +security-framework = "=3.5.1" security-framework-sys = "=2.15.0" serde = "=1.0.209" serde_json = "=1.0.127" sha2 = "=0.10.8" ssh-encoding = "=0.2.0" ssh-key = { version = "=0.6.7", default-features = false } -sysinfo = "=0.35.0" -thiserror = "=2.0.12" -tokio = "=1.45.0" -tokio-util = "=0.7.13" +sysinfo = "=0.37.2" +thiserror = "=2.0.17" +tokio = "=1.48.0" +tokio-util = "=0.7.17" tracing = "=0.1.41" tracing-subscriber = { version = "=0.3.20", features = [ "fmt", @@ -77,7 +77,7 @@ windows = "=0.61.1" windows-core = "=0.61.0" windows-future = "=0.2.0" windows-registry = "=0.6.1" -zbus = "=5.11.0" +zbus = "=5.12.0" zbus_polkit = "=5.0.0" zeroizing-alloc = "=0.1.0" diff --git a/apps/desktop/desktop_native/build.js b/apps/desktop/desktop_native/build.js index a7ed89a9c17..54a6dba8326 100644 --- a/apps/desktop/desktop_native/build.js +++ b/apps/desktop/desktop_native/build.js @@ -11,8 +11,8 @@ const rustTargetsMap = { "aarch64-pc-windows-msvc": { nodeArch: 'arm64', platform: 'win32' }, "x86_64-apple-darwin": { nodeArch: 'x64', platform: 'darwin' }, "aarch64-apple-darwin": { nodeArch: 'arm64', platform: 'darwin' }, - 'x86_64-unknown-linux-musl': { nodeArch: 'x64', platform: 'linux' }, - 'aarch64-unknown-linux-musl': { nodeArch: 'arm64', platform: 'linux' }, + 'x86_64-unknown-linux-gnu': { nodeArch: 'x64', platform: 'linux' }, + 'aarch64-unknown-linux-gnu': { nodeArch: 'arm64', platform: 'linux' }, } // Ensure the dist directory exists @@ -113,8 +113,8 @@ if (process.platform === "linux") { platformTargets.forEach(([target, _]) => { installTarget(target); - buildNapiModule(target); - buildProxyBin(target); - buildImporterBinaries(target); + buildNapiModule(target, mode === "release"); + buildProxyBin(target, mode === "release"); + buildImporterBinaries(target, mode === "release"); buildProcessIsolation(); }); diff --git a/apps/desktop/desktop_native/chromium_importer/src/chromium/mod.rs b/apps/desktop/desktop_native/chromium_importer/src/chromium/mod.rs index e57b40b5778..7011a2cce63 100644 --- a/apps/desktop/desktop_native/chromium_importer/src/chromium/mod.rs +++ b/apps/desktop/desktop_native/chromium_importer/src/chromium/mod.rs @@ -61,8 +61,8 @@ impl InstalledBrowserRetriever for DefaultInstalledBrowserRetriever { let mut browsers = Vec::with_capacity(SUPPORTED_BROWSER_MAP.len()); for (browser, config) in SUPPORTED_BROWSER_MAP.iter() { - let data_dir = get_browser_data_dir(config)?; - if data_dir.exists() { + let data_dir = get_and_validate_data_dir(config); + if data_dir.is_ok() { browsers.push((*browser).to_string()); } } @@ -114,7 +114,7 @@ pub async fn import_logins( #[derive(Debug, Clone, Copy)] pub(crate) struct BrowserConfig { pub name: &'static str, - pub data_dir: &'static str, + pub data_dir: &'static [&'static str], } pub(crate) static SUPPORTED_BROWSER_MAP: LazyLock< @@ -126,11 +126,19 @@ pub(crate) static SUPPORTED_BROWSER_MAP: LazyLock< .collect::>() }); -fn get_browser_data_dir(config: &BrowserConfig) -> Result { - let dir = dirs::home_dir() - .ok_or_else(|| anyhow!("Home directory not found"))? - .join(config.data_dir); - Ok(dir) +fn get_and_validate_data_dir(config: &BrowserConfig) -> Result { + for data_dir in config.data_dir.iter() { + let dir = dirs::home_dir() + .ok_or_else(|| anyhow!("Home directory not found"))? + .join(data_dir); + if dir.exists() { + return Ok(dir); + } + } + Err(anyhow!( + "Browser user data directory '{:?}' not found", + config.data_dir + )) } // @@ -174,13 +182,7 @@ fn load_local_state_for_browser(browser_name: &String) -> Result<(PathBuf, Local .get(browser_name.as_str()) .ok_or_else(|| anyhow!("Unsupported browser: {}", browser_name))?; - let data_dir = get_browser_data_dir(config)?; - if !data_dir.exists() { - return Err(anyhow!( - "Browser user data directory '{}' not found", - data_dir.display() - )); - } + let data_dir = get_and_validate_data_dir(config)?; let local_state = load_local_state(&data_dir)?; diff --git a/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/linux.rs b/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/linux.rs index 14e38797640..6fb6e6134c7 100644 --- a/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/linux.rs +++ b/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/linux.rs @@ -18,19 +18,22 @@ use crate::{ pub(crate) const SUPPORTED_BROWSERS: &[BrowserConfig] = &[ BrowserConfig { name: "Chrome", - data_dir: ".config/google-chrome", + data_dir: &[".config/google-chrome", "snap/chromium/common/chromium"], }, BrowserConfig { name: "Chromium", - data_dir: "snap/chromium/common/chromium", + data_dir: &["snap/chromium/common/chromium"], }, BrowserConfig { name: "Brave", - data_dir: "snap/brave/current/.config/BraveSoftware/Brave-Browser", + data_dir: &[ + "snap/brave/current/.config/BraveSoftware/Brave-Browser", + ".config/BraveSoftware/Brave-Browser", + ], }, BrowserConfig { name: "Opera", - data_dir: "snap/opera/current/.config/opera", + data_dir: &["snap/opera/current/.config/opera", ".config/opera"], }, ]; diff --git a/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/macos.rs b/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/macos.rs index 5d0b4f0c75c..6cd746d60b6 100644 --- a/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/macos.rs +++ b/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/macos.rs @@ -14,31 +14,31 @@ use crate::{ pub(crate) const SUPPORTED_BROWSERS: &[BrowserConfig] = &[ BrowserConfig { name: "Chrome", - data_dir: "Library/Application Support/Google/Chrome", + data_dir: &["Library/Application Support/Google/Chrome"], }, BrowserConfig { name: "Chromium", - data_dir: "Library/Application Support/Chromium", + data_dir: &["Library/Application Support/Chromium"], }, BrowserConfig { name: "Microsoft Edge", - data_dir: "Library/Application Support/Microsoft Edge", + data_dir: &["Library/Application Support/Microsoft Edge"], }, BrowserConfig { name: "Brave", - data_dir: "Library/Application Support/BraveSoftware/Brave-Browser", + data_dir: &["Library/Application Support/BraveSoftware/Brave-Browser"], }, BrowserConfig { name: "Arc", - data_dir: "Library/Application Support/Arc/User Data", + data_dir: &["Library/Application Support/Arc/User Data"], }, BrowserConfig { name: "Opera", - data_dir: "Library/Application Support/com.operasoftware.Opera", + data_dir: &["Library/Application Support/com.operasoftware.Opera"], }, BrowserConfig { name: "Vivaldi", - data_dir: "Library/Application Support/Vivaldi", + data_dir: &["Library/Application Support/Vivaldi"], }, ]; diff --git a/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/windows/mod.rs b/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/windows/mod.rs index 9cc89ed2161..524b5994873 100644 --- a/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/windows/mod.rs +++ b/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/windows/mod.rs @@ -25,27 +25,27 @@ pub use signature::*; pub(crate) const SUPPORTED_BROWSERS: &[BrowserConfig] = &[ BrowserConfig { name: "Brave", - data_dir: "AppData/Local/BraveSoftware/Brave-Browser/User Data", + data_dir: &["AppData/Local/BraveSoftware/Brave-Browser/User Data"], }, BrowserConfig { name: "Chrome", - data_dir: "AppData/Local/Google/Chrome/User Data", + data_dir: &["AppData/Local/Google/Chrome/User Data"], }, BrowserConfig { name: "Chromium", - data_dir: "AppData/Local/Chromium/User Data", + data_dir: &["AppData/Local/Chromium/User Data"], }, BrowserConfig { name: "Microsoft Edge", - data_dir: "AppData/Local/Microsoft/Edge/User Data", + data_dir: &["AppData/Local/Microsoft/Edge/User Data"], }, BrowserConfig { name: "Opera", - data_dir: "AppData/Roaming/Opera Software/Opera Stable", + data_dir: &["AppData/Roaming/Opera Software/Opera Stable"], }, BrowserConfig { name: "Vivaldi", - data_dir: "AppData/Local/Vivaldi/User Data", + data_dir: &["AppData/Local/Vivaldi/User Data"], }, ]; diff --git a/apps/desktop/desktop_native/chromium_importer/src/metadata.rs b/apps/desktop/desktop_native/chromium_importer/src/metadata.rs index 51a181f7f49..9aa2cea6e5e 100644 --- a/apps/desktop/desktop_native/chromium_importer/src/metadata.rs +++ b/apps/desktop/desktop_native/chromium_importer/src/metadata.rs @@ -7,9 +7,9 @@ pub struct NativeImporterMetadata { /// Identifies the importer pub id: String, /// Describes the strategies used to obtain imported data - pub loaders: Vec<&'static str>, + pub loaders: Vec, /// Identifies the instructions for the importer - pub instructions: &'static str, + pub instructions: String, } /// Returns a map of supported importers based on the current platform. @@ -36,9 +36,9 @@ pub fn get_supported_importers( PLATFORM_SUPPORTED_BROWSERS.iter().map(|b| b.name).collect(); for (id, browser_name) in IMPORTERS { - let mut loaders: Vec<&'static str> = vec!["file"]; + let mut loaders: Vec = vec!["file".to_string()]; if supported.contains(browser_name) { - loaders.push("chromium"); + loaders.push("chromium".to_string()); } if installed_browsers.contains(&browser_name.to_string()) { @@ -47,7 +47,7 @@ pub fn get_supported_importers( NativeImporterMetadata { id: id.to_string(), loaders, - instructions: "chromium", + instructions: "chromium".to_string(), }, ); } @@ -79,12 +79,9 @@ mod tests { map.keys().cloned().collect() } - fn get_loaders( - map: &HashMap, - id: &str, - ) -> HashSet<&'static str> { + fn get_loaders(map: &HashMap, id: &str) -> HashSet { map.get(id) - .map(|m| m.loaders.iter().copied().collect::>()) + .map(|m| m.loaders.iter().cloned().collect::>()) .unwrap_or_default() } @@ -107,7 +104,7 @@ mod tests { for (key, meta) in map.iter() { assert_eq!(&meta.id, key); assert_eq!(meta.instructions, "chromium"); - assert!(meta.loaders.contains(&"file")); + assert!(meta.loaders.contains(&"file".to_owned())); } } @@ -147,7 +144,7 @@ mod tests { for (key, meta) in map.iter() { assert_eq!(&meta.id, key); assert_eq!(meta.instructions, "chromium"); - assert!(meta.loaders.contains(&"file")); + assert!(meta.loaders.contains(&"file".to_owned())); } } @@ -183,7 +180,7 @@ mod tests { for (key, meta) in map.iter() { assert_eq!(&meta.id, key); assert_eq!(meta.instructions, "chromium"); - assert!(meta.loaders.contains(&"file")); + assert!(meta.loaders.contains(&"file".to_owned())); } } diff --git a/apps/desktop/desktop_native/core/src/biometric_v2/windows.rs b/apps/desktop/desktop_native/core/src/biometric_v2/windows.rs index 32d2eb7e6e6..669dd757c40 100644 --- a/apps/desktop/desktop_native/core/src/biometric_v2/windows.rs +++ b/apps/desktop/desktop_native/core/src/biometric_v2/windows.rs @@ -285,8 +285,8 @@ async fn windows_hello_authenticate_with_crypto( return Err(anyhow!("Failed to sign data")); } - let signature_buffer = signature.Result()?; - let signature_value = unsafe { as_mut_bytes(&signature_buffer)? }; + let mut signature_buffer = signature.Result()?; + let signature_value = unsafe { as_mut_bytes(&mut signature_buffer)? }; // The signature is deterministic based on the challenge and keychain key. Thus, it can be // hashed to a key. It is unclear what entropy this key provides. @@ -368,7 +368,7 @@ fn decrypt_data( Ok(plaintext) } -unsafe fn as_mut_bytes(buffer: &IBuffer) -> Result<&mut [u8]> { +unsafe fn as_mut_bytes(buffer: &mut IBuffer) -> Result<&mut [u8]> { let interop = buffer.cast::()?; unsafe { diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs b/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs index 8ba64618ffa..16cf778b575 100644 --- a/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs +++ b/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs @@ -226,7 +226,7 @@ impl BitwardenDesktopAgent { keystore.0.write().expect("RwLock is not poisoned").clear(); self.needs_unlock - .store(true, std::sync::atomic::Ordering::Relaxed); + .store(false, std::sync::atomic::Ordering::Relaxed); for (key, name, cipher_id) in new_keys.iter() { match parse_key_safe(key) { @@ -307,3 +307,87 @@ fn parse_key_safe(pem: &str) -> Result Err(anyhow::Error::msg(format!("Failed to parse key: {e}"))), } } + +#[cfg(test)] +mod tests { + use super::*; + + fn create_test_agent() -> ( + BitwardenDesktopAgent, + tokio::sync::mpsc::Receiver, + tokio::sync::broadcast::Sender<(u32, bool)>, + ) { + let (tx, rx) = tokio::sync::mpsc::channel(10); + let (response_tx, response_rx) = tokio::sync::broadcast::channel(10); + let agent = BitwardenDesktopAgent::new(tx, Arc::new(Mutex::new(response_rx))); + (agent, rx, response_tx) + } + + const TEST_ED25519_KEY: &str = "-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACCWETEIh/JX+ZaK0Xlg5xZ9QIfjiKD2Qs57PjhRY45trwAAAIhqmvSbapr0 +mwAAAAtzc2gtZWQyNTUxOQAAACCWETEIh/JX+ZaK0Xlg5xZ9QIfjiKD2Qs57PjhRY45trw +AAAEAHVflTgR/OEl8mg9UEKcO7SeB0FH4AiaUurhVfBWT4eZYRMQiH8lf5lorReWDnFn1A +h+OIoPZCzns+OFFjjm2vAAAAAAECAwQF +-----END OPENSSH PRIVATE KEY-----"; + + #[tokio::test] + async fn test_needs_unlock_initial_state() { + let (agent, _rx, _response_tx) = create_test_agent(); + + // Initially, needs_unlock should be true + assert!(agent + .needs_unlock + .load(std::sync::atomic::Ordering::Relaxed)); + } + + #[tokio::test] + async fn test_needs_unlock_after_set_keys() { + let (mut agent, _rx, _response_tx) = create_test_agent(); + agent + .is_running + .store(true, std::sync::atomic::Ordering::Relaxed); + + // Set keys should set needs_unlock to false + let keys = vec![( + TEST_ED25519_KEY.to_string(), + "test_key".to_string(), + "cipher_id".to_string(), + )]; + + agent.set_keys(keys).unwrap(); + + assert!(!agent + .needs_unlock + .load(std::sync::atomic::Ordering::Relaxed)); + } + + #[tokio::test] + async fn test_needs_unlock_after_clear_keys() { + let (mut agent, _rx, _response_tx) = create_test_agent(); + agent + .is_running + .store(true, std::sync::atomic::Ordering::Relaxed); + + // Set keys first + let keys = vec![( + TEST_ED25519_KEY.to_string(), + "test_key".to_string(), + "cipher_id".to_string(), + )]; + agent.set_keys(keys).unwrap(); + + // Verify needs_unlock is false + assert!(!agent + .needs_unlock + .load(std::sync::atomic::Ordering::Relaxed)); + + // Clear keys should set needs_unlock back to true + agent.clear_keys().unwrap(); + + // Verify needs_unlock is true + assert!(agent + .needs_unlock + .load(std::sync::atomic::Ordering::Relaxed)); + } +} diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/gather.rs b/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/gather.rs index 699203d613d..bf8e24dd79c 100644 --- a/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/gather.rs +++ b/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/gather.rs @@ -3,8 +3,12 @@ use sysinfo::{Pid, System}; use super::models::PeerInfo; pub fn get_peer_info(peer_pid: u32) -> Result { - let s = System::new_all(); - if let Some(process) = s.process(Pid::from_u32(peer_pid)) { + let mut system = System::new(); + system.refresh_processes( + sysinfo::ProcessesToUpdate::Some(&[Pid::from_u32(peer_pid)]), + true, + ); + if let Some(process) = system.process(Pid::from_u32(peer_pid)) { let peer_process_name = match process.name().to_str() { Some(name) => name.to_string(), None => { diff --git a/apps/desktop/desktop_native/macos_provider/Cargo.toml b/apps/desktop/desktop_native/macos_provider/Cargo.toml index 50f1834851d..8a34460268a 100644 --- a/apps/desktop/desktop_native/macos_provider/Cargo.toml +++ b/apps/desktop/desktop_native/macos_provider/Cargo.toml @@ -24,7 +24,7 @@ serde_json = { workspace = true } tokio = { workspace = true, features = ["sync"] } tracing = { workspace = true } tracing-subscriber = { workspace = true } -tracing-oslog = "0.3.0" +tracing-oslog = "=0.3.0" [build-dependencies] uniffi = { workspace = true, features = ["build"] } diff --git a/apps/desktop/desktop_native/macos_provider/README.md b/apps/desktop/desktop_native/macos_provider/README.md new file mode 100644 index 00000000000..1d4c1902465 --- /dev/null +++ b/apps/desktop/desktop_native/macos_provider/README.md @@ -0,0 +1,35 @@ +# Explainer: Mac OS Native Passkey Provider + +This document describes the changes introduced in https://github.com/bitwarden/clients/pull/13963, where we introduce the MacOS Native Passkey Provider. It gives the high level explanation of the architecture and some of the quirks and additional good to know context. + +## The high level +MacOS has native APIs (similar to iOS) to allow Credential Managers to provide credentials to the MacOS autofill system (in the PR referenced above, we only provide passkeys). + +We’ve written a Swift-based native autofill-extension. It’s bundled in the app-bundle in PlugIns, similar to the safari-extension. + +This swift extension currently communicates with our Electron app through IPC based on a unix socket. The IPC implementation is done in Rust and utilized through UniFFI + NAPI bindings. + +Footnotes: + +* We're not using the IPC framework as the implementation pre-dates the IPC framework. +* Alternatives like XPC or CFMessagePort may have better support for when the app is sandboxed. + +Electron receives the messages and passes it to Angular (through the electron-renderer event system). + +Our existing fido2 services in the renderer respond to events, displaying UI as necessary, and returns the signature back through the same mechanism, allowing people to authenticate with passkeys through the native system + UI. See [Mac OS Native Passkey Workflows](https://bitwarden.atlassian.net/wiki/spaces/EN/pages/1828356098/Mac+OS+Native+Passkey+Workflows) for demo videos. + +## Typescript + UI implementations + +We utilize the same FIDO2 implementation and interface that is already present for our browser authentication. It was designed by @coroiu with multiple ‘ui environments' in mind. + +Therefore, a lot of the plumbing is implemented in /autofill/services/desktop-fido2-user-interface.service.ts, which implements the interface that our fido2 authenticator/client expects to drive UI related behaviors. + +We’ve also implemented a couple FIDO2 UI components to handle registration/sign in flows, but also improved the “modal mode” of the desktop app. + +## Modal mode + +When modal mode is activated, the desktop app turns into a smaller modal that is always on top and cannot be resized. This is done to improve the UX of performing a passkey operation (or SSH operation). Once the operation is completed, the app returns to normal mode and its previous position. + +We are not using electron modal windows, for a couple reason. It would require us to send data in yet another layer of IPC, but also because we'd need to bootstrap entire renderer/app instead of reusing the existing window. + +Some modal modes may hide the 'traffic buttons' (window controls) due to design requirements. diff --git a/apps/desktop/desktop_native/macos_provider/build.sh b/apps/desktop/desktop_native/macos_provider/build.sh index 21e2e045af4..2f7a2d03541 100755 --- a/apps/desktop/desktop_native/macos_provider/build.sh +++ b/apps/desktop/desktop_native/macos_provider/build.sh @@ -8,6 +8,9 @@ rm -r tmp mkdir -p ./tmp/target/universal-darwin/release/ +rustup target add aarch64-apple-darwin +rustup target add x86_64-apple-darwin + cargo build --package macos_provider --target aarch64-apple-darwin --release cargo build --package macos_provider --target x86_64-apple-darwin --release diff --git a/apps/desktop/desktop_native/macos_provider/src/lib.rs b/apps/desktop/desktop_native/macos_provider/src/lib.rs index a5a134b0bfe..8619a77a0f2 100644 --- a/apps/desktop/desktop_native/macos_provider/src/lib.rs +++ b/apps/desktop/desktop_native/macos_provider/src/lib.rs @@ -57,6 +57,14 @@ trait Callback: Send + Sync { fn error(&self, error: BitwardenError); } +#[derive(uniffi::Enum, Debug)] +/// Store the connection status between the macOS credential provider extension +/// and the desktop application's IPC server. +pub enum ConnectionStatus { + Connected, + Disconnected, +} + #[derive(uniffi::Object)] pub struct MacOSProviderClient { to_server_send: tokio::sync::mpsc::Sender, @@ -65,8 +73,24 @@ pub struct MacOSProviderClient { response_callbacks_counter: AtomicU32, #[allow(clippy::type_complexity)] response_callbacks_queue: Arc, Instant)>>>, + + // Flag to track connection status - atomic for thread safety without locks + connection_status: Arc, } +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +/// Store native desktop status information to use for IPC communication +/// between the application and the macOS credential provider. +pub struct NativeStatus { + key: String, + value: String, +} + +// In our callback management, 0 is a reserved sequence number indicating that a message does not +// have a callback. +const NO_CALLBACK_INDICATOR: u32 = 0; + #[uniffi::export] impl MacOSProviderClient { // FIXME: Remove unwraps! They panic and terminate the whole application. @@ -93,13 +117,16 @@ impl MacOSProviderClient { let client = MacOSProviderClient { to_server_send, - response_callbacks_counter: AtomicU32::new(0), + response_callbacks_counter: AtomicU32::new(1), /* Start at 1 since 0 is reserved for + * "no callback" scenarios */ response_callbacks_queue: Arc::new(Mutex::new(HashMap::new())), + connection_status: Arc::new(std::sync::atomic::AtomicBool::new(false)), }; let path = desktop_core::ipc::path("af"); let queue = client.response_callbacks_queue.clone(); + let connection_status = client.connection_status.clone(); std::thread::spawn(move || { let rt = tokio::runtime::Builder::new_current_thread() @@ -117,9 +144,11 @@ impl MacOSProviderClient { match serde_json::from_str::(&message) { Ok(SerializedMessage::Command(CommandMessage::Connected)) => { info!("Connected to server"); + connection_status.store(true, std::sync::atomic::Ordering::Relaxed); } Ok(SerializedMessage::Command(CommandMessage::Disconnected)) => { info!("Disconnected from server"); + connection_status.store(false, std::sync::atomic::Ordering::Relaxed); } Ok(SerializedMessage::Message { sequence_number, @@ -157,12 +186,17 @@ impl MacOSProviderClient { client } + pub fn send_native_status(&self, key: String, value: String) { + let status = NativeStatus { key, value }; + self.send_message(status, None); + } + pub fn prepare_passkey_registration( &self, request: PasskeyRegistrationRequest, callback: Arc, ) { - self.send_message(request, Box::new(callback)); + self.send_message(request, Some(Box::new(callback))); } pub fn prepare_passkey_assertion( @@ -170,7 +204,7 @@ impl MacOSProviderClient { request: PasskeyAssertionRequest, callback: Arc, ) { - self.send_message(request, Box::new(callback)); + self.send_message(request, Some(Box::new(callback))); } pub fn prepare_passkey_assertion_without_user_interface( @@ -178,7 +212,18 @@ impl MacOSProviderClient { request: PasskeyAssertionWithoutUserInterfaceRequest, callback: Arc, ) { - self.send_message(request, Box::new(callback)); + self.send_message(request, Some(Box::new(callback))); + } + + pub fn get_connection_status(&self) -> ConnectionStatus { + let is_connected = self + .connection_status + .load(std::sync::atomic::Ordering::Relaxed); + if is_connected { + ConnectionStatus::Connected + } else { + ConnectionStatus::Disconnected + } } } @@ -200,7 +245,6 @@ enum SerializedMessage { } impl MacOSProviderClient { - // FIXME: Remove unwraps! They panic and terminate the whole application. #[allow(clippy::unwrap_used)] fn add_callback(&self, callback: Box) -> u32 { let sequence_number = self @@ -209,20 +253,23 @@ impl MacOSProviderClient { self.response_callbacks_queue .lock() - .unwrap() + .expect("response callbacks queue mutex should not be poisoned") .insert(sequence_number, (callback, Instant::now())); sequence_number } - // FIXME: Remove unwraps! They panic and terminate the whole application. #[allow(clippy::unwrap_used)] fn send_message( &self, message: impl Serialize + DeserializeOwned, - callback: Box, + callback: Option>, ) { - let sequence_number = self.add_callback(callback); + let sequence_number = if let Some(callback) = callback { + self.add_callback(callback) + } else { + NO_CALLBACK_INDICATOR + }; let message = serde_json::to_string(&SerializedMessage::Message { sequence_number, @@ -232,15 +279,17 @@ impl MacOSProviderClient { if let Err(e) = self.to_server_send.blocking_send(message) { // Make sure we remove the callback from the queue if we can't send the message - if let Some((cb, _)) = self - .response_callbacks_queue - .lock() - .unwrap() - .remove(&sequence_number) - { - cb.error(BitwardenError::Internal(format!( - "Error sending message: {e}" - ))); + if sequence_number != NO_CALLBACK_INDICATOR { + if let Some((callback, _)) = self + .response_callbacks_queue + .lock() + .expect("response callbacks queue mutex should not be poisoned") + .remove(&sequence_number) + { + callback.error(BitwardenError::Internal(format!( + "Error sending message: {e}" + ))); + } } } } diff --git a/apps/desktop/desktop_native/macos_provider/src/registration.rs b/apps/desktop/desktop_native/macos_provider/src/registration.rs index 9e697b75c16..c961566a86c 100644 --- a/apps/desktop/desktop_native/macos_provider/src/registration.rs +++ b/apps/desktop/desktop_native/macos_provider/src/registration.rs @@ -14,6 +14,7 @@ pub struct PasskeyRegistrationRequest { user_verification: UserVerification, supported_algorithms: Vec, window_xy: Position, + excluded_credentials: Vec>, } #[derive(uniffi::Record, Serialize, Deserialize)] diff --git a/apps/desktop/desktop_native/napi/index.d.ts b/apps/desktop/desktop_native/napi/index.d.ts index 01bfa65d571..375c65edb8d 100644 --- a/apps/desktop/desktop_native/napi/index.d.ts +++ b/apps/desktop/desktop_native/napi/index.d.ts @@ -1,125 +1,7 @@ -/* tslint:disable */ -/* eslint-disable */ - /* auto-generated by NAPI-RS */ - -export declare namespace passwords { - /** The error message returned when a password is not found during retrieval or deletion. */ - export const PASSWORD_NOT_FOUND: string - /** - * Fetch the stored password from the keychain. - * Throws {@link Error} with message {@link PASSWORD_NOT_FOUND} if the password does not exist. - */ - export function getPassword(service: string, account: string): Promise - /** - * Save the password to the keychain. Adds an entry if none exists otherwise updates the - * existing entry. - */ - export function setPassword(service: string, account: string, password: string): Promise - /** - * Delete the stored password from the keychain. - * Throws {@link Error} with message {@link PASSWORD_NOT_FOUND} if the password does not exist. - */ - export function deletePassword(service: string, account: string): Promise - /** Checks if the os secure storage is available */ - export function isAvailable(): Promise -} -export declare namespace biometrics { - export function prompt(hwnd: Buffer, message: string): Promise - export function available(): Promise - export function setBiometricSecret(service: string, account: string, secret: string, keyMaterial: KeyMaterial | undefined | null, ivB64: string): Promise - /** - * Retrieves the biometric secret for the given service and account. - * Throws Error with message [`passwords::PASSWORD_NOT_FOUND`] if the secret does not exist. - */ - export function getBiometricSecret(service: string, account: string, keyMaterial?: KeyMaterial | undefined | null): Promise - /** - * Derives key material from biometric data. Returns a string encoded with a - * base64 encoded key and the base64 encoded challenge used to create it - * separated by a `|` character. - * - * If the iv is provided, it will be used as the challenge. Otherwise a random challenge will - * be generated. - * - * `format!("|")` - */ - export function deriveKeyMaterial(iv?: string | undefined | null): Promise - export interface KeyMaterial { - osKeyPartB64: string - clientKeyPartB64?: string - } - export interface OsDerivedKey { - keyB64: string - ivB64: string - } -} -export declare namespace biometrics_v2 { - export function initBiometricSystem(): BiometricLockSystem - export function authenticate(biometricLockSystem: BiometricLockSystem, hwnd: Buffer, message: string): Promise - export function authenticateAvailable(biometricLockSystem: BiometricLockSystem): Promise - export function enrollPersistent(biometricLockSystem: BiometricLockSystem, userId: string, key: Buffer): Promise - export function provideKey(biometricLockSystem: BiometricLockSystem, userId: string, key: Buffer): Promise - export function unlock(biometricLockSystem: BiometricLockSystem, userId: string, hwnd: Buffer): Promise - export function unlockAvailable(biometricLockSystem: BiometricLockSystem, userId: string): Promise - export function hasPersistent(biometricLockSystem: BiometricLockSystem, userId: string): Promise - export function unenroll(biometricLockSystem: BiometricLockSystem, userId: string): Promise - export class BiometricLockSystem { } -} -export declare namespace clipboards { - export function read(): Promise - export function write(text: string, password: boolean): Promise -} -export declare namespace sshagent { - export interface PrivateKey { - privateKey: string - name: string - cipherId: string - } - export interface SshKey { - privateKey: string - publicKey: string - keyFingerprint: string - } - export interface SshUiRequest { - cipherId?: string - isList: boolean - processName: string - isForwarding: boolean - namespace?: string - } - export function serve(callback: (err: Error | null, arg: SshUiRequest) => any): Promise - export function stop(agentState: SshAgentState): void - export function isRunning(agentState: SshAgentState): boolean - export function setKeys(agentState: SshAgentState, newKeys: Array): void - export function lock(agentState: SshAgentState): void - export function clearKeys(agentState: SshAgentState): void - export class SshAgentState { } -} -export declare namespace processisolations { - export function disableCoredumps(): Promise - export function isCoreDumpingDisabled(): Promise - export function isolateProcess(): Promise -} -export declare namespace powermonitors { - export function onLock(callback: (err: Error | null, ) => any): Promise - export function isLockMonitorAvailable(): Promise -} -export declare namespace windows_registry { - export function createKey(key: string, subkey: string, value: string): Promise - export function deleteKey(key: string, subkey: string): Promise -} -export declare namespace ipc { - export interface IpcMessage { - clientId: number - kind: IpcMessageType - message?: string - } - export const enum IpcMessageType { - Connected = 0, - Disconnected = 1, - Message = 2 - } - export class IpcServer { +/* eslint-disable */ +export declare namespace autofill { + export class AutofillIpcServer { /** * Create and start the IPC server without blocking. * @@ -127,49 +9,18 @@ export declare namespace ipc { * connection and must be the same for both the server and client. @param callback * This function will be called whenever a message is received from a client. */ - static listen(name: string, callback: (error: null | Error, message: IpcMessage) => void): Promise + static listen(name: string, registrationCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyRegistrationRequest) => void, assertionCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyAssertionRequest) => void, assertionWithoutUserInterfaceCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyAssertionWithoutUserInterfaceRequest) => void, nativeStatusCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: NativeStatus) => void): Promise /** Return the path to the IPC server. */ getPath(): string /** Stop the IPC server. */ stop(): void - /** - * Send a message over the IPC server to all the connected clients - * - * @return The number of clients that the message was sent to. Note that the number of - * messages actually received may be less, as some clients could disconnect before - * receiving the message. - */ - send(message: string): number + completeRegistration(clientId: number, sequenceNumber: number, response: PasskeyRegistrationResponse): number + completeAssertion(clientId: number, sequenceNumber: number, response: PasskeyAssertionResponse): number + completeError(clientId: number, sequenceNumber: number, error: string): number } -} -export declare namespace autostart { - export function setAutostart(autostart: boolean, params: Array): Promise -} -export declare namespace autofill { - export function runCommand(value: string): Promise - export const enum UserVerification { - Preferred = 'preferred', - Required = 'required', - Discouraged = 'discouraged' - } - export interface Position { - x: number - y: number - } - export interface PasskeyRegistrationRequest { - rpId: string - userName: string - userHandle: Array - clientDataHash: Array - userVerification: UserVerification - supportedAlgorithms: Array - windowXy: Position - } - export interface PasskeyRegistrationResponse { - rpId: string - clientDataHash: Array - credentialId: Array - attestationObject: Array + export interface NativeStatus { + key: string + value: string } export interface PasskeyAssertionRequest { rpId: string @@ -178,6 +29,14 @@ export declare namespace autofill { allowedCredentials: Array> windowXy: Position } + export interface PasskeyAssertionResponse { + rpId: string + userHandle: Array + signature: Array + clientDataHash: Array + authenticatorData: Array + credentialId: Array + } export interface PasskeyAssertionWithoutUserInterfaceRequest { rpId: string credentialId: Array @@ -188,50 +47,93 @@ export declare namespace autofill { userVerification: UserVerification windowXy: Position } - export interface PasskeyAssertionResponse { + export interface PasskeyRegistrationRequest { rpId: string + userName: string userHandle: Array - signature: Array clientDataHash: Array - authenticatorData: Array + userVerification: UserVerification + supportedAlgorithms: Array + windowXy: Position + excludedCredentials: Array> + } + export interface PasskeyRegistrationResponse { + rpId: string + clientDataHash: Array credentialId: Array + attestationObject: Array } - export class IpcServer { - /** - * Create and start the IPC server without blocking. - * - * @param name The endpoint name to listen on. This name uniquely identifies the IPC - * connection and must be the same for both the server and client. @param callback - * This function will be called whenever a message is received from a client. - */ - static listen(name: string, registrationCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyRegistrationRequest) => void, assertionCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyAssertionRequest) => void, assertionWithoutUserInterfaceCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyAssertionWithoutUserInterfaceRequest) => void): Promise - /** Return the path to the IPC server. */ - getPath(): string - /** Stop the IPC server. */ - stop(): void - completeRegistration(clientId: number, sequenceNumber: number, response: PasskeyRegistrationResponse): number - completeAssertion(clientId: number, sequenceNumber: number, response: PasskeyAssertionResponse): number - completeError(clientId: number, sequenceNumber: number, error: string): number + export interface Position { + x: number + y: number + } + export function runCommand(value: string): Promise + export const enum UserVerification { + Preferred = 'preferred', + Required = 'required', + Discouraged = 'discouraged' } } -export declare namespace passkey_authenticator { - export function register(): void + +export declare namespace autostart { + export function setAutostart(autostart: boolean, params: Array): Promise } -export declare namespace logging { - export const enum LogLevel { - Trace = 0, - Debug = 1, - Info = 2, - Warn = 3, - Error = 4 + +export declare namespace autotype { + export function getForegroundWindowTitle(): string + export function typeInput(input: Array, keyboardShortcut: Array): void +} + +export declare namespace biometrics { + export function available(): Promise + /** + * Derives key material from biometric data. Returns a string encoded with a + * base64 encoded key and the base64 encoded challenge used to create it + * separated by a `|` character. + * + * If the iv is provided, it will be used as the challenge. Otherwise a random challenge will + * be generated. + * + * `format!("|")` + */ + export function deriveKeyMaterial(iv?: string | undefined | null): Promise + /** + * Retrieves the biometric secret for the given service and account. + * Throws Error with message [`passwords::PASSWORD_NOT_FOUND`] if the secret does not exist. + */ + export function getBiometricSecret(service: string, account: string, keyMaterial?: KeyMaterial | undefined | null): Promise + export interface KeyMaterial { + osKeyPartB64: string + clientKeyPartB64?: string } - export function initNapiLog(jsLogFn: (err: Error | null, arg0: LogLevel, arg1: string) => any): void + export interface OsDerivedKey { + keyB64: string + ivB64: string + } + export function prompt(hwnd: Buffer, message: string): Promise + export function setBiometricSecret(service: string, account: string, secret: string, keyMaterial: KeyMaterial | undefined | null, ivB64: string): Promise } + +export declare namespace biometrics_v2 { + export class BiometricLockSystem { + + } + export function authenticate(biometricLockSystem: BiometricLockSystem, hwnd: Buffer, message: string): Promise + export function authenticateAvailable(biometricLockSystem: BiometricLockSystem): Promise + export function enrollPersistent(biometricLockSystem: BiometricLockSystem, userId: string, key: Buffer): Promise + export function hasPersistent(biometricLockSystem: BiometricLockSystem, userId: string): Promise + export function initBiometricSystem(): BiometricLockSystem + export function provideKey(biometricLockSystem: BiometricLockSystem, userId: string, key: Buffer): Promise + export function unenroll(biometricLockSystem: BiometricLockSystem, userId: string): Promise + export function unlock(biometricLockSystem: BiometricLockSystem, userId: string, hwnd: Buffer): Promise + export function unlockAvailable(biometricLockSystem: BiometricLockSystem, userId: string): Promise +} + export declare namespace chromium_importer { - export interface ProfileInfo { - id: string - name: string - } + export function getAvailableProfiles(browser: string): Array + /** Returns OS aware metadata describing supported Chromium based importers as a JSON string. */ + export function getMetadata(): Record + export function importLogins(browser: string, profileId: string): Promise> export interface Login { url: string username: string @@ -252,12 +154,130 @@ export declare namespace chromium_importer { loaders: Array instructions: string } - /** Returns OS aware metadata describing supported Chromium based importers as a JSON string. */ - export function getMetadata(): Record - export function getAvailableProfiles(browser: string): Array - export function importLogins(browser: string, profileId: string): Promise> + export interface ProfileInfo { + id: string + name: string + } } -export declare namespace autotype { - export function getForegroundWindowTitle(): string - export function typeInput(input: Array, keyboardShortcut: Array): void + +export declare namespace clipboards { + export function read(): Promise + export function write(text: string, password: boolean): Promise +} + +export declare namespace ipc { + export class NativeIpcServer { + /** + * Create and start the IPC server without blocking. + * + * @param name The endpoint name to listen on. This name uniquely identifies the IPC + * connection and must be the same for both the server and client. @param callback + * This function will be called whenever a message is received from a client. + */ + static listen(name: string, callback: (error: null | Error, message: IpcMessage) => void): Promise + /** Return the path to the IPC server. */ + getPath(): string + /** Stop the IPC server. */ + stop(): void + /** + * Send a message over the IPC server to all the connected clients + * + * @return The number of clients that the message was sent to. Note that the number of + * messages actually received may be less, as some clients could disconnect before + * receiving the message. + */ + send(message: string): number + } + export interface IpcMessage { + clientId: number + kind: IpcMessageType + message?: string + } + export const enum IpcMessageType { + Connected = 0, + Disconnected = 1, + Message = 2 + } +} + +export declare namespace logging { + export function initNapiLog(jsLogFn: ((err: Error | null, arg0: LogLevel, arg1: string) => any)): void + export const enum LogLevel { + Trace = 0, + Debug = 1, + Info = 2, + Warn = 3, + Error = 4 + } +} + +export declare namespace passkey_authenticator { + export function register(): void +} + +export declare namespace passwords { + /** + * Delete the stored password from the keychain. + * Throws {@link Error} with message {@link PASSWORD_NOT_FOUND} if the password does not exist. + */ + export function deletePassword(service: string, account: string): Promise + /** + * Fetch the stored password from the keychain. + * Throws {@link Error} with message {@link PASSWORD_NOT_FOUND} if the password does not exist. + */ + export function getPassword(service: string, account: string): Promise + /** Checks if the os secure storage is available */ + export function isAvailable(): Promise + /** The error message returned when a password is not found during retrieval or deletion. */ + export const PASSWORD_NOT_FOUND: string + /** + * Save the password to the keychain. Adds an entry if none exists otherwise updates the + * existing entry. + */ + export function setPassword(service: string, account: string, password: string): Promise +} + +export declare namespace powermonitors { + export function isLockMonitorAvailable(): Promise + export function onLock(callback: ((err: Error | null, ) => any)): Promise +} + +export declare namespace processisolations { + export function disableCoredumps(): Promise + export function isCoreDumpingDisabled(): Promise + export function isolateProcess(): Promise +} + +export declare namespace sshagent { + export class SshAgentState { + + } + export function clearKeys(agentState: SshAgentState): void + export function isRunning(agentState: SshAgentState): boolean + export function lock(agentState: SshAgentState): void + export interface PrivateKey { + privateKey: string + name: string + cipherId: string + } + export function serve(callback: ((err: Error | null, arg: SshUiRequest) => Promise)): Promise + export function setKeys(agentState: SshAgentState, newKeys: Array): void + export interface SshKey { + privateKey: string + publicKey: string + keyFingerprint: string + } + export interface SshUiRequest { + cipherId?: string + isList: boolean + processName: string + isForwarding: boolean + namespace?: string + } + export function stop(agentState: SshAgentState): void +} + +export declare namespace windows_registry { + export function createKey(key: string, subkey: string, value: string): Promise + export function deleteKey(key: string, subkey: string): Promise } diff --git a/apps/desktop/desktop_native/napi/index.js b/apps/desktop/desktop_native/napi/index.js index 64819be4405..0362d9ee2bb 100644 --- a/apps/desktop/desktop_native/napi/index.js +++ b/apps/desktop/desktop_native/napi/index.js @@ -82,20 +82,20 @@ switch (platform) { switch (arch) { case "x64": nativeBinding = loadFirstAvailable( - ["desktop_napi.linux-x64-musl.node", "desktop_napi.linux-x64-gnu.node"], - "@bitwarden/desktop-napi-linux-x64-musl", + ["desktop_napi.linux-x64-gnu.node"], + "@bitwarden/desktop-napi-linux-x64-gnu", ); break; case "arm64": nativeBinding = loadFirstAvailable( - ["desktop_napi.linux-arm64-musl.node", "desktop_napi.linux-arm64-gnu.node"], - "@bitwarden/desktop-napi-linux-arm64-musl", + ["desktop_napi.linux-arm64-gnu.node"], + "@bitwarden/desktop-napi-linux-arm64-gnu", ); break; case "arm": nativeBinding = loadFirstAvailable( - ["desktop_napi.linux-arm-musl.node", "desktop_napi.linux-arm-gnu.node"], - "@bitwarden/desktop-napi-linux-arm-musl", + ["desktop_napi.linux-arm-gnu.node"], + "@bitwarden/desktop-napi-linux-arm-gnu", ); localFileExisted = existsSync(join(__dirname, "desktop_napi.linux-arm-gnueabihf.node")); try { diff --git a/apps/desktop/desktop_native/napi/package.json b/apps/desktop/desktop_native/napi/package.json index ca17377c9f2..0717bfd53ea 100644 --- a/apps/desktop/desktop_native/napi/package.json +++ b/apps/desktop/desktop_native/napi/package.json @@ -9,21 +9,17 @@ "author": "", "license": "GPL-3.0", "devDependencies": { - "@napi-rs/cli": "2.18.4" + "@napi-rs/cli": "3.2.0" }, "napi": { - "name": "desktop_napi", - "triples": { - "defaults": true, - "additional": [ - "x86_64-unknown-linux-musl", - "aarch64-unknown-linux-gnu", - "i686-pc-windows-msvc", - "armv7-unknown-linux-gnueabihf", - "aarch64-apple-darwin", - "aarch64-unknown-linux-musl", - "aarch64-pc-windows-msvc" - ] - } + "binaryName": "desktop_napi", + "targets": [ + "aarch64-apple-darwin", + "aarch64-pc-windows-msvc", + "aarch64-unknown-linux-gnu", + "armv7-unknown-linux-gnueabihf", + "i686-pc-windows-msvc", + "x86_64-unknown-linux-gnu" + ] } } diff --git a/apps/desktop/desktop_native/napi/scripts/build.js b/apps/desktop/desktop_native/napi/scripts/build.js index a6680f5d311..ad24b99d2fb 100644 --- a/apps/desktop/desktop_native/napi/scripts/build.js +++ b/apps/desktop/desktop_native/napi/scripts/build.js @@ -2,13 +2,21 @@ const { execSync } = require('child_process'); const args = process.argv.slice(2); + const isRelease = args.includes('--release'); +const argsString = args.join(' '); + if (isRelease) { console.log('Building release mode.'); + + execSync(`napi build --platform --no-js ${argsString}`, { stdio: 'inherit'}); + } else { console.log('Building debug mode.'); - process.env.RUST_LOG = 'debug'; -} -execSync(`napi build --platform --js false`, { stdio: 'inherit', env: process.env }); + execSync(`napi build --platform --no-js ${argsString}`, { + stdio: 'inherit', + env: { ...process.env, RUST_LOG: 'debug' } + }); +} diff --git a/apps/desktop/desktop_native/napi/src/lib.rs b/apps/desktop/desktop_native/napi/src/lib.rs index c34e7574f68..fe084349501 100644 --- a/apps/desktop/desktop_native/napi/src/lib.rs +++ b/apps/desktop/desktop_native/napi/src/lib.rs @@ -290,7 +290,7 @@ pub mod sshagent { use napi::{ bindgen_prelude::Promise, - threadsafe_function::{ErrorStrategy::CalleeHandled, ThreadsafeFunction}, + threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode}, }; use tokio::{self, sync::Mutex}; use tracing::error; @@ -326,13 +326,15 @@ pub mod sshagent { #[allow(clippy::unused_async)] // FIXME: Remove unused async! #[napi] pub async fn serve( - callback: ThreadsafeFunction, + callback: ThreadsafeFunction>, ) -> napi::Result { let (auth_request_tx, mut auth_request_rx) = tokio::sync::mpsc::channel::(32); let (auth_response_tx, auth_response_rx) = tokio::sync::broadcast::channel::<(u32, bool)>(32); let auth_response_tx_arc = Arc::new(Mutex::new(auth_response_tx)); + // Wrap callback in Arc so it can be shared across spawned tasks + let callback = Arc::new(callback); tokio::spawn(async move { let _ = auth_response_rx; @@ -342,42 +344,50 @@ pub mod sshagent { tokio::spawn(async move { let auth_response_tx_arc = cloned_response_tx_arc; let callback = cloned_callback; - let promise_result: Result, napi::Error> = callback - .call_async(Ok(SshUIRequest { + // In NAPI v3, obtain the JS callback return as a Promise and await it + // in Rust + let (tx, rx) = std::sync::mpsc::channel::>(); + let status = callback.call_with_return_value( + Ok(SshUIRequest { cipher_id: request.cipher_id, is_list: request.is_list, process_name: request.process_name, is_forwarding: request.is_forwarding, namespace: request.namespace, - })) - .await; - match promise_result { - Ok(promise_result) => match promise_result.await { - Ok(result) => { - let _ = auth_response_tx_arc - .lock() - .await - .send((request.request_id, result)) - .expect("should be able to send auth response to agent"); - } - Err(e) => { - error!(error = %e, "Calling UI callback promise was rejected"); - let _ = auth_response_tx_arc - .lock() - .await - .send((request.request_id, false)) - .expect("should be able to send auth response to agent"); + }), + ThreadsafeFunctionCallMode::Blocking, + move |ret: Result, napi::Error>, _env| { + if let Ok(p) = ret { + let _ = tx.send(p); } + Ok(()) }, - Err(e) => { - error!(error = %e, "Calling UI callback could not create promise"); - let _ = auth_response_tx_arc - .lock() - .await - .send((request.request_id, false)) - .expect("should be able to send auth response to agent"); + ); + + let result = if status == napi::Status::Ok { + match rx.recv() { + Ok(promise) => match promise.await { + Ok(v) => v, + Err(e) => { + error!(error = %e, "UI callback promise rejected"); + false + } + }, + Err(e) => { + error!(error = %e, "Failed to receive UI callback promise"); + false + } } - } + } else { + error!(error = ?status, "Calling UI callback failed"); + false + }; + + let _ = auth_response_tx_arc + .lock() + .await + .send((request.request_id, result)) + .expect("should be able to send auth response to agent"); }); } }); @@ -465,14 +475,12 @@ pub mod processisolations { #[napi] pub mod powermonitors { use napi::{ - threadsafe_function::{ - ErrorStrategy::CalleeHandled, ThreadsafeFunction, ThreadsafeFunctionCallMode, - }, + threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode}, tokio, }; #[napi] - pub async fn on_lock(callback: ThreadsafeFunction<(), CalleeHandled>) -> napi::Result<()> { + pub async fn on_lock(callback: ThreadsafeFunction<()>) -> napi::Result<()> { let (tx, mut rx) = tokio::sync::mpsc::channel::<()>(32); desktop_core::powermonitor::on_lock(tx) .await @@ -511,9 +519,7 @@ pub mod windows_registry { #[napi] pub mod ipc { use desktop_core::ipc::server::{Message, MessageType}; - use napi::threadsafe_function::{ - ErrorStrategy, ThreadsafeFunction, ThreadsafeFunctionCallMode, - }; + use napi::threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode}; #[napi(object)] pub struct IpcMessage { @@ -550,12 +556,12 @@ pub mod ipc { } #[napi] - pub struct IpcServer { + pub struct NativeIpcServer { server: desktop_core::ipc::server::Server, } #[napi] - impl IpcServer { + impl NativeIpcServer { /// Create and start the IPC server without blocking. /// /// @param name The endpoint name to listen on. This name uniquely identifies the IPC @@ -566,7 +572,7 @@ pub mod ipc { pub async fn listen( name: String, #[napi(ts_arg_type = "(error: null | Error, message: IpcMessage) => void")] - callback: ThreadsafeFunction, + callback: ThreadsafeFunction, ) -> napi::Result { let (send, mut recv) = tokio::sync::mpsc::channel::(32); tokio::spawn(async move { @@ -583,7 +589,7 @@ pub mod ipc { )) })?; - Ok(IpcServer { server }) + Ok(NativeIpcServer { server }) } /// Return the path to the IPC server. @@ -630,8 +636,9 @@ pub mod autostart { #[napi] pub mod autofill { use desktop_core::ipc::server::{Message, MessageType}; - use napi::threadsafe_function::{ - ErrorStrategy, ThreadsafeFunction, ThreadsafeFunctionCallMode, + use napi::{ + bindgen_prelude::FnArgs, + threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode}, }; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use tracing::error; @@ -686,6 +693,7 @@ pub mod autofill { pub user_verification: UserVerification, pub supported_algorithms: Vec, pub window_xy: Position, + pub excluded_credentials: Vec>, } #[napi(object)] @@ -724,6 +732,14 @@ pub mod autofill { pub window_xy: Position, } + #[napi(object)] + #[derive(Debug, Serialize, Deserialize)] + #[serde(rename_all = "camelCase")] + pub struct NativeStatus { + pub key: String, + pub value: String, + } + #[napi(object)] #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -737,14 +753,14 @@ pub mod autofill { } #[napi] - pub struct IpcServer { + pub struct AutofillIpcServer { server: desktop_core::ipc::server::Server, } // FIXME: Remove unwraps! They panic and terminate the whole application. #[allow(clippy::unwrap_used)] #[napi] - impl IpcServer { + impl AutofillIpcServer { /// Create and start the IPC server without blocking. /// /// @param name The endpoint name to listen on. This name uniquely identifies the IPC @@ -760,23 +776,24 @@ pub mod autofill { ts_arg_type = "(error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyRegistrationRequest) => void" )] registration_callback: ThreadsafeFunction< - (u32, u32, PasskeyRegistrationRequest), - ErrorStrategy::CalleeHandled, + FnArgs<(u32, u32, PasskeyRegistrationRequest)>, >, #[napi( ts_arg_type = "(error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyAssertionRequest) => void" )] assertion_callback: ThreadsafeFunction< - (u32, u32, PasskeyAssertionRequest), - ErrorStrategy::CalleeHandled, + FnArgs<(u32, u32, PasskeyAssertionRequest)>, >, #[napi( ts_arg_type = "(error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyAssertionWithoutUserInterfaceRequest) => void" )] assertion_without_user_interface_callback: ThreadsafeFunction< - (u32, u32, PasskeyAssertionWithoutUserInterfaceRequest), - ErrorStrategy::CalleeHandled, + FnArgs<(u32, u32, PasskeyAssertionWithoutUserInterfaceRequest)>, >, + #[napi( + ts_arg_type = "(error: null | Error, clientId: number, sequenceNumber: number, message: NativeStatus) => void" + )] + native_status_callback: ThreadsafeFunction<(u32, u32, NativeStatus)>, ) -> napi::Result { let (send, mut recv) = tokio::sync::mpsc::channel::(32); tokio::spawn(async move { @@ -801,7 +818,7 @@ pub mod autofill { Ok(msg) => { let value = msg .value - .map(|value| (client_id, msg.sequence_number, value)) + .map(|value| (client_id, msg.sequence_number, value).into()) .map_err(|e| napi::Error::from_reason(format!("{e:?}"))); assertion_callback @@ -820,7 +837,7 @@ pub mod autofill { Ok(msg) => { let value = msg .value - .map(|value| (client_id, msg.sequence_number, value)) + .map(|value| (client_id, msg.sequence_number, value).into()) .map_err(|e| napi::Error::from_reason(format!("{e:?}"))); assertion_without_user_interface_callback @@ -838,7 +855,7 @@ pub mod autofill { Ok(msg) => { let value = msg .value - .map(|value| (client_id, msg.sequence_number, value)) + .map(|value| (client_id, msg.sequence_number, value).into()) .map_err(|e| napi::Error::from_reason(format!("{e:?}"))); registration_callback .call(value, ThreadsafeFunctionCallMode::NonBlocking); @@ -849,6 +866,21 @@ pub mod autofill { } } + match serde_json::from_str::>(&message) { + Ok(msg) => { + let value = msg + .value + .map(|value| (client_id, msg.sequence_number, value)) + .map_err(|e| napi::Error::from_reason(format!("{e:?}"))); + native_status_callback + .call(value, ThreadsafeFunctionCallMode::NonBlocking); + continue; + } + Err(error) => { + error!(%error, "Unable to deserialze native status."); + } + } + error!(message, "Received an unknown message2"); } } @@ -863,7 +895,7 @@ pub mod autofill { )) })?; - Ok(IpcServer { server }) + Ok(AutofillIpcServer { server }) } /// Return the path to the IPC server. @@ -956,8 +988,9 @@ pub mod logging { use std::{fmt::Write, sync::OnceLock}; - use napi::threadsafe_function::{ - ErrorStrategy::CalleeHandled, ThreadsafeFunction, ThreadsafeFunctionCallMode, + use napi::{ + bindgen_prelude::FnArgs, + threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode}, }; use tracing::Level; use tracing_subscriber::{ @@ -968,7 +1001,7 @@ pub mod logging { Layer, }; - struct JsLogger(OnceLock>); + struct JsLogger(OnceLock>>); static JS_LOGGER: JsLogger = JsLogger(OnceLock::new()); #[napi] @@ -1040,13 +1073,13 @@ pub mod logging { let msg = (event.metadata().level().into(), buffer); if let Some(logger) = JS_LOGGER.0.get() { - let _ = logger.call(Ok(msg), ThreadsafeFunctionCallMode::NonBlocking); + let _ = logger.call(Ok(msg.into()), ThreadsafeFunctionCallMode::NonBlocking); }; } } #[napi] - pub fn init_napi_log(js_log_fn: ThreadsafeFunction<(LogLevel, String), CalleeHandled>) { + pub fn init_napi_log(js_log_fn: ThreadsafeFunction>) { let _ = JS_LOGGER.0.set(js_log_fn); // the log level hierarchy is determined by: @@ -1117,8 +1150,8 @@ pub mod chromium_importer { #[napi(object)] pub struct NativeImporterMetadata { pub id: String, - pub loaders: Vec<&'static str>, - pub instructions: &'static str, + pub loaders: Vec, + pub instructions: String, } impl From<_LoginImportResult> for LoginImportResult { @@ -1195,7 +1228,7 @@ pub mod chromium_importer { #[napi] pub mod autotype { #[napi] - pub fn get_foreground_window_title() -> napi::Result { + pub fn get_foreground_window_title() -> napi::Result { autotype::get_foreground_window_title().map_err(|_| { napi::Error::from_reason( "Autotype Error: failed to get foreground window title".to_string(), diff --git a/apps/desktop/desktop_native/objc/Cargo.toml b/apps/desktop/desktop_native/objc/Cargo.toml index 5ef791fb586..dd808537c28 100644 --- a/apps/desktop/desktop_native/objc/Cargo.toml +++ b/apps/desktop/desktop_native/objc/Cargo.toml @@ -14,8 +14,8 @@ tokio = { workspace = true } tracing = { workspace = true } [target.'cfg(target_os = "macos")'.build-dependencies] -cc = "=1.2.46" -glob = "=0.3.2" +cc = "=1.2.49" +glob = "=0.3.3" [lints] workspace = true diff --git a/apps/desktop/desktop_native/objc/src/native/autofill/commands/sync.m b/apps/desktop/desktop_native/objc/src/native/autofill/commands/sync.m index fc13c04591a..037a97c7590 100644 --- a/apps/desktop/desktop_native/objc/src/native/autofill/commands/sync.m +++ b/apps/desktop/desktop_native/objc/src/native/autofill/commands/sync.m @@ -14,40 +14,64 @@ void runSync(void* context, NSDictionary *params) { // Map credentials to ASPasswordCredential objects NSMutableArray *mappedCredentials = [NSMutableArray arrayWithCapacity:credentials.count]; + for (NSDictionary *credential in credentials) { - NSString *type = credential[@"type"]; - - if ([type isEqualToString:@"password"]) { - NSString *cipherId = credential[@"cipherId"]; - NSString *uri = credential[@"uri"]; - NSString *username = credential[@"username"]; - - ASCredentialServiceIdentifier *serviceId = [[ASCredentialServiceIdentifier alloc] - initWithIdentifier:uri type:ASCredentialServiceIdentifierTypeURL]; - ASPasswordCredentialIdentity *credential = [[ASPasswordCredentialIdentity alloc] - initWithServiceIdentifier:serviceId user:username recordIdentifier:cipherId]; - - [mappedCredentials addObject:credential]; - } - - if (@available(macos 14, *)) { - if ([type isEqualToString:@"fido2"]) { + @try { + NSString *type = credential[@"type"]; + + if ([type isEqualToString:@"password"]) { NSString *cipherId = credential[@"cipherId"]; - NSString *rpId = credential[@"rpId"]; - NSString *userName = credential[@"userName"]; - NSData *credentialId = decodeBase64URL(credential[@"credentialId"]); - NSData *userHandle = decodeBase64URL(credential[@"userHandle"]); + NSString *uri = credential[@"uri"]; + NSString *username = credential[@"username"]; + + // Skip credentials with null username since MacOS crashes if we send credentials with empty usernames + if ([username isKindOfClass:[NSNull class]] || username.length == 0) { + NSLog(@"Skipping credential, username is empty: %@", credential); + continue; + } - Class passkeyCredentialIdentityClass = NSClassFromString(@"ASPasskeyCredentialIdentity"); - id credential = [[passkeyCredentialIdentityClass alloc] - initWithRelyingPartyIdentifier:rpId - userName:userName - credentialID:credentialId - userHandle:userHandle - recordIdentifier:cipherId]; + ASCredentialServiceIdentifier *serviceId = [[ASCredentialServiceIdentifier alloc] + initWithIdentifier:uri type:ASCredentialServiceIdentifierTypeURL]; + ASPasswordCredentialIdentity *passwordIdentity = [[ASPasswordCredentialIdentity alloc] + initWithServiceIdentifier:serviceId user:username recordIdentifier:cipherId]; - [mappedCredentials addObject:credential]; + [mappedCredentials addObject:passwordIdentity]; + } + else if (@available(macos 14, *)) { + // Fido2CredentialView uses `userName` (camelCase) while Login uses `username`. + // This is intentional. Fido2 fields are flattened from the FIDO2 spec's nested structure + // (user.name -> userName, rp.id -> rpId) to maintain a clear distinction between these fields. + if ([type isEqualToString:@"fido2"]) { + NSString *cipherId = credential[@"cipherId"]; + NSString *rpId = credential[@"rpId"]; + NSString *userName = credential[@"userName"]; + + // Skip credentials with null username since MacOS crashes if we send credentials with empty usernames + if ([userName isKindOfClass:[NSNull class]] || userName.length == 0) { + NSLog(@"Skipping credential, username is empty: %@", credential); + continue; + } + + NSData *credentialId = decodeBase64URL(credential[@"credentialId"]); + NSData *userHandle = decodeBase64URL(credential[@"userHandle"]); + + Class passkeyCredentialIdentityClass = NSClassFromString(@"ASPasskeyCredentialIdentity"); + id passkeyIdentity = [[passkeyCredentialIdentityClass alloc] + initWithRelyingPartyIdentifier:rpId + userName:userName + credentialID:credentialId + userHandle:userHandle + recordIdentifier:cipherId]; + + [mappedCredentials addObject:passkeyIdentity]; + } } + } @catch (NSException *exception) { + // Silently skip any credential that causes an exception + // to make sure we don't fail the entire sync + // There is likely some invalid data in the credential, and not something the user should/could be asked to correct. + NSLog(@"ERROR: Exception processing credential: %@ - %@", exception.name, exception.reason); + continue; } } diff --git a/apps/desktop/desktop_native/objc/src/native/utils.m b/apps/desktop/desktop_native/objc/src/native/utils.m index 040c723a8ac..8f9493a7afb 100644 --- a/apps/desktop/desktop_native/objc/src/native/utils.m +++ b/apps/desktop/desktop_native/objc/src/native/utils.m @@ -18,9 +18,26 @@ NSString *serializeJson(NSDictionary *dictionary, NSError *error) { } NSData *decodeBase64URL(NSString *base64URLString) { + if (base64URLString.length == 0) { + return nil; + } + + // Replace URL-safe characters with standard base64 characters NSString *base64String = [base64URLString stringByReplacingOccurrencesOfString:@"-" withString:@"+"]; base64String = [base64String stringByReplacingOccurrencesOfString:@"_" withString:@"/"]; - + + // Add padding if needed + // Base 64 strings should be a multiple of 4 in length + NSUInteger paddingLength = 4 - (base64String.length % 4); + if (paddingLength < 4) { + NSMutableString *paddedString = [NSMutableString stringWithString:base64String]; + for (NSUInteger i = 0; i < paddingLength; i++) { + [paddedString appendString:@"="]; + } + base64String = paddedString; + } + + // Decode the string NSData *nsdataFromBase64String = [[NSData alloc] initWithBase64EncodedString:base64String options:0]; diff --git a/apps/desktop/desktop_native/rust-toolchain.toml b/apps/desktop/desktop_native/rust-toolchain.toml index c1ab6b3240a..0992ce9d294 100644 --- a/apps/desktop/desktop_native/rust-toolchain.toml +++ b/apps/desktop/desktop_native/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.87.0" +channel = "1.91.1" components = [ "rustfmt", "clippy" ] profile = "minimal" diff --git a/apps/desktop/desktop_native/windows_plugin_authenticator/src/lib.rs b/apps/desktop/desktop_native/windows_plugin_authenticator/src/lib.rs index 893fdf765fc..b38a1c725f2 100644 --- a/apps/desktop/desktop_native/windows_plugin_authenticator/src/lib.rs +++ b/apps/desktop/desktop_native/windows_plugin_authenticator/src/lib.rs @@ -153,7 +153,7 @@ fn add_authenticator() -> std::result::Result<(), String> { } } -type EXPERIMENTAL_WebAuthNPluginAddAuthenticatorFnDeclaration = unsafe extern "cdecl" fn( +type EXPERIMENTAL_WebAuthNPluginAddAuthenticatorFnDeclaration = unsafe extern "C" fn( pPluginAddAuthenticatorOptions: *const webauthn::ExperimentalWebAuthnPluginAddAuthenticatorOptions, ppPluginAddAuthenticatorResponse: *mut *mut webauthn::ExperimentalWebAuthnPluginAddAuthenticatorResponse, ) -> HRESULT; diff --git a/apps/desktop/electron-builder.json b/apps/desktop/electron-builder.json index 6e89799e9c4..f979df81fd0 100644 --- a/apps/desktop/electron-builder.json +++ b/apps/desktop/electron-builder.json @@ -20,7 +20,7 @@ "**/node_modules/@bitwarden/desktop-napi/index.js", "**/node_modules/@bitwarden/desktop-napi/desktop_napi.${platform}-${arch}*.node" ], - "electronVersion": "37.7.0", + "electronVersion": "39.2.6", "generateUpdatesFilesForAllChannels": true, "publish": { "provider": "generic", diff --git a/apps/desktop/macos/autofill-extension/Base.lproj/CredentialProviderViewController.xib b/apps/desktop/macos/autofill-extension/Base.lproj/CredentialProviderViewController.xib index 1e47cc54de2..132882c6477 100644 --- a/apps/desktop/macos/autofill-extension/Base.lproj/CredentialProviderViewController.xib +++ b/apps/desktop/macos/autofill-extension/Base.lproj/CredentialProviderViewController.xib @@ -8,63 +8,56 @@ + + + + + diff --git a/apps/desktop/macos/autofill-extension/CredentialProviderViewController.swift b/apps/desktop/macos/autofill-extension/CredentialProviderViewController.swift index 5568b2e75db..3de9468c8ab 100644 --- a/apps/desktop/macos/autofill-extension/CredentialProviderViewController.swift +++ b/apps/desktop/macos/autofill-extension/CredentialProviderViewController.swift @@ -11,63 +11,138 @@ import os class CredentialProviderViewController: ASCredentialProviderViewController { let logger: Logger - // There is something a bit strange about the initialization/deinitialization in this class. - // Sometimes deinit won't be called after a request has successfully finished, - // which would leave this class hanging in memory and the IPC connection open. - // - // If instead I make this a static, the deinit gets called correctly after each request. - // I think we still might want a static regardless, to be able to reuse the connection if possible. - let client: MacOsProviderClient = { - let logger = Logger(subsystem: "com.bitwarden.desktop.autofill-extension", category: "credential-provider") + @IBOutlet weak var statusLabel: NSTextField! + @IBOutlet weak var logoImageView: NSImageView! + + // The IPC client to communicate with the Bitwarden desktop app + private var client: MacOsProviderClient? + + // Timer for checking connection status + private var connectionMonitorTimer: Timer? + private var lastConnectionStatus: ConnectionStatus = .disconnected + + // We changed the getClient method to be async, here's why: + // This is so that we can check if the app is running, and launch it, without blocking the main thread + // Blocking the main thread caused MacOS layouting to 'fail' or at least be very delayed, which caused our getWindowPositioning code to sent 0,0. + // We also properly retry the IPC connection which sometimes would take some time to be up and running, depending on CPU load, phase of jupiters moon, etc. + private func getClient() async -> MacOsProviderClient { + if let client = self.client { + return client + } + let logger = Logger(subsystem: "com.bitwarden.desktop.autofill-extension", category: "credential-provider") + // Check if the Electron app is running let workspace = NSWorkspace.shared let isRunning = workspace.runningApplications.contains { app in app.bundleIdentifier == "com.bitwarden.desktop" } - + if !isRunning { - logger.log("[autofill-extension] Bitwarden Desktop not running, attempting to launch") - - // Try to launch the app + logger.log("[autofill-extension] Bitwarden Desktop not running, attempting to launch") + + // Launch the app and wait for it to be ready if let appURL = workspace.urlForApplication(withBundleIdentifier: "com.bitwarden.desktop") { - let semaphore = DispatchSemaphore(value: 0) - - workspace.openApplication(at: appURL, - configuration: NSWorkspace.OpenConfiguration()) { app, error in - if let error = error { - logger.error("[autofill-extension] Failed to launch Bitwarden Desktop: \(error.localizedDescription)") - } else if let app = app { - logger.log("[autofill-extension] Successfully launched Bitwarden Desktop") - } else { - logger.error("[autofill-extension] Failed to launch Bitwarden Desktop: unknown error") + await withCheckedContinuation { continuation in + workspace.openApplication(at: appURL, configuration: NSWorkspace.OpenConfiguration()) { app, error in + if let error = error { + logger.error("[autofill-extension] Failed to launch Bitwarden Desktop: \(error.localizedDescription)") + } else { + logger.log("[autofill-extension] Successfully launched Bitwarden Desktop") + } + continuation.resume() } - semaphore.signal() } - - // Wait for launch completion with timeout - _ = semaphore.wait(timeout: .now() + 5.0) - - // Add a small delay to allow for initialization - Thread.sleep(forTimeInterval: 1.0) - } else { - logger.error("[autofill-extension] Could not find Bitwarden Desktop app") } - } else { - logger.log("[autofill-extension] Bitwarden Desktop is running") + } + + logger.log("[autofill-extension] Connecting to Bitwarden over IPC") + + // Retry connecting to the Bitwarden IPC with an increasing delay + let maxRetries = 20 + let delayMs = 500 + var newClient: MacOsProviderClient? + + for attempt in 1...maxRetries { + logger.log("[autofill-extension] Connection attempt \(attempt)") + + // Create a new client instance for each retry + newClient = MacOsProviderClient.connect() + try? await Task.sleep(nanoseconds: UInt64(100 * attempt + (delayMs * 1_000_000))) // Convert ms to nanoseconds + let connectionStatus = newClient!.getConnectionStatus() + + logger.log("[autofill-extension] Connection attempt \(attempt), status: \(connectionStatus == .connected ? "connected" : "disconnected")") + + if connectionStatus == .connected { + logger.log("[autofill-extension] Successfully connected to Bitwarden (attempt \(attempt))") + break + } else { + if attempt < maxRetries { + logger.log("[autofill-extension] Retrying connection") + } else { + logger.error("[autofill-extension] Failed to connect after \(maxRetries) attempts, final status: \(connectionStatus == .connected ? "connected" : "disconnected")") + } + } } - logger.log("[autofill-extension] Connecting to Bitwarden over IPC") - - return MacOsProviderClient.connect() - }() + self.client = newClient + return newClient! + } + + // Setup the connection monitoring timer + private func setupConnectionMonitoring() { + // Check connection status every 1 second + connectionMonitorTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in + self?.checkConnectionStatus() + } + + // Make sure timer runs even when UI is busy + RunLoop.current.add(connectionMonitorTimer!, forMode: .common) + + // Initial check + checkConnectionStatus() + } + + // Check the connection status by calling into Rust + // If the connection is has changed and is now disconnected, cancel the request + private func checkConnectionStatus() { + // Only check connection status if the client has been initialized. + // Initialization is done asynchronously, so we might be called before it's ready + // In that case we just skip this check and wait for the next timer tick and re-check + guard let client = self.client else { + return + } + + // Get the current connection status from Rust + let currentStatus = client.getConnectionStatus() + + // Only post notification if state changed + if currentStatus != lastConnectionStatus { + if(currentStatus == .connected) { + logger.log("[autofill-extension] Connection status changed: Connected") + } else { + logger.log("[autofill-extension] Connection status changed: Disconnected") + } + + // Save the new status + lastConnectionStatus = currentStatus + + // If we just disconnected, try to cancel the request + if currentStatus == .disconnected { + self.extensionContext.cancelRequest(withError: BitwardenError.Internal("Bitwarden desktop app disconnected")) + } + } + } init() { logger = Logger(subsystem: "com.bitwarden.desktop.autofill-extension", category: "credential-provider") logger.log("[autofill-extension] initializing extension") - super.init(nibName: nil, bundle: nil) + super.init(nibName: "CredentialProviderViewController", bundle: nil) + + // Setup connection monitoring now that self is available + setupConnectionMonitoring() } required init?(coder: NSCoder) { @@ -76,45 +151,109 @@ class CredentialProviderViewController: ASCredentialProviderViewController { deinit { logger.log("[autofill-extension] deinitializing extension") - } - - - @IBAction func cancel(_ sender: AnyObject?) { - self.extensionContext.cancelRequest(withError: NSError(domain: ASExtensionErrorDomain, code: ASExtensionError.userCanceled.rawValue)) - } - - @IBAction func passwordSelected(_ sender: AnyObject?) { - let passwordCredential = ASPasswordCredential(user: "j_appleseed", password: "apple1234") - self.extensionContext.completeRequest(withSelectedCredential: passwordCredential, completionHandler: nil) - } - - private func getWindowPosition() -> Position { - let frame = self.view.window?.frame ?? .zero - let screenHeight = NSScreen.main?.frame.height ?? 0 - // frame.width and frame.height is always 0. Estimating works OK for now. - let estimatedWidth:CGFloat = 400; - let estimatedHeight:CGFloat = 200; - let centerX = Int32(round(frame.origin.x + estimatedWidth/2)) - let centerY = Int32(round(screenHeight - (frame.origin.y + estimatedHeight/2))) - - return Position(x: centerX, y:centerY) + // Stop the connection monitor timer + connectionMonitorTimer?.invalidate() + connectionMonitorTimer = nil } - override func loadView() { - let view = NSView() - // Hide the native window since we only need the IPC connection - view.isHidden = true - self.view = view + private func getWindowPosition() async -> Position { + let screenHeight = NSScreen.main?.frame.height ?? 1440 + + logger.log("[autofill-extension] position: Getting window position") + + // To whomever is reading this. Sorry. But MacOS couldn't give us an accurate window positioning, possibly due to animations + // So I added some retry logic, as well as a fall back to the mouse position which is likely at the sort of the right place. + // In my testing we often succed after 4-7 attempts. + // Wait for window frame to stabilize (animation to complete) + var lastFrame: CGRect = .zero + var stableCount = 0 + let requiredStableChecks = 3 + let maxAttempts = 20 + var attempts = 0 + + while stableCount < requiredStableChecks && attempts < maxAttempts { + let currentFrame: CGRect = self.view.window?.frame ?? .zero + + if currentFrame.equalTo(lastFrame) && !currentFrame.equalTo(.zero) { + stableCount += 1 + } else { + stableCount = 0 + lastFrame = currentFrame + } + + try? await Task.sleep(nanoseconds: 16_666_666) // ~60fps (16.67ms) + attempts += 1 + } + + let finalWindowFrame = self.view.window?.frame ?? .zero + logger.log("[autofill-extension] position: Final window frame: \(NSStringFromRect(finalWindowFrame))") + + // Use stabilized window frame if available, otherwise fallback to mouse position + if finalWindowFrame.origin.x != 0 || finalWindowFrame.origin.y != 0 { + let centerX = Int32(round(finalWindowFrame.origin.x)) + let centerY = Int32(round(screenHeight - finalWindowFrame.origin.y)) + logger.log("[autofill-extension] position: Using window position: x=\(centerX), y=\(centerY)") + return Position(x: centerX, y: centerY) + } else { + // Fallback to mouse position + let mouseLocation = NSEvent.mouseLocation + let mouseX = Int32(round(mouseLocation.x)) + let mouseY = Int32(round(screenHeight - mouseLocation.y)) + logger.log("[autofill-extension] position: Using mouse position fallback: x=\(mouseX), y=\(mouseY)") + return Position(x: mouseX, y: mouseY) + } } - + + override func viewDidLoad() { + super.viewDidLoad() + + // Initially hide the view + self.view.isHidden = true + } + + override func prepareInterfaceForExtensionConfiguration() { + // Show the configuration UI + self.view.isHidden = false + + // Set the localized message + statusLabel.stringValue = NSLocalizedString("autofillConfigurationMessage", comment: "Message shown when Bitwarden is enabled in system settings") + + // Send the native status request asynchronously + Task { + let client = await getClient() + client.sendNativeStatus(key: "request-sync", value: "") + } + + // Complete the configuration after 2 seconds + DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { [weak self] in + self?.extensionContext.completeExtensionConfigurationRequest() + } + } + + /* + In order to implement this method, we need to query the state of the vault to be unlocked and have one and only one matching credential so that it doesn't need to show ui. + If we do show UI, it's going to fail and disconnect after the platform timeout which is 3s. + For now we just claim to always need UI displayed. + */ override func provideCredentialWithoutUserInteraction(for credentialRequest: any ASCredentialRequest) { + let error = ASExtensionError(.userInteractionRequired) + self.extensionContext.cancelRequest(withError: error) + return + } + + /* + Implement this method if provideCredentialWithoutUserInteraction(for:) can fail with + ASExtensionError.userInteractionRequired. In this case, the system may present your extension's + UI and call this method. Show appropriate UI for authenticating the user then provide the password + by completing the extension request with the associated ASPasswordCredential. + */ + override func prepareInterfaceToProvideCredential(for credentialRequest: ASCredentialRequest) { let timeoutTimer = createTimer() - if let request = credentialRequest as? ASPasskeyCredentialRequest { if let passkeyIdentity = request.credentialIdentity as? ASPasskeyCredentialIdentity { - - logger.log("[autofill-extension] provideCredentialWithoutUserInteraction2(passkey) called \(request)") + + logger.log("[autofill-extension] prepareInterfaceToProvideCredential (passkey) called \(request)") class CallbackImpl: PreparePasskeyAssertionCallback { let ctx: ASCredentialProviderExtensionContext @@ -154,18 +293,25 @@ class CredentialProviderViewController: ASCredentialProviderViewController { UserVerification.discouraged } - let req = PasskeyAssertionWithoutUserInterfaceRequest( - rpId: passkeyIdentity.relyingPartyIdentifier, - credentialId: passkeyIdentity.credentialID, - userName: passkeyIdentity.userName, - userHandle: passkeyIdentity.userHandle, - recordIdentifier: passkeyIdentity.recordIdentifier, - clientDataHash: request.clientDataHash, - userVerification: userVerification, - windowXy: self.getWindowPosition() - ) - - self.client.preparePasskeyAssertionWithoutUserInterface(request: req, callback: CallbackImpl(self.extensionContext, self.logger, timeoutTimer)) + /* + We're still using the old request type here, because we're sending the same data, we're expecting a single credential to be used + */ + Task { + let windowPosition = await self.getWindowPosition() + let req = PasskeyAssertionWithoutUserInterfaceRequest( + rpId: passkeyIdentity.relyingPartyIdentifier, + credentialId: passkeyIdentity.credentialID, + userName: passkeyIdentity.userName, + userHandle: passkeyIdentity.userHandle, + recordIdentifier: passkeyIdentity.recordIdentifier, + clientDataHash: request.clientDataHash, + userVerification: userVerification, + windowXy: windowPosition + ) + + let client = await getClient() + client.preparePasskeyAssertionWithoutUserInterface(request: req, callback: CallbackImpl(self.extensionContext, self.logger, timeoutTimer)) + } return } } @@ -176,16 +322,6 @@ class CredentialProviderViewController: ASCredentialProviderViewController { self.extensionContext.cancelRequest(withError: BitwardenError.Internal("Invalid authentication request")) } - /* - Implement this method if provideCredentialWithoutUserInteraction(for:) can fail with - ASExtensionError.userInteractionRequired. In this case, the system may present your extension's - UI and call this method. Show appropriate UI for authenticating the user then provide the password - by completing the extension request with the associated ASPasswordCredential. - - override func prepareInterfaceToProvideCredential(for credentialIdentity: ASPasswordCredentialIdentity) { - } - */ - private func createTimer() -> DispatchWorkItem { // Create a timer for 600 second timeout let timeoutTimer = DispatchWorkItem { [weak self] in @@ -246,18 +382,32 @@ class CredentialProviderViewController: ASCredentialProviderViewController { UserVerification.discouraged } - let req = PasskeyRegistrationRequest( - rpId: passkeyIdentity.relyingPartyIdentifier, - userName: passkeyIdentity.userName, - userHandle: passkeyIdentity.userHandle, - clientDataHash: request.clientDataHash, - userVerification: userVerification, - supportedAlgorithms: request.supportedAlgorithms.map{ Int32($0.rawValue) }, - windowXy: self.getWindowPosition() - ) + // Convert excluded credentials to an array of credential IDs + var excludedCredentialIds: [Data] = [] + if #available(macOSApplicationExtension 15.0, *) { + if let excludedCreds = request.excludedCredentials { + excludedCredentialIds = excludedCreds.map { $0.credentialID } + } + } + logger.log("[autofill-extension] prepareInterface(passkey) calling preparePasskeyRegistration") - self.client.preparePasskeyRegistration(request: req, callback: CallbackImpl(self.extensionContext, self.logger, timeoutTimer)) + Task { + let windowPosition = await self.getWindowPosition() + let req = PasskeyRegistrationRequest( + rpId: passkeyIdentity.relyingPartyIdentifier, + userName: passkeyIdentity.userName, + userHandle: passkeyIdentity.userHandle, + clientDataHash: request.clientDataHash, + userVerification: userVerification, + supportedAlgorithms: request.supportedAlgorithms.map{ Int32($0.rawValue) }, + windowXy: windowPosition, + excludedCredentials: excludedCredentialIds + ) + + let client = await getClient() + client.preparePasskeyRegistration(request: req, callback: CallbackImpl(self.extensionContext, self.logger, timeoutTimer)) + } return } } @@ -310,18 +460,22 @@ class CredentialProviderViewController: ASCredentialProviderViewController { UserVerification.discouraged } - let req = PasskeyAssertionRequest( - rpId: requestParameters.relyingPartyIdentifier, - clientDataHash: requestParameters.clientDataHash, - userVerification: userVerification, - allowedCredentials: requestParameters.allowedCredentials, - windowXy: self.getWindowPosition() - //extensionInput: requestParameters.extensionInput, - ) - let timeoutTimer = createTimer() - self.client.preparePasskeyAssertion(request: req, callback: CallbackImpl(self.extensionContext, self.logger, timeoutTimer)) + Task { + let windowPosition = await self.getWindowPosition() + let req = PasskeyAssertionRequest( + rpId: requestParameters.relyingPartyIdentifier, + clientDataHash: requestParameters.clientDataHash, + userVerification: userVerification, + allowedCredentials: requestParameters.allowedCredentials, + windowXy: windowPosition + //extensionInput: requestParameters.extensionInput, // We don't support extensions yet + ) + + let client = await getClient() + client.preparePasskeyAssertion(request: req, callback: CallbackImpl(self.extensionContext, self.logger, timeoutTimer)) + } return } } diff --git a/apps/desktop/macos/autofill-extension/Info.plist b/apps/desktop/macos/autofill-extension/Info.plist index 539cfa35b9d..7de0d4d152b 100644 --- a/apps/desktop/macos/autofill-extension/Info.plist +++ b/apps/desktop/macos/autofill-extension/Info.plist @@ -10,9 +10,9 @@ ProvidesPasskeys + ShowsConfigurationUI + - ASCredentialProviderExtensionShowsConfigurationUI - NSExtensionPointIdentifier com.apple.authentication-services-credential-provider-ui diff --git a/apps/desktop/macos/autofill-extension/autofill_extension.entitlements b/apps/desktop/macos/autofill-extension/autofill_extension.entitlements index 86c7195768e..d5c7b8a2cc8 100644 --- a/apps/desktop/macos/autofill-extension/autofill_extension.entitlements +++ b/apps/desktop/macos/autofill-extension/autofill_extension.entitlements @@ -2,11 +2,9 @@ - com.apple.developer.authentication-services.autofill-credential-provider - - com.apple.security.app-sandbox - - com.apple.security.application-groups + com.apple.security.app-sandbox + + com.apple.security.application-groups LTZ2PFU5D6.com.bitwarden.desktop diff --git a/apps/desktop/macos/autofill-extension/bitwarden-icon.png b/apps/desktop/macos/autofill-extension/bitwarden-icon.png new file mode 100644 index 00000000000..9a05bc7bbdd Binary files /dev/null and b/apps/desktop/macos/autofill-extension/bitwarden-icon.png differ diff --git a/apps/desktop/macos/autofill-extension/en.lproj/Localizable.strings b/apps/desktop/macos/autofill-extension/en.lproj/Localizable.strings new file mode 100644 index 00000000000..95730dff286 --- /dev/null +++ b/apps/desktop/macos/autofill-extension/en.lproj/Localizable.strings @@ -0,0 +1,2 @@ +/* Message shown during passkey configuration */ +"autofillConfigurationMessage" = "Enabling Bitwarden..."; diff --git a/apps/desktop/macos/desktop.xcodeproj/project.pbxproj b/apps/desktop/macos/desktop.xcodeproj/project.pbxproj index ff257097f26..ed19fc9ef5d 100644 --- a/apps/desktop/macos/desktop.xcodeproj/project.pbxproj +++ b/apps/desktop/macos/desktop.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ 3368DB392C654B8100896B75 /* BitwardenMacosProviderFFI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3368DB382C654B8100896B75 /* BitwardenMacosProviderFFI.xcframework */; }; 3368DB3B2C654F3800896B75 /* BitwardenMacosProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3368DB3A2C654F3800896B75 /* BitwardenMacosProvider.swift */; }; + 9AE299092DF9D82E00AAE454 /* bitwarden-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 9AE299082DF9D82E00AAE454 /* bitwarden-icon.png */; }; + 9AE299122DFB57A200AAE454 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9AE2990D2DFB57A200AAE454 /* Localizable.strings */; }; E1DF713F2B342F6900F29026 /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1DF713E2B342F6900F29026 /* AuthenticationServices.framework */; }; E1DF71422B342F6900F29026 /* CredentialProviderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1DF71412B342F6900F29026 /* CredentialProviderViewController.swift */; }; E1DF71452B342F6900F29026 /* CredentialProviderViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E1DF71432B342F6900F29026 /* CredentialProviderViewController.xib */; }; @@ -18,6 +20,8 @@ 3368DB382C654B8100896B75 /* BitwardenMacosProviderFFI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = BitwardenMacosProviderFFI.xcframework; path = ../desktop_native/macos_provider/BitwardenMacosProviderFFI.xcframework; sourceTree = ""; }; 3368DB3A2C654F3800896B75 /* BitwardenMacosProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BitwardenMacosProvider.swift; sourceTree = ""; }; 968ED08A2C52A47200FFFEE6 /* ReleaseAppStore.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ReleaseAppStore.xcconfig; sourceTree = ""; }; + 9AE299082DF9D82E00AAE454 /* bitwarden-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "bitwarden-icon.png"; sourceTree = ""; }; + 9AE2990C2DFB57A200AAE454 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Localizable.strings; sourceTree = ""; }; D83832AB2D67B9AE003FB9F8 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; D83832AD2D67B9D0003FB9F8 /* ReleaseDeveloper.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ReleaseDeveloper.xcconfig; sourceTree = ""; }; E1DF713C2B342F6900F29026 /* autofill-extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "autofill-extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -41,6 +45,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 9AE2990E2DFB57A200AAE454 /* en.lproj */ = { + isa = PBXGroup; + children = ( + 9AE2990D2DFB57A200AAE454 /* Localizable.strings */, + ); + path = en.lproj; + sourceTree = ""; + }; E1DF711D2B342E2800F29026 = { isa = PBXGroup; children = ( @@ -73,6 +85,8 @@ E1DF71402B342F6900F29026 /* autofill-extension */ = { isa = PBXGroup; children = ( + 9AE2990E2DFB57A200AAE454 /* en.lproj */, + 9AE299082DF9D82E00AAE454 /* bitwarden-icon.png */, 3368DB3A2C654F3800896B75 /* BitwardenMacosProvider.swift */, E1DF71412B342F6900F29026 /* CredentialProviderViewController.swift */, E1DF71432B342F6900F29026 /* CredentialProviderViewController.xib */, @@ -124,6 +138,7 @@ knownRegions = ( en, Base, + sv, ); mainGroup = E1DF711D2B342E2800F29026; productRefGroup = E1DF71272B342E2800F29026 /* Products */; @@ -141,6 +156,8 @@ buildActionMask = 2147483647; files = ( E1DF71452B342F6900F29026 /* CredentialProviderViewController.xib in Resources */, + 9AE299122DFB57A200AAE454 /* Localizable.strings in Resources */, + 9AE299092DF9D82E00AAE454 /* bitwarden-icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -159,6 +176,14 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ + 9AE2990D2DFB57A200AAE454 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 9AE2990C2DFB57A200AAE454 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; E1DF71432B342F6900F29026 /* CredentialProviderViewController.xib */ = { isa = PBXVariantGroup; children = ( diff --git a/apps/desktop/native-messaging-test-runner/package-lock.json b/apps/desktop/native-messaging-test-runner/package-lock.json index 9ad1ffb3ec0..9e3b6ba23e0 100644 --- a/apps/desktop/native-messaging-test-runner/package-lock.json +++ b/apps/desktop/native-messaging-test-runner/package-lock.json @@ -19,7 +19,7 @@ "yargs": "18.0.0" }, "devDependencies": { - "@types/node": "22.19.1", + "@types/node": "22.19.3", "typescript": "5.4.2" } }, @@ -117,9 +117,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.19.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz", - "integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "license": "MIT", "peer": true, "dependencies": { diff --git a/apps/desktop/native-messaging-test-runner/package.json b/apps/desktop/native-messaging-test-runner/package.json index 21a6ba3626a..050bb653445 100644 --- a/apps/desktop/native-messaging-test-runner/package.json +++ b/apps/desktop/native-messaging-test-runner/package.json @@ -24,7 +24,7 @@ "yargs": "18.0.0" }, "devDependencies": { - "@types/node": "22.19.1", + "@types/node": "22.19.3", "typescript": "5.4.2" }, "_moduleAliases": { diff --git a/apps/desktop/package.json b/apps/desktop/package.json index bb8118cb7eb..97ab8585a69 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/desktop", "description": "A secure and free password manager for all of your devices.", - "version": "2025.12.0", + "version": "2025.12.1", "keywords": [ "bitwarden", "password", @@ -18,6 +18,7 @@ "scripts": { "postinstall": "electron-rebuild", "start": "cross-env ELECTRON_IS_DEV=0 ELECTRON_NO_UPDATER=1 electron ./build", + "build-native-macos": "cd desktop_native && ./macos_provider/build.sh && node build.js cross-platform", "build-native": "cd desktop_native && node build.js", "build": "concurrently -n Main,Rend,Prel -c yellow,cyan \"npm run build:main\" \"npm run build:renderer\" \"npm run build:preload\"", "build:dev": "concurrently -n Main,Rend,Prel -c yellow,cyan \"npm run build:main:dev\" \"npm run build:renderer:dev\" \"npm run build:preload:dev\"", @@ -44,10 +45,9 @@ "pack:mac": "npm run clean:dist && electron-builder --mac --universal -p never", "pack:mac:with-extension": "npm run clean:dist && npm run build:macos-extension:mac && electron-builder --mac --universal -p never", "pack:mac:arm64": "npm run clean:dist && electron-builder --mac --arm64 -p never", - "pack:mac:mas": "npm run clean:dist && electron-builder --mac mas --universal -p never", - "pack:mac:mas:with-extension": "npm run clean:dist && npm run build:macos-extension:mas && electron-builder --mac mas --universal -p never", - "pack:mac:masdev": "npm run clean:dist && electron-builder --mac mas-dev --universal -p never", - "pack:mac:masdev:with-extension": "npm run clean:dist && npm run build:macos-extension:masdev && electron-builder --mac mas-dev --universal -p never", + "pack:mac:mas": "npm run clean:dist && npm run build:macos-extension:mas && electron-builder --mac mas --universal -p never", + "pack:mac:masdev": "npm run clean:dist && npm run build:macos-extension:masdev && electron-builder --mac mas-dev --universal -p never", + "pack:local:mac": "npm run clean:dist && npm run build:macos-extension:masdev && electron-builder --mac mas-dev --universal -p never -c.mac.provisioningProfile=\"\" -c.mas.provisioningProfile=\"\"", "pack:win": "npm run clean:dist && electron-builder --win --x64 --arm64 --ia32 -p never -c.win.signtoolOptions.certificateSubjectName=\"8bit Solutions LLC\"", "pack:win:beta": "npm run clean:dist && electron-builder --config electron-builder.beta.json --win --x64 --arm64 --ia32 -p never -c.win.signtoolOptions.certificateSubjectName=\"8bit Solutions LLC\"", "pack:win:ci": "npm run clean:dist && electron-builder --win --x64 --arm64 --ia32 -p never", @@ -55,11 +55,8 @@ "dist:lin": "npm run build && npm run pack:lin", "dist:lin:arm64": "npm run build && npm run pack:lin:arm64", "dist:mac": "npm run build && npm run pack:mac", - "dist:mac:with-extension": "npm run build && npm run pack:mac:with-extension", "dist:mac:mas": "npm run build && npm run pack:mac:mas", - "dist:mac:mas:with-extension": "npm run build && npm run pack:mac:mas:with-extension", - "dist:mac:masdev": "npm run build:dev && npm run pack:mac:masdev", - "dist:mac:masdev:with-extension": "npm run build:dev && npm run pack:mac:masdev:with-extension", + "dist:mac:masdev": "npm run build && npm run pack:mac:masdev", "dist:win": "npm run build && npm run pack:win", "dist:win:ci": "npm run build && npm run pack:win:ci", "publish:lin": "npm run build && npm run clean:dist && electron-builder --linux --x64 -p always", diff --git a/apps/desktop/resources/com.bitwarden.desktop.devel.yaml b/apps/desktop/resources/com.bitwarden.desktop.devel.yaml index e72df98e22b..0f6e3ea370d 100644 --- a/apps/desktop/resources/com.bitwarden.desktop.devel.yaml +++ b/apps/desktop/resources/com.bitwarden.desktop.devel.yaml @@ -33,7 +33,10 @@ modules: - mkdir -p /app/bin - mkdir -p /app/bin/Bitwarden/ - cp -r ./* /app/bin/ + - mkdir -p ${FLATPAK_DEST}/share/applications/ + - cp com.bitwarden.desktop.desktop ${FLATPAK_DEST}/share/applications/ - install bitwarden.sh /app/bin/bitwarden.sh + - desktop-file-edit --set-key=Exec --set-value="bitwarden.sh %U" ${FLATPAK_DEST}/share/applications/com.bitwarden.desktop.desktop sources: - type: dir only-arches: [x86_64] @@ -41,6 +44,8 @@ modules: - type: dir only-arches: [aarch64] path: ../dist/linux-arm64-unpacked + - type: file + path: ./com.bitwarden.desktop.desktop - type: script dest-filename: bitwarden.sh commands: diff --git a/apps/desktop/resources/entitlements.mac.plist b/apps/desktop/resources/entitlements.mac.plist index fe49256d71c..7763b84624d 100644 --- a/apps/desktop/resources/entitlements.mac.plist +++ b/apps/desktop/resources/entitlements.mac.plist @@ -6,8 +6,6 @@ LTZ2PFU5D6.com.bitwarden.desktop com.apple.developer.team-identifier LTZ2PFU5D6 - com.apple.developer.authentication-services.autofill-credential-provider - com.apple.security.cs.allow-jit diff --git a/apps/desktop/resources/entitlements.mas.inherit.plist b/apps/desktop/resources/entitlements.mas.inherit.plist index fca5f02d52d..7194d9409fc 100644 --- a/apps/desktop/resources/entitlements.mas.inherit.plist +++ b/apps/desktop/resources/entitlements.mas.inherit.plist @@ -4,9 +4,9 @@ com.apple.security.app-sandbox - com.apple.security.inherit - com.apple.security.cs.allow-jit + com.apple.security.inherit + diff --git a/apps/desktop/resources/entitlements.mas.plist b/apps/desktop/resources/entitlements.mas.plist index 3ebd56f0fd7..226e9827e37 100644 --- a/apps/desktop/resources/entitlements.mas.plist +++ b/apps/desktop/resources/entitlements.mas.plist @@ -6,19 +6,19 @@ LTZ2PFU5D6.com.bitwarden.desktop com.apple.developer.team-identifier LTZ2PFU5D6 - com.apple.developer.authentication-services.autofill-credential-provider - com.apple.security.app-sandbox com.apple.security.application-groups LTZ2PFU5D6.com.bitwarden.desktop - com.apple.security.network.client + com.apple.security.cs.allow-jit + + com.apple.security.device.usb com.apple.security.files.user-selected.read-write - com.apple.security.device.usb + com.apple.security.network.client com.apple.security.temporary-exception.files.home-relative-path.read-write @@ -32,10 +32,9 @@ /Library/Application Support/Microsoft Edge Beta/NativeMessagingHosts/ /Library/Application Support/Microsoft Edge Dev/NativeMessagingHosts/ /Library/Application Support/Microsoft Edge Canary/NativeMessagingHosts/ - /Library/Application Support/Vivaldi/NativeMessagingHosts/ + /Library/Application Support/Vivaldi/NativeMessagingHosts/ /Library/Application Support/Zen/NativeMessagingHosts/ + /Library/Application Support/net.imput.helium - com.apple.security.cs.allow-jit - diff --git a/apps/desktop/scripts/after-sign.js b/apps/desktop/scripts/after-sign.js index 7c9ad381dc2..4275ec7d051 100644 --- a/apps/desktop/scripts/after-sign.js +++ b/apps/desktop/scripts/after-sign.js @@ -16,7 +16,7 @@ async function run(context) { const appPath = `${context.appOutDir}/${appName}.app`; const macBuild = context.electronPlatformName === "darwin"; const copySafariExtension = ["darwin", "mas"].includes(context.electronPlatformName); - const copyAutofillExtension = ["darwin", "mas"].includes(context.electronPlatformName); + const copyAutofillExtension = ["darwin"].includes(context.electronPlatformName); // Disabled for mas builds let shouldResign = false; diff --git a/apps/desktop/scripts/nx-serve.js b/apps/desktop/scripts/nx-serve.js index b92a045f8e8..235691f9ce8 100644 --- a/apps/desktop/scripts/nx-serve.js +++ b/apps/desktop/scripts/nx-serve.js @@ -37,6 +37,6 @@ concurrently( { prefix: "name", outputStream: process.stdout, - killOthers: ["success", "failure"], + killOthersOn: ["success", "failure"], }, ); diff --git a/apps/desktop/scripts/start.js b/apps/desktop/scripts/start.js index 0e11ebd9083..4ffbe2eebeb 100644 --- a/apps/desktop/scripts/start.js +++ b/apps/desktop/scripts/start.js @@ -34,6 +34,6 @@ concurrently( { prefix: "name", outputStream: process.stdout, - killOthers: ["success", "failure"], + killOthersOn: ["success", "failure"], }, ); diff --git a/apps/desktop/src/app/accounts/settings.component.html b/apps/desktop/src/app/accounts/settings.component.html index 8abd84ee39c..d5042918d2f 100644 --- a/apps/desktop/src/app/accounts/settings.component.html +++ b/apps/desktop/src/app/accounts/settings.component.html @@ -44,12 +44,12 @@

{{ "vaultTimeoutHeader" | i18n }}

- - + {{ diff --git a/apps/desktop/src/app/accounts/settings.component.spec.ts b/apps/desktop/src/app/accounts/settings.component.spec.ts index a424f230778..d518ac29aa4 100644 --- a/apps/desktop/src/app/accounts/settings.component.spec.ts +++ b/apps/desktop/src/app/accounts/settings.component.spec.ts @@ -187,7 +187,6 @@ describe("SettingsComponent", () => { i18nService.userSetLocale$ = of("en"); pinServiceAbstraction.isPinSet.mockResolvedValue(false); policyService.policiesByType$.mockReturnValue(of([null])); - desktopAutotypeService.resolvedAutotypeEnabled$ = of(false); desktopAutotypeService.autotypeEnabledUserSetting$ = of(false); desktopAutotypeService.autotypeKeyboardShortcut$ = of(["Control", "Shift", "B"]); billingAccountProfileStateService.hasPremiumFromAnySource$.mockReturnValue(of(false)); diff --git a/apps/desktop/src/app/accounts/settings.component.ts b/apps/desktop/src/app/accounts/settings.component.ts index 68863312ffe..3952335af48 100644 --- a/apps/desktop/src/app/accounts/settings.component.ts +++ b/apps/desktop/src/app/accounts/settings.component.ts @@ -55,7 +55,7 @@ import { } from "@bitwarden/components"; import { KeyService, BiometricStateService, BiometricsStatus } from "@bitwarden/key-management"; import { - SessionTimeoutInputComponent, + SessionTimeoutInputLegacyComponent, SessionTimeoutSettingsComponent, } from "@bitwarden/key-management-ui"; import { PermitCipherDetailsPopoverComponent } from "@bitwarden/vault"; @@ -97,7 +97,7 @@ import { NativeMessagingManifestService } from "../services/native-messaging-man SectionHeaderComponent, SelectModule, TypographyModule, - SessionTimeoutInputComponent, + SessionTimeoutInputLegacyComponent, SessionTimeoutSettingsComponent, PermitCipherDetailsPopoverComponent, PremiumBadgeComponent, @@ -970,10 +970,20 @@ export class SettingsComponent implements OnInit, OnDestroy { } async saveAutotypeShortcut() { + // disable the shortcut so that the user can't re-enter the existing + // shortcut and trigger the feature during the settings menu. + // it is not necessary to check if it's already enabled, because + // the edit shortcut is only avaialble if the feature is enabled + // in the settings. + await this.desktopAutotypeService.setAutotypeEnabledState(false); + const dialogRef = AutotypeShortcutComponent.open(this.dialogService); const newShortcutArray = await firstValueFrom(dialogRef.closed); + // re-enable + await this.desktopAutotypeService.setAutotypeEnabledState(true); + if (!newShortcutArray) { return; } diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index 8fab7df1cd8..6077afa8c12 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -42,14 +42,20 @@ import { } from "@bitwarden/auth/angular"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { AnonLayoutWrapperComponent, AnonLayoutWrapperData } from "@bitwarden/components"; -import { LockComponent, ConfirmKeyConnectorDomainComponent } from "@bitwarden/key-management-ui"; +import { + LockComponent, + ConfirmKeyConnectorDomainComponent, + RemovePasswordComponent, +} from "@bitwarden/key-management-ui"; import { maxAccountsGuardFn } from "../auth/guards/max-accounts.guard"; -import { RemovePasswordComponent } from "../key-management/key-connector/remove-password.component"; +import { reactiveUnlockVaultGuard } from "../autofill/guards/reactive-vault-guard"; +import { Fido2CreateComponent } from "../autofill/modal/credentials/fido2-create.component"; +import { Fido2ExcludedCiphersComponent } from "../autofill/modal/credentials/fido2-excluded-ciphers.component"; +import { Fido2VaultComponent } from "../autofill/modal/credentials/fido2-vault.component"; import { VaultV2Component } from "../vault/app/vault/vault-v2.component"; import { VaultComponent } from "../vault/app/vault-v3/vault.component"; -import { Fido2PlaceholderComponent } from "./components/fido2placeholder.component"; import { DesktopLayoutComponent } from "./layout/desktop-layout.component"; import { SendComponent } from "./tools/send/send.component"; import { SendV2Component } from "./tools/send-v2/send-v2.component"; @@ -115,17 +121,16 @@ const routes: Routes = [ canActivate: [authGuard], }, { - path: "remove-password", - component: RemovePasswordComponent, - canActivate: [authGuard], + path: "fido2-assertion", + component: Fido2VaultComponent, }, { - path: "passkeys", - component: Fido2PlaceholderComponent, + path: "fido2-creation", + component: Fido2CreateComponent, }, { - path: "passkeys", - component: Fido2PlaceholderComponent, + path: "fido2-excluded", + component: Fido2ExcludedCiphersComponent, }, { path: "", @@ -271,7 +276,7 @@ const routes: Routes = [ }, { path: "lock", - canActivate: [lockGuard()], + canActivate: [lockGuard(), reactiveUnlockVaultGuard], data: { pageIcon: LockIcon, pageTitle: { @@ -320,13 +325,24 @@ const routes: Routes = [ pageIcon: LockIcon, } satisfies AnonLayoutWrapperData, }, + { + path: "remove-password", + component: RemovePasswordComponent, + canActivate: [authGuard], + data: { + pageTitle: { + key: "verifyYourOrganization", + }, + pageIcon: LockIcon, + } satisfies RouteDataProperties & AnonLayoutWrapperData, + }, { path: "confirm-key-connector-domain", component: ConfirmKeyConnectorDomainComponent, canActivate: [], data: { pageTitle: { - key: "confirmKeyConnectorDomain", + key: "verifyYourOrganization", }, pageIcon: DomainIcon, } satisfies RouteDataProperties & AnonLayoutWrapperData, diff --git a/apps/desktop/src/app/app.component.ts b/apps/desktop/src/app/app.component.ts index 6243ba1e538..836328142b5 100644 --- a/apps/desktop/src/app/app.component.ts +++ b/apps/desktop/src/app/app.component.ts @@ -104,7 +104,7 @@ const SyncInterval = 6 * 60 * 60 * 1000; // 6 hours - +
@@ -141,6 +141,7 @@ export class AppComponent implements OnInit, OnDestroy { @ViewChild("loginApproval", { read: ViewContainerRef, static: true }) loginApprovalModalRef: ViewContainerRef; + showHeader$ = this.accountService.showHeader$; loading = false; private lastActivity: Date = null; diff --git a/apps/desktop/src/app/app.module.ts b/apps/desktop/src/app/app.module.ts index 4f53e587994..31131c6202a 100644 --- a/apps/desktop/src/app/app.module.ts +++ b/apps/desktop/src/app/app.module.ts @@ -15,7 +15,6 @@ import { DeleteAccountComponent } from "../auth/delete-account.component"; import { LoginModule } from "../auth/login/login.module"; import { SshAgentService } from "../autofill/services/ssh-agent.service"; import { PremiumComponent } from "../billing/app/accounts/premium.component"; -import { RemovePasswordComponent } from "../key-management/key-connector/remove-password.component"; import { VaultFilterModule } from "../vault/app/vault/vault-filter/vault-filter.module"; import { VaultV2Component } from "../vault/app/vault/vault-v2.component"; @@ -50,7 +49,6 @@ import { SharedModule } from "./shared/shared.module"; ColorPasswordCountPipe, HeaderComponent, PremiumComponent, - RemovePasswordComponent, SearchComponent, ], providers: [SshAgentService], diff --git a/apps/desktop/src/app/components/fido2placeholder.component.ts b/apps/desktop/src/app/components/fido2placeholder.component.ts deleted file mode 100644 index f1f52dae439..00000000000 --- a/apps/desktop/src/app/components/fido2placeholder.component.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { CommonModule } from "@angular/common"; -import { Component, OnDestroy, OnInit } from "@angular/core"; -import { Router } from "@angular/router"; -import { BehaviorSubject, Observable } from "rxjs"; - -import { - DesktopFido2UserInterfaceService, - DesktopFido2UserInterfaceSession, -} from "../../autofill/services/desktop-fido2-user-interface.service"; -import { DesktopSettingsService } from "../../platform/services/desktop-settings.service"; - -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -@Component({ - standalone: true, - imports: [CommonModule], - template: ` -
-

Select your passkey

- -
- -
- -
- - -
- `, -}) -export class Fido2PlaceholderComponent implements OnInit, OnDestroy { - session?: DesktopFido2UserInterfaceSession = null; - private cipherIdsSubject = new BehaviorSubject([]); - cipherIds$: Observable; - - constructor( - private readonly desktopSettingsService: DesktopSettingsService, - private readonly fido2UserInterfaceService: DesktopFido2UserInterfaceService, - private readonly router: Router, - ) {} - - ngOnInit() { - this.session = this.fido2UserInterfaceService.getCurrentSession(); - this.cipherIds$ = this.session?.availableCipherIds$; - } - - async chooseCipher(cipherId: string) { - // For now: Set UV to true - this.session?.confirmChosenCipher(cipherId, true); - - await this.router.navigate(["/"]); - await this.desktopSettingsService.setModalMode(false); - } - - ngOnDestroy() { - this.cipherIdsSubject.complete(); // Clean up the BehaviorSubject - } - - async confirmPasskey() { - try { - // Retrieve the current UI session to control the flow - if (!this.session) { - // todo: handle error - throw new Error("No session found"); - } - - // If we want to we could submit information to the session in order to create the credential - // const cipher = await session.createCredential({ - // userHandle: "userHandle2", - // userName: "username2", - // credentialName: "zxsd2", - // rpId: "webauthn.io", - // userVerification: true, - // }); - - this.session.notifyConfirmNewCredential(true); - - // Not sure this clean up should happen here or in session. - // The session currently toggles modal on and send us here - // But if this route is somehow opened outside of session we want to make sure we clean up? - await this.router.navigate(["/"]); - await this.desktopSettingsService.setModalMode(false); - } catch { - // TODO: Handle error appropriately - } - } - - async closeModal() { - await this.router.navigate(["/"]); - await this.desktopSettingsService.setModalMode(false); - - this.session.notifyConfirmNewCredential(false); - // little bit hacky: - this.session.confirmChosenCipher(null); - } -} diff --git a/apps/desktop/src/app/layout/desktop-layout.component.html b/apps/desktop/src/app/layout/desktop-layout.component.html index 94b9201ae21..1717b29acd1 100644 --- a/apps/desktop/src/app/layout/desktop-layout.component.html +++ b/apps/desktop/src/app/layout/desktop-layout.component.html @@ -1,9 +1,9 @@ - + - + diff --git a/apps/desktop/src/app/layout/desktop-layout.component.spec.ts b/apps/desktop/src/app/layout/desktop-layout.component.spec.ts index cc2f7e58dfb..74cddd02495 100644 --- a/apps/desktop/src/app/layout/desktop-layout.component.spec.ts +++ b/apps/desktop/src/app/layout/desktop-layout.component.spec.ts @@ -1,3 +1,4 @@ +import { ChangeDetectionStrategy, Component } from "@angular/core"; import { ComponentFixture, TestBed } from "@angular/core/testing"; import { RouterModule } from "@angular/router"; import { mock } from "jest-mock-extended"; @@ -5,8 +6,18 @@ import { mock } from "jest-mock-extended"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { NavigationModule } from "@bitwarden/components"; +import { SendFiltersNavComponent } from "../tools/send-v2/send-filters-nav.component"; + import { DesktopLayoutComponent } from "./desktop-layout.component"; +// Mock the child component to isolate DesktopLayoutComponent testing +@Component({ + selector: "app-send-filters-nav", + template: "", + changeDetection: ChangeDetectionStrategy.OnPush, +}) +class MockSendFiltersNavComponent {} + Object.defineProperty(window, "matchMedia", { writable: true, value: jest.fn().mockImplementation((query) => ({ @@ -34,7 +45,12 @@ describe("DesktopLayoutComponent", () => { useValue: mock(), }, ], - }).compileComponents(); + }) + .overrideComponent(DesktopLayoutComponent, { + remove: { imports: [SendFiltersNavComponent] }, + add: { imports: [MockSendFiltersNavComponent] }, + }) + .compileComponents(); fixture = TestBed.createComponent(DesktopLayoutComponent); component = fixture.componentInstance; @@ -58,4 +74,11 @@ describe("DesktopLayoutComponent", () => { expect(ngContent).toBeTruthy(); }); + + it("renders send filters navigation component", () => { + const compiled = fixture.nativeElement; + const sendFiltersNav = compiled.querySelector("app-send-filters-nav"); + + expect(sendFiltersNav).toBeTruthy(); + }); }); diff --git a/apps/desktop/src/app/layout/desktop-layout.component.ts b/apps/desktop/src/app/layout/desktop-layout.component.ts index 006055f475f..0ee7065fba8 100644 --- a/apps/desktop/src/app/layout/desktop-layout.component.ts +++ b/apps/desktop/src/app/layout/desktop-layout.component.ts @@ -5,13 +5,22 @@ import { PasswordManagerLogo } from "@bitwarden/assets/svg"; import { LayoutComponent, NavigationModule } from "@bitwarden/components"; import { I18nPipe } from "@bitwarden/ui-common"; +import { SendFiltersNavComponent } from "../tools/send-v2/send-filters-nav.component"; + import { DesktopSideNavComponent } from "./desktop-side-nav.component"; // FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "app-layout", - imports: [RouterModule, I18nPipe, LayoutComponent, NavigationModule, DesktopSideNavComponent], + imports: [ + RouterModule, + I18nPipe, + LayoutComponent, + NavigationModule, + DesktopSideNavComponent, + SendFiltersNavComponent, + ], templateUrl: "./desktop-layout.component.html", }) export class DesktopLayoutComponent { diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index 03d6eb5c908..382b680efbc 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -51,10 +51,12 @@ import { } from "@bitwarden/common/auth/abstractions/auth.service"; import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; +import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { ClientType } from "@bitwarden/common/enums"; import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service"; +import { AccountCryptographicStateService } from "@bitwarden/common/key-management/account-cryptography/account-cryptographic-state.service"; import { KeyGenerationService } from "@bitwarden/common/key-management/crypto"; import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; @@ -62,6 +64,7 @@ import { WebCryptoFunctionService } from "@bitwarden/common/key-management/crypt import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { PinServiceAbstraction } from "@bitwarden/common/key-management/pin/pin.service.abstraction"; import { DefaultProcessReloadService } from "@bitwarden/common/key-management/services/default-process-reload.service"; +import { SessionTimeoutTypeService } from "@bitwarden/common/key-management/session-timeout"; import { VaultTimeoutSettingsService, VaultTimeoutStringType, @@ -101,6 +104,7 @@ import { GlobalStateProvider, StateProvider } from "@bitwarden/common/platform/s import { SyncService } from "@bitwarden/common/platform/sync"; import { CipherService as CipherServiceAbstraction } from "@bitwarden/common/vault/abstractions/cipher.service"; import { DialogService, ToastService } from "@bitwarden/components"; +import { GeneratorServicesModule } from "@bitwarden/generator-components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { KdfConfigService, @@ -128,7 +132,7 @@ import { DesktopBiometricsService } from "../../key-management/biometrics/deskto import { RendererBiometricsService } from "../../key-management/biometrics/renderer-biometrics.service"; import { ElectronKeyService } from "../../key-management/electron-key.service"; import { DesktopLockComponentService } from "../../key-management/lock/services/desktop-lock-component.service"; -import { DesktopSessionTimeoutSettingsComponentService } from "../../key-management/session-timeout/services/desktop-session-timeout-settings-component.service"; +import { DesktopSessionTimeoutTypeService } from "../../key-management/session-timeout/services/desktop-session-timeout-type.service"; import { flagEnabled } from "../../platform/flags"; import { DesktopSettingsService } from "../../platform/services/desktop-settings.service"; import { ElectronLogRendererService } from "../../platform/services/electron-log.renderer.service"; @@ -165,12 +169,12 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: BiometricsService, useClass: RendererBiometricsService, - deps: [], + deps: [TokenService], }), safeProvider({ provide: DesktopBiometricsService, useClass: RendererBiometricsService, - deps: [], + deps: [TokenService], }), safeProvider(NativeMessagingService), safeProvider(BiometricMessageHandlerService), @@ -200,8 +204,16 @@ const safeProviders: SafeProvider[] = [ // We manually override the value of SUPPORTS_SECURE_STORAGE here to avoid // the TokenService having to inject the PlatformUtilsService which introduces a // circular dependency on Desktop only. + // + // For Windows portable builds, we disable secure storage to ensure tokens are + // stored on disk (in bitwarden-appdata) rather than in Windows Credential + // Manager, making them portable across machines. This allows users to move the USB drive + // between computers while maintaining authentication. + // + // Note: Portable mode does not use secure storage for read/write/clear operations, + // preventing any collision with tokens from a regular desktop installation. provide: SUPPORTS_SECURE_STORAGE, - useValue: ELECTRON_SUPPORTS_SECURE_STORAGE, + useValue: ELECTRON_SUPPORTS_SECURE_STORAGE && !ipc.platform.isWindowsPortable, }), safeProvider({ provide: DEFAULT_VAULT_TIMEOUT, @@ -344,6 +356,7 @@ const safeProviders: SafeProvider[] = [ ConfigService, Fido2AuthenticatorServiceAbstraction, AccountService, + AuthService, PlatformUtilsService, ], }), @@ -404,6 +417,7 @@ const safeProviders: SafeProvider[] = [ OrganizationUserApiService, InternalUserDecryptionOptionsServiceAbstraction, MessagingServiceAbstraction, + AccountCryptographicStateService, ], }), safeProvider({ @@ -477,6 +491,7 @@ const safeProviders: SafeProvider[] = [ PlatformUtilsServiceAbstraction, BillingAccountProfileStateService, DesktopAutotypeDefaultSettingPolicy, + LogService, ], }), safeProvider({ @@ -484,15 +499,20 @@ const safeProviders: SafeProvider[] = [ useClass: DesktopAutotypeDefaultSettingPolicy, deps: [AccountServiceAbstraction, AuthServiceAbstraction, InternalPolicyService, ConfigService], }), + safeProvider({ + provide: SessionTimeoutTypeService, + useClass: DesktopSessionTimeoutTypeService, + deps: [], + }), safeProvider({ provide: SessionTimeoutSettingsComponentService, - useClass: DesktopSessionTimeoutSettingsComponentService, - deps: [I18nServiceAbstraction], + useClass: SessionTimeoutSettingsComponentService, + deps: [I18nServiceAbstraction, SessionTimeoutTypeService, PolicyServiceAbstraction], }), ]; @NgModule({ - imports: [JslibServicesModule], + imports: [JslibServicesModule, GeneratorServicesModule], declarations: [], // Do not register your dependency here! Add it to the typesafeProviders array using the helper function providers: safeProviders, diff --git a/apps/desktop/src/app/services/set-initial-password/desktop-set-initial-password.service.spec.ts b/apps/desktop/src/app/services/set-initial-password/desktop-set-initial-password.service.spec.ts index 717af25a1dc..6b29a464e2c 100644 --- a/apps/desktop/src/app/services/set-initial-password/desktop-set-initial-password.service.spec.ts +++ b/apps/desktop/src/app/services/set-initial-password/desktop-set-initial-password.service.spec.ts @@ -15,6 +15,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction"; import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request"; +import { AccountCryptographicStateService } from "@bitwarden/common/key-management/account-cryptography/account-cryptographic-state.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; @@ -43,6 +44,7 @@ describe("DesktopSetInitialPasswordService", () => { let organizationUserApiService: MockProxy; let userDecryptionOptionsService: MockProxy; let messagingService: MockProxy; + let accountCryptographicStateService: MockProxy; beforeEach(() => { apiService = mock(); @@ -56,6 +58,7 @@ describe("DesktopSetInitialPasswordService", () => { organizationUserApiService = mock(); userDecryptionOptionsService = mock(); messagingService = mock(); + accountCryptographicStateService = mock(); sut = new DesktopSetInitialPasswordService( apiService, @@ -69,6 +72,7 @@ describe("DesktopSetInitialPasswordService", () => { organizationUserApiService, userDecryptionOptionsService, messagingService, + accountCryptographicStateService, ); }); diff --git a/apps/desktop/src/app/services/set-initial-password/desktop-set-initial-password.service.ts b/apps/desktop/src/app/services/set-initial-password/desktop-set-initial-password.service.ts index 8de7e73fafe..cedfa3fe589 100644 --- a/apps/desktop/src/app/services/set-initial-password/desktop-set-initial-password.service.ts +++ b/apps/desktop/src/app/services/set-initial-password/desktop-set-initial-password.service.ts @@ -9,6 +9,7 @@ import { InternalUserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction"; +import { AccountCryptographicStateService } from "@bitwarden/common/key-management/account-cryptography/account-cryptographic-state.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -32,6 +33,7 @@ export class DesktopSetInitialPasswordService protected organizationUserApiService: OrganizationUserApiService, protected userDecryptionOptionsService: InternalUserDecryptionOptionsServiceAbstraction, private messagingService: MessagingService, + protected accountCryptographicStateService: AccountCryptographicStateService, ) { super( apiService, @@ -44,6 +46,7 @@ export class DesktopSetInitialPasswordService organizationApiService, organizationUserApiService, userDecryptionOptionsService, + accountCryptographicStateService, ); } diff --git a/apps/desktop/src/app/tools/export/export-desktop.component.html b/apps/desktop/src/app/tools/export/export-desktop.component.html index 9aa59c5a636..5f4f0058577 100644 --- a/apps/desktop/src/app/tools/export/export-desktop.component.html +++ b/apps/desktop/src/app/tools/export/export-desktop.component.html @@ -1,5 +1,5 @@ - {{ "exportVault" | i18n }} + {{ "exportNoun" | i18n }} - {{ "exportVault" | i18n }} + {{ "exportVerb" | i18n }}
-
{{ send.file.fileName }} ({{ send.file.sizeName }})
+
+ {{ send.file.fileName }} ({{ send.file.sizeName }}) +
diff --git a/apps/desktop/src/auth/login/desktop-login-component.service.spec.ts b/apps/desktop/src/auth/login/desktop-login-component.service.spec.ts index c88627250c9..414bbaca56f 100644 --- a/apps/desktop/src/auth/login/desktop-login-component.service.spec.ts +++ b/apps/desktop/src/auth/login/desktop-login-component.service.spec.ts @@ -136,6 +136,7 @@ describe("DesktopLoginComponentService", () => { codeChallenge, state, email, + undefined, ); } else { expect(ssoLoginService.setSsoState).toHaveBeenCalledWith(state); @@ -145,4 +146,55 @@ describe("DesktopLoginComponentService", () => { }); }); }); + + describe("redirectToSsoLoginWithOrganizationSsoIdentifier", () => { + // Array of all permutations of isAppImage and isDev + const permutations = [ + [true, false], // Case 1: isAppImage true + [false, true], // Case 2: isDev true + [true, true], // Case 3: all true + [false, false], // Case 4: all false + ]; + + permutations.forEach(([isAppImage, isDev]) => { + it("calls redirectToSso with orgSsoIdentifier", async () => { + (global as any).ipc.platform.isAppImage = isAppImage; + (global as any).ipc.platform.isDev = isDev; + + const email = "test@bitwarden.com"; + const state = "testState"; + const codeVerifier = "testCodeVerifier"; + const codeChallenge = "testCodeChallenge"; + const orgSsoIdentifier = "orgSsoId"; + + passwordGenerationService.generatePassword.mockResolvedValueOnce(state); + passwordGenerationService.generatePassword.mockResolvedValueOnce(codeVerifier); + jest.spyOn(Utils, "fromBufferToUrlB64").mockReturnValue(codeChallenge); + + await service.redirectToSsoLoginWithOrganizationSsoIdentifier(email, orgSsoIdentifier); + + if (isAppImage || isDev) { + expect(ipc.platform.localhostCallbackService.openSsoPrompt).toHaveBeenCalledWith( + codeChallenge, + state, + email, + orgSsoIdentifier, + ); + } else { + expect(ssoUrlService.buildSsoUrl).toHaveBeenCalledWith( + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + email, + orgSsoIdentifier, + ); + expect(ssoLoginService.setSsoState).toHaveBeenCalledWith(state); + expect(ssoLoginService.setCodeVerifier).toHaveBeenCalledWith(codeVerifier); + expect(platformUtilsService.launchUri).toHaveBeenCalled(); + } + }); + }); + }); }); diff --git a/apps/desktop/src/auth/login/desktop-login-component.service.ts b/apps/desktop/src/auth/login/desktop-login-component.service.ts index d7e7ba0178b..6ef39eaa018 100644 --- a/apps/desktop/src/auth/login/desktop-login-component.service.ts +++ b/apps/desktop/src/auth/login/desktop-login-component.service.ts @@ -48,11 +48,12 @@ export class DesktopLoginComponentService email: string, state: string, codeChallenge: string, + orgSsoIdentifier?: string, ): Promise { // For platforms that cannot support a protocol-based (e.g. bitwarden://) callback, we use a localhost callback // Otherwise, we launch the SSO component in a browser window and wait for the callback if (ipc.platform.isAppImage || ipc.platform.isDev) { - await this.initiateSsoThroughLocalhostCallback(email, state, codeChallenge); + await this.initiateSsoThroughLocalhostCallback(email, state, codeChallenge, orgSsoIdentifier); } else { const env = await firstValueFrom(this.environmentService.environment$); const webVaultUrl = env.getWebVaultUrl(); @@ -66,6 +67,7 @@ export class DesktopLoginComponentService state, codeChallenge, email, + orgSsoIdentifier, ); this.platformUtilsService.launchUri(ssoWebAppUrl); @@ -76,9 +78,15 @@ export class DesktopLoginComponentService email: string, state: string, challenge: string, + orgSsoIdentifier?: string, ): Promise { try { - await ipc.platform.localhostCallbackService.openSsoPrompt(challenge, state, email); + await ipc.platform.localhostCallbackService.openSsoPrompt( + challenge, + state, + email, + orgSsoIdentifier, + ); // FIXME: Remove when updating file. Eslint update // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (err) { diff --git a/apps/desktop/src/autofill/guards/reactive-vault-guard.ts b/apps/desktop/src/autofill/guards/reactive-vault-guard.ts new file mode 100644 index 00000000000..d16787ef46a --- /dev/null +++ b/apps/desktop/src/autofill/guards/reactive-vault-guard.ts @@ -0,0 +1,42 @@ +import { inject } from "@angular/core"; +import { CanActivateFn, Router } from "@angular/router"; +import { combineLatest, map, switchMap, distinctUntilChanged } from "rxjs"; + +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; +import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; + +import { DesktopSettingsService } from "../../platform/services/desktop-settings.service"; + +/** + * Reactive route guard that redirects to the unlocked vault. + * Redirects to vault when unlocked in main window. + */ +export const reactiveUnlockVaultGuard: CanActivateFn = () => { + const router = inject(Router); + const authService = inject(AuthService); + const accountService = inject(AccountService); + const desktopSettingsService = inject(DesktopSettingsService); + + return combineLatest([accountService.activeAccount$, desktopSettingsService.modalMode$]).pipe( + switchMap(([account, modalMode]) => { + if (!account) { + return [true]; + } + + // Monitor when the vault has been unlocked. + return authService.authStatusFor$(account.id).pipe( + distinctUntilChanged(), + map((authStatus) => { + // If vault is unlocked and we're not in modal mode, redirect to vault + if (authStatus === AuthenticationStatus.Unlocked && !modalMode?.isModalModeActive) { + return router.createUrlTree(["/vault"]); + } + + // Otherwise keep user on the lock screen + return true; + }), + ); + }), + ); +}; diff --git a/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts b/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts index 4dcf05a4220..ea2bdd1fe12 100644 --- a/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts +++ b/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts @@ -5,51 +5,46 @@ import { LogService } from "@bitwarden/logging"; import { WindowMain } from "../../main/window.main"; import { stringIsNotUndefinedNullAndEmpty } from "../../utils"; +import { AutotypeConfig } from "../models/autotype-config"; import { AutotypeMatchError } from "../models/autotype-errors"; import { AutotypeVaultData } from "../models/autotype-vault-data"; +import { AUTOTYPE_IPC_CHANNELS } from "../models/ipc-channels"; import { AutotypeKeyboardShortcut } from "../models/main-autotype-keyboard-shortcut"; export class MainDesktopAutotypeService { - autotypeKeyboardShortcut: AutotypeKeyboardShortcut; + private autotypeKeyboardShortcut: AutotypeKeyboardShortcut; constructor( private logService: LogService, private windowMain: WindowMain, ) { this.autotypeKeyboardShortcut = new AutotypeKeyboardShortcut(); + + this.registerIpcListeners(); } - init() { - ipcMain.on("autofill.configureAutotype", (event, data) => { - if (data.enabled) { - const newKeyboardShortcut = new AutotypeKeyboardShortcut(); - const newKeyboardShortcutIsValid = newKeyboardShortcut.set(data.keyboardShortcut); - - if (newKeyboardShortcutIsValid) { - this.disableAutotype(); - this.autotypeKeyboardShortcut = newKeyboardShortcut; - this.enableAutotype(); - } else { - this.logService.error( - "Attempting to configure autotype but the shortcut given is invalid.", - ); - } + registerIpcListeners() { + ipcMain.on(AUTOTYPE_IPC_CHANNELS.TOGGLE, (_event, enable: boolean) => { + if (enable) { + this.enableAutotype(); } else { this.disableAutotype(); - - // Deregister the incoming keyboard shortcut if needed - const setCorrectly = this.autotypeKeyboardShortcut.set(data.keyboardShortcut); - if ( - setCorrectly && - globalShortcut.isRegistered(this.autotypeKeyboardShortcut.getElectronFormat()) - ) { - globalShortcut.unregister(this.autotypeKeyboardShortcut.getElectronFormat()); - this.logService.info("Autotype disabled."); - } } }); - ipcMain.on("autofill.completeAutotypeRequest", (_event, vaultData: AutotypeVaultData) => { + ipcMain.on(AUTOTYPE_IPC_CHANNELS.CONFIGURE, (_event, config: AutotypeConfig) => { + const newKeyboardShortcut = new AutotypeKeyboardShortcut(); + const newKeyboardShortcutIsValid = newKeyboardShortcut.set(config.keyboardShortcut); + + if (!newKeyboardShortcutIsValid) { + this.logService.error("Configure autotype failed: the keyboard shortcut is invalid."); + return; + } + + this.setKeyboardShortcut(newKeyboardShortcut); + }); + + ipcMain.on(AUTOTYPE_IPC_CHANNELS.EXECUTE, (_event, vaultData: AutotypeVaultData) => { if ( stringIsNotUndefinedNullAndEmpty(vaultData.username) && stringIsNotUndefinedNullAndEmpty(vaultData.password) @@ -67,30 +62,74 @@ export class MainDesktopAutotypeService { }); } + // Deregister the keyboard shortcut if registered. disableAutotype() { - // Deregister the current keyboard shortcut if needed const formattedKeyboardShortcut = this.autotypeKeyboardShortcut.getElectronFormat(); + if (globalShortcut.isRegistered(formattedKeyboardShortcut)) { globalShortcut.unregister(formattedKeyboardShortcut); - this.logService.info("Autotype disabled."); + this.logService.debug("Autotype disabled."); + } else { + this.logService.debug("Autotype is not registered, implicitly disabled."); } } + dispose() { + ipcMain.removeAllListeners(AUTOTYPE_IPC_CHANNELS.TOGGLE); + ipcMain.removeAllListeners(AUTOTYPE_IPC_CHANNELS.CONFIGURE); + ipcMain.removeAllListeners(AUTOTYPE_IPC_CHANNELS.EXECUTE); + + // Also unregister the global shortcut + this.disableAutotype(); + } + + // Register the current keyboard shortcut if not already registered. private enableAutotype() { + const formattedKeyboardShortcut = this.autotypeKeyboardShortcut.getElectronFormat(); + if (globalShortcut.isRegistered(formattedKeyboardShortcut)) { + this.logService.debug( + "Autotype is already enabled with this keyboard shortcut: " + formattedKeyboardShortcut, + ); + return; + } + const result = globalShortcut.register( this.autotypeKeyboardShortcut.getElectronFormat(), () => { const windowTitle = autotype.getForegroundWindowTitle(); - this.windowMain.win.webContents.send("autofill.listenAutotypeRequest", { + this.windowMain.win.webContents.send(AUTOTYPE_IPC_CHANNELS.LISTEN, { windowTitle, }); }, ); result - ? this.logService.info("Autotype enabled.") - : this.logService.info("Enabling autotype failed."); + ? this.logService.debug("Autotype enabled.") + : this.logService.error("Failed to enable Autotype."); + } + + // Set the keyboard shortcut if it differs from the present one. If + // the keyboard shortcut is set, de-register the old shortcut first. + private setKeyboardShortcut(keyboardShortcut: AutotypeKeyboardShortcut) { + if ( + keyboardShortcut.getElectronFormat() !== this.autotypeKeyboardShortcut.getElectronFormat() + ) { + const registered = globalShortcut.isRegistered( + this.autotypeKeyboardShortcut.getElectronFormat(), + ); + if (registered) { + this.disableAutotype(); + } + this.autotypeKeyboardShortcut = keyboardShortcut; + if (registered) { + this.enableAutotype(); + } + } else { + this.logService.debug( + "setKeyboardShortcut() called but shortcut is not different from current.", + ); + } } private doAutotype(vaultData: AutotypeVaultData, keyboardShortcut: string[]) { diff --git a/apps/desktop/src/autofill/main/main-ssh-agent.service.ts b/apps/desktop/src/autofill/main/main-ssh-agent.service.ts index 595ef778bcf..31196e4cf98 100644 --- a/apps/desktop/src/autofill/main/main-ssh-agent.service.ts +++ b/apps/desktop/src/autofill/main/main-ssh-agent.service.ts @@ -37,7 +37,7 @@ export class MainSshAgentService { init() { // handle sign request passing to UI sshagent - .serve(async (err: Error, sshUiRequest: sshagent.SshUiRequest) => { + .serve(async (err: Error | null, sshUiRequest: sshagent.SshUiRequest): Promise => { // clear all old (> SIGN_TIMEOUT) requests this.requestResponses = this.requestResponses.filter( (response) => response.timestamp > new Date(Date.now() - this.SIGN_TIMEOUT), diff --git a/apps/desktop/src/autofill/modal/credentials/fido2-create.component.html b/apps/desktop/src/autofill/modal/credentials/fido2-create.component.html new file mode 100644 index 00000000000..67fc76aa317 --- /dev/null +++ b/apps/desktop/src/autofill/modal/credentials/fido2-create.component.html @@ -0,0 +1,66 @@ + diff --git a/apps/desktop/src/autofill/modal/credentials/fido2-create.component.spec.ts b/apps/desktop/src/autofill/modal/credentials/fido2-create.component.spec.ts new file mode 100644 index 00000000000..dbef860aafe --- /dev/null +++ b/apps/desktop/src/autofill/modal/credentials/fido2-create.component.spec.ts @@ -0,0 +1,240 @@ +import { TestBed } from "@angular/core/testing"; +import { Router } from "@angular/router"; +import { mock, MockProxy } from "jest-mock-extended"; +import { BehaviorSubject, of } from "rxjs"; + +import { AccountService, Account } from "@bitwarden/common/auth/abstractions/account.service"; +import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { mockAccountInfoWith } from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherRepromptType, CipherType } from "@bitwarden/common/vault/enums"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { DialogService } from "@bitwarden/components"; +import { PasswordRepromptService } from "@bitwarden/vault"; + +import { DesktopAutofillService } from "../../../autofill/services/desktop-autofill.service"; +import { DesktopSettingsService } from "../../../platform/services/desktop-settings.service"; +import { + DesktopFido2UserInterfaceService, + DesktopFido2UserInterfaceSession, +} from "../../services/desktop-fido2-user-interface.service"; + +import { Fido2CreateComponent } from "./fido2-create.component"; + +describe("Fido2CreateComponent", () => { + let component: Fido2CreateComponent; + let mockDesktopSettingsService: MockProxy; + let mockFido2UserInterfaceService: MockProxy; + let mockAccountService: MockProxy; + let mockCipherService: MockProxy; + let mockDesktopAutofillService: MockProxy; + let mockDialogService: MockProxy; + let mockDomainSettingsService: MockProxy; + let mockLogService: MockProxy; + let mockPasswordRepromptService: MockProxy; + let mockRouter: MockProxy; + let mockSession: MockProxy; + let mockI18nService: MockProxy; + + const activeAccountSubject = new BehaviorSubject({ + id: "test-user-id" as UserId, + ...mockAccountInfoWith({ + email: "test@example.com", + name: "Test User", + }), + }); + + beforeEach(async () => { + mockDesktopSettingsService = mock(); + mockFido2UserInterfaceService = mock(); + mockAccountService = mock(); + mockCipherService = mock(); + mockDesktopAutofillService = mock(); + mockDialogService = mock(); + mockDomainSettingsService = mock(); + mockLogService = mock(); + mockPasswordRepromptService = mock(); + mockRouter = mock(); + mockSession = mock(); + mockI18nService = mock(); + + mockFido2UserInterfaceService.getCurrentSession.mockReturnValue(mockSession); + mockAccountService.activeAccount$ = activeAccountSubject; + + await TestBed.configureTestingModule({ + providers: [ + Fido2CreateComponent, + { provide: DesktopSettingsService, useValue: mockDesktopSettingsService }, + { provide: DesktopFido2UserInterfaceService, useValue: mockFido2UserInterfaceService }, + { provide: AccountService, useValue: mockAccountService }, + { provide: CipherService, useValue: mockCipherService }, + { provide: DesktopAutofillService, useValue: mockDesktopAutofillService }, + { provide: DialogService, useValue: mockDialogService }, + { provide: DomainSettingsService, useValue: mockDomainSettingsService }, + { provide: LogService, useValue: mockLogService }, + { provide: PasswordRepromptService, useValue: mockPasswordRepromptService }, + { provide: Router, useValue: mockRouter }, + { provide: I18nService, useValue: mockI18nService }, + ], + }).compileComponents(); + + component = TestBed.inject(Fido2CreateComponent); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + function createMockCiphers(): CipherView[] { + const cipher1 = new CipherView(); + cipher1.id = "cipher-1"; + cipher1.name = "Test Cipher 1"; + cipher1.type = CipherType.Login; + cipher1.login = { + username: "test1@example.com", + uris: [{ uri: "https://example.com", match: null }], + matchesUri: jest.fn().mockReturnValue(true), + get hasFido2Credentials() { + return false; + }, + } as any; + cipher1.reprompt = CipherRepromptType.None; + cipher1.deletedDate = null; + + return [cipher1]; + } + + describe("ngOnInit", () => { + beforeEach(() => { + mockSession.getRpId.mockResolvedValue("example.com"); + Object.defineProperty(mockDesktopAutofillService, "lastRegistrationRequest", { + get: jest.fn().mockReturnValue({ + userHandle: new Uint8Array([1, 2, 3]), + }), + configurable: true, + }); + mockDomainSettingsService.getUrlEquivalentDomains.mockReturnValue(of(new Set())); + }); + + it("should initialize session and set show header to false", async () => { + const mockCiphers = createMockCiphers(); + mockCipherService.getAllDecrypted.mockResolvedValue(mockCiphers); + + await component.ngOnInit(); + + expect(mockFido2UserInterfaceService.getCurrentSession).toHaveBeenCalled(); + expect(component.session).toBe(mockSession); + }); + + it("should show error dialog when no active session found", async () => { + mockFido2UserInterfaceService.getCurrentSession.mockReturnValue(null); + mockDialogService.openSimpleDialog.mockResolvedValue(false); + + await component.ngOnInit(); + + expect(mockDialogService.openSimpleDialog).toHaveBeenCalledWith({ + title: { key: "unableToSavePasskey" }, + content: { key: "closeThisBitwardenWindow" }, + type: "danger", + acceptButtonText: { key: "closeThisWindow" }, + acceptAction: expect.any(Function), + cancelButtonText: null, + }); + }); + }); + + describe("addCredentialToCipher", () => { + beforeEach(() => { + component.session = mockSession; + }); + + it("should add passkey to cipher", async () => { + const cipher = createMockCiphers()[0]; + + await component.addCredentialToCipher(cipher); + + expect(mockSession.notifyConfirmCreateCredential).toHaveBeenCalledWith(true, cipher); + }); + + it("should not add passkey when password reprompt is cancelled", async () => { + const cipher = createMockCiphers()[0]; + cipher.reprompt = CipherRepromptType.Password; + mockPasswordRepromptService.showPasswordPrompt.mockResolvedValue(false); + + await component.addCredentialToCipher(cipher); + + expect(mockSession.notifyConfirmCreateCredential).toHaveBeenCalledWith(false, cipher); + }); + + it("should call openSimpleDialog when cipher already has a fido2 credential", async () => { + const cipher = createMockCiphers()[0]; + Object.defineProperty(cipher.login, "hasFido2Credentials", { + get: jest.fn().mockReturnValue(true), + }); + mockDialogService.openSimpleDialog.mockResolvedValue(true); + + await component.addCredentialToCipher(cipher); + + expect(mockDialogService.openSimpleDialog).toHaveBeenCalledWith({ + title: { key: "overwritePasskey" }, + content: { key: "alreadyContainsPasskey" }, + type: "warning", + }); + expect(mockSession.notifyConfirmCreateCredential).toHaveBeenCalledWith(true, cipher); + }); + + it("should not add passkey when user cancels overwrite dialog", async () => { + const cipher = createMockCiphers()[0]; + Object.defineProperty(cipher.login, "hasFido2Credentials", { + get: jest.fn().mockReturnValue(true), + }); + mockDialogService.openSimpleDialog.mockResolvedValue(false); + + await component.addCredentialToCipher(cipher); + + expect(mockSession.notifyConfirmCreateCredential).toHaveBeenCalledWith(false, cipher); + }); + }); + + describe("confirmPasskey", () => { + beforeEach(() => { + component.session = mockSession; + }); + + it("should confirm passkey creation successfully", async () => { + await component.confirmPasskey(); + + expect(mockSession.notifyConfirmCreateCredential).toHaveBeenCalledWith(true); + }); + + it("should call openSimpleDialog when session is null", async () => { + component.session = null; + mockDialogService.openSimpleDialog.mockResolvedValue(false); + + await component.confirmPasskey(); + + expect(mockDialogService.openSimpleDialog).toHaveBeenCalledWith({ + title: { key: "unableToSavePasskey" }, + content: { key: "closeThisBitwardenWindow" }, + type: "danger", + acceptButtonText: { key: "closeThisWindow" }, + acceptAction: expect.any(Function), + cancelButtonText: null, + }); + }); + }); + + describe("closeModal", () => { + it("should close modal and notify session", async () => { + component.session = mockSession; + + await component.closeModal(); + + expect(mockSession.notifyConfirmCreateCredential).toHaveBeenCalledWith(false); + expect(mockSession.confirmChosenCipher).toHaveBeenCalledWith(null); + }); + }); +}); diff --git a/apps/desktop/src/autofill/modal/credentials/fido2-create.component.ts b/apps/desktop/src/autofill/modal/credentials/fido2-create.component.ts new file mode 100644 index 00000000000..67237bedccd --- /dev/null +++ b/apps/desktop/src/autofill/modal/credentials/fido2-create.component.ts @@ -0,0 +1,219 @@ +import { CommonModule } from "@angular/common"; +import { ChangeDetectionStrategy, Component, OnInit, OnDestroy } from "@angular/core"; +import { RouterModule, Router } from "@angular/router"; +import { combineLatest, map, Observable, Subject, switchMap } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { BitwardenShield, NoResults } from "@bitwarden/assets/svg"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service"; +import { Fido2Utils } from "@bitwarden/common/platform/services/fido2/fido2-utils"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherType } from "@bitwarden/common/vault/enums/cipher-type"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { + DialogService, + BadgeModule, + ButtonModule, + DialogModule, + IconModule, + ItemModule, + SectionComponent, + TableModule, + SectionHeaderComponent, + BitIconButtonComponent, + SimpleDialogOptions, +} from "@bitwarden/components"; +import { PasswordRepromptService } from "@bitwarden/vault"; + +import { DesktopAutofillService } from "../../../autofill/services/desktop-autofill.service"; +import { DesktopSettingsService } from "../../../platform/services/desktop-settings.service"; +import { + DesktopFido2UserInterfaceService, + DesktopFido2UserInterfaceSession, +} from "../../services/desktop-fido2-user-interface.service"; + +@Component({ + standalone: true, + imports: [ + CommonModule, + RouterModule, + SectionHeaderComponent, + BitIconButtonComponent, + TableModule, + JslibModule, + IconModule, + ButtonModule, + DialogModule, + SectionComponent, + ItemModule, + BadgeModule, + ], + templateUrl: "fido2-create.component.html", + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class Fido2CreateComponent implements OnInit, OnDestroy { + session?: DesktopFido2UserInterfaceSession = null; + ciphers$: Observable; + private destroy$ = new Subject(); + readonly Icons = { BitwardenShield, NoResults }; + + private get DIALOG_MESSAGES() { + return { + unexpectedErrorShort: { + title: { key: "unexpectedErrorShort" }, + content: { key: "closeThisBitwardenWindow" }, + type: "danger", + acceptButtonText: { key: "closeThisWindow" }, + cancelButtonText: null as null, + acceptAction: async () => this.dialogService.closeAll(), + }, + unableToSavePasskey: { + title: { key: "unableToSavePasskey" }, + content: { key: "closeThisBitwardenWindow" }, + type: "danger", + acceptButtonText: { key: "closeThisWindow" }, + cancelButtonText: null as null, + acceptAction: async () => this.dialogService.closeAll(), + }, + overwritePasskey: { + title: { key: "overwritePasskey" }, + content: { key: "alreadyContainsPasskey" }, + type: "warning", + }, + } as const satisfies Record; + } + + constructor( + private readonly desktopSettingsService: DesktopSettingsService, + private readonly fido2UserInterfaceService: DesktopFido2UserInterfaceService, + private readonly accountService: AccountService, + private readonly cipherService: CipherService, + private readonly desktopAutofillService: DesktopAutofillService, + private readonly dialogService: DialogService, + private readonly domainSettingsService: DomainSettingsService, + private readonly passwordRepromptService: PasswordRepromptService, + private readonly router: Router, + ) {} + + async ngOnInit(): Promise { + this.session = this.fido2UserInterfaceService.getCurrentSession(); + + if (this.session) { + const rpid = await this.session.getRpId(); + this.initializeCiphersObservable(rpid); + } else { + await this.showErrorDialog(this.DIALOG_MESSAGES.unableToSavePasskey); + } + } + + async ngOnDestroy(): Promise { + this.destroy$.next(); + this.destroy$.complete(); + await this.closeModal(); + } + + async addCredentialToCipher(cipher: CipherView): Promise { + const isConfirmed = await this.validateCipherAccess(cipher); + + try { + if (!this.session) { + throw new Error("Missing session"); + } + + this.session.notifyConfirmCreateCredential(isConfirmed, cipher); + } catch { + await this.showErrorDialog(this.DIALOG_MESSAGES.unableToSavePasskey); + return; + } + + await this.closeModal(); + } + + async confirmPasskey(): Promise { + try { + if (!this.session) { + throw new Error("Missing session"); + } + + this.session.notifyConfirmCreateCredential(true); + } catch { + await this.showErrorDialog(this.DIALOG_MESSAGES.unableToSavePasskey); + } + + await this.closeModal(); + } + + async closeModal(): Promise { + await this.desktopSettingsService.setModalMode(false); + await this.accountService.setShowHeader(true); + + if (this.session) { + this.session.notifyConfirmCreateCredential(false); + this.session.confirmChosenCipher(null); + } + + await this.router.navigate(["/"]); + } + + private initializeCiphersObservable(rpid: string): void { + const lastRegistrationRequest = this.desktopAutofillService.lastRegistrationRequest; + + if (!lastRegistrationRequest || !rpid) { + return; + } + + const userHandle = Fido2Utils.bufferToString( + new Uint8Array(lastRegistrationRequest.userHandle), + ); + + this.ciphers$ = combineLatest([ + this.accountService.activeAccount$.pipe(map((a) => a?.id)), + this.domainSettingsService.getUrlEquivalentDomains(rpid), + ]).pipe( + switchMap(async ([activeUserId, equivalentDomains]) => { + if (!activeUserId) { + return []; + } + + try { + const allCiphers = await this.cipherService.getAllDecrypted(activeUserId); + return allCiphers.filter( + (cipher) => + cipher != null && + cipher.type == CipherType.Login && + cipher.login?.matchesUri(rpid, equivalentDomains) && + Fido2Utils.cipherHasNoOtherPasskeys(cipher, userHandle) && + !cipher.deletedDate, + ); + } catch { + await this.showErrorDialog(this.DIALOG_MESSAGES.unexpectedErrorShort); + return []; + } + }), + ); + } + + private async validateCipherAccess(cipher: CipherView): Promise { + if (cipher.login.hasFido2Credentials) { + const overwriteConfirmed = await this.dialogService.openSimpleDialog( + this.DIALOG_MESSAGES.overwritePasskey, + ); + + if (!overwriteConfirmed) { + return false; + } + } + + if (cipher.reprompt) { + return this.passwordRepromptService.showPasswordPrompt(); + } + + return true; + } + + private async showErrorDialog(config: SimpleDialogOptions): Promise { + await this.dialogService.openSimpleDialog(config); + await this.closeModal(); + } +} diff --git a/apps/desktop/src/autofill/modal/credentials/fido2-excluded-ciphers.component.html b/apps/desktop/src/autofill/modal/credentials/fido2-excluded-ciphers.component.html new file mode 100644 index 00000000000..792934deedc --- /dev/null +++ b/apps/desktop/src/autofill/modal/credentials/fido2-excluded-ciphers.component.html @@ -0,0 +1,44 @@ +
+ + +
+ + +

+ {{ "savePasskeyQuestion" | i18n }} +

+
+ + +
+
+ +
+ +
+ +
+ {{ "passkeyAlreadyExists" | i18n }} + {{ "applicationDoesNotSupportDuplicates" | i18n }} +
+ +
+
+
+
diff --git a/apps/desktop/src/autofill/modal/credentials/fido2-excluded-ciphers.component.spec.ts b/apps/desktop/src/autofill/modal/credentials/fido2-excluded-ciphers.component.spec.ts new file mode 100644 index 00000000000..6a465136458 --- /dev/null +++ b/apps/desktop/src/autofill/modal/credentials/fido2-excluded-ciphers.component.spec.ts @@ -0,0 +1,78 @@ +import { NO_ERRORS_SCHEMA } from "@angular/core"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { Router } from "@angular/router"; +import { mock, MockProxy } from "jest-mock-extended"; + +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; + +import { DesktopSettingsService } from "../../../platform/services/desktop-settings.service"; +import { + DesktopFido2UserInterfaceService, + DesktopFido2UserInterfaceSession, +} from "../../services/desktop-fido2-user-interface.service"; + +import { Fido2ExcludedCiphersComponent } from "./fido2-excluded-ciphers.component"; + +describe("Fido2ExcludedCiphersComponent", () => { + let component: Fido2ExcludedCiphersComponent; + let fixture: ComponentFixture; + let mockDesktopSettingsService: MockProxy; + let mockFido2UserInterfaceService: MockProxy; + let mockAccountService: MockProxy; + let mockRouter: MockProxy; + let mockSession: MockProxy; + let mockI18nService: MockProxy; + + beforeEach(async () => { + mockDesktopSettingsService = mock(); + mockFido2UserInterfaceService = mock(); + mockAccountService = mock(); + mockRouter = mock(); + mockSession = mock(); + mockI18nService = mock(); + + mockFido2UserInterfaceService.getCurrentSession.mockReturnValue(mockSession); + + await TestBed.configureTestingModule({ + imports: [Fido2ExcludedCiphersComponent], + providers: [ + { provide: DesktopSettingsService, useValue: mockDesktopSettingsService }, + { provide: DesktopFido2UserInterfaceService, useValue: mockFido2UserInterfaceService }, + { provide: AccountService, useValue: mockAccountService }, + { provide: Router, useValue: mockRouter }, + { provide: I18nService, useValue: mockI18nService }, + ], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + + fixture = TestBed.createComponent(Fido2ExcludedCiphersComponent); + component = fixture.componentInstance; + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + describe("ngOnInit", () => { + it("should initialize session", async () => { + await component.ngOnInit(); + + expect(mockFido2UserInterfaceService.getCurrentSession).toHaveBeenCalled(); + expect(component.session).toBe(mockSession); + }); + }); + + describe("closeModal", () => { + it("should close modal and notify session when session exists", async () => { + component.session = mockSession; + + await component.closeModal(); + + expect(mockDesktopSettingsService.setModalMode).toHaveBeenCalledWith(false); + expect(mockAccountService.setShowHeader).toHaveBeenCalledWith(true); + expect(mockSession.notifyConfirmCreateCredential).toHaveBeenCalledWith(false); + expect(mockRouter.navigate).toHaveBeenCalledWith(["/"]); + }); + }); +}); diff --git a/apps/desktop/src/autofill/modal/credentials/fido2-excluded-ciphers.component.ts b/apps/desktop/src/autofill/modal/credentials/fido2-excluded-ciphers.component.ts new file mode 100644 index 00000000000..049771c2252 --- /dev/null +++ b/apps/desktop/src/autofill/modal/credentials/fido2-excluded-ciphers.component.ts @@ -0,0 +1,78 @@ +import { CommonModule } from "@angular/common"; +import { ChangeDetectionStrategy, Component, OnInit, OnDestroy } from "@angular/core"; +import { RouterModule, Router } from "@angular/router"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { BitwardenShield, NoResults } from "@bitwarden/assets/svg"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { + BadgeModule, + ButtonModule, + DialogModule, + IconModule, + ItemModule, + SectionComponent, + TableModule, + SectionHeaderComponent, + BitIconButtonComponent, +} from "@bitwarden/components"; + +import { DesktopSettingsService } from "../../../platform/services/desktop-settings.service"; +import { + DesktopFido2UserInterfaceService, + DesktopFido2UserInterfaceSession, +} from "../../services/desktop-fido2-user-interface.service"; + +@Component({ + standalone: true, + imports: [ + CommonModule, + RouterModule, + SectionHeaderComponent, + BitIconButtonComponent, + TableModule, + JslibModule, + IconModule, + ButtonModule, + DialogModule, + SectionComponent, + ItemModule, + BadgeModule, + ], + templateUrl: "fido2-excluded-ciphers.component.html", + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class Fido2ExcludedCiphersComponent implements OnInit, OnDestroy { + session?: DesktopFido2UserInterfaceSession = null; + readonly Icons = { BitwardenShield, NoResults }; + + constructor( + private readonly desktopSettingsService: DesktopSettingsService, + private readonly fido2UserInterfaceService: DesktopFido2UserInterfaceService, + private readonly accountService: AccountService, + private readonly router: Router, + ) {} + + async ngOnInit(): Promise { + this.session = this.fido2UserInterfaceService.getCurrentSession(); + } + + async ngOnDestroy(): Promise { + await this.closeModal(); + } + + async closeModal(): Promise { + // Clean up modal state + await this.desktopSettingsService.setModalMode(false); + await this.accountService.setShowHeader(true); + + // Clean up session state + if (this.session) { + this.session.notifyConfirmCreateCredential(false); + this.session.confirmChosenCipher(null); + } + + // Navigate away + await this.router.navigate(["/"]); + } +} diff --git a/apps/desktop/src/autofill/modal/credentials/fido2-vault.component.html b/apps/desktop/src/autofill/modal/credentials/fido2-vault.component.html new file mode 100644 index 00000000000..ed04993d09f --- /dev/null +++ b/apps/desktop/src/autofill/modal/credentials/fido2-vault.component.html @@ -0,0 +1,37 @@ +
+ + +
+ + +

{{ "passkeyLogin" | i18n }}

+
+ +
+
+ + + + + {{ c.subTitle }} + {{ "select" | i18n }} + + + +
diff --git a/apps/desktop/src/autofill/modal/credentials/fido2-vault.component.spec.ts b/apps/desktop/src/autofill/modal/credentials/fido2-vault.component.spec.ts new file mode 100644 index 00000000000..70ef4461f6a --- /dev/null +++ b/apps/desktop/src/autofill/modal/credentials/fido2-vault.component.spec.ts @@ -0,0 +1,196 @@ +import { NO_ERRORS_SCHEMA } from "@angular/core"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { Router } from "@angular/router"; +import { mock, MockProxy } from "jest-mock-extended"; +import { of } from "rxjs"; + +import { AccountService, Account } from "@bitwarden/common/auth/abstractions/account.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherRepromptType, CipherType } from "@bitwarden/common/vault/enums"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { PasswordRepromptService } from "@bitwarden/vault"; + +import { DesktopSettingsService } from "../../../platform/services/desktop-settings.service"; +import { + DesktopFido2UserInterfaceService, + DesktopFido2UserInterfaceSession, +} from "../../services/desktop-fido2-user-interface.service"; + +import { Fido2VaultComponent } from "./fido2-vault.component"; + +describe("Fido2VaultComponent", () => { + let component: Fido2VaultComponent; + let fixture: ComponentFixture; + let mockDesktopSettingsService: MockProxy; + let mockFido2UserInterfaceService: MockProxy; + let mockCipherService: MockProxy; + let mockAccountService: MockProxy; + let mockLogService: MockProxy; + let mockPasswordRepromptService: MockProxy; + let mockRouter: MockProxy; + let mockSession: MockProxy; + let mockI18nService: MockProxy; + + const mockActiveAccount = { id: "test-user-id", email: "test@example.com" }; + const mockCipherIds = ["cipher-1", "cipher-2", "cipher-3"]; + + beforeEach(async () => { + mockDesktopSettingsService = mock(); + mockFido2UserInterfaceService = mock(); + mockCipherService = mock(); + mockAccountService = mock(); + mockLogService = mock(); + mockPasswordRepromptService = mock(); + mockRouter = mock(); + mockSession = mock(); + mockI18nService = mock(); + + mockAccountService.activeAccount$ = of(mockActiveAccount as Account); + mockFido2UserInterfaceService.getCurrentSession.mockReturnValue(mockSession); + mockSession.availableCipherIds$ = of(mockCipherIds); + mockCipherService.cipherListViews$ = jest.fn().mockReturnValue(of([])); + + await TestBed.configureTestingModule({ + imports: [Fido2VaultComponent], + providers: [ + { provide: DesktopSettingsService, useValue: mockDesktopSettingsService }, + { provide: DesktopFido2UserInterfaceService, useValue: mockFido2UserInterfaceService }, + { provide: CipherService, useValue: mockCipherService }, + { provide: AccountService, useValue: mockAccountService }, + { provide: LogService, useValue: mockLogService }, + { provide: PasswordRepromptService, useValue: mockPasswordRepromptService }, + { provide: Router, useValue: mockRouter }, + { provide: I18nService, useValue: mockI18nService }, + ], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + + fixture = TestBed.createComponent(Fido2VaultComponent); + component = fixture.componentInstance; + }); + + const mockCiphers: any[] = [ + { + id: "cipher-1", + name: "Test Cipher 1", + type: CipherType.Login, + login: { + username: "test1@example.com", + }, + reprompt: CipherRepromptType.None, + deletedDate: null, + }, + { + id: "cipher-2", + name: "Test Cipher 2", + type: CipherType.Login, + login: { + username: "test2@example.com", + }, + reprompt: CipherRepromptType.None, + deletedDate: null, + }, + { + id: "cipher-3", + name: "Test Cipher 3", + type: CipherType.Login, + login: { + username: "test3@example.com", + }, + reprompt: CipherRepromptType.Password, + deletedDate: null, + }, + ]; + + describe("ngOnInit", () => { + it("should initialize session and load ciphers successfully", async () => { + mockCipherService.cipherListViews$ = jest.fn().mockReturnValue(of(mockCiphers)); + + await component.ngOnInit(); + + expect(mockFido2UserInterfaceService.getCurrentSession).toHaveBeenCalled(); + expect(component.session).toBe(mockSession); + expect(component.cipherIds$).toBe(mockSession.availableCipherIds$); + expect(mockCipherService.cipherListViews$).toHaveBeenCalledWith(mockActiveAccount.id); + }); + + it("should handle when no active session found", async () => { + mockFido2UserInterfaceService.getCurrentSession.mockReturnValue(null); + + await component.ngOnInit(); + + expect(component.session).toBeNull(); + }); + + it("should filter out deleted ciphers", async () => { + const ciphersWithDeleted = [ + ...mockCiphers.slice(0, 1), + { ...mockCiphers[1], deletedDate: new Date() }, + ...mockCiphers.slice(2), + ]; + mockCipherService.cipherListViews$ = jest.fn().mockReturnValue(of(ciphersWithDeleted)); + + await component.ngOnInit(); + await new Promise((resolve) => setTimeout(resolve, 0)); + + let ciphersResult: CipherView[] = []; + component.ciphers$.subscribe((ciphers) => { + ciphersResult = ciphers; + }); + + expect(ciphersResult).toHaveLength(2); + expect(ciphersResult.every((cipher) => !cipher.deletedDate)).toBe(true); + }); + }); + + describe("chooseCipher", () => { + const cipher = mockCiphers[0]; + + beforeEach(() => { + component.session = mockSession; + }); + + it("should choose cipher when access is validated", async () => { + cipher.reprompt = CipherRepromptType.None; + + await component.chooseCipher(cipher); + + expect(mockSession.confirmChosenCipher).toHaveBeenCalledWith(cipher.id, true); + expect(mockRouter.navigate).toHaveBeenCalledWith(["/"]); + }); + + it("should prompt for password when cipher requires reprompt", async () => { + cipher.reprompt = CipherRepromptType.Password; + mockPasswordRepromptService.showPasswordPrompt.mockResolvedValue(true); + + await component.chooseCipher(cipher); + + expect(mockPasswordRepromptService.showPasswordPrompt).toHaveBeenCalled(); + expect(mockSession.confirmChosenCipher).toHaveBeenCalledWith(cipher.id, true); + }); + + it("should not choose cipher when password reprompt is cancelled", async () => { + cipher.reprompt = CipherRepromptType.Password; + mockPasswordRepromptService.showPasswordPrompt.mockResolvedValue(false); + + await component.chooseCipher(cipher); + + expect(mockPasswordRepromptService.showPasswordPrompt).toHaveBeenCalled(); + expect(mockSession.confirmChosenCipher).toHaveBeenCalledWith(cipher.id, false); + }); + }); + + describe("closeModal", () => { + it("should close modal and notify session", async () => { + component.session = mockSession; + + await component.closeModal(); + + expect(mockRouter.navigate).toHaveBeenCalledWith(["/"]); + expect(mockSession.notifyConfirmCreateCredential).toHaveBeenCalledWith(false); + expect(mockSession.confirmChosenCipher).toHaveBeenCalledWith(null); + }); + }); +}); diff --git a/apps/desktop/src/autofill/modal/credentials/fido2-vault.component.ts b/apps/desktop/src/autofill/modal/credentials/fido2-vault.component.ts new file mode 100644 index 00000000000..897e825c53e --- /dev/null +++ b/apps/desktop/src/autofill/modal/credentials/fido2-vault.component.ts @@ -0,0 +1,161 @@ +import { CommonModule } from "@angular/common"; +import { ChangeDetectionStrategy, Component, OnInit, OnDestroy } from "@angular/core"; +import { RouterModule, Router } from "@angular/router"; +import { + firstValueFrom, + map, + combineLatest, + of, + BehaviorSubject, + Observable, + Subject, + takeUntil, +} from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { BitwardenShield } from "@bitwarden/assets/svg"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherRepromptType } from "@bitwarden/common/vault/enums"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { + BadgeModule, + ButtonModule, + DialogModule, + DialogService, + IconModule, + ItemModule, + SectionComponent, + TableModule, + BitIconButtonComponent, + SectionHeaderComponent, +} from "@bitwarden/components"; +import { PasswordRepromptService } from "@bitwarden/vault"; + +import { DesktopSettingsService } from "../../../platform/services/desktop-settings.service"; +import { + DesktopFido2UserInterfaceService, + DesktopFido2UserInterfaceSession, +} from "../../services/desktop-fido2-user-interface.service"; + +@Component({ + standalone: true, + imports: [ + CommonModule, + RouterModule, + SectionHeaderComponent, + BitIconButtonComponent, + TableModule, + JslibModule, + IconModule, + ButtonModule, + DialogModule, + SectionComponent, + ItemModule, + BadgeModule, + ], + templateUrl: "fido2-vault.component.html", + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class Fido2VaultComponent implements OnInit, OnDestroy { + session?: DesktopFido2UserInterfaceSession = null; + private destroy$ = new Subject(); + private ciphersSubject = new BehaviorSubject([]); + ciphers$: Observable = this.ciphersSubject.asObservable(); + cipherIds$: Observable | undefined; + readonly Icons = { BitwardenShield }; + + constructor( + private readonly desktopSettingsService: DesktopSettingsService, + private readonly fido2UserInterfaceService: DesktopFido2UserInterfaceService, + private readonly cipherService: CipherService, + private readonly accountService: AccountService, + private readonly dialogService: DialogService, + private readonly logService: LogService, + private readonly passwordRepromptService: PasswordRepromptService, + private readonly router: Router, + ) {} + + async ngOnInit(): Promise { + this.session = this.fido2UserInterfaceService.getCurrentSession(); + this.cipherIds$ = this.session?.availableCipherIds$; + await this.loadCiphers(); + } + + async ngOnDestroy(): Promise { + this.destroy$.next(); + this.destroy$.complete(); + } + + async chooseCipher(cipher: CipherView): Promise { + if (!this.session) { + await this.dialogService.openSimpleDialog({ + title: { key: "unexpectedErrorShort" }, + content: { key: "closeThisBitwardenWindow" }, + type: "danger", + acceptButtonText: { key: "closeThisWindow" }, + cancelButtonText: null, + }); + await this.closeModal(); + + return; + } + + const isConfirmed = await this.validateCipherAccess(cipher); + this.session.confirmChosenCipher(cipher.id, isConfirmed); + + await this.closeModal(); + } + + async closeModal(): Promise { + await this.desktopSettingsService.setModalMode(false); + await this.accountService.setShowHeader(true); + + if (this.session) { + this.session.notifyConfirmCreateCredential(false); + this.session.confirmChosenCipher(null); + } + + await this.router.navigate(["/"]); + } + + private async loadCiphers(): Promise { + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(map((a) => a?.id)), + ); + + if (!activeUserId) { + return; + } + + // Combine cipher list with optional cipher IDs filter + combineLatest([this.cipherService.cipherListViews$(activeUserId), this.cipherIds$ || of(null)]) + .pipe( + map(([ciphers, cipherIds]) => { + // Filter out deleted ciphers + const activeCiphers = ciphers.filter((cipher) => !cipher.deletedDate); + + // If specific IDs provided, filter by them + if (cipherIds?.length > 0) { + return activeCiphers.filter((cipher) => cipherIds.includes(cipher.id as string)); + } + + return activeCiphers; + }), + takeUntil(this.destroy$), + ) + .subscribe({ + next: (ciphers) => this.ciphersSubject.next(ciphers as CipherView[]), + error: (error: unknown) => this.logService.error("Failed to load ciphers", error), + }); + } + + private async validateCipherAccess(cipher: CipherView): Promise { + if (cipher.reprompt !== CipherRepromptType.None) { + return this.passwordRepromptService.showPasswordPrompt(); + } + + return true; + } +} diff --git a/apps/desktop/src/autofill/models/autotype-config.ts b/apps/desktop/src/autofill/models/autotype-config.ts new file mode 100644 index 00000000000..dda39023c8c --- /dev/null +++ b/apps/desktop/src/autofill/models/autotype-config.ts @@ -0,0 +1,3 @@ +export interface AutotypeConfig { + keyboardShortcut: string[]; +} diff --git a/apps/desktop/src/autofill/models/ipc-channels.ts b/apps/desktop/src/autofill/models/ipc-channels.ts new file mode 100644 index 00000000000..5fea2daf0cf --- /dev/null +++ b/apps/desktop/src/autofill/models/ipc-channels.ts @@ -0,0 +1,9 @@ +export const AUTOTYPE_IPC_CHANNELS = { + INIT: "autofill.initAutotype", + INITIALIZED: "autofill.autotypeIsInitialized", + TOGGLE: "autofill.toggleAutotype", + CONFIGURE: "autofill.configureAutotype", + LISTEN: "autofill.listenAutotypeRequest", + EXECUTION_ERROR: "autofill.autotypeExecutionError", + EXECUTE: "autofill.executeAutotype", +} as const; diff --git a/apps/desktop/src/autofill/preload.ts b/apps/desktop/src/autofill/preload.ts index e839ac223b7..f4f5552944c 100644 --- a/apps/desktop/src/autofill/preload.ts +++ b/apps/desktop/src/autofill/preload.ts @@ -5,13 +5,17 @@ import type { autofill } from "@bitwarden/desktop-napi"; import { Command } from "../platform/main/autofill/command"; import { RunCommandParams, RunCommandResult } from "../platform/main/autofill/native-autofill.main"; +import { AutotypeConfig } from "./models/autotype-config"; import { AutotypeMatchError } from "./models/autotype-errors"; import { AutotypeVaultData } from "./models/autotype-vault-data"; +import { AUTOTYPE_IPC_CHANNELS } from "./models/ipc-channels"; export default { runCommand: (params: RunCommandParams): Promise> => ipcRenderer.invoke("autofill.runCommand", params), + listenerReady: () => ipcRenderer.send("autofill.listenerReady"), + listenPasskeyRegistration: ( fn: ( clientId: number, @@ -130,8 +134,29 @@ export default { }, ); }, - configureAutotype: (enabled: boolean, keyboardShortcut: string[]) => { - ipcRenderer.send("autofill.configureAutotype", { enabled, keyboardShortcut }); + listenNativeStatus: ( + fn: (clientId: number, sequenceNumber: number, status: { key: string; value: string }) => void, + ) => { + ipcRenderer.on( + "autofill.nativeStatus", + ( + event, + data: { + clientId: number; + sequenceNumber: number; + status: { key: string; value: string }; + }, + ) => { + const { clientId, sequenceNumber, status } = data; + fn(clientId, sequenceNumber, status); + }, + ); + }, + configureAutotype: (config: AutotypeConfig) => { + ipcRenderer.send(AUTOTYPE_IPC_CHANNELS.CONFIGURE, config); + }, + toggleAutotype: (enable: boolean) => { + ipcRenderer.send(AUTOTYPE_IPC_CHANNELS.TOGGLE, enable); }, listenAutotypeRequest: ( fn: ( @@ -140,7 +165,7 @@ export default { ) => void, ) => { ipcRenderer.on( - "autofill.listenAutotypeRequest", + AUTOTYPE_IPC_CHANNELS.LISTEN, ( _event, data: { @@ -155,11 +180,12 @@ export default { windowTitle, errorMessage: error.message, }; - ipcRenderer.send("autofill.completeAutotypeError", matchError); + ipcRenderer.send(AUTOTYPE_IPC_CHANNELS.EXECUTION_ERROR, matchError); return; } + if (vaultData !== null) { - ipcRenderer.send("autofill.completeAutotypeRequest", vaultData); + ipcRenderer.send(AUTOTYPE_IPC_CHANNELS.EXECUTE, vaultData); } }); }, diff --git a/apps/desktop/src/autofill/services/desktop-autofill.service.ts b/apps/desktop/src/autofill/services/desktop-autofill.service.ts index 18f4652d72a..c50964e31e3 100644 --- a/apps/desktop/src/autofill/services/desktop-autofill.service.ts +++ b/apps/desktop/src/autofill/services/desktop-autofill.service.ts @@ -1,6 +1,8 @@ import { Injectable, OnDestroy } from "@angular/core"; import { Subject, + combineLatest, + debounceTime, distinctUntilChanged, filter, firstValueFrom, @@ -8,10 +10,11 @@ import { mergeMap, switchMap, takeUntil, - EMPTY, } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; +import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { getOptionalUserId } from "@bitwarden/common/auth/services/account.service"; import { DeviceType } from "@bitwarden/common/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -48,6 +51,7 @@ import type { NativeWindowObject } from "./desktop-fido2-user-interface.service" @Injectable() export class DesktopAutofillService implements OnDestroy { private destroy$ = new Subject(); + private registrationRequest: autofill.PasskeyRegistrationRequest; constructor( private logService: LogService, @@ -55,6 +59,7 @@ export class DesktopAutofillService implements OnDestroy { private configService: ConfigService, private fido2AuthenticatorService: Fido2AuthenticatorServiceAbstraction, private accountService: AccountService, + private authService: AuthService, private platformUtilsService: PlatformUtilsService, ) {} @@ -68,28 +73,56 @@ export class DesktopAutofillService implements OnDestroy { .getFeatureFlag$(FeatureFlag.MacOsNativeCredentialSync) .pipe( distinctUntilChanged(), - switchMap((enabled) => { - if (!enabled) { - return EMPTY; - } - - return this.accountService.activeAccount$.pipe( - map((account) => account?.id), - filter((userId): userId is UserId => userId != null), - switchMap((userId) => this.cipherService.cipherViews$(userId)), + filter((enabled) => enabled === true), // Only proceed if feature is enabled + switchMap(() => { + return combineLatest([ + this.accountService.activeAccount$.pipe( + map((account) => account?.id), + filter((userId): userId is UserId => userId != null), + ), + this.authService.activeAccountStatus$, + ]).pipe( + // Only proceed when the vault is unlocked + filter(([, status]) => status === AuthenticationStatus.Unlocked), + // Then get cipher views + switchMap(([userId]) => this.cipherService.cipherViews$(userId)), ); }), - // TODO: This will unset all the autofill credentials on the OS - // when the account locks. We should instead explicilty clear the credentials - // when the user logs out. Maybe by subscribing to the encrypted ciphers observable instead. + debounceTime(100), // just a precaution to not spam the sync if there are multiple changes (we typically observe a null change) + // No filter for empty arrays here - we want to sync even if there are 0 items + filter((cipherViewMap) => cipherViewMap !== null), + mergeMap((cipherViewMap) => this.sync(Object.values(cipherViewMap ?? []))), takeUntil(this.destroy$), ) .subscribe(); + // Listen for sign out to clear credentials + this.authService.activeAccountStatus$ + .pipe( + filter((status) => status === AuthenticationStatus.LoggedOut), + mergeMap(() => this.sync([])), // sync an empty array + takeUntil(this.destroy$), + ) + .subscribe(); + this.listenIpc(); } + async adHocSync(): Promise { + this.logService.debug("Performing AdHoc sync"); + const account = await firstValueFrom(this.accountService.activeAccount$); + const userId = account?.id; + + if (!userId) { + throw new Error("No active user found"); + } + + const cipherViewMap = await firstValueFrom(this.cipherService.cipherViews$(userId)); + this.logService.info("Performing AdHoc sync", Object.values(cipherViewMap ?? [])); + await this.sync(Object.values(cipherViewMap ?? [])); + } + /** Give metadata about all available credentials in the users vault */ async sync(cipherViews: CipherView[]) { const status = await this.status(); @@ -130,6 +163,11 @@ export class DesktopAutofillService implements OnDestroy { })); } + this.logService.info("Syncing autofill credentials", { + fido2Credentials, + passwordCredentials, + }); + const syncResult = await ipc.autofill.runCommand({ namespace: "autofill", command: "sync", @@ -155,107 +193,152 @@ export class DesktopAutofillService implements OnDestroy { }); } + get lastRegistrationRequest() { + return this.registrationRequest; + } + listenIpc() { - ipc.autofill.listenPasskeyRegistration((clientId, sequenceNumber, request, callback) => { - this.logService.warning("listenPasskeyRegistration", clientId, sequenceNumber, request); - this.logService.warning( - "listenPasskeyRegistration2", - this.convertRegistrationRequest(request), - ); + ipc.autofill.listenPasskeyRegistration(async (clientId, sequenceNumber, request, callback) => { + if (!(await this.configService.getFeatureFlag(FeatureFlag.MacOsNativeCredentialSync))) { + this.logService.debug( + "listenPasskeyRegistration: MacOsNativeCredentialSync feature flag is disabled", + ); + callback(new Error("MacOsNativeCredentialSync feature flag is disabled"), null); + return; + } + + this.registrationRequest = request; + + this.logService.debug("listenPasskeyRegistration", clientId, sequenceNumber, request); + this.logService.debug("listenPasskeyRegistration2", this.convertRegistrationRequest(request)); const controller = new AbortController(); - void this.fido2AuthenticatorService - .makeCredential( + + try { + const response = await this.fido2AuthenticatorService.makeCredential( this.convertRegistrationRequest(request), - { windowXy: request.windowXy }, + { windowXy: normalizePosition(request.windowXy) }, controller, - ) - .then((response) => { - callback(null, this.convertRegistrationResponse(request, response)); - }) - .catch((error) => { - this.logService.error("listenPasskeyRegistration error", error); - callback(error, null); - }); + ); + + callback(null, this.convertRegistrationResponse(request, response)); + } catch (error) { + this.logService.error("listenPasskeyRegistration error", error); + callback(error, null); + } }); ipc.autofill.listenPasskeyAssertionWithoutUserInterface( async (clientId, sequenceNumber, request, callback) => { - this.logService.warning( + if (!(await this.configService.getFeatureFlag(FeatureFlag.MacOsNativeCredentialSync))) { + this.logService.debug( + "listenPasskeyAssertionWithoutUserInterface: MacOsNativeCredentialSync feature flag is disabled", + ); + callback(new Error("MacOsNativeCredentialSync feature flag is disabled"), null); + return; + } + + this.logService.debug( "listenPasskeyAssertion without user interface", clientId, sequenceNumber, request, ); - // For some reason the credentialId is passed as an empty array in the request, so we need to - // get it from the cipher. For that we use the recordIdentifier, which is the cipherId. - if (request.recordIdentifier && request.credentialId.length === 0) { - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(getOptionalUserId), - ); - if (!activeUserId) { - this.logService.error("listenPasskeyAssertion error", "Active user not found"); - callback(new Error("Active user not found"), null); - return; - } - - const cipher = await this.cipherService.get(request.recordIdentifier, activeUserId); - if (!cipher) { - this.logService.error("listenPasskeyAssertion error", "Cipher not found"); - callback(new Error("Cipher not found"), null); - return; - } - - const decrypted = await this.cipherService.decrypt(cipher, activeUserId); - - const fido2Credential = decrypted.login.fido2Credentials?.[0]; - if (!fido2Credential) { - this.logService.error("listenPasskeyAssertion error", "Fido2Credential not found"); - callback(new Error("Fido2Credential not found"), null); - return; - } - - request.credentialId = Array.from( - new Uint8Array(parseCredentialId(decrypted.login.fido2Credentials?.[0].credentialId)), - ); - } - const controller = new AbortController(); - void this.fido2AuthenticatorService - .getAssertion( - this.convertAssertionRequest(request), - { windowXy: request.windowXy }, + + try { + // For some reason the credentialId is passed as an empty array in the request, so we need to + // get it from the cipher. For that we use the recordIdentifier, which is the cipherId. + if (request.recordIdentifier && request.credentialId.length === 0) { + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getOptionalUserId), + ); + if (!activeUserId) { + this.logService.error("listenPasskeyAssertion error", "Active user not found"); + callback(new Error("Active user not found"), null); + return; + } + + const cipher = await this.cipherService.get(request.recordIdentifier, activeUserId); + if (!cipher) { + this.logService.error("listenPasskeyAssertion error", "Cipher not found"); + callback(new Error("Cipher not found"), null); + return; + } + + const decrypted = await this.cipherService.decrypt(cipher, activeUserId); + + const fido2Credential = decrypted.login.fido2Credentials?.[0]; + if (!fido2Credential) { + this.logService.error("listenPasskeyAssertion error", "Fido2Credential not found"); + callback(new Error("Fido2Credential not found"), null); + return; + } + + request.credentialId = Array.from( + new Uint8Array(parseCredentialId(decrypted.login.fido2Credentials?.[0].credentialId)), + ); + } + + const response = await this.fido2AuthenticatorService.getAssertion( + this.convertAssertionRequest(request, true), + { windowXy: normalizePosition(request.windowXy) }, controller, - ) - .then((response) => { - callback(null, this.convertAssertionResponse(request, response)); - }) - .catch((error) => { - this.logService.error("listenPasskeyAssertion error", error); - callback(error, null); - }); + ); + + callback(null, this.convertAssertionResponse(request, response)); + } catch (error) { + this.logService.error("listenPasskeyAssertion error", error); + callback(error, null); + return; + } }, ); ipc.autofill.listenPasskeyAssertion(async (clientId, sequenceNumber, request, callback) => { - this.logService.warning("listenPasskeyAssertion", clientId, sequenceNumber, request); + if (!(await this.configService.getFeatureFlag(FeatureFlag.MacOsNativeCredentialSync))) { + this.logService.debug( + "listenPasskeyAssertion: MacOsNativeCredentialSync feature flag is disabled", + ); + callback(new Error("MacOsNativeCredentialSync feature flag is disabled"), null); + return; + } + + this.logService.debug("listenPasskeyAssertion", clientId, sequenceNumber, request); const controller = new AbortController(); - void this.fido2AuthenticatorService - .getAssertion( + try { + const response = await this.fido2AuthenticatorService.getAssertion( this.convertAssertionRequest(request), - { windowXy: request.windowXy }, + { windowXy: normalizePosition(request.windowXy) }, controller, - ) - .then((response) => { - callback(null, this.convertAssertionResponse(request, response)); - }) - .catch((error) => { - this.logService.error("listenPasskeyAssertion error", error); - callback(error, null); - }); + ); + + callback(null, this.convertAssertionResponse(request, response)); + } catch (error) { + this.logService.error("listenPasskeyAssertion error", error); + callback(error, null); + } }); + + // Listen for native status messages + ipc.autofill.listenNativeStatus(async (clientId, sequenceNumber, status) => { + if (!(await this.configService.getFeatureFlag(FeatureFlag.MacOsNativeCredentialSync))) { + this.logService.debug( + "listenNativeStatus: MacOsNativeCredentialSync feature flag is disabled", + ); + return; + } + + this.logService.info("Received native status", status.key, status.value); + if (status.key === "request-sync") { + // perform ad-hoc sync + await this.adHocSync(); + } + }); + + ipc.autofill.listenerReady(); } private convertRegistrationRequest( @@ -277,7 +360,10 @@ export class DesktopAutofillService implements OnDestroy { alg, type: "public-key", })), - excludeCredentialDescriptorList: [], + excludeCredentialDescriptorList: request.excludedCredentials.map((credentialId) => ({ + id: new Uint8Array(credentialId), + type: "public-key" as const, + })), requireResidentKey: true, requireUserVerification: request.userVerification === "required" || request.userVerification === "preferred", @@ -309,18 +395,19 @@ export class DesktopAutofillService implements OnDestroy { request: | autofill.PasskeyAssertionRequest | autofill.PasskeyAssertionWithoutUserInterfaceRequest, + assumeUserPresence: boolean = false, ): Fido2AuthenticatorGetAssertionParams { let allowedCredentials; if ("credentialId" in request) { allowedCredentials = [ { - id: new Uint8Array(request.credentialId), + id: new Uint8Array(request.credentialId).buffer, type: "public-key" as const, }, ]; } else { allowedCredentials = request.allowedCredentials.map((credentialId) => ({ - id: new Uint8Array(credentialId), + id: new Uint8Array(credentialId).buffer, type: "public-key" as const, })); } @@ -333,7 +420,7 @@ export class DesktopAutofillService implements OnDestroy { requireUserVerification: request.userVerification === "required" || request.userVerification === "preferred", fallbackSupported: false, - assumeUserPresence: true, // For desktop assertions, it's safe to assume UP has been checked by OS dialogues + assumeUserPresence, }; } @@ -358,3 +445,13 @@ export class DesktopAutofillService implements OnDestroy { this.destroy$.complete(); } } + +function normalizePosition(position: { x: number; y: number }): { x: number; y: number } { + // Add 100 pixels to the x-coordinate to offset the native OS dialog positioning. + const xPositionOffset = 100; + + return { + x: Math.round(position.x + xPositionOffset), + y: Math.round(position.y), + }; +} diff --git a/apps/desktop/src/autofill/services/desktop-autotype-policy.service.spec.ts b/apps/desktop/src/autofill/services/desktop-autotype-policy.service.spec.ts index 555e6ceef5b..907da2fe85c 100644 --- a/apps/desktop/src/autofill/services/desktop-autotype-policy.service.spec.ts +++ b/apps/desktop/src/autofill/services/desktop-autotype-policy.service.spec.ts @@ -10,6 +10,7 @@ import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { Account, UserId } from "@bitwarden/common/platform/models/domain/account"; +import { mockAccountInfoWith } from "@bitwarden/common/spec"; import { DesktopAutotypeDefaultSettingPolicy } from "./desktop-autotype-policy.service"; @@ -30,9 +31,10 @@ describe("DesktopAutotypeDefaultSettingPolicy", () => { beforeEach(() => { mockAccountSubject = new BehaviorSubject({ id: mockUserId, - email: "test@example.com", - emailVerified: true, - name: "Test User", + ...mockAccountInfoWith({ + email: "test@example.com", + name: "Test User", + }), }); mockFeatureFlagSubject = new BehaviorSubject(true); mockAuthStatusSubject = new BehaviorSubject( diff --git a/apps/desktop/src/autofill/services/desktop-autotype.service.ts b/apps/desktop/src/autofill/services/desktop-autotype.service.ts index 7ee889e7b81..46fec662d7a 100644 --- a/apps/desktop/src/autofill/services/desktop-autotype.service.ts +++ b/apps/desktop/src/autofill/services/desktop-autotype.service.ts @@ -1,4 +1,17 @@ -import { combineLatest, filter, firstValueFrom, map, Observable, of, switchMap } from "rxjs"; +import { Injectable, OnDestroy } from "@angular/core"; +import { + combineLatest, + concatMap, + distinctUntilChanged, + filter, + firstValueFrom, + map, + Observable, + of, + Subject, + switchMap, + takeUntil, +} from "rxjs"; import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; @@ -15,8 +28,10 @@ import { } from "@bitwarden/common/platform/state"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { LogService } from "@bitwarden/logging"; import { UserId } from "@bitwarden/user-core"; +import { AutotypeConfig } from "../models/autotype-config"; import { AutotypeVaultData } from "../models/autotype-vault-data"; import { DesktopAutotypeDefaultSettingPolicy } from "./desktop-autotype-policy.service"; @@ -44,16 +59,26 @@ export const AUTOTYPE_KEYBOARD_SHORTCUT = new KeyDefinition( { deserializer: (b) => b }, ); -export class DesktopAutotypeService { +@Injectable({ + providedIn: "root", +}) +export class DesktopAutotypeService implements OnDestroy { private readonly autotypeEnabledState = this.globalStateProvider.get(AUTOTYPE_ENABLED); private readonly autotypeKeyboardShortcut = this.globalStateProvider.get( AUTOTYPE_KEYBOARD_SHORTCUT, ); - autotypeEnabledUserSetting$: Observable = of(false); - resolvedAutotypeEnabled$: Observable = of(false); + // if the user's account is Premium + private readonly isPremiumAccount$: Observable; + + // The enabled/disabled state from the user settings menu + autotypeEnabledUserSetting$: Observable; + + // The keyboard shortcut from the user settings menu autotypeKeyboardShortcut$: Observable = of(defaultWindowsAutotypeKeyboardShortcut); + private destroy$ = new Subject(); + constructor( private accountService: AccountService, private authService: AuthService, @@ -63,76 +88,110 @@ export class DesktopAutotypeService { private platformUtilsService: PlatformUtilsService, private billingAccountProfileStateService: BillingAccountProfileStateService, private desktopAutotypePolicy: DesktopAutotypeDefaultSettingPolicy, + private logService: LogService, ) { + this.autotypeEnabledUserSetting$ = this.autotypeEnabledState.state$.pipe( + map((enabled) => enabled ?? false), + distinctUntilChanged(), // Only emit when the boolean result changes + takeUntil(this.destroy$), + ); + + this.isPremiumAccount$ = this.accountService.activeAccount$.pipe( + filter((account): account is Account => !!account), + switchMap((account) => + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + distinctUntilChanged(), // Only emit when the boolean result changes + takeUntil(this.destroy$), + ); + + this.autotypeKeyboardShortcut$ = this.autotypeKeyboardShortcut.state$.pipe( + map((shortcut) => shortcut ?? defaultWindowsAutotypeKeyboardShortcut), + takeUntil(this.destroy$), + ); + } + + async init() { + // Currently Autotype is only supported for Windows + if (this.platformUtilsService.getDevice() !== DeviceType.WindowsDesktop) { + return; + } + ipc.autofill.listenAutotypeRequest(async (windowTitle, callback) => { const possibleCiphers = await this.matchCiphersToWindowTitle(windowTitle); const firstCipher = possibleCiphers?.at(0); const [error, vaultData] = getAutotypeVaultData(firstCipher); callback(error, vaultData); }); - } - async init() { - this.autotypeEnabledUserSetting$ = this.autotypeEnabledState.state$; - this.autotypeKeyboardShortcut$ = this.autotypeKeyboardShortcut.state$.pipe( - map((shortcut) => shortcut ?? defaultWindowsAutotypeKeyboardShortcut), - ); - - // Currently Autotype is only supported for Windows - if (this.platformUtilsService.getDevice() === DeviceType.WindowsDesktop) { - // If `autotypeDefaultPolicy` is `true` for a user's organization, and the - // user has never changed their local autotype setting (`autotypeEnabledState`), - // we set their local setting to `true` (once the local user setting is changed - // by this policy or the user themselves, the default policy should - // never change the user setting again). - combineLatest([ - this.autotypeEnabledState.state$, - this.desktopAutotypePolicy.autotypeDefaultSetting$, - ]) - .pipe( - map(async ([autotypeEnabledState, autotypeDefaultPolicy]) => { + // If `autotypeDefaultPolicy` is `true` for a user's organization, and the + // user has never changed their local autotype setting (`autotypeEnabledState`), + // we set their local setting to `true` (once the local user setting is changed + // by this policy or the user themselves, the default policy should + // never change the user setting again). + combineLatest([ + this.autotypeEnabledState.state$, + this.desktopAutotypePolicy.autotypeDefaultSetting$, + ]) + .pipe( + concatMap(async ([autotypeEnabledState, autotypeDefaultPolicy]) => { + try { if (autotypeDefaultPolicy === true && autotypeEnabledState === null) { await this.setAutotypeEnabledState(true); } - }), - ) - .subscribe(); + } catch { + this.logService.error("Failed to set Autotype enabled state."); + } + }), + takeUntil(this.destroy$), + ) + .subscribe(); - // autotypeEnabledUserSetting$ publicly represents the value the - // user has set for autotyeEnabled in their local settings. - this.autotypeEnabledUserSetting$ = this.autotypeEnabledState.state$; + // listen for changes in keyboard shortcut settings + this.autotypeKeyboardShortcut$ + .pipe( + concatMap(async (keyboardShortcut) => { + const config: AutotypeConfig = { + keyboardShortcut, + }; + ipc.autofill.configureAutotype(config); + }), + takeUntil(this.destroy$), + ) + .subscribe(); - // resolvedAutotypeEnabled$ represents the final determination if the Autotype - // feature should be on or off. - this.resolvedAutotypeEnabled$ = combineLatest([ - this.autotypeEnabledState.state$, - this.configService.getFeatureFlag$(FeatureFlag.WindowsDesktopAutotype), - this.accountService.activeAccount$.pipe( - map((activeAccount) => activeAccount?.id), - switchMap((userId) => this.authService.authStatusFor$(userId)), - ), - this.accountService.activeAccount$.pipe( - filter((account): account is Account => !!account), - switchMap((account) => - this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), - ), - ), - ]).pipe( - map( - ([autotypeEnabled, windowsDesktopAutotypeFeatureFlag, authStatus, hasPremium]) => - autotypeEnabled && - windowsDesktopAutotypeFeatureFlag && - authStatus == AuthenticationStatus.Unlocked && - hasPremium, - ), - ); + this.autotypeFeatureEnabled$ + .pipe( + concatMap(async (enabled) => { + ipc.autofill.toggleAutotype(enabled); + }), + takeUntil(this.destroy$), + ) + .subscribe(); + } - combineLatest([this.resolvedAutotypeEnabled$, this.autotypeKeyboardShortcut$]).subscribe( - ([resolvedAutotypeEnabled, autotypeKeyboardShortcut]) => { - ipc.autofill.configureAutotype(resolvedAutotypeEnabled, autotypeKeyboardShortcut); - }, - ); - } + // Returns an observable that represents whether autotype is enabled for the current user. + private get autotypeFeatureEnabled$(): Observable { + return combineLatest([ + // if the user has enabled the setting + this.autotypeEnabledUserSetting$, + // if the feature flag is set + this.configService.getFeatureFlag$(FeatureFlag.WindowsDesktopAutotype), + // if there is an active account with an unlocked vault + this.authService.activeAccountStatus$, + // if the active user's account is Premium + this.isPremiumAccount$, + ]).pipe( + map( + ([settingsEnabled, ffEnabled, authStatus, isPremiumAcct]) => + settingsEnabled && + ffEnabled && + authStatus === AuthenticationStatus.Unlocked && + isPremiumAcct, + ), + distinctUntilChanged(), // Only emit when the boolean result changes + takeUntil(this.destroy$), + ); } async setAutotypeEnabledState(enabled: boolean): Promise { @@ -176,6 +235,11 @@ export class DesktopAutotypeService { return possibleCiphers; } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } } /** diff --git a/apps/desktop/src/autofill/services/desktop-fido2-user-interface.service.ts b/apps/desktop/src/autofill/services/desktop-fido2-user-interface.service.ts index 3caf13fa5b7..cf29370840d 100644 --- a/apps/desktop/src/autofill/services/desktop-fido2-user-interface.service.ts +++ b/apps/desktop/src/autofill/services/desktop-fido2-user-interface.service.ts @@ -43,9 +43,7 @@ export type NativeWindowObject = { windowXy?: { x: number; y: number }; }; -export class DesktopFido2UserInterfaceService - implements Fido2UserInterfaceServiceAbstraction -{ +export class DesktopFido2UserInterfaceService implements Fido2UserInterfaceServiceAbstraction { constructor( private authService: AuthService, private cipherService: CipherService, @@ -66,7 +64,7 @@ export class DesktopFido2UserInterfaceService nativeWindowObject: NativeWindowObject, abortController?: AbortController, ): Promise { - this.logService.warning("newSession", fallbackSupported, abortController, nativeWindowObject); + this.logService.debug("newSession", fallbackSupported, abortController, nativeWindowObject); const session = new DesktopFido2UserInterfaceSession( this.authService, this.cipherService, @@ -94,9 +92,11 @@ export class DesktopFido2UserInterfaceSession implements Fido2UserInterfaceSessi ) {} private confirmCredentialSubject = new Subject(); - private createdCipher: Cipher; - private availableCipherIdsSubject = new BehaviorSubject(null); + private updatedCipher: CipherView; + + private rpId = new BehaviorSubject(null); + private availableCipherIdsSubject = new BehaviorSubject([""]); /** * Observable that emits available cipher IDs once they're confirmed by the UI */ @@ -114,7 +114,7 @@ export class DesktopFido2UserInterfaceSession implements Fido2UserInterfaceSessi assumeUserPresence, masterPasswordRepromptRequired, }: PickCredentialParams): Promise<{ cipherId: string; userVerified: boolean }> { - this.logService.warning("pickCredential desktop function", { + this.logService.debug("pickCredential desktop function", { cipherIds, userVerification, assumeUserPresence, @@ -123,6 +123,7 @@ export class DesktopFido2UserInterfaceSession implements Fido2UserInterfaceSessi try { // Check if we can return the credential without user interaction + await this.accountService.setShowHeader(false); if (assumeUserPresence && cipherIds.length === 1 && !masterPasswordRepromptRequired) { this.logService.debug( "shortcut - Assuming user presence and returning cipherId", @@ -136,22 +137,27 @@ export class DesktopFido2UserInterfaceSession implements Fido2UserInterfaceSessi // make the cipherIds available to the UI. this.availableCipherIdsSubject.next(cipherIds); - await this.showUi("/passkeys", this.windowObject.windowXy); + await this.showUi("/fido2-assertion", this.windowObject.windowXy, false); const chosenCipherResponse = await this.waitForUiChosenCipher(); this.logService.debug("Received chosen cipher", chosenCipherResponse); return { - cipherId: chosenCipherResponse.cipherId, - userVerified: chosenCipherResponse.userVerified, + cipherId: chosenCipherResponse?.cipherId, + userVerified: chosenCipherResponse?.userVerified, }; } finally { // Make sure to clean up so the app is never stuck in modal mode? await this.desktopSettingsService.setModalMode(false); + await this.accountService.setShowHeader(true); } } + async getRpId(): Promise { + return firstValueFrom(this.rpId.pipe(filter((id) => id != null))); + } + confirmChosenCipher(cipherId: string, userVerified: boolean = false): void { this.chosenCipherSubject.next({ cipherId, userVerified }); this.chosenCipherSubject.complete(); @@ -159,7 +165,7 @@ export class DesktopFido2UserInterfaceSession implements Fido2UserInterfaceSessi private async waitForUiChosenCipher( timeoutMs: number = 60000, - ): Promise<{ cipherId: string; userVerified: boolean } | undefined> { + ): Promise<{ cipherId?: string; userVerified: boolean } | undefined> { try { return await lastValueFrom(this.chosenCipherSubject.pipe(timeout(timeoutMs))); } catch { @@ -174,7 +180,10 @@ export class DesktopFido2UserInterfaceSession implements Fido2UserInterfaceSessi /** * Notifies the Fido2UserInterfaceSession that the UI operations has completed and it can return to the OS. */ - notifyConfirmNewCredential(confirmed: boolean): void { + notifyConfirmCreateCredential(confirmed: boolean, updatedCipher?: CipherView): void { + if (updatedCipher) { + this.updatedCipher = updatedCipher; + } this.confirmCredentialSubject.next(confirmed); this.confirmCredentialSubject.complete(); } @@ -195,60 +204,79 @@ export class DesktopFido2UserInterfaceSession implements Fido2UserInterfaceSessi async confirmNewCredential({ credentialName, userName, + userHandle, userVerification, rpId, }: NewCredentialParams): Promise<{ cipherId: string; userVerified: boolean }> { - this.logService.warning( + this.logService.debug( "confirmNewCredential", credentialName, userName, + userHandle, userVerification, rpId, ); + this.rpId.next(rpId); try { - await this.showUi("/passkeys", this.windowObject.windowXy); + await this.showUi("/fido2-creation", this.windowObject.windowXy, false); // Wait for the UI to wrap up const confirmation = await this.waitForUiNewCredentialConfirmation(); if (!confirmation) { return { cipherId: undefined, userVerified: false }; } - // Create the credential - await this.createCredential({ - credentialName, - userName, - rpId, - userHandle: "", - userVerification, - }); - // wait for 10ms to help RXJS catch up(?) - // We sometimes get a race condition from this.createCredential not updating cipherService in time - //console.log("waiting 10ms.."); - //await new Promise((resolve) => setTimeout(resolve, 10)); - //console.log("Just waited 10ms"); - - // Return the new cipher (this.createdCipher) - return { cipherId: this.createdCipher.id, userVerified: userVerification }; + if (this.updatedCipher) { + await this.updateCredential(this.updatedCipher); + return { cipherId: this.updatedCipher.id, userVerified: userVerification }; + } else { + // Create the cipher + const createdCipher = await this.createCipher({ + credentialName, + userName, + rpId, + userHandle, + userVerification, + }); + return { cipherId: createdCipher.id, userVerified: userVerification }; + } } finally { // Make sure to clean up so the app is never stuck in modal mode? await this.desktopSettingsService.setModalMode(false); + await this.accountService.setShowHeader(true); } } - private async showUi(route: string, position?: { x: number; y: number }): Promise { + private async hideUi(): Promise { + await this.desktopSettingsService.setModalMode(false); + await this.router.navigate(["/"]); + } + + private async showUi( + route: string, + position?: { x: number; y: number }, + showTrafficButtons: boolean = false, + disableRedirect?: boolean, + ): Promise { // Load the UI: - await this.desktopSettingsService.setModalMode(true, position); - await this.router.navigate(["/passkeys"]); + await this.desktopSettingsService.setModalMode(true, showTrafficButtons, position); + await this.accountService.setShowHeader(showTrafficButtons); + await this.router.navigate([ + route, + { + "disable-redirect": disableRedirect || null, + }, + ]); } /** - * Can be called by the UI to create a new credential with user input etc. + * Can be called by the UI to create a new cipher with user input etc. * @param param0 */ - async createCredential({ credentialName, userName, rpId }: NewCredentialParams): Promise { + async createCipher({ credentialName, userName, rpId }: NewCredentialParams): Promise { // Store the passkey on a new cipher to avoid replacing something important + const cipher = new CipherView(); cipher.name = credentialName; @@ -267,32 +295,81 @@ export class DesktopFido2UserInterfaceSession implements Fido2UserInterfaceSessi this.accountService.activeAccount$.pipe(map((a) => a?.id)), ); + if (!activeUserId) { + throw new Error("No active user ID found!"); + } + const encCipher = await this.cipherService.encrypt(cipher, activeUserId); - const createdCipher = await this.cipherService.createWithServer(encCipher); - this.createdCipher = createdCipher; + try { + const createdCipher = await this.cipherService.createWithServer(encCipher); - return createdCipher; + return createdCipher; + } catch { + throw new Error("Unable to create cipher"); + } + } + + async updateCredential(cipher: CipherView): Promise { + this.logService.info("updateCredential"); + await firstValueFrom( + this.accountService.activeAccount$.pipe( + map(async (a) => { + if (a) { + const encCipher = await this.cipherService.encrypt(cipher, a.id); + await this.cipherService.updateWithServer(encCipher); + } + }), + ), + ); } async informExcludedCredential(existingCipherIds: string[]): Promise { - this.logService.warning("informExcludedCredential", existingCipherIds); + this.logService.debug("informExcludedCredential", existingCipherIds); + + // make the cipherIds available to the UI. + this.availableCipherIdsSubject.next(existingCipherIds); + + await this.accountService.setShowHeader(false); + await this.showUi("/fido2-excluded", this.windowObject.windowXy, false); } async ensureUnlockedVault(): Promise { - this.logService.warning("ensureUnlockedVault"); + this.logService.debug("ensureUnlockedVault"); const status = await firstValueFrom(this.authService.activeAccountStatus$); if (status !== AuthenticationStatus.Unlocked) { - throw new Error("Vault is not unlocked"); + await this.showUi("/lock", this.windowObject.windowXy, true, true); + + let status2: AuthenticationStatus; + try { + status2 = await lastValueFrom( + this.authService.activeAccountStatus$.pipe( + filter((s) => s === AuthenticationStatus.Unlocked), + take(1), + timeout(1000 * 60 * 5), // 5 minutes + ), + ); + } catch (error) { + this.logService.warning("Error while waiting for vault to unlock", error); + } + + if (status2 === AuthenticationStatus.Unlocked) { + await this.router.navigate(["/"]); + } + + if (status2 !== AuthenticationStatus.Unlocked) { + await this.hideUi(); + throw new Error("Vault is not unlocked"); + } } } async informCredentialNotFound(): Promise { - this.logService.warning("informCredentialNotFound"); + this.logService.debug("informCredentialNotFound"); } async close() { - this.logService.warning("close"); + this.logService.debug("close"); } } diff --git a/apps/desktop/src/autofill/services/ssh-agent.service.ts b/apps/desktop/src/autofill/services/ssh-agent.service.ts index d5aed7f3289..7e289720ec8 100644 --- a/apps/desktop/src/autofill/services/ssh-agent.service.ts +++ b/apps/desktop/src/autofill/services/ssh-agent.service.ts @@ -46,8 +46,6 @@ export class SshAgentService implements OnDestroy { private authorizedSshKeys: Record = {}; - private isFeatureFlagEnabled = false; - private destroy$ = new Subject(); constructor( @@ -91,14 +89,14 @@ export class SshAgentService implements OnDestroy { filter(({ enabled }) => enabled), map(({ message }) => message), withLatestFrom(this.authService.activeAccountStatus$, this.accountService.activeAccount$), - // This switchMap handles unlocking the vault if it is locked: - // - If the vault is locked, we will wait for it to be unlocked. - // - If the vault is not unlocked within the timeout, we will abort the flow. + // This switchMap handles unlocking the vault if it is not unlocked: + // - If the vault is locked or logged out, we will wait for it to be unlocked: + // - If the vault is not unlocked in within the timeout, we will abort the flow. // - If the vault is unlocked, we will continue with the flow. // switchMap is used here to prevent multiple requests from being processed at the same time, // and will cancel the previous request if a new one is received. switchMap(([message, status, account]) => { - if (status !== AuthenticationStatus.Unlocked) { + if (status !== AuthenticationStatus.Unlocked || account == null) { ipc.platform.focusWindow(); this.toastService.showToast({ variant: "info", @@ -127,7 +125,11 @@ export class SshAgentService implements OnDestroy { throw error; }), - map(() => [message, account.id]), + concatMap(async () => { + // The active account may have switched with account switching during unlock + const updatedAccount = await firstValueFrom(this.accountService.activeAccount$); + return [message, updatedAccount.id] as const; + }), ); } @@ -200,10 +202,6 @@ export class SshAgentService implements OnDestroy { this.accountService.activeAccount$.pipe(skip(1), takeUntil(this.destroy$)).subscribe({ next: (account) => { - if (!this.isFeatureFlagEnabled) { - return; - } - this.authorizedSshKeys = {}; this.logService.info("Active account changed, clearing SSH keys"); ipc.platform.sshAgent @@ -211,20 +209,12 @@ export class SshAgentService implements OnDestroy { .catch((e) => this.logService.error("Failed to clear SSH keys", e)); }, error: (e: unknown) => { - if (!this.isFeatureFlagEnabled) { - return; - } - this.logService.error("Error in active account observable", e); ipc.platform.sshAgent .clearKeys() .catch((e) => this.logService.error("Failed to clear SSH keys", e)); }, complete: () => { - if (!this.isFeatureFlagEnabled) { - return; - } - this.logService.info("Active account observable completed, clearing SSH keys"); this.authorizedSshKeys = {}; ipc.platform.sshAgent @@ -239,10 +229,6 @@ export class SshAgentService implements OnDestroy { ]) .pipe( concatMap(async ([, enabled]) => { - if (!this.isFeatureFlagEnabled) { - return; - } - if (!enabled) { await ipc.platform.sshAgent.clearKeys(); return; diff --git a/apps/desktop/src/key-management/biometrics/renderer-biometrics.service.ts b/apps/desktop/src/key-management/biometrics/renderer-biometrics.service.ts index 8e28d3ca614..3a47086b1aa 100644 --- a/apps/desktop/src/key-management/biometrics/renderer-biometrics.service.ts +++ b/apps/desktop/src/key-management/biometrics/renderer-biometrics.service.ts @@ -1,5 +1,7 @@ import { Injectable } from "@angular/core"; +import { firstValueFrom } from "rxjs"; +import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; @@ -13,6 +15,10 @@ import { DesktopBiometricsService } from "./desktop.biometrics.service"; */ @Injectable() export class RendererBiometricsService extends DesktopBiometricsService { + constructor(private tokenService: TokenService) { + super(); + } + async authenticateWithBiometrics(): Promise { return await ipc.keyManagement.biometric.authenticateWithBiometrics(); } @@ -31,6 +37,10 @@ export class RendererBiometricsService extends DesktopBiometricsService { } async getBiometricsStatusForUser(id: UserId): Promise { + if ((await firstValueFrom(this.tokenService.hasAccessToken$(id))) === false) { + return BiometricsStatus.NotEnabledInConnectedDesktopApp; + } + return await ipc.keyManagement.biometric.getBiometricsStatusForUser(id); } diff --git a/apps/desktop/src/key-management/electron-key.service.spec.ts b/apps/desktop/src/key-management/electron-key.service.spec.ts index cc1d68ed050..c5e010b1766 100644 --- a/apps/desktop/src/key-management/electron-key.service.spec.ts +++ b/apps/desktop/src/key-management/electron-key.service.spec.ts @@ -13,11 +13,13 @@ import { UserKey } from "@bitwarden/common/types/key"; import { BiometricStateService, KdfConfigService } from "@bitwarden/key-management"; import { - makeSymmetricCryptoKey, FakeAccountService, - mockAccountServiceWith, FakeStateProvider, + makeSymmetricCryptoKey, + mockAccountServiceWith, } from "../../../../libs/common/spec"; +// eslint-disable-next-line no-restricted-imports +import { VAULT_TIMEOUT } from "../../../../libs/common/src/key-management/vault-timeout"; import { DesktopBiometricsService } from "./biometrics/desktop.biometrics.service"; import { ElectronKeyService } from "./electron-key.service"; @@ -40,11 +42,13 @@ describe("ElectronKeyService", () => { let accountService: FakeAccountService; let masterPasswordService: FakeMasterPasswordService; - beforeEach(() => { + beforeEach(async () => { accountService = mockAccountServiceWith(mockUserId); masterPasswordService = new FakeMasterPasswordService(); stateProvider = new FakeStateProvider(accountService); + await stateProvider.setUserState(VAULT_TIMEOUT, 10, mockUserId); + keyService = new ElectronKeyService( masterPasswordService, keyGenerationService, @@ -79,38 +83,17 @@ describe("ElectronKeyService", () => { expect(biometricStateService.getBiometricUnlockEnabled).toHaveBeenCalledWith(mockUserId); }); - describe("biometric unlock enabled", () => { - beforeEach(() => { - biometricStateService.getBiometricUnlockEnabled.mockResolvedValue(true); - }); + it("sets biometric key when biometric unlock enabled", async () => { + biometricStateService.getBiometricUnlockEnabled.mockResolvedValue(true); - it("sets null biometric client key half and biometric unlock key when require password on start disabled", async () => { - biometricStateService.getRequirePasswordOnStart.mockResolvedValue(false); + await keyService.setUserKey(userKey, mockUserId); - await keyService.setUserKey(userKey, mockUserId); - - expect(biometricService.setBiometricProtectedUnlockKeyForUser).toHaveBeenCalledWith( - mockUserId, - userKey, - ); - expect(biometricStateService.setEncryptedClientKeyHalf).not.toHaveBeenCalled(); - expect(biometricStateService.getBiometricUnlockEnabled).toHaveBeenCalledWith(mockUserId); - }); - - describe("require password on start enabled", () => { - beforeEach(() => { - biometricStateService.getRequirePasswordOnStart.mockResolvedValue(true); - }); - - it("sets biometric key", async () => { - await keyService.setUserKey(userKey, mockUserId); - - expect(biometricService.setBiometricProtectedUnlockKeyForUser).toHaveBeenCalledWith( - mockUserId, - userKey, - ); - }); - }); + expect(biometricService.setBiometricProtectedUnlockKeyForUser).toHaveBeenCalledWith( + mockUserId, + userKey, + ); + expect(biometricStateService.setEncryptedClientKeyHalf).not.toHaveBeenCalled(); + expect(biometricStateService.getBiometricUnlockEnabled).toHaveBeenCalledWith(mockUserId); }); }); }); diff --git a/apps/desktop/src/key-management/key-connector/remove-password.component.html b/apps/desktop/src/key-management/key-connector/remove-password.component.html deleted file mode 100644 index 5276e00c531..00000000000 --- a/apps/desktop/src/key-management/key-connector/remove-password.component.html +++ /dev/null @@ -1,20 +0,0 @@ -
-
-

{{ "removeMasterPassword" | i18n }}

-

{{ "removeMasterPasswordForOrganizationUserKeyConnector" | i18n }}

-

{{ "organizationName" | i18n }}:

-

{{ organization.name }}

-

{{ "keyConnectorDomain" | i18n }}:

-

{{ organization.keyConnectorUrl }}

-
- - -
-
-
diff --git a/apps/desktop/src/key-management/key-connector/remove-password.component.ts b/apps/desktop/src/key-management/key-connector/remove-password.component.ts deleted file mode 100644 index d9fea9409f8..00000000000 --- a/apps/desktop/src/key-management/key-connector/remove-password.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from "@angular/core"; - -import { RemovePasswordComponent as BaseRemovePasswordComponent } from "@bitwarden/key-management-ui"; - -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -@Component({ - selector: "app-remove-password", - templateUrl: "remove-password.component.html", - standalone: false, -}) -export class RemovePasswordComponent extends BaseRemovePasswordComponent {} diff --git a/apps/desktop/src/key-management/session-timeout/services/desktop-session-timeout-settings-component.service.ts b/apps/desktop/src/key-management/session-timeout/services/desktop-session-timeout-settings-component.service.ts deleted file mode 100644 index 91c8126cdd7..00000000000 --- a/apps/desktop/src/key-management/session-timeout/services/desktop-session-timeout-settings-component.service.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { defer, from, map, Observable } from "rxjs"; - -import { - VaultTimeout, - VaultTimeoutOption, - VaultTimeoutStringType, -} from "@bitwarden/common/key-management/vault-timeout"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { SessionTimeoutSettingsComponentService } from "@bitwarden/key-management-ui"; - -export class DesktopSessionTimeoutSettingsComponentService - implements SessionTimeoutSettingsComponentService -{ - availableTimeoutOptions$: Observable = defer(() => - from(ipc.platform.powermonitor.isLockMonitorAvailable()).pipe( - map((isLockMonitorAvailable) => { - const options: VaultTimeoutOption[] = [ - { name: this.i18nService.t("oneMinute"), value: 1 }, - { name: this.i18nService.t("fiveMinutes"), value: 5 }, - { name: this.i18nService.t("fifteenMinutes"), value: 15 }, - { name: this.i18nService.t("thirtyMinutes"), value: 30 }, - { name: this.i18nService.t("oneHour"), value: 60 }, - { name: this.i18nService.t("fourHours"), value: 240 }, - { name: this.i18nService.t("onIdle"), value: VaultTimeoutStringType.OnIdle }, - { name: this.i18nService.t("onSleep"), value: VaultTimeoutStringType.OnSleep }, - ]; - - if (isLockMonitorAvailable) { - options.push({ - name: this.i18nService.t("onLocked"), - value: VaultTimeoutStringType.OnLocked, - }); - } - - options.push( - { name: this.i18nService.t("onRestart"), value: VaultTimeoutStringType.OnRestart }, - { name: this.i18nService.t("never"), value: VaultTimeoutStringType.Never }, - ); - - return options; - }), - ), - ); - - constructor(private readonly i18nService: I18nService) {} - - onTimeoutSave(_: VaultTimeout): void {} -} diff --git a/apps/desktop/src/key-management/session-timeout/services/desktop-session-timeout-type.service.spec.ts b/apps/desktop/src/key-management/session-timeout/services/desktop-session-timeout-type.service.spec.ts new file mode 100644 index 00000000000..d3ece8842b2 --- /dev/null +++ b/apps/desktop/src/key-management/session-timeout/services/desktop-session-timeout-type.service.spec.ts @@ -0,0 +1,125 @@ +import { + VaultTimeoutNumberType, + VaultTimeoutStringType, +} from "@bitwarden/common/key-management/vault-timeout"; + +import { DesktopSessionTimeoutTypeService } from "./desktop-session-timeout-type.service"; + +describe("DesktopSessionTimeoutTypeService", () => { + let service: DesktopSessionTimeoutTypeService; + let mockIsLockMonitorAvailable: jest.Mock; + + beforeEach(() => { + mockIsLockMonitorAvailable = jest.fn(); + + (global as any).ipc = { + platform: { + powermonitor: { + isLockMonitorAvailable: mockIsLockMonitorAvailable, + }, + }, + }; + + service = new DesktopSessionTimeoutTypeService(); + }); + + describe("isAvailable", () => { + it("should return false for Immediately", async () => { + const result = await service.isAvailable(VaultTimeoutNumberType.Immediately); + + expect(result).toBe(false); + }); + + it.each([ + VaultTimeoutStringType.OnIdle, + VaultTimeoutStringType.OnSleep, + VaultTimeoutStringType.OnRestart, + VaultTimeoutStringType.Never, + VaultTimeoutStringType.Custom, + ])("should return true for always available type: %s", async (timeoutType) => { + const result = await service.isAvailable(timeoutType); + + expect(result).toBe(true); + }); + + it.each([VaultTimeoutNumberType.OnMinute, VaultTimeoutNumberType.EightHours])( + "should return true for numeric timeout type: %s", + async (timeoutType) => { + const result = await service.isAvailable(timeoutType); + + expect(result).toBe(true); + }, + ); + + describe("OnLocked availability", () => { + it("should return true when lock monitor is available", async () => { + mockIsLockMonitorAvailable.mockResolvedValue(true); + + const result = await service.isAvailable(VaultTimeoutStringType.OnLocked); + + expect(result).toBe(true); + expect(mockIsLockMonitorAvailable).toHaveBeenCalled(); + }); + + it("should return false when lock monitor is not available", async () => { + mockIsLockMonitorAvailable.mockResolvedValue(false); + + const result = await service.isAvailable(VaultTimeoutStringType.OnLocked); + + expect(result).toBe(false); + expect(mockIsLockMonitorAvailable).toHaveBeenCalled(); + }); + }); + }); + + describe("getOrPromoteToAvailable", () => { + it.each([ + VaultTimeoutNumberType.OnMinute, + VaultTimeoutStringType.OnIdle, + VaultTimeoutStringType.OnSleep, + VaultTimeoutStringType.OnRestart, + VaultTimeoutStringType.OnLocked, + VaultTimeoutStringType.Never, + VaultTimeoutStringType.Custom, + ])("should return the original type when it is available: %s", async (timeoutType) => { + jest.spyOn(service, "isAvailable").mockResolvedValue(true); + + const result = await service.getOrPromoteToAvailable(timeoutType); + + expect(result).toBe(timeoutType); + expect(service.isAvailable).toHaveBeenCalledWith(timeoutType); + }); + + it("should return OnMinute when Immediately is not available", async () => { + jest.spyOn(service, "isAvailable").mockResolvedValue(false); + + const result = await service.getOrPromoteToAvailable(VaultTimeoutNumberType.Immediately); + + expect(result).toBe(VaultTimeoutNumberType.OnMinute); + expect(service.isAvailable).toHaveBeenCalledWith(VaultTimeoutNumberType.Immediately); + }); + + it("should return OnSleep when OnLocked is not available", async () => { + jest.spyOn(service, "isAvailable").mockResolvedValue(false); + + const result = await service.getOrPromoteToAvailable(VaultTimeoutStringType.OnLocked); + + expect(result).toBe(VaultTimeoutStringType.OnSleep); + expect(service.isAvailable).toHaveBeenCalledWith(VaultTimeoutStringType.OnLocked); + }); + + it.each([ + VaultTimeoutStringType.OnIdle, + VaultTimeoutStringType.OnSleep, + VaultTimeoutNumberType.OnMinute, + 5, + ])("should return OnRestart when type is not available: %s", async (timeoutType) => { + jest.spyOn(service, "isAvailable").mockResolvedValue(false); + + const result = await service.getOrPromoteToAvailable(timeoutType); + + expect(result).toBe(VaultTimeoutStringType.OnRestart); + expect(service.isAvailable).toHaveBeenCalledWith(timeoutType); + }); + }); +}); diff --git a/apps/desktop/src/key-management/session-timeout/services/desktop-session-timeout-type.service.ts b/apps/desktop/src/key-management/session-timeout/services/desktop-session-timeout-type.service.ts new file mode 100644 index 00000000000..1f09e83b0f1 --- /dev/null +++ b/apps/desktop/src/key-management/session-timeout/services/desktop-session-timeout-type.service.ts @@ -0,0 +1,46 @@ +import { SessionTimeoutTypeService } from "@bitwarden/common/key-management/session-timeout"; +import { + isVaultTimeoutTypeNumeric, + VaultTimeout, + VaultTimeoutNumberType, + VaultTimeoutStringType, +} from "@bitwarden/common/key-management/vault-timeout"; + +export class DesktopSessionTimeoutTypeService implements SessionTimeoutTypeService { + async isAvailable(type: VaultTimeout): Promise { + switch (type) { + case VaultTimeoutNumberType.Immediately: + return false; + case VaultTimeoutStringType.OnIdle: + case VaultTimeoutStringType.OnSleep: + case VaultTimeoutStringType.OnRestart: + case VaultTimeoutStringType.Never: + case VaultTimeoutStringType.Custom: + return true; + case VaultTimeoutStringType.OnLocked: + return await ipc.platform.powermonitor.isLockMonitorAvailable(); + default: + if (isVaultTimeoutTypeNumeric(type)) { + return true; + } + break; + } + + return false; + } + + async getOrPromoteToAvailable(type: VaultTimeout): Promise { + const available = await this.isAvailable(type); + if (!available) { + switch (type) { + case VaultTimeoutNumberType.Immediately: + return VaultTimeoutNumberType.OnMinute; + case VaultTimeoutStringType.OnLocked: + return VaultTimeoutStringType.OnSleep; + default: + return VaultTimeoutStringType.OnRestart; + } + } + return type; + } +} diff --git a/apps/desktop/src/locales/af/messages.json b/apps/desktop/src/locales/af/messages.json index 1c6a2bc49c9..720e0dde7c2 100644 --- a/apps/desktop/src/locales/af/messages.json +++ b/apps/desktop/src/locales/af/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "'n Onverwagte fout het voorgekom." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Iteminligting" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Leer meer" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Funksie Onbeskikbaar" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Volg Ons" }, - "syncVault": { - "message": "Sichroniseer Kluis" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Verander Hoofwagwoord" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GG geënkripteerde berging vir lêeraanhegsels." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Stuur Kluis Uit" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Lêerformaat" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Alle Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Hoofwagwoord is verwyder" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Is u seker u wil die “Nooit”-opsie gebruik? Deur u vergrendelopsies op “Nooit” te stel word u kluis se enkripsie op u toestel bewaar. Indien u hierdie opsie gebruik moet u verseker dat u toestel behoorlik beskerm is." }, "vault": { - "message": "Kluis" + "message": "Kluis", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Meld aan met meesterwagwoord" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Invoer data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Invoer fout" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json index ca404f4e179..d6c42f5883a 100644 --- a/apps/desktop/src/locales/ar/messages.json +++ b/apps/desktop/src/locales/ar/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "حدث خطأ غير متوقع." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "معلومات العنصر" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "اعرف المزيد" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "الميزة غير متوفرة" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "تابعنا" }, - "syncVault": { - "message": "مزامنة الخزانة" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "تغيير كلمة المرور الرئيسية" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 جيغابايت وحدة تخزين مشفرة لمرفقات الملفات." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "خيارات تسجيل الدخول بخطوتين المملوكة مثل YubiKey و Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "تصدير من" }, - "exportVault": { - "message": "تصدير الخزانة" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "صيغة الملف" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "كل الإرسالات", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "تمت إزالة كلمة المرور الرئيسية." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "هل أنت متأكد من أنك تريد استخدام خيار \"مطلقا\"؟ إعداد خيارات القفل إلى \"مطلقا\" يخزن مفتاح تشفير المستودع الخاص بك على جهازك. إذا كنت تستخدم هذا الخيار، يجب أن تتأكد من الحفاظ على حماية جهازك بشكل صحيح." }, "vault": { - "message": "الخزانة" + "message": "الخزانة", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "تسجيل الدخول باستخدام كلمة المرور الرئيسية" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "الاسم البديل للنطاق" }, - "importData": { - "message": "استيراد البيانات", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "خطأ في الاستيراد" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "تم حفظ الملف على الجهاز. إدارة من تنزيلات جهازك." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index 55c2bdcd677..ba6cad30e4f 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Qoşma əlavə et" }, + "itemsTransferred": { + "message": "Elementlər köçürüldü" + }, + "fixEncryption": { + "message": "Şifrələməni düzəlt" + }, + "fixEncryptionTooltip": { + "message": "Bu fayl, köhnə bir şifrələmə üsulunu istifadə edir." + }, + "attachmentUpdated": { + "message": "Qoşma güncəllənib" + }, "maxFileSizeSansPunctuation": { "message": "Maksimal fayl həcmi 500 MB-dır" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Gözlənilməz bir səhv baş verdi." }, + "unexpectedErrorShort": { + "message": "Gözlənilməz xəta" + }, + "closeThisBitwardenWindow": { + "message": "Bu Bitwarden pəncərəsini bağlayıb yenidən sınayın." + }, "itemInformation": { "message": "Element məlumatları" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Daha ətraflı" }, + "migrationsFailed": { + "message": "Şifrələmə ayarlarını güncəlləyərkən bir xəta baş verdi." + }, + "updateEncryptionSettingsTitle": { + "message": "Şifrələmə ayarlarınızı güncəlləyin" + }, + "updateEncryptionSettingsDesc": { + "message": "Tövsiyə edilən yeni şifrələmə ayarları, hesabınızın təhlükəsizliyini artıracaq. İndi güncəlləmək üçün ana parolunuzu daxil edin." + }, + "confirmIdentityToContinue": { + "message": "Davam etmək üçün kimliyinizi təsdiqləyin" + }, + "enterYourMasterPassword": { + "message": "Ana parolunuzu daxil edin" + }, + "updateSettings": { + "message": "Ayarları güncəllə" + }, "featureUnavailable": { "message": "Özəllik əlçatmazdır" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Bizi izləyin" }, - "syncVault": { - "message": "Seyfi sinxronlaşdır" + "syncNow": { + "message": "İndi sinxr." }, "changeMasterPass": { "message": "Ana parolu dəyişdir" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "Fayl qoşmaları üçün 1 GB şifrələnmiş saxlama sahəsi." }, + "premiumSignUpStorageV2": { + "message": "Fayl qoşmaları üçün $SIZE$ şifrələnmiş anbar sahəsi.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "YubiKey və Duo kimi mülkiyyətçi iki addımlı giriş seçimləri." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Buradan xaricə köçür" }, - "exportVault": { - "message": "Seyfi xaricə köçür" + "exportNoun": { + "message": "Xaricə köçürmə", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Xaricə köçür", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Daxilə köçürmə", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Daxilə köçür", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Fayl formatı" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Əlaqə məlumatları" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Bütün \"Send\"lər", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Ana parol silindi." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Aşağıdakı təşkilatların üzvləri üçün artıq ana parol tələb olunmur. Lütfən aşağıdakı domeni təşkilatınızın inzibatçısı ilə təsdiqləyin." - }, "organizationName": { "message": "Təşkilat adı" }, @@ -2991,7 +3050,8 @@ "message": "\"Heç vaxt\"i seçmək istədiyinizə əminsiniz? Kilid seçimini \"Heç vaxt\" olaraq ayarlasanız, seyfinizin şifrələmə açarı cihazınızda saxlanılacaq. Bu seçimi istifadə etsəniz, cihazınızı daha yaxşı mühafizə etdiyinizə əmin olmalısınız." }, "vault": { - "message": "Seyf" + "message": "Seyf", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Ana parolla giriş et" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Domen ləqəbi" }, - "importData": { - "message": "Veriləri daxilə köçür", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Daxilə köçürmə xətası" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Fayl cihazda saxlanıldı. Endirilənləri cihazınızdan idarə edin." }, + "importantNotice": { + "message": "Vacib bildiriş" + }, + "setupTwoStepLogin": { + "message": "İki addımlı girişi qur" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden, 2025-ci ilin Fevral ayından etibarən yeni cihazlardan gələn girişləri doğrulamaq üçün hesabınızın e-poçtuna bir kod göndərəcək." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Hesabınızı qorumaq üçün alternativ bir yol kimi iki addımlı girişi qura və ya e-poçtunuzu erişə biləcəyiniz bir e-poçtla dəyişdirə bilərsiniz." + }, + "remindMeLater": { + "message": "Daha sonra xatırlat" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "$EMAIL$ e-poçtunuza güvənli şəkildə erişə bilirsiniz?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Xeyr, bilmirəm" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Bəli, e-poçtuma güvənli şəkildə erişə bilirəm" + }, + "turnOnTwoStepLogin": { + "message": "İki addımlı girişi işə sal" + }, + "changeAcctEmail": { + "message": "Hesabın e-poçtunu dəyişdir" + }, + "passkeyLogin": { + "message": "Keçid açarı ilə giriş edilsin?" + }, + "savePasskeyQuestion": { + "message": "Keçid açarı saxlanılsın?" + }, + "saveNewPasskey": { + "message": "Yeni giriş kimi saxla" + }, + "savePasskeyNewLogin": { + "message": "Keçid açarını yeni bir giriş olaraq saxla" + }, + "noMatchingLoginsForSite": { + "message": "Bu sayt üçün uyuşan giriş məlumatı yoxdur" + }, + "overwritePasskey": { + "message": "Keçid açarının üzərinə yazılsın?" + }, + "unableToSavePasskey": { + "message": "Keçid açarı saxlanıla bilmir" + }, + "alreadyContainsPasskey": { + "message": "Bu elementdə artıq bir keçid açarı var. Hazırkı keçid açarının üzərinə yazmaq istədiyinizə əminsiniz?" + }, + "passkeyAlreadyExists": { + "message": "Bu tətbiq üçün bir keçid açarı artıq mövcuddur." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Bu tətbiq, təkrarları dəstəkləmir." + }, + "closeThisWindow": { + "message": "Bu pəncərəni bağla" + }, "allowScreenshots": { "message": "Ekranı çəkməyə icazə ver" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "Və daha çoxu!" }, - "planDescPremium": { - "message": "Tam onlayn təhlükəsizlik" + "advancedOnlineSecurity": { + "message": "Qabaqcıl onlayn təhlükəsizlik" }, "upgradeToPremium": { "message": "\"Premium\"a yüksəlt" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Təşkilatınız, artıq Bitwarden-ə giriş etmək üçün ana parol istifadə etmir. Davam etmək üçün təşkilatı və domeni doğrulayın." + }, + "continueWithLogIn": { + "message": "Giriş etməyə davam" + }, + "doNotContinue": { + "message": "Davam etmə" + }, + "domain": { + "message": "Domen" + }, + "keyConnectorDomainTooltip": { + "message": "Bu domen, hesabınızın şifrələmə açarlarını saxlayacaq, ona görə də, bu domenə güvəndiyinizə əmin olun. Əmin deyilsinizsə, adminizlə əlaqə saxlayın." + }, + "verifyYourOrganization": { + "message": "Giriş etmək üçün təşkilatınızı doğrulayın" + }, + "organizationVerified": { + "message": "Təşkilat doğrulandı" + }, + "domainVerified": { + "message": "Domen doğrulandı" + }, + "leaveOrganizationContent": { + "message": "Təşkilatınızı doğrulamasanız, təşkilata erişiminiz ləğv ediləcək." + }, + "leaveNow": { + "message": "İndi tərk et" + }, + "verifyYourDomainToLogin": { + "message": "Giriş etmək üçün domeninizi doğrulayın" + }, + "verifyYourDomainDescription": { + "message": "Giriş prosesini davam etdirmək üçün bu domeni doğrulayın." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Giriş prosesini davam etdirmək üçün bu təşkilatı və domeni doğrulayın." + }, "sessionTimeoutSettingsAction": { "message": "Vaxt bitmə əməliyyatı" }, "sessionTimeoutHeader": { "message": "Sessiya vaxt bitməsi" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Bu ayar, təşkilatınız tərəfindən idarə olunur." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Təşkilatınız, maksimum seyf bitmə vaxtını $HOURS$ saat $MINUTES$ dəqiqə olaraq ayarladı.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Təşkilatınız, seansın ilkin bitmə vaxtını Sistem kilidi açılanda olaraq təyin etdi." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Təşkilatınız, seansın ilkin bitmə vaxtını Yenidən başladılanda olaraq təyin etdi." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maksimum bitmə vaxtı $HOURS$ saat $MINUTES$ dəqiqə dəyərini aşa bilməz", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Yenidən başladılanda" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Vaxt bitmə əməliyyatınızı dəyişdirmək üçün bir kilid açma üsulu qurun" + }, + "upgrade": { + "message": "Yüksəlt" + }, + "leaveConfirmationDialogTitle": { + "message": "Tərk etmək istədiyinizə əminsiniz?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Rədd cavabı versəniz, fərdi elementləriniz hesabınızda qalacaq, paylaşılan elementlərə və təşkilat özəlliklərinə erişimi itirəcəksiniz." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Erişimi təkrar qazanmaq üçün admininizlə əlaqə saxlayın." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Tərk et: $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Seyfimi necə idarə edim?" + }, + "transferItemsToOrganizationTitle": { + "message": "Elementləri bura köçür: $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$, təhlükəsizlik və riayətlilik üçün bütün elementlərin təşkilata aid olmasını tələb edir. Elementlərinizin sahibliyini transfer etmək üçün qəbul edin.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Transferi qəbul et" + }, + "declineAndLeave": { + "message": "Rədd et və tərk et" + }, + "whyAmISeeingThis": { + "message": "Bunu niyə görürəm?" } } diff --git a/apps/desktop/src/locales/be/messages.json b/apps/desktop/src/locales/be/messages.json index b2e4db47b32..50f7bdc668e 100644 --- a/apps/desktop/src/locales/be/messages.json +++ b/apps/desktop/src/locales/be/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Адбылася нечаканая памылка." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Звесткі аб элеменце" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Даведацца больш" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Функцыя недаступна" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Сачыце за намі" }, - "syncVault": { - "message": "Сінхранізаваць сховішча" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Змяніць асноўны пароль" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 ГБ зашыфраванага сховішча для далучаных файлаў." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Прапрыетарныя варыянты двухэтапнага ўваходу, такія як YubiKey, FIDO U2F і Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Экспартаваць сховішча" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Фармат файла" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Усе Send'ы", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Асноўны пароль выдалены." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Вы сапраўды хочаце адключыць блакіроўку сховішча? Прызначыўшы параметр блакіравання \"Ніколі\", ключ шыфравання будзе захоўвацца на вашай прыладзе. Калі вы выкарыстоўваеце гэты параметр, вы павінны быць упэўнены ў тым, што ваша прылада надзейна абаронена." }, "vault": { - "message": "Сховішча" + "message": "Сховішча", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Увайсці з асноўным паролем" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json index ad03c2cc023..539cfb344aa 100644 --- a/apps/desktop/src/locales/bg/messages.json +++ b/apps/desktop/src/locales/bg/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Добавяне на прикачен файл" }, + "itemsTransferred": { + "message": "Елементите са прехвърлени" + }, + "fixEncryption": { + "message": "Поправяне на шифроването" + }, + "fixEncryptionTooltip": { + "message": "Този файл използва остарял метод на шифроване." + }, + "attachmentUpdated": { + "message": "Прикаченият файл е актуализиран" + }, "maxFileSizeSansPunctuation": { "message": "Максималният размер на файла е 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Неочаквана грешка." }, + "unexpectedErrorShort": { + "message": "Неочаквана грешка" + }, + "closeThisBitwardenWindow": { + "message": "Затворете прозореца на Битуорден и опитайте отново." + }, "itemInformation": { "message": "Сведения за елемента" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Научете повече" }, + "migrationsFailed": { + "message": "Възникна грешка при обновяването на настройките за шифроване." + }, + "updateEncryptionSettingsTitle": { + "message": "Обновете настройките си за шифроване" + }, + "updateEncryptionSettingsDesc": { + "message": "Новите препоръчани настройки за шифроване ще подобрят сигурността на акаунта Ви. Въведете главната си парола, за да ги обновите сега." + }, + "confirmIdentityToContinue": { + "message": "Потвърдете самоличността си, за да продължите" + }, + "enterYourMasterPassword": { + "message": "Въведете главната си парола" + }, + "updateSettings": { + "message": "Обновяване на настройките" + }, "featureUnavailable": { "message": "Функцията е недостъпна" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Следвайте ни" }, - "syncVault": { - "message": "Синхронизиране" + "syncNow": { + "message": "Синхронизиране сега" }, "changeMasterPass": { "message": "Промяна на главната парола" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 ГБ пространство за файлове, които се шифроват." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ пространство за файлове, които се шифрират.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Частно двустепенно удостоверяване чрез YubiKey и Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Изнасяне от" }, - "exportVault": { - "message": "Изнасяне на трезора" + "exportNoun": { + "message": "Изнасяне", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Изнасяне", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Внасяне", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Внасяне", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Формат на файла" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Информация за контакт" }, + "send": { + "message": "Изпращане", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Всички изпращания", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Главната парола е премахната." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "За членовете на следната организация вече не се изисква главна парола. Потвърдете домейна по-долу с администратора на организацията си." - }, "organizationName": { "message": "Име на организацията" }, @@ -2991,7 +3050,8 @@ "message": "Уверени ли сте, че искате да зададете стойност „Никога“? Това води до съхранение на шифриращия ключ за трезора във устройството ви. Ако използвате тази възможност, е много важно да имате надлежна защита на устройството си." }, "vault": { - "message": "Трезор" + "message": "Трезор", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Вписване с главната парола" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Псевдонимен домейн" }, - "importData": { - "message": "Внасяне на данни", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Грешка при внасянето" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Файлът е запазен на устройството. Можете да го намерите в мястото за сваляния на устройството." }, + "importantNotice": { + "message": "Важно съобщение" + }, + "setupTwoStepLogin": { + "message": "Настройте двустепенно удостоверяване" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Битуорден ще изпрати код до е-пощата Ви, за потвърждаване на вписването от нови устройства. Това ще започне от февруари 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Можете да настроите двустепенно удостоверяване, като различен метод на защита, или ако е необходимо да промените е-пощата си с такава, до която имате достъп." + }, + "remindMeLater": { + "message": "Напомнете ми по-късно" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Имате ли сигурен достъп до е-пощата си – $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Не, нямам" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Да, имам достъп до е-пощата си" + }, + "turnOnTwoStepLogin": { + "message": "Включване на двустепенното удостоверяване" + }, + "changeAcctEmail": { + "message": "Промяна на е-пощата" + }, + "passkeyLogin": { + "message": "Вписване със секретен ключ?" + }, + "savePasskeyQuestion": { + "message": "Да се запази на секретният ключ?" + }, + "saveNewPasskey": { + "message": "Запазване като нов елемент за вписване" + }, + "savePasskeyNewLogin": { + "message": "Запазване на секретния ключ като нов елемент за вписване" + }, + "noMatchingLoginsForSite": { + "message": "Няма записи за вписване отговарящи на този уеб сайт" + }, + "overwritePasskey": { + "message": "Да се замени ли секретният ключ?" + }, + "unableToSavePasskey": { + "message": "Секретният ключ не може да бъде запазен" + }, + "alreadyContainsPasskey": { + "message": "Този елемент вече съдържа секретен ключ. Наистина ли искате да замените текущия секретен ключ?" + }, + "passkeyAlreadyExists": { + "message": "За това приложение вече съществува секретен ключ." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Това приложение не поддържа дубликати." + }, + "closeThisWindow": { + "message": "Затворете този прозорец" + }, "allowScreenshots": { "message": "Позволяване на заснемането на екрана" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "И още!" }, - "planDescPremium": { - "message": "Пълна сигурност в Интернет" + "advancedOnlineSecurity": { + "message": "Разширена сигурност в Интернет" }, "upgradeToPremium": { "message": "Надградете до Платения план" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Вашата организация вече не използва главни пароли за вписване в Битуорден. За да продължите, потвърдете организацията и домейна." + }, + "continueWithLogIn": { + "message": "Продължаване с вписването" + }, + "doNotContinue": { + "message": "Не продължавам" + }, + "domain": { + "message": "Домейн" + }, + "keyConnectorDomainTooltip": { + "message": "Този домейн ще съхранява ключовете за шифроване на акаунта Ви, така че се уверете, че му имате доверие. Ако имате съмнения, свържете се с администратора си." + }, + "verifyYourOrganization": { + "message": "Потвърдете организацията си, за да се впишете" + }, + "organizationVerified": { + "message": "Организацията е потвърдена" + }, + "domainVerified": { + "message": "Домейнът е потвърден" + }, + "leaveOrganizationContent": { + "message": "Ако не потвърдите организацията, достъпът Ви до нея ще бъде преустановен." + }, + "leaveNow": { + "message": "Напускане сега" + }, + "verifyYourDomainToLogin": { + "message": "Потвърдете домейна си, за да се впишете" + }, + "verifyYourDomainDescription": { + "message": "За да продължите с вписването, потвърдете този домейн." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "За да продължите с вписването, потвърдете организацията и домейна." + }, "sessionTimeoutSettingsAction": { "message": "Действие при изтичането на времето за достъп" }, "sessionTimeoutHeader": { "message": "Изтичане на времето за сесията" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Тази настройка се управлява от организацията Ви." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Организацията Ви е настроила максималното разрешено време за достъп на [%1$i] час(а) и [%2$i] минути.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Организацията Ви е настроила стандартното разрешено време за достъп да бъде до заключване на системата." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Организацията Ви е настроила стандартното разрешено време за достъп да бъде до рестартиране." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Максималното време на достъп не може да превишава $HOURS$ час(а) и $MINUTES$ минути", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "При рестартиране" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Задайте метод за отключване, за да може да промените действието при изтичане на времето за достъп" + }, + "upgrade": { + "message": "Надграждане" + }, + "leaveConfirmationDialogTitle": { + "message": "Наистина ли искате да напуснете?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Ако откажете, Вашите собствени елементи ще останат в акаунта Ви, но ще загубите достъп до споделените елементи и функционалностите на организацията." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Свържете се с администратор, за да получите достъп отново." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Напускане на $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Как да управлявам трезора си?" + }, + "transferItemsToOrganizationTitle": { + "message": "Прехвърляне на елементи към $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ изисква всички елементи да станат притежание на организацията, за по-добра сигурност и съвместимост. Изберете, че приемате, за да прехвърлите собствеността на елементите си към организацията.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Приемане на прехвърлянето" + }, + "declineAndLeave": { + "message": "Отказване и напускане" + }, + "whyAmISeeingThis": { + "message": "Защо виждам това?" } } diff --git a/apps/desktop/src/locales/bn/messages.json b/apps/desktop/src/locales/bn/messages.json index d6c61c1ab51..bde81f83b42 100644 --- a/apps/desktop/src/locales/bn/messages.json +++ b/apps/desktop/src/locales/bn/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "একটি অপ্রত্যাশিত ত্রুটি ঘটেছে।" }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "বস্তু তথ্য" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "আরও জানুন" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "বৈশিষ্ট্য অনুপলব্ধ" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "ভল্ট সিঙ্ক করুন" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "মূল পাসওয়ার্ড পরিবর্তন" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "ফাইল সংযুক্তির জন্য ১ জিবি এনক্রিপ্টেড স্থান।" }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "ভল্ট রফতানি" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "ফাইলের ধরণ" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/bs/messages.json b/apps/desktop/src/locales/bs/messages.json index 569f1072c4b..3ed7dee9e92 100644 --- a/apps/desktop/src/locales/bs/messages.json +++ b/apps/desktop/src/locales/bs/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Neočekivana greška se dogodila." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Informacije o stavki" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Saznajte više" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Funkcija nije dostupna" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Pratite nas" }, - "syncVault": { - "message": "Sinhronizujte trezor sada" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Promijenite glavnu lozinku" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB šifriranog prostora za pohranu podataka." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Izvezi trezor" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format datoteke" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Svi Send-ovi", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Uvoz podataka", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Greška pri uvozu" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index de468f1e8b3..57041a87a31 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Afig adjunt" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "La mida màxima del fitxer és de 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "S'ha produït un error inesperat." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Informació de l'element" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Més informació" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Característica no disponible" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Seguiu-nos" }, - "syncVault": { - "message": "Sincronitza la caixa forta" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Canvia la contrasenya mestra" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB d'emmagatzematge xifrat per als fitxers adjunts." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Opcions propietàries de doble factor com ara YubiKey i Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Exporta des de" }, - "exportVault": { - "message": "Exporta caixa forta" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format de fitxer" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Informació de contacte" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Tots els Send", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "S'ha suprimit la contrasenya mestra." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Ja no cal contrasenya mestra per als membres de la següent organització. Confirmeu el domini següent amb l'administrador de l'organització." - }, "organizationName": { "message": "Nom de l'organització" }, @@ -2991,7 +3050,8 @@ "message": "Esteu segur que voleu utilitzar l'opció \"Mai\"? En configurar les opcions de bloqueig a \"Mai\" s'emmagatzema la clau de xifratge de la vostra caixa forta al vostre dispositiu. Si utilitzeu aquesta opció, heu d'assegurar-vos que conserveu el dispositiu degudament protegit." }, "vault": { - "message": "Caixa forta" + "message": "Caixa forta", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Inici de sessió amb contrasenya mestra" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Domini d'àlies" }, - "importData": { - "message": "Importa dades", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Error d'importació" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Permet capturar la pantalla" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json index c02dbabbc93..fe0c814f2a2 100644 --- a/apps/desktop/src/locales/cs/messages.json +++ b/apps/desktop/src/locales/cs/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Přidat přílohu" }, + "itemsTransferred": { + "message": "Převedené položky" + }, + "fixEncryption": { + "message": "Opravit šifrování" + }, + "fixEncryptionTooltip": { + "message": "Tento soubor používá zastaralou šifrovací metodu." + }, + "attachmentUpdated": { + "message": "Příloha byla aktualizována" + }, "maxFileSizeSansPunctuation": { "message": "Maximální velikost souboru je 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Vyskytla se neočekávaná chyba." }, + "unexpectedErrorShort": { + "message": "Neočekávaná chyba" + }, + "closeThisBitwardenWindow": { + "message": "Zavřete toto okno Bitwardenu a zkuste to znovu." + }, "itemInformation": { "message": "Informace o položce" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Dozvědět se více" }, + "migrationsFailed": { + "message": "Došlo k chybě při aktualizaci nastavení šifrování." + }, + "updateEncryptionSettingsTitle": { + "message": "Aktualizovat nastavení šifrování" + }, + "updateEncryptionSettingsDesc": { + "message": "Nové doporučené nastavení šifrování zlepší bezpečnost Vašeho účtu. Pokud chcete aktualizovat nyní, zadejte hlavní heslo." + }, + "confirmIdentityToContinue": { + "message": "Pro pokračování potvrďte svou identitu" + }, + "enterYourMasterPassword": { + "message": "Zadejte své hlavní heslo" + }, + "updateSettings": { + "message": "Aktualizovat nastavení" + }, "featureUnavailable": { "message": "Funkce není dostupná" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Sledujte nás" }, - "syncVault": { - "message": "Synchronizovat trezor" + "syncNow": { + "message": "Synchronizovat nyní" }, "changeMasterPass": { "message": "Změnit hlavní heslo" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB šifrovaného uložiště pro přílohy." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ šifrovaného úložiště pro přílohy.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Volby proprietálních dvoufázových přihlášení jako je YubiKey a Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Exportovat z" }, - "exportVault": { - "message": "Exportovat trezor" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Exportovat", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importovat", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formát souboru" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Všechny Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Hlavní heslo bylo odebráno" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Hlavní heslo již není vyžadováno pro členy následující organizace. Potvrďte níže uvedenou doménu u správce Vaší organizace." - }, "organizationName": { "message": "Název organizace" }, @@ -2991,7 +3050,8 @@ "message": "Opravdu chcete použít volbu \"Nikdy\"? Nastavením volby uzamčení na \"Nikdy\" bude šifrovací klíč k trezoru uložen přímo ve Vašem zařízení. Pokud tuto možnost použijete, měli byste Vaše zařízení řádně zabezpečit a chránit." }, "vault": { - "message": "Trezor" + "message": "Trezor", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Přihlásit se pomocí hlavního hesla" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Doména aliasu" }, - "importData": { - "message": "Importovat data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Chyba importu" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Soubor byl uložen. Můžete jej nalézt ve stažené složce v zařízení." }, + "importantNotice": { + "message": "Důležité upozornění" + }, + "setupTwoStepLogin": { + "message": "Nastavit dvoufázové přihlášení" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden odešle kód na e-mail Vašeho účtu pro ověření přihlášení z nových zařízení počínaje únorem 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Dvoufázové přihlášení můžete nastavit jako alternativní způsob ochrany Vašeho účtu nebo změnit svůj e-mail na ten, k němuž můžete přistupovat." + }, + "remindMeLater": { + "message": "Připomenout později" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Máte spolehlivý přístup ke svému e-mailu $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Ne, nemám" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Ano, ke svému e-mailu mám přístup" + }, + "turnOnTwoStepLogin": { + "message": "Zapnout dvoufázové přihlášení" + }, + "changeAcctEmail": { + "message": "Změnit e-mail účtu" + }, + "passkeyLogin": { + "message": "Přihlásit se pomocí přístupového klíče?" + }, + "savePasskeyQuestion": { + "message": "Uložit přístupový klíč?" + }, + "saveNewPasskey": { + "message": "Uložit jako nové přihlašovací údaje" + }, + "savePasskeyNewLogin": { + "message": "Uložit přístupový klíč jako nové přihlášení" + }, + "noMatchingLoginsForSite": { + "message": "Žádné odpovídající přihlašovací údaje pro tento web" + }, + "overwritePasskey": { + "message": "Přepsat přístupový klíč?" + }, + "unableToSavePasskey": { + "message": "Nelze uložit přístupový klíč" + }, + "alreadyContainsPasskey": { + "message": "Tato položka již obsahuje přístupový klíč. Jste si jisti, že chcete přepsat aktuální přístupový klíč?" + }, + "passkeyAlreadyExists": { + "message": "Přístupový klíč pro tuto aplikaci již existuje." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Tato aplikace nepodporuje duplikáty." + }, + "closeThisWindow": { + "message": "Zavřít toto okno" + }, "allowScreenshots": { "message": "Povolit záznam obrazovky" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "A ještě více!" }, - "planDescPremium": { - "message": "Dokončit online zabezpečení" + "advancedOnlineSecurity": { + "message": "Pokročilé zabezpečení online" }, "upgradeToPremium": { "message": "Aktualizovat na Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Vaše organizace již k přihlášení do Bitwardenu nepoužívá hlavní hesla. Chcete-li pokračovat, ověřte organizaci a doménu." + }, + "continueWithLogIn": { + "message": "Pokračovat s přihlášením" + }, + "doNotContinue": { + "message": "Nepokračovat" + }, + "domain": { + "message": "Doména" + }, + "keyConnectorDomainTooltip": { + "message": "Tato doména uloží šifrovací klíče Vašeho účtu, takže se ujistěte, že jí věříte. Pokud si nejste jisti, kontaktujte Vašeho správce." + }, + "verifyYourOrganization": { + "message": "Ověřte svou organizaci pro přihlášení" + }, + "organizationVerified": { + "message": "Organizace byla ověřena" + }, + "domainVerified": { + "message": "Doména byla ověřena" + }, + "leaveOrganizationContent": { + "message": "Pokud neověříte svou organizaci, Váš přístup k organizaci bude zrušen." + }, + "leaveNow": { + "message": "Opustit hned" + }, + "verifyYourDomainToLogin": { + "message": "Ověřte svou doménu pro přihlášení" + }, + "verifyYourDomainDescription": { + "message": "Chcete-li pokračovat v přihlášení, ověřte tuto doménu." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Chcete-li pokračovat v přihlášení, ověřte organizaci a doménu." + }, "sessionTimeoutSettingsAction": { "message": "Akce vypršení časového limitu" }, "sessionTimeoutHeader": { "message": "Časový limit relace" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Tato nastavení je spravováno Vaší organizací." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Vaše organizace nastavila maximální časový limit relace na $HOURS$ hodin a $MINUTES$ minut.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Vaše organizace nastavila výchozí časový limit relace na Při uzamknutí systému." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Vaše organizace nastavila výchozí časový limit relace na Při restartu." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximální časový limit nesmí překročit $HOURS$ hodin a $MINUTES$ minut", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Při restartu" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Nastavte metodu odemknutí, abyste změnili akci při vypršení časového limitu" + }, + "upgrade": { + "message": "Aktualizovat" + }, + "leaveConfirmationDialogTitle": { + "message": "Opravdu chcete odejít?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Odmítnutím zůstanou Vaše osobní položky ve Vašem účtu, ale ztratíte přístup ke sdíleným položkám a funkcím organizace." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Obraťte se na svého správce, abyste znovu získali přístup." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Opustit $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Jak mohu spravovat svůj trezor?" + }, + "transferItemsToOrganizationTitle": { + "message": "Přenést položky do $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ vyžaduje, aby byly všechny položky vlastněny organizací z důvodu bezpečnosti a shody. Klepnutím na tlačítko pro převod vlastnictví Vašich položek.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Přijmout převod" + }, + "declineAndLeave": { + "message": "Odmítnout a odejít" + }, + "whyAmISeeingThis": { + "message": "Proč se mi toto zobrazuje?" } } diff --git a/apps/desktop/src/locales/cy/messages.json b/apps/desktop/src/locales/cy/messages.json index 25b52fcc101..af6bb971ab3 100644 --- a/apps/desktop/src/locales/cy/messages.json +++ b/apps/desktop/src/locales/cy/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json index 1d135a533f2..5b864c57d62 100644 --- a/apps/desktop/src/locales/da/messages.json +++ b/apps/desktop/src/locales/da/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "En uventet fejl opstod." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Emneinformation" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Læs mere" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Funktion utilgængelig" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Følg os" }, - "syncVault": { - "message": "Synk boks" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Skift hovedadgangskode" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB krypteret lagerplads til filvedhæftninger." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietære totrins-login muligheder, såsom YubiKey og Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Eksportér fra" }, - "exportVault": { - "message": "Eksportér boks" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Filformat" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Alle Send", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Hovedadgangskode fjernet." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Sikker på, at indstillingen \"Aldrig\" skal bruges? Sættes låseindstillinger til \"Aldrig\", gemmes din bokskrypteringsnøgle på enheden. Bruges denne indstilling, så sørg for at holde din enhed ordentligt beskyttet." }, "vault": { - "message": "Boks" + "message": "Boks", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log ind med hovedadgangskoden" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Aliasdomæne" }, - "importData": { - "message": "Dataimport", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Importfejl" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Fil gemt på enheden. Håndtér fra enhedens downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index 6fc220faded..b49654c4dbe 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -70,7 +70,7 @@ } }, "noEditPermissions": { - "message": "Keine Berechtigung zum Bearbeiten dieses Eintrags" + "message": "Du bist nicht berechtigt, diesen Eintrag zu bearbeiten" }, "welcomeBack": { "message": "Willkommen zurück" @@ -708,6 +708,18 @@ "addAttachment": { "message": "Anhang hinzufügen" }, + "itemsTransferred": { + "message": "Einträge wurden übertragen" + }, + "fixEncryption": { + "message": "Verschlüsselung reparieren" + }, + "fixEncryptionTooltip": { + "message": "Diese Datei verwendet eine veraltete Verschlüsselungsmethode." + }, + "attachmentUpdated": { + "message": "Anhang aktualisiert" + }, "maxFileSizeSansPunctuation": { "message": "Die maximale Dateigröße beträgt 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Ein unerwarteter Fehler ist aufgetreten." }, + "unexpectedErrorShort": { + "message": "Unerwarteter Fehler" + }, + "closeThisBitwardenWindow": { + "message": "Schließe dieses Bitwarden-Fenster und versuche es erneut." + }, "itemInformation": { "message": "Eintragsinformationen" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Mehr erfahren" }, + "migrationsFailed": { + "message": "Beim Aktualisieren der Verschlüsselungseinstellungen ist ein Fehler aufgetreten." + }, + "updateEncryptionSettingsTitle": { + "message": "Aktualisiere deine Verschlüsselungseinstellungen" + }, + "updateEncryptionSettingsDesc": { + "message": "Die neuen empfohlenen Verschlüsselungseinstellungen verbessern deine Kontosicherheit. Gib dein Master-Passwort ein, um sie zu aktualisieren." + }, + "confirmIdentityToContinue": { + "message": "Bestätige deine Identität, um fortzufahren" + }, + "enterYourMasterPassword": { + "message": "Gib dein Master-Passwort ein" + }, + "updateSettings": { + "message": "Einstellungen aktualisieren" + }, "featureUnavailable": { "message": "Funktion nicht verfügbar" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Folge uns" }, - "syncVault": { - "message": "Tresor synchronisieren" + "syncNow": { + "message": "Jetzt synchronisieren" }, "changeMasterPass": { "message": "Master-Passwort ändern" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB verschlüsselter Speicherplatz für Dateianhänge." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ verschlüsselter Speicher für Dateianhänge.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietäre Optionen für die Zwei-Faktor Authentifizierung wie YubiKey und Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export aus" }, - "exportVault": { - "message": "Tresor exportieren" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Exportieren", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importieren", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Dateiformat" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Kontaktinformationen" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Alle Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master-Passwort entfernt" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Für Mitglieder der folgenden Organisation ist kein Master-Passwort mehr erforderlich. Bitte bestätige die folgende Domain bei deinem Organisations-Administrator." - }, "organizationName": { "message": "Name der Organisation" }, @@ -2991,7 +3050,8 @@ "message": "Bist du sicher, dass du die Option \"Nie\" verwenden möchtest? Durch das Setzen der Sperroptionen zu \"Nie\" wird der Verschlüsselungscode deines Tresors auf deinem Gerät gespeichert. Wenn du diese Option verwendest, solltest du sicherstellen, dass dein Gerät ausreichend geschützt ist." }, "vault": { - "message": "Tresor" + "message": "Tresor", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Mit Master-Passwort anmelden" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias-Domain" }, - "importData": { - "message": "Daten importieren", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Importfehler" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Datei auf Gerät gespeichert. Greife darauf über die Downloads deines Geräts zu." }, + "importantNotice": { + "message": "Wichtiger Hinweis" + }, + "setupTwoStepLogin": { + "message": "Zwei-Faktor-Authentifizierung einrichten" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Ab Februar 2025 wird Bitwarden einen Code an deine Konto-E-Mail-Adresse senden, um Anmeldungen von neuen Geräten zu verifizieren." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Du kannst die Zwei-Faktor-Authentifizierung als eine alternative Methode einrichten, um dein Konto zu schützen, oder deine E-Mail-Adresse zu einer anderen ändern, auf die du zugreifen kannst." + }, + "remindMeLater": { + "message": "Erinnere mich später" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Hast du zuverlässigen Zugriff auf deine E-Mail-Adresse $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nein, habe ich nicht" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Ja, ich kann zuverlässig auf meine E-Mails zugreifen" + }, + "turnOnTwoStepLogin": { + "message": "Zwei-Faktor-Authentifizierung aktivieren" + }, + "changeAcctEmail": { + "message": "E-Mail-Adresse des Kontos ändern" + }, + "passkeyLogin": { + "message": "Mit Passkey anmelden?" + }, + "savePasskeyQuestion": { + "message": "Passkey speichern?" + }, + "saveNewPasskey": { + "message": "Als neue Zugangsdaten speichern" + }, + "savePasskeyNewLogin": { + "message": "Passkey als neue Zugangsdaten speichern" + }, + "noMatchingLoginsForSite": { + "message": "Keine passenden Zugangsdaten für diese Seite" + }, + "overwritePasskey": { + "message": "Passkey überschreiben?" + }, + "unableToSavePasskey": { + "message": "Passkey konnte nicht gespeichert werden" + }, + "alreadyContainsPasskey": { + "message": "Dieser Eintrag enthält bereits einen Passkey. Bist du sicher, dass du den aktuellen Passkey überschreiben möchtest?" + }, + "passkeyAlreadyExists": { + "message": "Für diese Anwendung existiert bereits ein Passkey." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Diese Anwendung unterstützt keine mehrfachen Instanzen." + }, + "closeThisWindow": { + "message": "Dieses Fenster schließen" + }, "allowScreenshots": { "message": "Bildschirmaufnahme erlauben" }, @@ -4180,7 +4305,7 @@ "message": "Eintrag wurde archiviert" }, "itemWasUnarchived": { - "message": "Eintrag wurde wiederhergestellt" + "message": "Eintrag wird nicht mehr archiviert" }, "archiveItem": { "message": "Eintrag archivieren" @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "Und vieles mehr!" }, - "planDescPremium": { - "message": "Kompletter Online-Sicherheitsplan" + "advancedOnlineSecurity": { + "message": "Erweiterte Online-Sicherheit" }, "upgradeToPremium": { "message": "Auf Premium upgraden" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Deine Organisation verwendet keine Master-Passwörter mehr, um sich bei Bitwarden anzumelden. Verifiziere die Organisation und Domain, um fortzufahren." + }, + "continueWithLogIn": { + "message": "Mit der Anmeldung fortfahren" + }, + "doNotContinue": { + "message": "Nicht fortfahren" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "Diese Domain speichert die Verschlüsselungsschlüssel deines Kontos. Stelle daher sicher, dass du ihr vertraust. Wenn du dir nicht sicher bist, wende dich an deinen Administrator." + }, + "verifyYourOrganization": { + "message": "Verifiziere deine Organisation, um dich anzumelden" + }, + "organizationVerified": { + "message": "Organisation verifiziert" + }, + "domainVerified": { + "message": "Domain verifiziert" + }, + "leaveOrganizationContent": { + "message": "Wenn du deine Organisation nicht verifizierst, wird dein Zugriff auf die Organisation widerrufen." + }, + "leaveNow": { + "message": "Jetzt verlassen" + }, + "verifyYourDomainToLogin": { + "message": "Verifiziere deine Domain, um dich anzumelden" + }, + "verifyYourDomainDescription": { + "message": "Verifiziere diese Domain, um mit der Anmeldung fortzufahren." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Um mit der Anmeldung fortzufahren, verifiziere die Organisation und Domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout-Aktion" }, "sessionTimeoutHeader": { "message": "Sitzungs-Timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Diese Einstellung wird von deiner Organisation verwaltet." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Deine Organisation hat das maximale Sitzungs-Timeout auf $HOURS$ Stunde(n) und $MINUTES$ Minute(n) festgelegt.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Deine Organisation hat das Standard-Sitzungs-Timeout auf \"Wenn System gesperrt\" gesetzt." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Deine Organisation hat das Standard-Sitzungs-Timeout auf \"Beim Neustart der App\" gesetzt." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Das maximale Timeout darf $HOURS$ Stunde(n) und $MINUTES$ Minute(n) nicht überschreiten", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Beim Neustart der App" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Stell eine Entsperrmethode ein, um deine Timeout-Aktion zu ändern" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Bist du sicher, dass du gehen willst?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Wenn du ablehnst, bleiben deine persönlichen Einträge in deinem Konto erhalten, aber du wirst den Zugriff auf geteilte Einträge und Organisationsfunktionen verlieren." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Kontaktiere deinen Administrator, um wieder Zugriff zu erhalten." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "$ORGANIZATION$ verlassen", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Wie kann ich meinen Tresor verwalten?" + }, + "transferItemsToOrganizationTitle": { + "message": "Einträge zu $ORGANIZATION$ übertragen", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ erfordert zur Sicherheit und Compliance, dass alle Einträge der Organisation gehören. Klicke auf Akzeptieren, um den Besitz deiner Einträge zu übertragen.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Übertragung annehmen" + }, + "declineAndLeave": { + "message": "Ablehnen und verlassen" + }, + "whyAmISeeingThis": { + "message": "Warum wird mir das angezeigt?" } } diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index 0b869c1e02f..68b773c74f4 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Προσθήκη συνημμένου" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Το μέγιστο μέγεθος αρχείου είναι 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Παρουσιάστηκε ένα μη αναμενόμενο σφάλμα." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Πληροφορίες αντικειμένου" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Μάθετε περισσότερα" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Μη διαθέσιμη λειτουργία" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Ακολουθήστε μας" }, - "syncVault": { - "message": "Συγχρονισμός κρύπτης" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Αλλαγή κύριου κωδικού πρόσβασης" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB κρυπτογραφημένο αποθηκευτικό χώρο για συνημμένα αρχεία." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Ιδιόκτητες επιλογές σύνδεσης δύο βημάτων, όπως το YubiKey και το Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Εξαγωγή από" }, - "exportVault": { - "message": "Εξαγωγή κρύπτης" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Τύπος αρχείου" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Στοιχεία επικοινωνίας" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Όλα τα Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Ο κύριος κωδικός αφαιρέθηκε" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Είστε βέβαιοι ότι θέλετε να χρησιμοποιήσετε την επιλογή \"Ποτέ\"; Ο ορισμός των επιλογών κλειδώματος σε \"Ποτέ\" αποθηκεύει το κλειδί κρυπτογράφησης του θησαυ/κίου σας στη συσκευή σας. Εάν χρησιμοποιήσετε αυτήν την επιλογή, θα πρέπει να διασφαλίσετε ότι θα διατηρείτε τη συσκευή σας κατάλληλα προστατευμένη." }, "vault": { - "message": "Κρύπτη" + "message": "Κρύπτη", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Συνδεθείτε με τον κύριο κωδικό πρόσβασης" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Ψευδώνυμο τομέα" }, - "importData": { - "message": "Εισαγωγή δεδομένων", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Σφάλμα κατά την εισαγωγή" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Το αρχείο αποθηκεύτηκε στη συσκευή. Διαχείριση από τις λήψεις της συσκευής σας." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 757059c4e41..d26a46a9efe 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1739,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2601,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -3338,7 +3384,7 @@ "orgTrustWarning1": { "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." }, - "trustUser":{ + "trustUser": { "message": "Trust user" }, "inputRequired": { @@ -3459,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3868,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4226,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector":{ + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified":{ + "message": "Organization verified" + }, + "domainVerified":{ + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/en_GB/messages.json b/apps/desktop/src/locales/en_GB/messages.json index 16af69361c6..3ad78742666 100644 --- a/apps/desktop/src/locales/en_GB/messages.json +++ b/apps/desktop/src/locales/en_GB/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organisation. Please confirm the domain below with your organisation administrator." - }, "organizationName": { "message": "Organisation name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organisation is no longer using master passwords to log into Bitwarden. To continue, verify the organisation and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organisation to log in" + }, + "organizationVerified": { + "message": "Organisation verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organisation, your access to the organisation will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organisation and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organisation." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organisation has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organisation has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organisation has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organisation features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organisation for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/en_IN/messages.json b/apps/desktop/src/locales/en_IN/messages.json index c6f1253bb59..987d8d0925c 100644 --- a/apps/desktop/src/locales/en_IN/messages.json +++ b/apps/desktop/src/locales/en_IN/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organisation. Please confirm the domain below with your organisation administrator." - }, "organizationName": { "message": "Organisation name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organisation is no longer using master passwords to log into Bitwarden. To continue, verify the organisation and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organisation to log in" + }, + "organizationVerified": { + "message": "Organisation verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organisation, your access to the organisation will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organisation and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organisation." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organisation has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organisation has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organisation has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organisation features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organisation for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/eo/messages.json b/apps/desktop/src/locales/eo/messages.json index 28a9f3b8bce..1e70ad9a180 100644 --- a/apps/desktop/src/locales/eo/messages.json +++ b/apps/desktop/src/locales/eo/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Informo de ero" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Lerni pli" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "La funkcio nedisponeblas" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Sekvu nin" }, - "syncVault": { - "message": "Speguli la trezorejon" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Ŝanĝi la ĉefan pasvorton" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Elporti el" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Dosierformato" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Ĉiuj Send'oj", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "La ĉefa pasvorto foriĝis" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Nomo de la organizo" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Trezorejo" + "message": "Trezorejo", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Saluti per la ĉefa pasvorto" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Enporti datumon", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Enporti eraron" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "La dosiero konserviĝis en la aparato. La elŝutojn administru de via aparato." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/es/messages.json b/apps/desktop/src/locales/es/messages.json index 9966fa1064c..9ce531994a0 100644 --- a/apps/desktop/src/locales/es/messages.json +++ b/apps/desktop/src/locales/es/messages.json @@ -70,7 +70,7 @@ } }, "noEditPermissions": { - "message": "You don't have permission to edit this item" + "message": "No tienes permiso para editar este elemento" }, "welcomeBack": { "message": "Bienvenido de nuevo" @@ -706,10 +706,22 @@ "message": "El adjunto se ha guardado." }, "addAttachment": { - "message": "Add attachment" + "message": "Añadir adjunto" + }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Corregir cifrado" + }, + "fixEncryptionTooltip": { + "message": "El archivo está usando un método de cifrado obsoleto." + }, + "attachmentUpdated": { + "message": "Adjunto actualizado" }, "maxFileSizeSansPunctuation": { - "message": "Maximum file size is 500 MB" + "message": "El tamaño máximo del archivo es de 500 MB" }, "file": { "message": "Archivo" @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Ha ocurrido un error inesperado." }, + "unexpectedErrorShort": { + "message": "Error inesperado" + }, + "closeThisBitwardenWindow": { + "message": "Cierra esta ventana de Bitwarden e inténtalo de nuevo." + }, "itemInformation": { "message": "Información del elemento" }, @@ -1039,7 +1057,7 @@ "message": "Debes añadir o bien la URL del servidor base, o al menos un entorno personalizado." }, "selfHostedEnvMustUseHttps": { - "message": "URLs must use HTTPS." + "message": "Las URLs deben usar HTTPS." }, "customEnvironment": { "message": "Entorno personalizado" @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Más información" }, + "migrationsFailed": { + "message": "Se ha producido un error al actualizar los ajustes de cifrado." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirma tu identidad para continuar" + }, + "enterYourMasterPassword": { + "message": "Introduce tu contraseña maestra" + }, + "updateSettings": { + "message": "Actualizar ajustes" + }, "featureUnavailable": { "message": "Característica no disponible" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Síguenos" }, - "syncVault": { - "message": "Sincronizar caja fuerte" + "syncNow": { + "message": "Sincronizar ahora" }, "changeMasterPass": { "message": "Cambiar contraseña maestra" @@ -1232,7 +1268,7 @@ "message": "Contraseña maestra no válida" }, "invalidMasterPasswordConfirmEmailAndHost": { - "message": "Invalid master password. Confirm your email is correct and your account was created on $HOST$.", + "message": "Contraseña maestra incorrecta. Confirma que tu correo electrónico es correcto y que tu cuenta fue creada en $HOST$.", "placeholders": { "host": { "content": "$1", @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1GB de espacio en disco cifrado." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Opciones de inicio de sesión con autenticación de dos pasos propietarios como YubiKey y Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Exportar desde" }, - "exportVault": { - "message": "Exportar caja fuerte" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formato de archivo" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Información de contacto" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Todos los Send", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Contraseña maestra eliminada." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Ya no es necesaria una contraseña maestra para los miembros de la siguiente organización. Por favor, confirma el dominio que aparece a continuación con el administrador de tu organización." - }, "organizationName": { "message": "Nombre de la organización" }, @@ -2991,7 +3050,8 @@ "message": "¿Está seguro de que quieres usar la opción \"Nunca\"? Al ajustar las opciones de bloqueo a \"Nunca\", la clave de cifrado de su caja fuerte se guardará en tu dispositivo. Si usas esta opción, asegúrate de mantener tu dispositivo debidamente protegido." }, "vault": { - "message": "Caja fuerte" + "message": "Caja fuerte", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Iniciar sesión con contraseña maestra" @@ -3089,18 +3149,18 @@ "message": "You denied a login attempt from another device. If this was you, try to log in with the device again." }, "webApp": { - "message": "Web app" + "message": "Aplicación web" }, "mobile": { - "message": "Mobile", + "message": "Móvil", "description": "Mobile app" }, "extension": { - "message": "Extension", + "message": "Extensión", "description": "Browser extension/addon" }, "desktop": { - "message": "Desktop", + "message": "Escritorio", "description": "Desktop app" }, "cli": { @@ -3111,7 +3171,7 @@ "description": "Software Development Kit" }, "server": { - "message": "Server" + "message": "Servidor" }, "loginRequest": { "message": "Login request" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias de dominio" }, - "importData": { - "message": "Importar datos", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Error de importación" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Aviso importante" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Recuérdame más tarde" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "¿Tienes acceso fiable a tu correo electrónico, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, no lo tengo" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "¿Iniciar sesión con clave de acceso?" + }, + "savePasskeyQuestion": { + "message": "¿Guardar clave de acceso?" + }, + "saveNewPasskey": { + "message": "Guardar como nuevo inicio de sesión" + }, + "savePasskeyNewLogin": { + "message": "Guardar clave de acceso como nuevo inicio de sesión" + }, + "noMatchingLoginsForSite": { + "message": "No hay inicios de sesión coincidentes para este sitio" + }, + "overwritePasskey": { + "message": "¿Sobrescribir clave de acceso?" + }, + "unableToSavePasskey": { + "message": "No se puede guardar la clave de acceso" + }, + "alreadyContainsPasskey": { + "message": "Este elemento ya contiene una clave de acceso. ¿Estás seguro de que quieres sobrescribir la clave de acceso actual?" + }, + "passkeyAlreadyExists": { + "message": "Ya existe una clave de acceso para esta aplicación." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Esta aplicación no soporta duplicados." + }, + "closeThisWindow": { + "message": "Cerrar esta ventana" + }, "allowScreenshots": { "message": "Permitir captura de pantalla" }, @@ -4117,10 +4242,10 @@ } }, "showMore": { - "message": "Show more" + "message": "Mostrar más" }, "showLess": { - "message": "Show less" + "message": "Mostrar menos" }, "enableAutotypeDescription": { "message": "Bitwarden no valida las ubicaciones de entrada, asegúrate de que estás en la ventana y en el capo correctos antes de usar el atajo." @@ -4132,20 +4257,20 @@ "message": "Include one or two of the following modifiers: Ctrl, Alt, Win, or Shift, and a letter." }, "invalidShortcut": { - "message": "Invalid shortcut" + "message": "Atajo inválido" }, "moreBreadcrumbs": { "message": "More breadcrumbs", "description": "This is used in the context of a breadcrumb navigation, indicating that there are more items in the breadcrumb trail that are not currently displayed." }, "next": { - "message": "Next" + "message": "Siguiente" }, "confirmKeyConnectorDomain": { "message": "Confirm Key Connector domain" }, "confirm": { - "message": "Confirm" + "message": "Confirmar" }, "enableAutotypeShortcutPreview": { "message": "Enable autotype shortcut (Feature Preview)" @@ -4154,18 +4279,18 @@ "message": "Be sure you are in the correct field before using the shortcut to avoid filling data into the wrong place." }, "editShortcut": { - "message": "Edit shortcut" + "message": "Editar atajo" }, "archiveNoun": { - "message": "Archive", + "message": "Archivo", "description": "Noun" }, "archiveVerb": { - "message": "Archive", + "message": "Archivar", "description": "Verb" }, "unArchive": { - "message": "Unarchive" + "message": "Desarchivar" }, "itemsInArchive": { "message": "Items in archive" @@ -4189,13 +4314,13 @@ "message": "Archived items are excluded from general search results and autofill suggestions. Are you sure you want to archive this item?" }, "zipPostalCodeLabel": { - "message": "ZIP / Postal code" + "message": "ZIP / Código postal" }, "cardNumberLabel": { - "message": "Card number" + "message": "Número de tarjeta" }, "upgradeNow": { - "message": "Upgrade now" + "message": "Actualizar ahora" }, "builtInAuthenticator": { "message": "Built-in authenticator" @@ -4204,24 +4329,155 @@ "message": "Secure file storage" }, "emergencyAccess": { - "message": "Emergency access" + "message": "Acceso de emergencia" }, "breachMonitoring": { "message": "Breach monitoring" }, "andMoreFeatures": { - "message": "And more!" + "message": "¡Y más!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { - "message": "Upgrade to Premium" + "message": "Actualizar a Premium" + }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continuar con el inicio de sesión" + }, + "doNotContinue": { + "message": "No continuar" + }, + "domain": { + "message": "Dominio" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verifica tu organización para iniciar sesión" + }, + "organizationVerified": { + "message": "Organización verificada" + }, + "domainVerified": { + "message": "Dominio verificado" + }, + "leaveOrganizationContent": { + "message": "Si no verificas tu organización, tu acceso a la organización será revocado." + }, + "leaveNow": { + "message": "Salir ahora" + }, + "verifyYourDomainToLogin": { + "message": "Verifica tu dominio para iniciar sesión" + }, + "verifyYourDomainDescription": { + "message": "Para continuar con el inicio de sesión, verifica este dominio." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Para continuar con el inicio de sesión, verifica la organización y el dominio." }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Al reiniciar" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/et/messages.json b/apps/desktop/src/locales/et/messages.json index d85c52bb763..0c96d531e40 100644 --- a/apps/desktop/src/locales/et/messages.json +++ b/apps/desktop/src/locales/et/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Tekkis ootamatu viga." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Kirje andmed" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Loe edasi" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Funktsioon pole saadaval" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Jälgi meid" }, - "syncVault": { - "message": "Sünkroniseeri hoidla" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Muuda ülemparooli" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB ulatuses krüpteeritud salvestusruum." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Eraomanduses kaheastmelise logimise valikud, nagu näiteks YubiKey ja Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Ekspordi asukohast" }, - "exportVault": { - "message": "Ekspordi hoidla" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Failivorming" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Kõik Sendid", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Ülemparool on eemaldatud." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Oled kindel, et soovid kasutada valikut \"Mitte kunagi\"? Sellega talletatakse sinu hoidla krüpteerimise võtit seadme mälus. Peaksid olema väga hoolas ja kindel, et seade on ohutu ja selles ei ole pahavara." }, "vault": { - "message": "Hoidla" + "message": "Hoidla", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Logi sisse ülemparooliga" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Varidomeen" }, - "importData": { - "message": "Impordi andmed", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Tõrge importimisel" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Fail salvestatud. Halda oma seadmesse allalaaditud faile." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/eu/messages.json b/apps/desktop/src/locales/eu/messages.json index 36401df0078..e86f29770d6 100644 --- a/apps/desktop/src/locales/eu/messages.json +++ b/apps/desktop/src/locales/eu/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Ustekabeko akatsa gertatu da." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Elementuaren informazioa" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Gehiago ikasi" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Ezaugarria ez dago erabilgarri" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Jarraitu gaitzazu" }, - "syncVault": { - "message": "Sinkronizatu kutxa gotorra" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Aldatu pasahitz nagusia" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "Eranskinentzako 1GB-eko zifratutako biltegia." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Esportatu kutxa gotorra" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Fitxategiaren formatua" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Send guztiak", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Pasahitz nagusia ezabatua." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Ziur zaude \"Inoiz ez\" aukera erabili nahi duzula? Zure blokeo aukerak \"Inoiz ez\" bezala konfiguratzeak kutxa gotorraren zifratze-gakoa gailuan gordetzen du. Aukera hau erabiltzen baduzu, gailua behar bezala babestuta duzula ziurtatu behar duzu." }, "vault": { - "message": "Kutxa gotorra" + "message": "Kutxa gotorra", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Hasi saioa pasahitz nagusiarekin" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/fa/messages.json b/apps/desktop/src/locales/fa/messages.json index ac0e83dd44d..45cda22a45f 100644 --- a/apps/desktop/src/locales/fa/messages.json +++ b/apps/desktop/src/locales/fa/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "افزودن پیوست" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "حداکثر حجم فایل ۵۰۰ مگابایت است" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "یک خطای غیر منتظره رخ داده است." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "اطلاعات مورد" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "بیشتر بدانید" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "ویژگی موجود نیست" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "ﻣﺎ ﺭﺍ ﺩﻧﺒﺎﻝ ﮐﻨﻴﺪ" }, - "syncVault": { - "message": "همگام‌سازی گاوصندوق" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "تغییر کلمه عبور اصلی" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "۱ گیگابایت فضای ذخیره‌سازی رمزنگاری شده برای پرونده‌های پیوست." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "گزینه‌های ورود اضافی دو مرحله‌ای مانند YubiKey و Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "برون ریزی از" }, - "exportVault": { - "message": "برون ریزی گاوصندوق" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "فرمت پرونده" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "اطلاعات تماس" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "همه ارسال‌ها", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "کلمه عبور اصلی حذف شد" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "برای اعضای سازمان زیر، کلمه عبور اصلی دیگر لازم نیست. لطفاً دامنه زیر را با مدیر سازمان خود تأیید کنید." - }, "organizationName": { "message": "نام سازمان" }, @@ -2991,7 +3050,8 @@ "message": "آیا جداً می‌خواهید از گزینه \"هرگز\" استفاده کنید؟ تنظیم کردن گزینه قفل به \"هرگز\" کلیدهای رمزنگاری گاوصندوقتان را بر روی دستگاه شما ذخیره خواهد کرد. اگر از این گزینه استفاده می‌کنید باید اطمینان داشته باشید که دستگاه شما کاملا محافظت شده است." }, "vault": { - "message": "گاوصندوق" + "message": "گاوصندوق", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "با کلمه عبور اصلی وارد شوید" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "دامنه مستعار" }, - "importData": { - "message": "درون ریزی داده", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "خطای درون ریزی" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "پرونده در دستگاه ذخیره شد. از بخش بارگیری‌های دستگاه خود مدیریت کنید." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "اجازه ضبط صفحه" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "و بیشتر!" }, - "planDescPremium": { - "message": "امنیت آنلاین کامل" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "ارتقا به نسخه پرمیوم" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "اقدام وقفه زمانی" }, "sessionTimeoutHeader": { "message": "وقفه زمانی نشست" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index e2952659d03..7cee4e0c5e5 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Tapahtui odottamaton virhe." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Kohteen tiedot" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Lue lisää" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Ominaisuus ei ole käytettävissä" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Seuraa meitä" }, - "syncVault": { - "message": "Synkronoi holvi" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Vaihda pääsalasana" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 Gt salattua tallennustilaa tiedostoliitteille." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Kaksivaiheisen kirjautumisen erikoisvaihtoehdot, kuten YubiKey ja Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Vie lähteestä" }, - "exportVault": { - "message": "Vie holvi" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Tiedostomuoto" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Yhteystiedot" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Kaikki Sendit", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Pääsalasana poistettiin" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Haluatko varmasti käyttää asetusta \"Ei koskaan\"? Se tallentaa holvisi salausavaimen laitteellesi. Jos käytät asetusta, varmista, että laite on suojattu hyvin." }, "vault": { - "message": "Holvi" + "message": "Holvi", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Kirjaudu pääsalasanalla" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Aliaksen verkkotunnus" }, - "importData": { - "message": "Tuo tietoja", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Tuontivirhe" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Tiedosto tallennettiin laitteelle. Hallitse sitä laitteesi latauksista." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Salli kuvankaappaus" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/fil/messages.json b/apps/desktop/src/locales/fil/messages.json index 6eaa5577807..39651e16f4a 100644 --- a/apps/desktop/src/locales/fil/messages.json +++ b/apps/desktop/src/locales/fil/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Isang hindi inaasahang error ang naganap." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Impormasyon ng item" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Matuto nang higit pa" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Hindi magagamit ang tampok" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Sundin mo kami" }, - "syncVault": { - "message": "Vault ng Sync" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Palitan ang master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB naka encrypt na imbakan para sa mga attachment ng file." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "I-export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format ng file" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Lahat ng Mga Padala", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Tinanggal ang password ng master" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Sigurado ka bang gusto mong gamitin ang opsyon na \"Never\" Ang pagtatakda ng iyong mga pagpipilian sa lock sa \"Hindi kailanman\" ay nag iimbak ng key ng pag encrypt ng iyong vault sa iyong aparato. Kung gagamitin mo ang pagpipiliang ito dapat mong tiyakin na pinapanatili mong protektado nang maayos ang iyong aparato." }, "vault": { - "message": "Ayos" + "message": "Ayos", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Mag-login gamit ang pangunahing password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json index 6cca98444b8..503c93f9f19 100644 --- a/apps/desktop/src/locales/fr/messages.json +++ b/apps/desktop/src/locales/fr/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Ajouter une pièce jointe" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "La taille maximale des fichiers est de 500 Mo" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Une erreur inattendue est survenue." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Informations sur l'élément" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "En savoir plus" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Fonctionnalité non disponible" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Suivez-nous" }, - "syncVault": { - "message": "Synchroniser le coffre" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Changer le mot de passe principal" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 Go de stockage chiffré pour les fichiers joints." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Options de connexion propriétaires à deux facteurs telles que YubiKey et Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Exporter depuis" }, - "exportVault": { - "message": "Exporter le coffre" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format de fichier" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Informations de contact" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Tous les Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Mot de passe principal supprimé" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Un mot de passe maître n'est plus requis pour les membres de l'organisation suivante. Veuillez confirmer le domaine ci-dessous avec l'administrateur de votre organisation." - }, "organizationName": { "message": "Nom de l'organisation" }, @@ -2991,7 +3050,8 @@ "message": "Êtes-vous sûr de vouloir utiliser l'option \"Jamais\" ? Définir le verrouillage sur \"Jamais\" stocke la clé de chiffrement de votre coffre sur votre appareil. Si vous utilisez cette option, vous devez vous assurer de correctement protéger votre appareil." }, "vault": { - "message": "Coffre" + "message": "Coffre", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Se connecter avec le mot de passe principal" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Domaine de l'alias" }, - "importData": { - "message": "Importer des données", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Erreur lors de l'importation" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Fichier enregistré sur l'appareil. Gérez à partir des téléchargements de votre appareil." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Autoriser les captures d'écran" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "Et encore plus !" }, - "planDescPremium": { - "message": "Sécurité en ligne complète" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Mettre à niveau vers Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Action à l’expiration" }, "sessionTimeoutHeader": { "message": "Délai d'expiration de la session" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/gl/messages.json b/apps/desktop/src/locales/gl/messages.json index d607bb8d097..2d0019a1f31 100644 --- a/apps/desktop/src/locales/gl/messages.json +++ b/apps/desktop/src/locales/gl/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/he/messages.json b/apps/desktop/src/locales/he/messages.json index 868cd9ccbc5..cde90fcc7ef 100644 --- a/apps/desktop/src/locales/he/messages.json +++ b/apps/desktop/src/locales/he/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "הוסף צרופה" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "גודל הקובץ המרבי הוא 500MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "אירעה שגיאה לא צפויה." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "מידע על הפריט" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "למידע נוסף" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "יכולת זו לא זמינה" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "עקוב אחרינו" }, - "syncVault": { - "message": "סנכרון כספת" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "החלף סיסמה ראשית" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 ג'יגה של מקום אחסון מוצפן עבור קבצים מצורפים." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "אפשרויות כניסה דו־שלבית קנייניות כגון YubiKey ו־Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "ייצוא מ־" }, - "exportVault": { - "message": "יצוא כספת" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "תבנית קובץ" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "פרטי איש קשר" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "כל הסֵנְדים", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "הסיסמה הראשית הוסרה" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "סיסמה ראשית אינה נדרשת עוד עבור חברים בארגון הבא. נא לאשר את הדומיין שלהלן עם מנהל הארגון שלך." - }, "organizationName": { "message": "שם הארגון" }, @@ -2991,7 +3050,8 @@ "message": "האם אתה בטוח שברצונך להשתמש באפשרות \"לעולם לא\"? הגדרת אפשרויות הנעילה שלך ל\"לעולם לא\" מאחסנת את מפתח ההצפנה של הכספת שלך במכשיר שלך. אם אתה משתמש באפשרות זו עליך לוודא שאתה שומר על המכשיר שלך מוגן כראוי." }, "vault": { - "message": "כספת" + "message": "כספת", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "כניסה עם סיסמה ראשית" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "דומיין כינוי" }, - "importData": { - "message": "ייבא נתונים", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "שגיאת ייבוא" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "הקובץ נשמר למכשיר. נהל מהורדות המכשיר שלך." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "אפשר לכידת מסך" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "ועוד!" }, - "planDescPremium": { - "message": "השלם אבטחה מקוונת" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "שדרג לפרימיום" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "פעולת פסק זמן" }, "sessionTimeoutHeader": { "message": "פסק זמן להפעלה" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/hi/messages.json b/apps/desktop/src/locales/hi/messages.json index 2ab323eedc9..d3f65bef701 100644 --- a/apps/desktop/src/locales/hi/messages.json +++ b/apps/desktop/src/locales/hi/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json index 0f7a8185118..10cf3fac635 100644 --- a/apps/desktop/src/locales/hr/messages.json +++ b/apps/desktop/src/locales/hr/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Dodaj privitak" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Najveća veličina datoteke je 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Došlo je do neočekivane pogreške." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Informacije o stavci" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Saznaj više" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Značajka nije dostupna" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Prati nas" }, - "syncVault": { - "message": "Sinkronizraj trezor" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Promjeni glavnu lozinku" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB šifriranog prostora za pohranu podataka." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Mogućnosti za prijavu u dva koraka kao što su YubiKey i Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Izvezi iz" }, - "exportVault": { - "message": "Izvezi trezor" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format datoteke" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Kontaktne informacije" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Svi Sendovi", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Glavna lozinka uklonjena." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Glavna lozinka više nije obavezna za članove ove organizacije. Provjeri prikazanu domenu sa svojim administratorom." - }, "organizationName": { "message": "Naziv Organizacije" }, @@ -2991,7 +3050,8 @@ "message": "Sigurno želiš koristiti opciju „Nikada”? Postavljanje opcija zaključavanja na „Nikada” pohranjuje šifru tvojeg trezora na tvom uređaju. Ako koristiš ovu opciju, trebalo bi osigurati da je uređaj pravilno zaštićen." }, "vault": { - "message": "Trezor" + "message": "Trezor", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Prijava glavnom lozinkom" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domene" }, - "importData": { - "message": "Uvezi podatke", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Greška prilikom uvoza" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Datoteka spremljena na uređaj. Upravljaj u preuzimanjima svog uređaja." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Dozvoli snimanje zaslona" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "I više!" }, - "planDescPremium": { - "message": "Dovrši online sigurnost" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": " Nadogradi na Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Radnja nakon isteka" }, "sessionTimeoutHeader": { "message": "Istek sesije" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json index 9a6dd787f8c..8cb8897ab09 100644 --- a/apps/desktop/src/locales/hu/messages.json +++ b/apps/desktop/src/locales/hu/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Melléklet hozzáadása" }, + "itemsTransferred": { + "message": "Az elemek átvitelre kerültek." + }, + "fixEncryption": { + "message": "Titkosítás javítása" + }, + "fixEncryptionTooltip": { + "message": "Ez a fájl elavult titkosítási módszert használ." + }, + "attachmentUpdated": { + "message": "A melléklet frissítésre került." + }, "maxFileSizeSansPunctuation": { "message": "A maximális fájlméret 500 MB." }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Váratlan hiba történt." }, + "unexpectedErrorShort": { + "message": "Váratlan hiba" + }, + "closeThisBitwardenWindow": { + "message": "Zárjuk be ezt a Bitwarden ablakot és próbáljuk újra." + }, "itemInformation": { "message": "Elem információ" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "További információ" }, + "migrationsFailed": { + "message": "Hiba történt a titkosítási beállítások frissítésekor." + }, + "updateEncryptionSettingsTitle": { + "message": "A titkosítási beállítások frissítése" + }, + "updateEncryptionSettingsDesc": { + "message": "Az új ajánlott titkosítási beállítások javítják a fiók biztonságát. Adjuk meg a mesterjelszót a frissítéshez most." + }, + "confirmIdentityToContinue": { + "message": "A folytatáshoz meg kell erősíteni a személyazonosságot." + }, + "enterYourMasterPassword": { + "message": "Mesterjelszó megadása" + }, + "updateSettings": { + "message": "Beállítások frissítése" + }, "featureUnavailable": { "message": "Ez a funkció nem érhető el." }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Követés" }, - "syncVault": { - "message": "Széf szinkronizálása" + "syncNow": { + "message": "Szinkronizálás most" }, "changeMasterPass": { "message": "Mesterjelszó módosítása" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB titkosított fájlmelléklet tárhely." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ titkosított tárhely a fájlmellékletekhez.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Saját kétlépcsős bejelentkezési lehetőségek mint a YubiKey és a Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Exportálás innen:" }, - "exportVault": { - "message": "Széf exportálása" + "exportNoun": { + "message": "Exportálás", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Exportálás", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Importálás", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importálás", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Fájlformátum" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Elérhetőségi adatok" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Összes küldés", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "A mesterjelszó eltávolításra került." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A következő szervezet tagjai számára már nincs szükség mesterjelszóra. Erősítsük meg az alábbi tartományt a szervezet adminisztrátorával." - }, "organizationName": { "message": "Szervezet neve" }, @@ -2991,7 +3050,8 @@ "message": "Biztosan szeretnénk használni a \"Soha\" opciót? A zárolási opciók \"Soha\" értékre állítása a széf titkosítási kulcsát az eszközön tárolja. Ennek az opciónak a használatakor célszerű az eszköz megfelelő védettségét biztosítani." }, "vault": { - "message": "Széf" + "message": "Széf", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Bejelentkezés mesterjelszóval" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Áldomain" }, - "importData": { - "message": "Adatok importálása", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Importálási hiba" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "A fájl mentésre került az eszközre. Kezeljük az eszközről a letöltéseket." }, + "importantNotice": { + "message": "Fontos megjegyzés" + }, + "setupTwoStepLogin": { + "message": "Kétlépéses bejelentkezés beüzemelése" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "A Bitwarden 2025 februárjától kódot küld a fiókhoz tartozó email címre, amellyel ellenőrizhetők az új eszközökről történő bejelentkezések." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "A fiók védelmének alternatív módjaként beállíthatunk kétlépéses bejelentkezést vagy módosíthatjuk az email címet egy elérhetőre." + }, + "remindMeLater": { + "message": "Emlékeztetés később" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Megbízható a hozzáférés $EMAIL$ email címhez?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nem, nem érem el" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Igen, megbízhatóan hozzáférek az email címhez" + }, + "turnOnTwoStepLogin": { + "message": "Kétlépéses bejelentkezés bekapcsolása" + }, + "changeAcctEmail": { + "message": "Fiók email cím megváltoztatása" + }, + "passkeyLogin": { + "message": "Bejelentkezés belépőkulccsal?" + }, + "savePasskeyQuestion": { + "message": "Belépőkulcs mentése?" + }, + "saveNewPasskey": { + "message": "Mentés új bejelentkezésként" + }, + "savePasskeyNewLogin": { + "message": "Belépőkulcs mentése új bejelentkezésként" + }, + "noMatchingLoginsForSite": { + "message": "Nincsenek egyező bejelentkezések ehhez a webhelyhez." + }, + "overwritePasskey": { + "message": "Belépőkulcs felülírása?" + }, + "unableToSavePasskey": { + "message": "Nem lehet menteni a belépőkulcsot." + }, + "alreadyContainsPasskey": { + "message": "Ez az elem már tartalmaz egy belépőkulcsot. Biztosan felülírásra kerüljön az aktuális belépőkulcs?" + }, + "passkeyAlreadyExists": { + "message": "Ehhez az alkalmazáshoz már létezik belépőkulcs." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Ez az alkalmazás nem támogatja a másolatokat." + }, + "closeThisWindow": { + "message": "Ezen ablak bezárása" + }, "allowScreenshots": { "message": "Képernyőrögzítés engedélyezése" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "És még több!" }, - "planDescPremium": { - "message": "Teljes körű online biztonság" + "advancedOnlineSecurity": { + "message": "Bővített online biztonság" }, "upgradeToPremium": { "message": "Áttérés Prémium csomagra" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "A szervezet már nem használ mesterjelszavakat a Bitwardenbe bejelentkezéshez. A folytatáshoz ellenőrizzük a szervezetet és a tartományt." + }, + "continueWithLogIn": { + "message": "Folytatás bejelentkezéssel" + }, + "doNotContinue": { + "message": "Nincs folytatás" + }, + "domain": { + "message": "Tartomány" + }, + "keyConnectorDomainTooltip": { + "message": "Ez a tartomány tárolja a fiók titkosítási kulcsait, ezért győződjünk meg róla, hogy megbízunk-e benne. Ha nem vagyunk biztos benne, érdeklődjünk adminisztrátornál." + }, + "verifyYourOrganization": { + "message": "Szervezet ellenőrzése a bejelentkezéshez" + }, + "organizationVerified": { + "message": "A szervezet ellenőrzésre került." + }, + "domainVerified": { + "message": "A tartomány ellenőrzésre került." + }, + "leaveOrganizationContent": { + "message": "Ha nem ellenőrizzük a szervezetet, a szervezethez hozzáférés visszavonásra kerül." + }, + "leaveNow": { + "message": "Elhagyás most" + }, + "verifyYourDomainToLogin": { + "message": "Tartomány ellenőrzése a bejelentkezéshez" + }, + "verifyYourDomainDescription": { + "message": "A bejelentkezés folytatásához ellenőrizzük ezt a tartományt." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "A bejelentkezés folytatásához ellenőrizzük a szervezetet és a tartományt." + }, "sessionTimeoutSettingsAction": { "message": "Időkifutási művelet" }, "sessionTimeoutHeader": { "message": "Munkamenet időkifutás" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Ezt a beállítást a szervezet lezeli." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "A szervezet a munkamenet maximális munkamenet időkifutását $HOURS$ órára és $MINUTES$ percre állította be.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "A szervezet az alapértelmezett munkamenet időkifutástr Rendszerzár be értékre állította." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "A szervezet a maximális munkamenet időkifutást Újraindításkor értékre állította." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "A maximális időtúllépés nem haladhatja meg a $HOURS$ óra és $MINUTES$ perc értéket.", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Újraindításkor" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Állítsunk be egy feloldási módot a széf időkifutási műveletének módosításához." + }, + "upgrade": { + "message": "Áttérés" + }, + "leaveConfirmationDialogTitle": { + "message": "Biztosan szeretnénk kilépni?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Az elutasítással a személyes elemek a fiókban maradnak, de elveszítjük hozzáférést a megosztott elemekhez és a szervezeti funkciókhoz." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Lépjünk kapcsolatba az adminisztrátorral a hozzáférés visszaszerzéséért." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "$ORGANIZATION$ elhagyása", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Hogyan kezeljem a széfet?" + }, + "transferItemsToOrganizationTitle": { + "message": "Elemek átvitele $ORGANIZATION$ szervezethez", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ megköveteli, hogy minden elem a szervezet tulajdonában legyen a biztonság és a megfelelőség érdekében. Kattintás az elfogadásra az elemek tulajdonjogának átruházásához.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Átvitel elfogadása" + }, + "declineAndLeave": { + "message": "Elutasítás és kilépés" + }, + "whyAmISeeingThis": { + "message": "Miért látható ez?" } } diff --git a/apps/desktop/src/locales/id/messages.json b/apps/desktop/src/locales/id/messages.json index 188ee153da1..32a030e584c 100644 --- a/apps/desktop/src/locales/id/messages.json +++ b/apps/desktop/src/locales/id/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Terjadi kesalahan yang tak diduga." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Informasi Item" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Pelajari lebih lanjut" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Fitur Tidak Tersedia" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Ikuti Kami" }, - "syncVault": { - "message": "Sinkronisasi Brankas" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Ubah Kata Sandi Utama" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB penyimpanan berkas yang dienkripsi." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Ekspor Brankas" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File Format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Semua Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Sandi utama dihapus" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Brankas" + "message": "Brankas", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index 8caf4982356..bc3076bbc3c 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Aggiungi allegato" }, + "itemsTransferred": { + "message": "Elementi trasferiti" + }, + "fixEncryption": { + "message": "Correggi la crittografia" + }, + "fixEncryptionTooltip": { + "message": "Questo file usa un metodo di crittografia obsoleto." + }, + "attachmentUpdated": { + "message": "Allegato aggiornato" + }, "maxFileSizeSansPunctuation": { "message": "La dimensione massima consentita è 500 MB." }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Si è verificato un errore imprevisto." }, + "unexpectedErrorShort": { + "message": "Errore inaspettato" + }, + "closeThisBitwardenWindow": { + "message": "Chiudi questa finestra di Bitwarden e riprova." + }, "itemInformation": { "message": "Informazioni sull'elemento" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Ulteriori informazioni" }, + "migrationsFailed": { + "message": "Si è verificato un errore durante l'aggiornamento delle impostazioni di cifratura." + }, + "updateEncryptionSettingsTitle": { + "message": "Aggiorna le impostazioni di crittografia" + }, + "updateEncryptionSettingsDesc": { + "message": "Le nuove impostazioni di crittografia consigliate miglioreranno la sicurezza del tuo account. Inserisci la tua password principale per aggiornare." + }, + "confirmIdentityToContinue": { + "message": "Conferma la tua identità per continuare" + }, + "enterYourMasterPassword": { + "message": "Inserisci la tua password principale" + }, + "updateSettings": { + "message": "Aggiorna impostazioni" + }, "featureUnavailable": { "message": "Funzionalità non disponibile" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Seguici" }, - "syncVault": { - "message": "Sincronizza cassaforte" + "syncNow": { + "message": "Sincronizza" }, "changeMasterPass": { "message": "Cambia password principale" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB di spazio di archiviazione crittografato per gli allegati." }, + "premiumSignUpStorageV2": { + "message": "Archivio crittografato di $SIZE$ per allegati.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Opzioni di verifica in due passaggi proprietarie come YubiKey e Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Esporta da" }, - "exportVault": { - "message": "Esporta cassaforte" + "exportNoun": { + "message": "Esporta", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Esporta", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Importa", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importa", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formato file" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Informazioni di contatto" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Tutti i Send", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Password principale rimossa" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "La password principale non è più richiesta per i membri dell'organizzazione. Per favore, conferma il dominio qui sotto con l'amministratore." - }, "organizationName": { "message": "Nome dell'organizzazione" }, @@ -2991,7 +3050,8 @@ "message": "Sei sicuro di voler usare l'opzione \"Mai\"? Impostare le opzioni di blocco su \"Mai\" salverà la chiave di crittografia della cassaforte sul tuo dispositivo. Se usi questa opzione, assicurati di mantenere il tuo dispositivo adeguatamente protetto." }, "vault": { - "message": "Cassaforte" + "message": "Cassaforte", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Accedi con password principale" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Dominio alias" }, - "importData": { - "message": "Importa dati", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Errore di importazione" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File salvato sul dispositivo. Gestisci dai download del dispositivo." }, + "importantNotice": { + "message": "Avviso importante" + }, + "setupTwoStepLogin": { + "message": "Imposta l'accesso in due passaggi" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden invierà un codice all'email del tuo account per verificare gli accessi da nuovi dispositivi." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Puoi impostare l'accesso in due passaggi per proteggere il tuo account, oppure scegliere una email alla quale hai accesso." + }, + "remindMeLater": { + "message": "Ricordamelo in seguito" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Confermi di poter accedere all'email $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Sì, ho accesso all'email" + }, + "turnOnTwoStepLogin": { + "message": "Attiva l'accesso in due passaggi" + }, + "changeAcctEmail": { + "message": "Cambia l'email dell'account" + }, + "passkeyLogin": { + "message": "Vuoi accedere con la passkey?" + }, + "savePasskeyQuestion": { + "message": "Vuoi salvare la passkey?" + }, + "saveNewPasskey": { + "message": "Salva come nuovo login" + }, + "savePasskeyNewLogin": { + "message": "Salva la passkey come nuovo elemento" + }, + "noMatchingLoginsForSite": { + "message": "Nessun login salvato per questa pagina" + }, + "overwritePasskey": { + "message": "Vuoi sovrascrivere la passkey?" + }, + "unableToSavePasskey": { + "message": "Impossibile salvare la passkey" + }, + "alreadyContainsPasskey": { + "message": "Questo elemento contiene già una passkey. Vuoi sovrascriverla?" + }, + "passkeyAlreadyExists": { + "message": "Esiste già una passkey per questa applicazione." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Questa applicazione non supporta duplicati." + }, + "closeThisWindow": { + "message": "Chiudi questa finestra" + }, "allowScreenshots": { "message": "Permetti cattura dello schermo" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "E molto altro!" }, - "planDescPremium": { - "message": "Sicurezza online completa" + "advancedOnlineSecurity": { + "message": "Sicurezza online avanzata" }, "upgradeToPremium": { "message": "Aggiorna a Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "La tua organizzazione non utilizza più le password principali per accedere a Bitwarden. Per continuare, verifica l'organizzazione e il dominio." + }, + "continueWithLogIn": { + "message": "Accedi e continua" + }, + "doNotContinue": { + "message": "Non continuare" + }, + "domain": { + "message": "Dominio" + }, + "keyConnectorDomainTooltip": { + "message": "Questo dominio memorizzerà le chiavi di crittografia del tuo account, quindi assicurati di impostarlo come affidabile. Se non hai la certezza che lo sia, verifica con l'amministratore." + }, + "verifyYourOrganization": { + "message": "Verifica la tua organizzazione per accedere" + }, + "organizationVerified": { + "message": "Organizzazione verificata" + }, + "domainVerified": { + "message": "Dominio verificato" + }, + "leaveOrganizationContent": { + "message": "Se non verifichi l'organizzazione, il tuo accesso sarà revocato." + }, + "leaveNow": { + "message": "Abbandona" + }, + "verifyYourDomainToLogin": { + "message": "Verifica il tuo dominio per accedere" + }, + "verifyYourDomainDescription": { + "message": "Per continuare con l'accesso, verifica questo dominio." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Per continuare con l'accesso, verifica l'organizzazione e il dominio." + }, "sessionTimeoutSettingsAction": { "message": "Azione al timeout" }, "sessionTimeoutHeader": { "message": "Timeout della sessione" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Questa impostazione è gestita dalla tua organizzazione." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "La tua organizzazione ha impostato $HOURS$ ora/e e $MINUTES$ minuto/i come durata massima della sessione.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "In base alle impostazioni della tua organizzazione, la sessione terminerà al blocco del dispositivo." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "In base alle impostazioni della tua organizzazione, la sessione terminerà al riavvio dell'applicazione." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "La durata della sessione non può superare $HOURS$ ora/e e $MINUTES$ minuto/i", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Al riavvio" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Imposta un metodo di sblocco per modificare l'azione al timeout" + }, + "upgrade": { + "message": "Aggiorna" + }, + "leaveConfirmationDialogTitle": { + "message": "Vuoi davvero abbandonare?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Se rifiuti, tutti gli elementi esistenti resteranno nel tuo account, ma perderai l'accesso agli oggetti condivisi e alle funzioni organizzative." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contatta il tuo amministratore per recuperare l'accesso." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Abbandona $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Come si gestisce la cassaforte?" + }, + "transferItemsToOrganizationTitle": { + "message": "Trasferisci gli elementi in $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ richiede che tutti gli elementi siano di proprietà dell'organizzazione per motivi di conformità e sicurezza. Clicca su 'Accetta' per trasferire la proprietà.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accetta il trasferimento" + }, + "declineAndLeave": { + "message": "Rifiuta e abbandona" + }, + "whyAmISeeingThis": { + "message": "Perché vedo questo avviso?" } } diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index ca50828b12c..e517bdcbe72 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "予期せぬエラーが発生しました。" }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "アイテム情報" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "詳細情報" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "サービスが利用できません" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "フォロー" }, - "syncVault": { - "message": "保管庫の同期" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "マスターパスワードの変更" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1GB の暗号化されたファイルストレージ。" }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "YubiKey、Duo などのプロプライエタリな2段階認証オプション。" }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "エクスポート元" }, - "exportVault": { - "message": "保管庫のエクスポート" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "ファイル形式" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "すべての Send", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "マスターパスワードを削除しました。" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "本当に「なし」オプションを使用しますか?ロックオプションを「なし」に設定すると、保管庫の暗号化キーがデバイスに保存されます。 このオプションを使用する場合は、デバイスを適切に保護する必要があります。" }, "vault": { - "message": "保管庫" + "message": "保管庫", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "マスターパスワードでログイン" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "エイリアスドメイン" }, - "importData": { - "message": "データのインポート", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "インポート エラー" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "ファイルをデバイスに保存しました。デバイスのダウンロードで管理できます。" }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "スクリーンショットを許可" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/ka/messages.json b/apps/desktop/src/locales/ka/messages.json index 9337286d3fd..caf75a81f38 100644 --- a/apps/desktop/src/locales/ka/messages.json +++ b/apps/desktop/src/locales/ka/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "გაიგეთ მეტი" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "საცავი" + "message": "საცავი", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "მონაცემების შემოტანა", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "შემოტანის შეცდომა" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/km/messages.json b/apps/desktop/src/locales/km/messages.json index d607bb8d097..2d0019a1f31 100644 --- a/apps/desktop/src/locales/km/messages.json +++ b/apps/desktop/src/locales/km/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/kn/messages.json b/apps/desktop/src/locales/kn/messages.json index d1375efee8c..edfb1b6dd6e 100644 --- a/apps/desktop/src/locales/kn/messages.json +++ b/apps/desktop/src/locales/kn/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "ಅನಿರೀಕ್ಷಿತ ದೋಷ ಸಂಭವಿಸಿದೆ." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "ಐಟಂ ಮಾಹಿತಿ" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "ವೈಶಿಷ್ಟ್ಯ ಲಭ್ಯವಿಲ್ಲ" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "ನಮ್ಮನ್ನು ಅನುಸರಿಸಿ" }, - "syncVault": { - "message": "ಸಿಂಕ್ ವಾಲ್ಟ್" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "ಮಾಸ್ಟರ್ ಪಾಸ್ವರ್ಡ್ ಬದಲಾಯಿಸಿ" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "ಫೈಲ್ ಲಗತ್ತುಗಳಿಗಾಗಿ 1 ಜಿಬಿ ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಿದ ಸಂಗ್ರಹ." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "ರಫ್ತು ವಾಲ್ಟ್" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "ಕಡತದ ಮಾದರಿ" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "ಎಲ್ಲಾ ಕಳುಹಿಸುತ್ತದೆ", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/ko/messages.json b/apps/desktop/src/locales/ko/messages.json index 2e40b8d7f23..4d4e3221651 100644 --- a/apps/desktop/src/locales/ko/messages.json +++ b/apps/desktop/src/locales/ko/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "예기치 못한 오류가 발생했습니다." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "항목 정보" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "더 알아보기" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "기능 사용할 수 없음" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "팔로우하기" }, - "syncVault": { - "message": "보관함 동기화" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "마스터 비밀번호 변경" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1GB의 암호화된 파일 저장소." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "보관함 내보내기" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "파일 형식" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "모든 Send", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "마스터 비밀번호가 제거되었습니다." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "정말 \"잠그지 않음\" 옵션을 사용하시겠습니까? 잠금 옵션을 \"잠그지 않음\"으로 설정하면 사용자 보관함의 암호화 키를 사용자의 기기에 보관합니다. 이 옵션을 사용하기 전에 사용자의 기기가 잘 보호되어 있는 상태인지 확인하십시오." }, "vault": { - "message": "보관함" + "message": "보관함", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "마스터 비밀번호로 로그인" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "데이터 가져오기", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/lt/messages.json b/apps/desktop/src/locales/lt/messages.json index 16f328d6240..ead4c1d89f9 100644 --- a/apps/desktop/src/locales/lt/messages.json +++ b/apps/desktop/src/locales/lt/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Įvyko netikėta klaida." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Elemento informacija" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Sužinoti daugiau" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Funkcija nepasiekiama" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Sekite mus" }, - "syncVault": { - "message": "Sinchronizuoti saugyklą" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Keisti pagrindinį slaptažodį" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB užšifruotos vietos diske failų prisegimams." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Patentuotos dviejų žingsnių prisijungimo parinktys, tokios kaip YubiKey ir Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Eksportuoti saugyklą" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Failo formatas" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Visi Sendai", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Pagrindinis slaptažodis pašalintas" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Ar jūs tikrai norite naudoti \"Niekada\" pasirinkimą? Nustačius savo užraktą į \"Niekada\", saugyklos šifravimo raktas bus laikomas jūsų įrenginyje. Jei norite naudotis šiuo pasirinkimu, užtikrinkite savo įrenginio saugą." }, "vault": { - "message": "Saugykla" + "message": "Saugykla", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Prisijungti su pagrindiniu slaptažodžiu" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domenas" }, - "importData": { - "message": "Importuoti duomenis", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Importavimo klaida" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index 7800a4e9024..427a6ac2e16 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Pievienot pielikumu" }, + "itemsTransferred": { + "message": "Vienumi pārcelti" + }, + "fixEncryption": { + "message": "Salabot šifrēšanu" + }, + "fixEncryptionTooltip": { + "message": "Šī datne izmanto novecojušu šifrēšanas veidu." + }, + "attachmentUpdated": { + "message": "Pielikums atjaunināts" + }, "maxFileSizeSansPunctuation": { "message": "Lielākais pieļaujamais datnes izmērs ir 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Atgadījās neparedzēta kļūda." }, + "unexpectedErrorShort": { + "message": "Neparedzēta kļūda" + }, + "closeThisBitwardenWindow": { + "message": "Šis Bitwarden logs jāaizver un jāmēģina vēlreiz." + }, "itemInformation": { "message": "Vienuma informācija" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Uzzināt vairāk" }, + "migrationsFailed": { + "message": "Atgadījās kļūda šifrēšanas iestatījumu atjaunināšanā." + }, + "updateEncryptionSettingsTitle": { + "message": "Atjaunini savus šifrēšanas iestatījumus" + }, + "updateEncryptionSettingsDesc": { + "message": "Jaunie ieteicamie šifrēšanas iestatījumi uzlabos Tava konta drošību. Jāievada sava galvenā parole, lai atjauninātu tagad." + }, + "confirmIdentityToContinue": { + "message": "Jāapliecina sava identitāte, lai turpinātu" + }, + "enterYourMasterPassword": { + "message": "Jāievada sava galvenā parole" + }, + "updateSettings": { + "message": "Atjaunināt Iestatījumus" + }, "featureUnavailable": { "message": "Iespēja nav pieejama" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Sekot mums" }, - "syncVault": { - "message": "Sinhronizēt glabātavu" + "syncNow": { + "message": "Sinhronizēt tūlīt" }, "changeMasterPass": { "message": "Mainīt galveno paroli" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB šifrētas krātuves datņu pielikumiem." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ šifrētas krātuves datņu pielikumiem.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Tādas slēgtā pirmavota divpakāpju pieteikšanās iespējas kā YubiKey un Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Izgūt no" }, - "exportVault": { - "message": "Izgūt glabātavas saturu" + "exportNoun": { + "message": "Izgūšana", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Izgūt", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Ievietošana", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Ievietot", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Datnes veids" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Saziņas informācija" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Visi Send", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Galvenā parole tika noņemta." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Galvenā parole vairs nav nepieciešama turpmāk minētās apvienības dalībniekiem. Lūgums saskaņot zemāk esošo domēnu ar savas apvienības pārvaldītāju." - }, "organizationName": { "message": "Apvienības nosaukums" }, @@ -2991,7 +3050,8 @@ "message": "Vai tiešām izmantot uzstādījumu \"Nekad\"? Uzstādot aizslēgšanas iespēju uz \"Nekad\", šifrēšanas atslēga tiek glabāta ierīcē. Ja šī iespēja tiek izmantota, jāpārliecinās, ka ierīce tiek pienācīgi aizsargāta." }, "vault": { - "message": "Glabātava" + "message": "Glabātava", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Pieteikties ar galveno paroli" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Aizstājdomēns" }, - "importData": { - "message": "Ievietot datus", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Ievietošanas kļūda" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Datne saglabāta ierīcē. Tā ir atrodama ierīces lejupielāžu mapē." }, + "importantNotice": { + "message": "Svarīgs paziņojums" + }, + "setupTwoStepLogin": { + "message": "Iestatīt divpakāpju pieteikšanos" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden, sākot ar 2025. gada februāri, nosūtīs kodu uz konta e-pasta adresi, lai apliecinātu pieteikšanos jaunās ierīcēs." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Var iestatīt divpakāpju pieteikšanos kā citu veidu, kā aizsargāt savu kontu, vai iestatīt savu e-pasta adresi uz tādu, kurai ir piekļuve." + }, + "remindMeLater": { + "message": "Atgādināt man vēlāk" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Vai ir uzticama piekļuve savai e-pasta adresei $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nē, nav" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Jā, varu uzticami piekļūt savam e-pastam" + }, + "turnOnTwoStepLogin": { + "message": "Ieslēgt divpakāpju pieteikšanos" + }, + "changeAcctEmail": { + "message": "Mainīt konta e-pasta adresi" + }, + "passkeyLogin": { + "message": "Pieteikties ar piekļuves atslēgu?" + }, + "savePasskeyQuestion": { + "message": "Saglabāt piekļuves atslēgu?" + }, + "saveNewPasskey": { + "message": "Saglabāt kā jaunu pieteikšanās vienumu" + }, + "savePasskeyNewLogin": { + "message": "Saglabāt piekļuves atslēgu kā jaunu pieteikšanās vienumu" + }, + "noMatchingLoginsForSite": { + "message": "Šai vietnei nav atbilstošu pieteikšanās vietnumu" + }, + "overwritePasskey": { + "message": "Pārrakstīt piekļuves atslēgu?" + }, + "unableToSavePasskey": { + "message": "Nevar saglabāt piekļuves atslēgu" + }, + "alreadyContainsPasskey": { + "message": "Šis vienums jau satur piekļuves atslēgu. Vai tiešām pārrakstīt pašreizējo piekļuves atslēgu?" + }, + "passkeyAlreadyExists": { + "message": "Šai lietotnei jau pastāv piekļuves atslēga." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Aizvērt šo logu" + }, "allowScreenshots": { "message": "Atļaut ekrāna tveršanu" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "Un vēl!" }, - "planDescPremium": { - "message": "Pilnīga drošība tiešsaistē" + "advancedOnlineSecurity": { + "message": "Izvērsta tiešsaistes drošība" }, "upgradeToPremium": { "message": "Uzlabot uz Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Apvienība vairs neizmanto galvenās paroles, lai pieteiktos Bitwarden. Lai turpinātu, jāapliecina apvienība un domēns." + }, + "continueWithLogIn": { + "message": "Turpināt ar pieteikšanos" + }, + "doNotContinue": { + "message": "Neturpināt" + }, + "domain": { + "message": "Domēns" + }, + "keyConnectorDomainTooltip": { + "message": "Šajā domēnā tiks glabātas konta šifrēšanas atslēgas, tādēļ jāpārliecinās par uzticamību. Ja nav pārliecības, jāsazinās ar savu pārvaldītāju." + }, + "verifyYourOrganization": { + "message": "Jāapliecina apvienība, lai pieteiktos" + }, + "organizationVerified": { + "message": "Apvienība apliecināta" + }, + "domainVerified": { + "message": "Domēns ir apliecināts" + }, + "leaveOrganizationContent": { + "message": "Ja neapliecināsi apvienību, tiks atsaukta piekļuve tai." + }, + "leaveNow": { + "message": "Pamest tagad" + }, + "verifyYourDomainToLogin": { + "message": "Jāapliecina domēns, lai pieteiktos" + }, + "verifyYourDomainDescription": { + "message": "Lai turpinātu pieteikšanos, jāapliecina šis domēns." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Lai turpinātu pieteikšanos, jāapliecina apvienība un domēns." + }, "sessionTimeoutSettingsAction": { "message": "Noildzes darbība" }, "sessionTimeoutHeader": { "message": "Sesijas noildze" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Šo iestatījumu pārvalda apvienība." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Uzlabot" + }, + "leaveConfirmationDialogTitle": { + "message": "Vai tiešām pamest?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Pēc noraidīšanas personīgie vienumi paliks Tavā kontā, bet Tu zaudēsi piekļvuvi kopīgotajiem vienumiem un apvienību iespējām." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Jāsazinās ar savu pārvaldītāju, lai atgūtu piekļuvi." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Pamest $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Kā es varu pārvaldīt savu glabātavu?" + }, + "transferItemsToOrganizationTitle": { + "message": "Pārcelt vienumus uz $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/me/messages.json b/apps/desktop/src/locales/me/messages.json index 29e3cefee0c..a5a2212b2b1 100644 --- a/apps/desktop/src/locales/me/messages.json +++ b/apps/desktop/src/locales/me/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Došlo je do neočekivane greške." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Informacija o stavki" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Saznaj više" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Funkcija nije dostupna" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Prati nas" }, - "syncVault": { - "message": "Sinhronizacija trezora" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Promjena glavne lozinke" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB šifrovanog skladišta za priloge datoteka." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Izvezi trezor" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format datoteke" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/ml/messages.json b/apps/desktop/src/locales/ml/messages.json index 662ce9a1fc6..d71af9f752a 100644 --- a/apps/desktop/src/locales/ml/messages.json +++ b/apps/desktop/src/locales/ml/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "ഒരു അപ്രതീക്ഷിത പിശക് സംഭവിച്ചു." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "വിവരം" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "കൂടുതൽ അറിയുക" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "സവിശേഷത ലഭ്യമല്ല" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "ഞങ്ങളെ പിന്തുടരുക" }, - "syncVault": { - "message": "വാൾട് സമന്വയിപ്പിക്കുക" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "പ്രാഥമിക പാസ്‌വേഡ് മാറ്റുക" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "ഫയൽ അറ്റാച്ചുമെന്റുകൾക്കായി 1 GB എൻക്രിപ്റ്റുചെയ്‌ത സ്റ്റോറേജ്." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "വാൾട് എക്സ്പോർട്" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "ഫയൽ ഫോർമാറ്റ്" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "എല്ലാം Send-കൾ", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/mr/messages.json b/apps/desktop/src/locales/mr/messages.json index d607bb8d097..2d0019a1f31 100644 --- a/apps/desktop/src/locales/mr/messages.json +++ b/apps/desktop/src/locales/mr/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/my/messages.json b/apps/desktop/src/locales/my/messages.json index bcbd26cede3..12c10bbcd3a 100644 --- a/apps/desktop/src/locales/my/messages.json +++ b/apps/desktop/src/locales/my/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/nb/messages.json b/apps/desktop/src/locales/nb/messages.json index 42fb6d479c0..069250a562a 100644 --- a/apps/desktop/src/locales/nb/messages.json +++ b/apps/desktop/src/locales/nb/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "En uventet feil har oppstått." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Objektsinformasjon" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Lær mer" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Funksjonen er utilgjengelig" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Følg oss" }, - "syncVault": { - "message": "Synkroniser hvelvet" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Endre hovedpassordet" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB med kryptert fillagring." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Eksporter fra" }, - "exportVault": { - "message": "Eksporter hvelvet" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Filformat" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Kontaktinformasjon" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Alle Send-er", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Hovedpassordet er fjernet." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organisasjonens navn" }, @@ -2991,7 +3050,8 @@ "message": "Er du sikker på at du vil bruke alternativet «Aldri»? Ved å angi låsemulighetene til «Aldri» lagres hvelvets krypteringsnøkkel på enheten. Hvis du bruker dette alternativet, bør du sørge for at du holder enheten forsvarlig beskyttet." }, "vault": { - "message": "Hvelv" + "message": "Hvelv", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Logg inn med hovedpassord" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias-domene" }, - "importData": { - "message": "Importer data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Importeringsfeil" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Tillat skjermklipp/-opptak" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/ne/messages.json b/apps/desktop/src/locales/ne/messages.json index cce8f6a2ba5..a37dc2f0b5f 100644 --- a/apps/desktop/src/locales/ne/messages.json +++ b/apps/desktop/src/locales/ne/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json index 82b51b018c5..824bad9508d 100644 --- a/apps/desktop/src/locales/nl/messages.json +++ b/apps/desktop/src/locales/nl/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Bijlage toevoegen" }, + "itemsTransferred": { + "message": "Items overgedragen" + }, + "fixEncryption": { + "message": "Versleuteling repareren" + }, + "fixEncryptionTooltip": { + "message": "Dit bestand gebruikt een verouderde versleutelingsmethode." + }, + "attachmentUpdated": { + "message": "Bijlagen bijgewerkt" + }, "maxFileSizeSansPunctuation": { "message": "Maximale bestandsgrootte is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Er is een onverwachte fout opgetreden." }, + "unexpectedErrorShort": { + "message": "Onverwachte fout" + }, + "closeThisBitwardenWindow": { + "message": "Sluit dit Bitwarden-venster en probeer het opnieuw." + }, "itemInformation": { "message": "Item-informatie" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Meer informatie" }, + "migrationsFailed": { + "message": "Er is een fout opgetreden bij het bijwerken van de versleutelingsinstellingen." + }, + "updateEncryptionSettingsTitle": { + "message": "Je versleutelingsinstellingen bijwerken" + }, + "updateEncryptionSettingsDesc": { + "message": "De nieuwe aanbevolen versleutelingsinstellingen verbeteren de beveiliging van je account. Voer je hoofdwachtwoord in om nu bij te werken." + }, + "confirmIdentityToContinue": { + "message": "Bevestig je identiteit om door te gaan" + }, + "enterYourMasterPassword": { + "message": "Voer je hoofdwachtwoord in" + }, + "updateSettings": { + "message": "Instellingen bijwerken" + }, "featureUnavailable": { "message": "Functionaliteit niet beschikbaar" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Volg ons" }, - "syncVault": { - "message": "Kluis synchroniseren" + "syncNow": { + "message": "Nu synchroniseren" }, "changeMasterPass": { "message": "Hoofdwachtwoord wijzigen" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB versleutelde opslag voor bijlagen." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ versleutelde opslag voor bijlagen.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Eigen opties voor tweestapsaanmelding zoals YubiKey en Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Exporteren vanuit" }, - "exportVault": { - "message": "Kluis exporteren" + "exportNoun": { + "message": "Exporteren", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Exporteren", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Importeren", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importeren", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Bestandsindeling" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact informatie" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Alle Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Hoofdwachtwoord verwijderd." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Voor leden van de volgende organisatie is een hoofdwachtwoord niet langer nodig. Bevestig het domein hieronder met de beheerder van je organisatie." - }, "organizationName": { "message": "Organisatienaam" }, @@ -2991,7 +3050,8 @@ "message": "Weet je zeker dat je de optie \"Nooit\" wilt gebruiken? De vergrendelingsoptie \"Nooit\" bewaart de sleutel van je kluis op je apparaat. Als je deze optie gebruikt, moet je ervoor zorgen dat je je apparaat naar behoren beschermt." }, "vault": { - "message": "Kluis" + "message": "Kluis", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Inloggen met je hoofdwachtwoord" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Aliasdomein" }, - "importData": { - "message": "Data importeren", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Fout bij importeren" }, @@ -3631,7 +3687,7 @@ "message": "Import directly from browser" }, "browserProfile": { - "message": "Browser Profile" + "message": "Browserprofiel" }, "seeDetailedInstructions": { "message": "Zie gedetailleerde instructies op onze helpsite op", @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Bestand op apparaat opgeslagen. Beheer vanaf de downloads op je apparaat." }, + "importantNotice": { + "message": "Belangrijke melding" + }, + "setupTwoStepLogin": { + "message": "Tweestapsaanmelding instellen" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Vanaf februari 2025 stuurt Bitwarden een code naar het e-mailadres van je account om inloggen op nieuwe apparaten te verifiëren." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Je kunt tweestapsaanmelding instellen als een alternatieve manier om je account te beschermen of je e-mailadres te veranderen naar een waar je toegang toe hebt." + }, + "remindMeLater": { + "message": "Herinner me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Heb je betrouwbare toegang tot je e-mail, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nee, dat heb ik niet" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Ja, ik heb betrouwbare toegang tot mijn e-mail" + }, + "turnOnTwoStepLogin": { + "message": "Tweestapsaanmelding inschakelen" + }, + "changeAcctEmail": { + "message": "E-mailadres van het account veranderen" + }, + "passkeyLogin": { + "message": "Inloggen met passkey?" + }, + "savePasskeyQuestion": { + "message": "Passkey opslaan?" + }, + "saveNewPasskey": { + "message": "Opslaan als nieuwe login" + }, + "savePasskeyNewLogin": { + "message": "Passkey als nieuwe login opslaan" + }, + "noMatchingLoginsForSite": { + "message": "Geen overeenkomende logins voor deze site" + }, + "overwritePasskey": { + "message": "Passkey overschrijven?" + }, + "unableToSavePasskey": { + "message": "Kon passkey niet opslaan" + }, + "alreadyContainsPasskey": { + "message": "Dit item heeft al een passkey. Weet je zeker dat je de huidige passkey wilt overschrijven?" + }, + "passkeyAlreadyExists": { + "message": "Er bestaat al een passkey voor deze applicatie." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Deze applicatie ondersteunt geen duplicaten." + }, + "closeThisWindow": { + "message": "Sluit dit venster" + }, "allowScreenshots": { "message": "Schermopname toestaan" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "En meer!" }, - "planDescPremium": { - "message": "Online beveiliging voltooien" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Opwaarderen naar Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Je organisatie maakt niet langer gebruik van hoofdwachtwoorden om in te loggen op Bitwarden. Controleer de organisatie en het domein om door te gaan." + }, + "continueWithLogIn": { + "message": "Doorgaan met inloggen" + }, + "doNotContinue": { + "message": "Niet verder gaan" + }, + "domain": { + "message": "Domein" + }, + "keyConnectorDomainTooltip": { + "message": "Dit domein zal de encryptiesleutels van je account opslaan, dus zorg ervoor dat je het vertrouwt. Als je het niet zeker weet, controleer dan bij je beheerder." + }, + "verifyYourOrganization": { + "message": "Verifieer je organisatie om in te loggen" + }, + "organizationVerified": { + "message": "Organisatie geverifieerd" + }, + "domainVerified": { + "message": "Domein geverifieerd" + }, + "leaveOrganizationContent": { + "message": "Als je je organisatie niet verifieert, wordt je toegang tot de organisatie ingetrokken." + }, + "leaveNow": { + "message": "Nu verlaten" + }, + "verifyYourDomainToLogin": { + "message": "Verifieer je domein om in te loggen" + }, + "verifyYourDomainDescription": { + "message": "Bevestig dit domein om verder te gaan met inloggen." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Bevestig organisatie en domein om verder te gaan met inloggen." + }, "sessionTimeoutSettingsAction": { "message": "Time-out actie" }, "sessionTimeoutHeader": { "message": "Sessietime-out" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Deze instelling wordt beheerd door je organisatie." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Je organisatie heeft de maximale sessietime-out ingesteld op $HOURS$ uur en $MINUTES$ minuten.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Je organisatie heeft de standaard sessietime-out ingesteld op Systeem vergrendelen." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Je organisatie heeft de standaard sessietime-out ingesteld op Herstarten applicatie." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximale time-out kan niet langer zijn dan $HOURS$ uur en $MINUTES$ minu(u)t(en)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Herstarten" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Stel een ontgrendelingsmethode in om je kluis time-out actie te wijzigen" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Weet je zeker dat je wilt verlaten?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Door te weigeren, blijven je persoonlijke items in je account, maar verlies je toegang tot gedeelde items en organisatiefunctionaliteit." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Neem contact op met je beheerder om weer toegang te krijgen." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "$ORGANIZATION$ verlaten", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Hoe beheer ik mijn kluis?" + }, + "transferItemsToOrganizationTitle": { + "message": "Items overdragen aan $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ vereist dat alle items eigendom zijn van de organisatie voor veiligheid en naleving. Klik op accepteren voor het overdragen van eigendom van je items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Overdacht accepteren" + }, + "declineAndLeave": { + "message": "Weigeren en verlaten" + }, + "whyAmISeeingThis": { + "message": "Waarom zie ik dit?" } } diff --git a/apps/desktop/src/locales/nn/messages.json b/apps/desktop/src/locales/nn/messages.json index 08567979e8b..3fc7075911c 100644 --- a/apps/desktop/src/locales/nn/messages.json +++ b/apps/desktop/src/locales/nn/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Det har oppstått ein feil." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Elementinformasjon" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Lær meir" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Funksjon er utilgjengeleg" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Følg oss" }, - "syncVault": { - "message": "Synkroniser kvelven" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Endre hovudpassord" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Filformat" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Alle Send-ar", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/or/messages.json b/apps/desktop/src/locales/or/messages.json index 4ca05acaac5..2307e43adab 100644 --- a/apps/desktop/src/locales/or/messages.json +++ b/apps/desktop/src/locales/or/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index c05e7f05cb1..1724a713a30 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Dodaj załącznik" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maksymalny rozmiar pliku to 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Wystąpił nieoczekiwany błąd." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Informacje o elemencie" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Dowiedz się więcej" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Funkcja jest niedostępna" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Obserwuj nas" }, - "syncVault": { - "message": "Synchronizuj sejf" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Zmień hasło główne" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB miejsca na zaszyfrowane załączniki." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Specjalne opcje logowania dwustopniowego, takie jak YubiKey i Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Eksportuj z" }, - "exportVault": { - "message": "Eksportuj sejf" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format pliku" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Informacje kontaktowe" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Wszystkie wysyłki", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Hasło główne zostało usunięte" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Hasło główne nie jest już wymagane dla członków następującej organizacji. Potwierdź poniższą domenę z administratorem organizacji." - }, "organizationName": { "message": "Nazwa organizacji" }, @@ -2991,7 +3050,8 @@ "message": "Czy na pewno chcesz użyć opcji „Nigdy”? Ustawienie blokady na „Nigdy” spowoduje przechowywanie klucza szyfrowania sejfu na urządzeniu. Upewnij się, że urządzenie jest odpowiednio chronione." }, "vault": { - "message": "Sejf" + "message": "Sejf", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Logowanie hasłem głównym" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Domena aliasu" }, - "importData": { - "message": "Importuj dane", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Błąd importowania" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Plik zapisany na urządzeniu. Zarządzaj plikiem na swoim urządzeniu." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Zezwalaj na wykonywanie zrzutów ekranu" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/pt_BR/messages.json b/apps/desktop/src/locales/pt_BR/messages.json index e351bfb7dba..2246233a560 100644 --- a/apps/desktop/src/locales/pt_BR/messages.json +++ b/apps/desktop/src/locales/pt_BR/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Adicionar anexo" }, + "itemsTransferred": { + "message": "Itens transferidos" + }, + "fixEncryption": { + "message": "Corrigir criptografia" + }, + "fixEncryptionTooltip": { + "message": "Este arquivo está usando um método de criptografia desatualizado." + }, + "attachmentUpdated": { + "message": "Anexo atualizado" + }, "maxFileSizeSansPunctuation": { "message": "O tamanho máximo do arquivo é de 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Ocorreu um erro inesperado." }, + "unexpectedErrorShort": { + "message": "Erro inesperado" + }, + "closeThisBitwardenWindow": { + "message": "Feche esta janela do Bitwarden e tente novamente." + }, "itemInformation": { "message": "Informações do item" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Saiba mais" }, + "migrationsFailed": { + "message": "Ocorreu um erro ao atualizar as configurações de criptografia." + }, + "updateEncryptionSettingsTitle": { + "message": "Atualize suas configurações de criptografia" + }, + "updateEncryptionSettingsDesc": { + "message": "As novas configurações de criptografia recomendadas melhorarão a segurança da sua conta. Digite sua senha principal para atualizar agora." + }, + "confirmIdentityToContinue": { + "message": "Confirme sua identidade para continuar" + }, + "enterYourMasterPassword": { + "message": "Digite sua senha principal" + }, + "updateSettings": { + "message": "Atualizar configurações" + }, "featureUnavailable": { "message": "Recurso indisponível" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Siga-nos" }, - "syncVault": { - "message": "Sincronizar cofre" + "syncNow": { + "message": "Sincronizar agora" }, "changeMasterPass": { "message": "Alterar senha principal" @@ -1247,19 +1283,19 @@ "message": "Autenticação em duas etapas" }, "vaultTimeoutHeader": { - "message": "Tempo limite do cofre" + "message": "Limite de tempo do cofre" }, "vaultTimeout": { - "message": "Tempo limite do cofre" + "message": "Limite de tempo do cofre" }, "vaultTimeout1": { - "message": "Tempo limite" + "message": "Limite de tempo" }, "vaultTimeoutAction1": { - "message": "Ação do tempo limite" + "message": "Ação do limite de tempo" }, "vaultTimeoutDesc": { - "message": "Escolha quando o seu cofre executará a ação do tempo limite do cofre." + "message": "Escolha quando o seu cofre executará a ação do limite de tempo do cofre." }, "immediately": { "message": "Imediatamente" @@ -1490,11 +1526,20 @@ "premiumSignUpStorage": { "message": "1 GB de armazenamento criptografado para anexos de arquivos." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ de armazenamento criptografado para anexos de arquivo.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Opções proprietárias de autenticação em duas etapas como YubiKey e Duo." }, "premiumSignUpReports": { - "message": "Higiene de senha, saúde da conta, e relatórios de brechas de dados para manter o seu cofre seguro." + "message": "Relatórios de higiene de senha, saúde da conta, e vazamentos de dados para manter o seu cofre seguro." }, "premiumSignUpTotp": { "message": "Gerador de códigos de verificação TOTP (2FA) para credenciais no seu cofre." @@ -1650,7 +1695,7 @@ "message": "Confira se a senha foi exposta." }, "passwordExposed": { - "message": "Esta senha foi exposta $VALUE$ vez(es) em brechas de dados. Você deve alterá-la.", + "message": "Esta senha foi exposta $VALUE$ vez(es) em vazamentos de dados. Você deve alterá-la.", "placeholders": { "value": { "content": "$1", @@ -1659,7 +1704,7 @@ } }, "passwordSafe": { - "message": "Esta senha não foi encontrada em brechas de dados conhecidas. Deve ser segura de usar." + "message": "Esta senha não foi encontrada em vazamentos de dados conhecidos. Deve ser segura de usar." }, "baseDomain": { "message": "Domínio de base", @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Exportar de" }, - "exportVault": { - "message": "Exportar cofre" + "exportNoun": { + "message": "Exportação", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Exportar", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Importação", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importar", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formato do arquivo" @@ -1780,7 +1838,7 @@ "message": "Confirmar exportação do cofre" }, "exportWarningDesc": { - "message": "Esta exportação contém os dados do seu cofre em um formato não criptografado. Você não deve armazenar ou enviar o arquivo exportado por canais inseguros (como e-mail). Apague o arquivo imediatamente após terminar de usá-lo." + "message": "Esta exportação contém os dados do seu cofre em um formato sem criptografia. Você não deve armazenar ou enviar o arquivo exportado por canais inseguros (como e-mail). Apague o arquivo imediatamente após terminar de usá-lo." }, "encExportKeyWarningDesc": { "message": "Esta exportação criptografa seus dados usando a chave de criptografia da sua conta. Se você rotacionar a chave de criptografia da sua conta, você deve exportar novamente, já que você não será capaz de descriptografar este arquivo de exportação." @@ -1935,7 +1993,7 @@ "message": "Uma ou mais políticas da organização estão afetando as configurações do seu gerador." }, "vaultTimeoutAction": { - "message": "Ação do tempo limite do cofre" + "message": "Ação do limite de tempo do cofre" }, "vaultTimeoutActionLockDesc": { "message": "A senha principal ou outro método de desbloqueio é necessário para acessar seu cofre novamente." @@ -1944,7 +2002,7 @@ "message": "Reautenticação é necessária para acessar seu cofre novamente." }, "unlockMethodNeededToChangeTimeoutActionDesc": { - "message": "Configure um método de desbloqueio para alterar a ação do tempo limite do cofre." + "message": "Configure um método de desbloqueio para alterar a ação do limite de tempo do cofre." }, "lock": { "message": "Bloquear", @@ -1973,10 +2031,10 @@ "message": "Apagar para sempre" }, "vaultTimeoutLogOutConfirmation": { - "message": "Ao desconectar-se, todo o seu acesso ao cofre será removido e será necessário autenticação on-line após o período do tempo limite. Tem certeza que quer usar esta configuração?" + "message": "Ao desconectar-se, todo o seu acesso ao cofre será removido e será necessário autenticação on-line após o período do limite de tempo. Tem certeza que quer usar esta configuração?" }, "vaultTimeoutLogOutConfirmationTitle": { - "message": "Confirmação de ação do tempo limite" + "message": "Confirmação de ação do limite de tempo" }, "enterpriseSingleSignOn": { "message": "Autenticação única empresarial" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Informações de contato" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Todos os Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2504,7 +2566,7 @@ } }, "vaultTimeoutPolicyWithActionInEffect": { - "message": "As políticas da sua organização estão afetando o tempo limite do seu cofre. O máximo permitido do tempo limite do cofre é $HOURS$ hora(s) e $MINUTES$ minuto(s). A ação de tempo limite do seu cofre está configurada para $ACTION$.", + "message": "As políticas da sua organização estão afetando o limite de tempo do seu cofre. O máximo permitido do limite de tempo do cofre é $HOURS$ hora(s) e $MINUTES$ minuto(s). A ação de limite de tempo do seu cofre está configurada para $ACTION$.", "placeholders": { "hours": { "content": "$1", @@ -2521,7 +2583,7 @@ } }, "vaultTimeoutActionPolicyInEffect": { - "message": "As políticas da sua organização configuraram a ação do tempo limite do seu cofre para $ACTION$.", + "message": "As políticas da sua organização configuraram a ação do limite de tempo do seu cofre para $ACTION$.", "placeholders": { "action": { "content": "$1", @@ -2530,13 +2592,13 @@ } }, "vaultTimeoutTooLarge": { - "message": "O tempo limite do seu cofre excede as restrições definidas por sua organização." + "message": "O limite de tempo do seu cofre excede as restrições definidas por sua organização." }, "vaultTimeoutPolicyAffectingOptions": { - "message": "Os requisitos das políticas corporativas foram aplicados às suas opções de tempo limite" + "message": "Os requisitos das políticas corporativas foram aplicados às suas opções de limite de tempo" }, "vaultTimeoutPolicyInEffect": { - "message": "As políticas da sua organização configuraram o seu máximo permitido do tempo limite do cofre para $HOURS$ hora(s) e $MINUTES$ minuto(s).", + "message": "As políticas da sua organização configuraram o seu máximo permitido do limite de tempo do cofre para $HOURS$ hora(s) e $MINUTES$ minuto(s).", "placeholders": { "hours": { "content": "$1", @@ -2549,7 +2611,7 @@ } }, "vaultTimeoutPolicyMaximumError": { - "message": "O tempo limite excede a restrição definida pela sua organização: máximo de $HOURS$ hora(s) e $MINUTES$ minuto(s)", + "message": "O limite de tempo excede a restrição definida pela sua organização: máximo de $HOURS$ hora(s) e $MINUTES$ minuto(s)", "placeholders": { "hours": { "content": "$1", @@ -2562,7 +2624,7 @@ } }, "vaultCustomTimeoutMinimum": { - "message": "O mínimo do tempo limite personalizado é de 1 minuto." + "message": "O mínimo do limite de tempo personalizado é de 1 minuto." }, "inviteAccepted": { "message": "Convite aceito" @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Senha principal removida" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Uma senha principal não é mais necessária para membros da seguinte organização. Confirme o domínio abaixo com o administrador da sua organização." - }, "organizationName": { "message": "Nome da organização" }, @@ -2991,7 +3050,8 @@ "message": "Você tem certeza que deseja usar a opção \"Nunca\"? Ao usar o \"Nunca\", a chave de criptografia do seu cofre é armazenada no seu dispositivo. Se você usar esta opção, deve garantir que mantém seu dispositivo devidamente protegido." }, "vault": { - "message": "Cofre" + "message": "Cofre", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Conectar-se com senha principal" @@ -3073,7 +3133,7 @@ } }, "loginRequestApprovedForEmailOnDevice": { - "message": "Solicitação de autenticação aprovada para $EMAIL$ em $DEVICE$", + "message": "Solicitação de acesso aprovada para $EMAIL$ em $DEVICE$", "placeholders": { "email": { "content": "$1", @@ -3086,7 +3146,7 @@ } }, "youDeniedLoginAttemptFromAnotherDevice": { - "message": "Você negou uma tentativa de autenticação por outro dispositivo. Se foi você, tente conectar-se com o dispositivo novamente." + "message": "Você negou uma tentativa de acesso de outro dispositivo. Se era você, tente se conectar com o dispositivo novamente." }, "webApp": { "message": "Aplicativo web" @@ -3114,7 +3174,7 @@ "message": "Servidor" }, "loginRequest": { - "message": "Solicitação de autenticação" + "message": "Solicitação de acesso" }, "deviceType": { "message": "Tipo do dispositivo" @@ -3198,7 +3258,7 @@ "message": "Senha fraca identificada e encontrada em um vazamento de dados. Use uma senha forte e única para proteger a sua conta. Tem certeza de que deseja usar essa senha?" }, "checkForBreaches": { - "message": "Conferir vazamentos de dados conhecidos por esta senha" + "message": "Conferir se esta senha vazou ao público" }, "loggedInExclamation": { "message": "Conectado!" @@ -3292,7 +3352,7 @@ "message": "Problemas para acessar?" }, "loginApproved": { - "message": "Autenticação aprovada" + "message": "Acesso aprovado" }, "userEmailMissing": { "message": "E-mail do usuário ausente" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Domínio de alias" }, - "importData": { - "message": "Importar dados", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Erro ao importar" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Arquivo salvo no dispositivo. Gerencie a partir das transferências do seu dispositivo." }, + "importantNotice": { + "message": "Aviso importante" + }, + "setupTwoStepLogin": { + "message": "Configurar autenticação em duas etapas" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "O Bitwarden enviará um código no e-mail da sua conta para verificar o acesso de novos dispositivos começando em fevereiro de 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Você pode configurar a autenticação em duas etapas como um método alternativo de proteção da sua conta, ou você pode alterar o seu e-mail para um que possa acessar." + }, + "remindMeLater": { + "message": "Lembre-me depois" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Você tem acesso adequado ao seu e-mail, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Não tenho" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Sim, consigo acessar meu e-mail adequadamente" + }, + "turnOnTwoStepLogin": { + "message": "Ativar autenticação em duas etapas" + }, + "changeAcctEmail": { + "message": "Alterar e-mail da conta" + }, + "passkeyLogin": { + "message": "Conectar-se com chave de acesso?" + }, + "savePasskeyQuestion": { + "message": "Salvar chave de acesso?" + }, + "saveNewPasskey": { + "message": "Salvar como nova credencial" + }, + "savePasskeyNewLogin": { + "message": "Salvar chave de acesso como nova credencial" + }, + "noMatchingLoginsForSite": { + "message": "Nenhuma credencial correspondente para este site" + }, + "overwritePasskey": { + "message": "Substituir chave de acesso?" + }, + "unableToSavePasskey": { + "message": "Não é possível salvar a chave de acesso" + }, + "alreadyContainsPasskey": { + "message": "Este item já contém uma chave de acesso. Tem certeza que deseja substituir a atual?" + }, + "passkeyAlreadyExists": { + "message": "Uma chave de acesso já existe para este aplicativo." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Este aplicativo não suporta duplicatas." + }, + "closeThisWindow": { + "message": "Fechar esta janela" + }, "allowScreenshots": { "message": "Permitir captura de tela" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "E mais!" }, - "planDescPremium": { - "message": "Segurança on-line completa" + "advancedOnlineSecurity": { + "message": "Segurança on-line avançada" }, "upgradeToPremium": { "message": "Faça upgrade para o Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "A sua organização não está mais usando senhas principais para se conectar ao Bitwarden. Para continuar, verifique a organização e o domínio." + }, + "continueWithLogIn": { + "message": "Continuar acessando" + }, + "doNotContinue": { + "message": "Não continuar" + }, + "domain": { + "message": "Domínio" + }, + "keyConnectorDomainTooltip": { + "message": "Este domínio armazenará as chaves de criptografia da sua conta, então certifique-se que confia nele. Se não tiver certeza, verifique com o seu administrador." + }, + "verifyYourOrganization": { + "message": "Verifique sua organização para se conectar" + }, + "organizationVerified": { + "message": "Organização verificada" + }, + "domainVerified": { + "message": "Domínio verificado" + }, + "leaveOrganizationContent": { + "message": "Se você não verificar a sua organização, o seu acesso à organização será revogado." + }, + "leaveNow": { + "message": "Sair agora" + }, + "verifyYourDomainToLogin": { + "message": "Verifique seu domínio para se conectar" + }, + "verifyYourDomainDescription": { + "message": "Para continuar se conectando, verifique este domínio." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Para continuar se conectando, verifique a organização e o domínio." + }, "sessionTimeoutSettingsAction": { - "message": "Ação do tempo limite" + "message": "Ação do limite de tempo" }, "sessionTimeoutHeader": { - "message": "Tempo limite da sessão" + "message": "Limite de tempo da sessão" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Esta configuração é gerenciada pela sua organização." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "A sua organização configurou o limite de tempo máximo da sessão para $HOURS$ hora(s) e $MINUTES$ minuto(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "A sua organização configurou o limite de tempo padrão da sessão para ser no bloqueio do sistema." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "A sua organização configurou o limite de tempo padrão da sessão para ser no reinício." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "O limite de tempo máximo não pode exceder $HOURS$ hora(s) e $MINUTES$ minuto(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "No reinício" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Configure um método de desbloqueio para alterar a ação do limite de tempo" + }, + "upgrade": { + "message": "Fazer upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Tem certeza de que quer sair?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Se recusar, seus itens pessoais continuarão na sua conta, mas você perderá o acesso aos itens compartilhados e os recursos de organização." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Entre em contato com o seu administrador para recuperar o acesso." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Sair de $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Como gerencio meu cofre?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transferir itens para $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ exige que todos os itens sejam propriedade da organização por segurança e conformidade. Clique em aceitar para transferir a propriedade dos seus itens.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Aceitar transferência" + }, + "declineAndLeave": { + "message": "Recusar e sair" + }, + "whyAmISeeingThis": { + "message": "Por que estou vendo isso?" } } diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json index de0427ddab0..d0e216df217 100644 --- a/apps/desktop/src/locales/pt_PT/messages.json +++ b/apps/desktop/src/locales/pt_PT/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Adicionar anexo" }, + "itemsTransferred": { + "message": "Itens transferidos" + }, + "fixEncryption": { + "message": "Corrigir encriptação" + }, + "fixEncryptionTooltip": { + "message": "Este ficheiro está a utilizar um método de encriptação desatualizado." + }, + "attachmentUpdated": { + "message": "Anexo atualizado" + }, "maxFileSizeSansPunctuation": { "message": "O tamanho máximo do ficheiro é de 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Ocorreu um erro inesperado." }, + "unexpectedErrorShort": { + "message": "Erro inesperado" + }, + "closeThisBitwardenWindow": { + "message": "Feche esta janela do Bitwarden e tente novamente." + }, "itemInformation": { "message": "Informações do item" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Saber mais" }, + "migrationsFailed": { + "message": "Ocorreu um erro ao atualizar as definições de encriptação." + }, + "updateEncryptionSettingsTitle": { + "message": "Atualize as suas definições de encriptação" + }, + "updateEncryptionSettingsDesc": { + "message": "As novas definições de encriptação recomendadas irão melhorar a segurança da sua conta. Introduza a sua palavra-passe mestra para atualizar agora." + }, + "confirmIdentityToContinue": { + "message": "Confirme a sua identidade para continuar" + }, + "enterYourMasterPassword": { + "message": "Introduza a sua palavra-passe mestra" + }, + "updateSettings": { + "message": "Atualizar definições" + }, "featureUnavailable": { "message": "Funcionalidade indisponível" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Siga-nos" }, - "syncVault": { - "message": "Sincronizar cofre" + "syncNow": { + "message": "Sincronizar agora" }, "changeMasterPass": { "message": "Alterar palavra-passe mestra" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB de armazenamento encriptado para anexos de ficheiros." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ de armazenamento encriptado para anexos de ficheiros.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Opções proprietárias de verificação de dois passos, como YubiKey e Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Exportar de" }, - "exportVault": { - "message": "Exportar cofre" + "exportNoun": { + "message": "Exportação", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Exportar", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Importação", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importar", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formato do ficheiro" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Informações de contacto" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Todos os Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Palavra-passe mestra removida" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Já não é necessária uma palavra-passe mestra para os membros da seguinte organização. Por favor, confirme o domínio abaixo com o administrador da sua organização." - }, "organizationName": { "message": "Nome da organização" }, @@ -2991,7 +3050,8 @@ "message": "Tem a certeza de que deseja utilizar a opção \"Nunca\"? Ao definir as opções de bloqueio para \"Nunca\" armazena a chave de encriptação do seu cofre no seu dispositivo. Se utilizar esta opção deve assegurar-se de que mantém o seu dispositivo devidamente protegido." }, "vault": { - "message": "Cofre" + "message": "Cofre", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Iniciar sessão com a palavra-passe mestra" @@ -3048,7 +3108,7 @@ "message": "Será notificado quando o pedido for aprovado" }, "needAnotherOption": { - "message": "O início de sessão com o dispositivo deve ser ativado nas definições da aplicação Bitwarden. Precisa de outra opção?" + "message": "O início de sessão com o dispositivo deve ser ativado nas definições da app Bitwarden. Precisa de outra opção?" }, "viewAllLogInOptions": { "message": "Ver todas as opções de início de sessão" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias de domínio" }, - "importData": { - "message": "Importar dados", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Erro de importação" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Ficheiro guardado no dispositivo. Faça a gestão a partir das transferências do seu dispositivo." }, + "importantNotice": { + "message": "Aviso importante" + }, + "setupTwoStepLogin": { + "message": "Definir a verificação de dois passos" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "O Bitwarden enviará um código para o e-mail da sua conta para verificar as credenciais de novos dispositivos a partir de fevereiro de 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Pode configurar a verificação de dois passos como forma alternativa de proteger a sua conta ou alterar o seu e-mail para um a que possa aceder." + }, + "remindMeLater": { + "message": "Lembrar-me mais tarde" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Tem um acesso fiável ao seu e-mail, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Não, não tenho" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Sim, consigo aceder de forma fiável ao meu e-mail" + }, + "turnOnTwoStepLogin": { + "message": "Ativar a verificação de dois passos" + }, + "changeAcctEmail": { + "message": "Alterar o e-mail da conta" + }, + "passkeyLogin": { + "message": "Iniciar sessão com a chave de acesso?" + }, + "savePasskeyQuestion": { + "message": "Guardar a chave de acesso?" + }, + "saveNewPasskey": { + "message": "Guardar como nova credencial" + }, + "savePasskeyNewLogin": { + "message": "Guarde a chave de acesso como uma nova credencial" + }, + "noMatchingLoginsForSite": { + "message": "Sem credenciais correspondentes para este site" + }, + "overwritePasskey": { + "message": "Substituir chave de acesso?" + }, + "unableToSavePasskey": { + "message": "Não é possível guardar a chave de acesso" + }, + "alreadyContainsPasskey": { + "message": "Este item já contém uma chave de acesso. Tem a certeza de que pretende substituir a chave de acesso atual?" + }, + "passkeyAlreadyExists": { + "message": "Já existe uma chave de acesso para esta aplicação." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Esta aplicação não suporta duplicados." + }, + "closeThisWindow": { + "message": "Fechar esta janela" + }, "allowScreenshots": { "message": "Permitir a captura de ecrã" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "E muito mais!" }, - "planDescPremium": { - "message": "Segurança total online" + "advancedOnlineSecurity": { + "message": "Segurança online avançada" }, "upgradeToPremium": { "message": "Atualizar para o Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "A sua organização já não utiliza palavras-passe mestras para iniciar sessão no Bitwarden. Para continuar, verifique a organização e o domínio." + }, + "continueWithLogIn": { + "message": "Continuar com o início de sessão" + }, + "doNotContinue": { + "message": "Não continuar" + }, + "domain": { + "message": "Domínio" + }, + "keyConnectorDomainTooltip": { + "message": "Este domínio armazenará as chaves de encriptação da sua conta, portanto certifique-se de que confia nele. Se não tiver a certeza, verifique com o seu administrador." + }, + "verifyYourOrganization": { + "message": "Verifique a sua organização para iniciar sessão" + }, + "organizationVerified": { + "message": "Organização verificada" + }, + "domainVerified": { + "message": "Domínio verificado" + }, + "leaveOrganizationContent": { + "message": "Se não verificar a sua organização, o seu acesso à organização será revogado." + }, + "leaveNow": { + "message": "Sair agora" + }, + "verifyYourDomainToLogin": { + "message": "Verifique o seu domínio para iniciar sessão" + }, + "verifyYourDomainDescription": { + "message": "Para continuar com o início de sessão, verifique este domínio." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Para continuar com o início de sessão, verifique a organização e o domínio." + }, "sessionTimeoutSettingsAction": { "message": "Ação de tempo limite" }, "sessionTimeoutHeader": { "message": "Tempo limite da sessão" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Esta configuração é gerida pela sua organização." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "A sua organização definiu o tempo limite máximo da sessão para $HOURS$ hora(s) e $MINUTES$ minuto(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "A sua organização definiu o tempo limite de sessão predefinido para Ao bloquear o sistema." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "A sua organização definiu o tempo limite predefinido da sessão para Ao reiniciar a app." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "O tempo limite máximo não pode ser superior a $HOURS$ hora(s) e $MINUTES$ minuto(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Ao reiniciar" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Configure um método de desbloqueio para alterar a sua ação de tempo limite" + }, + "upgrade": { + "message": "Atualizar" + }, + "leaveConfirmationDialogTitle": { + "message": "Tem a certeza de que pretende sair?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Ao recusar, os seus itens pessoais permanecerão na sua conta, mas perderá o acesso aos itens partilhados e às funcionalidades da organização." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Entre em contacto com o seu administrador para recuperar o acesso." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Sair de $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Como posso gerir o meu cofre?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transferir itens para $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ exige que todos os itens sejam propriedade da organização por motivos de segurança e conformidade. Clique em Aceitar para transferir a propriedade dos seus itens.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Aceitar transferência" + }, + "declineAndLeave": { + "message": "Recusar e sair" + }, + "whyAmISeeingThis": { + "message": "Porque é que estou a ver isto?" } } diff --git a/apps/desktop/src/locales/ro/messages.json b/apps/desktop/src/locales/ro/messages.json index a72ce3547e9..173cf6f5f5b 100644 --- a/apps/desktop/src/locales/ro/messages.json +++ b/apps/desktop/src/locales/ro/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "A survenit o eroare neașteptată." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Informații despre articol" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Aflați mai multe" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Funcție indisponibilă" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Urmăriți-ne" }, - "syncVault": { - "message": "Sincronizare seif" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Schimbare parolă principală" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB spațiu de stocare criptat pentru atașamente de fișiere." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export de seif" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format de fișier" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Toate Send-urile", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Parola principală înlăturată" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Sunteți sigur că doriți să folosiți opțiunea „Niciodată”? Setarea opțiunilor de blocare la „Niciodată” stochează cheia de criptare a seifului pe dispozitivul dumneavoastră. Dacă utilizați această opțiune, trebuie să vă asigurați că vă păstrați dispozitivul protejat corespunzător." }, "vault": { - "message": "Seif" + "message": "Seif", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Autentificați-vă cu parola principală" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json index 914bb603630..c0a838d86e2 100644 --- a/apps/desktop/src/locales/ru/messages.json +++ b/apps/desktop/src/locales/ru/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Добавить вложение" }, + "itemsTransferred": { + "message": "Элементы переданы" + }, + "fixEncryption": { + "message": "Исправить шифрование" + }, + "fixEncryptionTooltip": { + "message": "Этот файл использует устаревший метод шифрования." + }, + "attachmentUpdated": { + "message": "Вложение обновлено" + }, "maxFileSizeSansPunctuation": { "message": "Максимальный размер файла 500 МБ" }, @@ -775,7 +787,7 @@ "message": "Использовать единый вход" }, "yourOrganizationRequiresSingleSignOn": { - "message": "Your organization requires single sign-on." + "message": "Ваша организация требует единого входа." }, "submit": { "message": "Отправить" @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Произошла непредвиденная ошибка." }, + "unexpectedErrorShort": { + "message": "Неожиданная ошибка" + }, + "closeThisBitwardenWindow": { + "message": "Закройте это окно Bitwarden и повторите попытку." + }, "itemInformation": { "message": "Информация об элементе" }, @@ -1051,7 +1069,7 @@ "message": "Тайм-аут аутентификации" }, "authenticationSessionTimedOut": { - "message": "Сеанс аутентификации завершился по времени. Пожалуйста, перезапустите процесс авторизации." + "message": "Сессия аутентификации завершилась по времени. Пожалуйста, перезапустите процесс авторизации." }, "selfHostBaseUrl": { "message": "URL собственного сервера", @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Подробнее" }, + "migrationsFailed": { + "message": "Произошла ошибка при обновлении настроек шифрования." + }, + "updateEncryptionSettingsTitle": { + "message": "Обновите настройки шифрования" + }, + "updateEncryptionSettingsDesc": { + "message": "Новые рекомендуемые настройки шифрования повысят безопасность вашего аккаунта. Введите мастер-пароль, чтобы обновить сейчас." + }, + "confirmIdentityToContinue": { + "message": "Подтвердите вашу личность, чтобы продолжить" + }, + "enterYourMasterPassword": { + "message": "Введите ваш мастер-пароль" + }, + "updateSettings": { + "message": "Обновить настройки" + }, "featureUnavailable": { "message": "Функция недоступна" }, @@ -1103,7 +1139,7 @@ "message": "Вы вышли из своего аккаунта." }, "loginExpired": { - "message": "Истек срок действия вашего сеанса." + "message": "Истек срок действия вашей сессии." }, "restartRegistration": { "message": "Перезапустить регистрацию" @@ -1162,8 +1198,8 @@ "followUs": { "message": "Подписывайтесь на нас" }, - "syncVault": { - "message": "Синхронизировать хранилище" + "syncNow": { + "message": "Синхронизировать" }, "changeMasterPass": { "message": "Изменить мастер-пароль" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 ГБ зашифрованного хранилища для вложенных файлов." }, + "premiumSignUpStorageV2": { + "message": "Зашифрованного хранилища для вложенных файлов: $SIZE$", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Проприетарные варианты двухэтапной аутентификации, такие как YubiKey или Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Экспорт из" }, - "exportVault": { - "message": "Экспорт хранилища" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Формат файла" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Контактная информация" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Все Send’ы", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2431,10 +2493,10 @@ "message": "Обновить мастер-пароль" }, "updateMasterPasswordWarning": { - "message": "Мастер-пароль недавно был изменен администратором вашей организации. Чтобы получить доступ к хранилищу, вы должны обновить его сейчас. В результате текущий сеанс будет завершен, потребуется повторный вход. Сеансы на других устройствах могут оставаться активными в течение одного часа." + "message": "Мастер-пароль недавно был изменен администратором вашей организации. Чтобы получить доступ к хранилищу, вы должны обновить его сейчас. В результате текущая сессия будет завершена, потребуется повторный вход. Сессии на других устройствах могут оставаться активными в течение одного часа." }, "updateWeakMasterPasswordWarning": { - "message": "Ваш мастер-пароль не соответствует требованиям политики вашей организации. Для доступа к хранилищу вы должны обновить свой мастер-пароль прямо сейчас. При этом текущий сеанс будет завершен и потребуется повторная авторизация. Сеансы на других устройствах могут оставаться активными в течение часа." + "message": "Ваш мастер-пароль не соответствует требованиям политики вашей организации. Для доступа к хранилищу вы должны обновить свой мастер-пароль прямо сейчас. При этом текущая сессия будет завершена и потребуется повторная авторизация. Сессии на других устройствах могут оставаться активными в течение часа." }, "changePasswordWarning": { "message": "После смены пароля потребуется авторизоваться с новым паролем. Активные сессии на других устройствах будут завершены в течение одного часа." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Мастер-пароль удален." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Мастер-пароль больше не требуется для членов следующей организации. Пожалуйста, подтвердите указанный ниже домен у администратора вашей организации." - }, "organizationName": { "message": "Название организации" }, @@ -2643,7 +2702,7 @@ "message": "Опции" }, "sessionTimeout": { - "message": "Время вашего сеанса истекло. Пожалуйста, вернитесь и попробуйте войти снова." + "message": "Время вашей сессии истекло. Пожалуйста, вернитесь и попробуйте войти снова." }, "exportingPersonalVaultTitle": { "message": "Экспорт личного хранилища" @@ -2991,7 +3050,8 @@ "message": "Вы действительно хотите отключить блокировку хранилища? В этом случае ключ шифрования вашего хранилища будет сохранен на вашем устройстве. Отключая блокировку, вы должны убедиться, что ваше устройство надежно защищено." }, "vault": { - "message": "Хранилище" + "message": "Хранилище", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Войти с мастер-паролем" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Псевдоним домена" }, - "importData": { - "message": "Импорт данных", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Ошибка импорта" }, @@ -3854,11 +3910,80 @@ "fileSavedToDevice": { "message": "Файл сохранен на устройстве. Управляйте им из загрузок устройства." }, + "importantNotice": { + "message": "Важное уведомление" + }, + "setupTwoStepLogin": { + "message": "Настроить двухэтапную аутентификацию" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Начиная с февраля 2025 года Bitwarden будет отправлять код на электронную почту вашего аккаунта для подтверждения авторизации с новых устройств." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "В качестве альтернативного способа защиты учетной записи вы можете настроить двухэтапную аутентификацию или сменить электронную почту на ту, к которой вы можете получить доступ." + }, + "remindMeLater": { + "message": "Напомнить позже" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Есть ли у вас надежный доступ к электронной почте $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Нет, не знаю" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Да, я имею надежный доступ к своей электронной почте" + }, + "turnOnTwoStepLogin": { + "message": "Включить двухэтапную аутентификацию" + }, + "changeAcctEmail": { + "message": "Изменить email аккаунта" + }, + "passkeyLogin": { + "message": "Войти с passkey?" + }, + "savePasskeyQuestion": { + "message": "Сохранить passkey?" + }, + "saveNewPasskey": { + "message": "Сохранить как новый логин" + }, + "savePasskeyNewLogin": { + "message": "Сохранить passkey как новый логин" + }, + "noMatchingLoginsForSite": { + "message": "Нет подходящих логинов для этого сайта" + }, + "overwritePasskey": { + "message": "Перезаписать passkey?" + }, + "unableToSavePasskey": { + "message": "Не удалось сохранить passkey" + }, + "alreadyContainsPasskey": { + "message": "Этот элемент уже содержит passkey. Вы уверены, что хотите перезаписать текущий passkey?" + }, + "passkeyAlreadyExists": { + "message": "Для данного приложения уже существует passkey." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Это приложение не поддерживает дубликаты." + }, + "closeThisWindow": { + "message": "Закрыть это окно" + }, "allowScreenshots": { "message": "Разрешить захват экрана" }, "allowScreenshotsDesc": { - "message": "Разрешить приложению Bitwarden захват экрана для скриншотов и просмотра в сеансах удаленного рабочего стола. Отключение параметра запретит доступ на некоторых внешних дисплеях." + "message": "Разрешить приложению Bitwarden захват экрана для скриншотов и просмотра в сессиях удаленного рабочего стола. Отключение параметра запретит доступ на некоторых внешних дисплеях." }, "confirmWindowStillVisibleTitle": { "message": "Окно подтверждения остается видимым" @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "И многое другое!" }, - "planDescPremium": { - "message": "Полная онлайн-защищенность" + "advancedOnlineSecurity": { + "message": "Расширенная онлайн-безопасность" }, "upgradeToPremium": { "message": "Обновить до Премиум" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Ваша организация больше не использует мастер-пароли для входа в Bitwarden. Чтобы продолжить, подтвердите организацию и домен." + }, + "continueWithLogIn": { + "message": "Продолжить с логином" + }, + "doNotContinue": { + "message": "Не продолжать" + }, + "domain": { + "message": "Домен" + }, + "keyConnectorDomainTooltip": { + "message": "В этом домене будут храниться ключи шифрования вашего аккаунта, поэтому убедитесь, что вы ему доверяете. Если вы не уверены, обратитесь к своему администратору." + }, + "verifyYourOrganization": { + "message": "Подтвердите свою организацию для входа" + }, + "organizationVerified": { + "message": "Организация подтверждена" + }, + "domainVerified": { + "message": "Домен верифицирован" + }, + "leaveOrganizationContent": { + "message": "Если вы не подтвердите свою организацию, ваш доступ к ней будет аннулирован." + }, + "leaveNow": { + "message": "Покинуть" + }, + "verifyYourDomainToLogin": { + "message": "Подтвердите свой домен для входа" + }, + "verifyYourDomainDescription": { + "message": "Чтобы продолжить с логином, подтвердите этот домен." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Чтобы продолжить с логином, подтвердите организацию и домен." + }, "sessionTimeoutSettingsAction": { "message": "Тайм-аут действия" }, "sessionTimeoutHeader": { - "message": "Тайм-аут сеанса" + "message": "Тайм-аут сессии" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Эта настройка управляется вашей организацией." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "В вашей организации максимальный тайм-аут сессии установлен равным $HOURS$ час. и $MINUTES$ мин.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Ваша организация установила тайм-аут сессии по умолчанию на При блокировке системы." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Ваша организация установила тайм-аут сессии по умолчанию на При перезапуске." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Максимальный тайм-аут не может превышать $HOURS$ час. и $MINUTES$ мин.", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "При перезапуске" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Установите способ разблокировки для изменения действия при истечении тайм-аута" + }, + "upgrade": { + "message": "Перейти" + }, + "leaveConfirmationDialogTitle": { + "message": "Вы уверены, что хотите покинуть?" + }, + "leaveConfirmationDialogContentOne": { + "message": "В случае отказа ваши личные данные останутся в вашем аккаунте, но вы потеряете доступ к общим элементам и возможностям организации." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Свяжитесь с вашим администратором для восстановления доступа." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Покинуть $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Как я могу управлять своим хранилищем?" + }, + "transferItemsToOrganizationTitle": { + "message": "Перенести элементы в $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ требует, чтобы все элементы принадлежали организации для обеспечения безопасности и соответствия требованиям. Нажмите Принять, чтобы передать собственность на ваши элементы.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Принять передачу" + }, + "declineAndLeave": { + "message": "Отклонить и покинуть" + }, + "whyAmISeeingThis": { + "message": "Почему я это вижу?" } } diff --git a/apps/desktop/src/locales/si/messages.json b/apps/desktop/src/locales/si/messages.json index a83b2cbf536..d53bb073f49 100644 --- a/apps/desktop/src/locales/si/messages.json +++ b/apps/desktop/src/locales/si/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index 0b14b961bbb..23c3d3ae3d0 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Priložiť prílohu" }, + "itemsTransferred": { + "message": "Položky boli prenesené" + }, + "fixEncryption": { + "message": "Opraviť šifrovanie" + }, + "fixEncryptionTooltip": { + "message": "Tento súbor používa zastaranú metódu šifrovania." + }, + "attachmentUpdated": { + "message": "Príloha bola aktualizovaná" + }, "maxFileSizeSansPunctuation": { "message": "Maximálna veľkosť súboru je 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Vyskytla sa neočakávaná chyba." }, + "unexpectedErrorShort": { + "message": "Neočakávaná chyba" + }, + "closeThisBitwardenWindow": { + "message": "Zatvorte toto okno Bitwardenu a skúste to znova." + }, "itemInformation": { "message": "Informácie o položke" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Zistiť viac" }, + "migrationsFailed": { + "message": "Pri aktualizácii nastavení šifrovania došlo k chybe." + }, + "updateEncryptionSettingsTitle": { + "message": "Aktualizujte nastavenie šifrovania" + }, + "updateEncryptionSettingsDesc": { + "message": "Nové odporúčané nastavenia šifrovania zlepšia bezpečnosť vášho účtu. Ak ich chcete aktualizovať teraz, zadajte hlavné heslo." + }, + "confirmIdentityToContinue": { + "message": "Ak chcete pokračovať, potvrďte svoju identitu" + }, + "enterYourMasterPassword": { + "message": "Zadajte hlavné heslo" + }, + "updateSettings": { + "message": "Aktualizovať nastavenia" + }, "featureUnavailable": { "message": "Funkcia nie je k dispozícii" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Sledujte nás" }, - "syncVault": { - "message": "Synchronizovať trezor" + "syncNow": { + "message": "Synchronizovať teraz" }, "changeMasterPass": { "message": "Zmeniť hlavné heslo" @@ -1301,7 +1337,7 @@ "message": "Keď je systém v režime spánku" }, "onLocked": { - "message": "Keď je systém uzamknutý" + "message": "Pri uzamknutí systému" }, "onRestart": { "message": "Pri reštarte" @@ -1378,7 +1414,7 @@ "message": "Zobraziť Bitwarden v Docku aj keď je minimalizovaný na panel úloh." }, "confirmTrayTitle": { - "message": "Potvrdiť vypnutie systémovej lišty" + "message": "Potvrdiť skrývanie systémovej lišty" }, "confirmTrayDesc": { "message": "Vypnutím tohto nastavenia vypnete aj ostatné nastavenia súvisiace so systémovou lištou." @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB šifrovaného úložiska." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ šifrovaného úložiska na prílohy.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietárne možnosti dvojstupňového prihlásenia ako napríklad YubiKey a Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Exportovať z" }, - "exportVault": { - "message": "Export trezoru" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Exportovať", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importovať", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Formát súboru" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Kontaktné informácie" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Všetky Sendy", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Hlavné heslo bolo odstránené." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Hlavné heslo sa už nevyžaduje pre členov tejto organizácie. Nižšie uvedenú doménu potvrďte u správcu organizácie." - }, "organizationName": { "message": "Názov organizácie" }, @@ -2790,10 +2849,10 @@ "message": "Použiť možnosti subadresovania svojho poskytovateľa e-mailu." }, "catchallEmail": { - "message": "E-mail Catch-all" + "message": "Doménový kôš" }, "catchallEmailDesc": { - "message": "Použiť doručenú poštu typu catch-all nastavenú na doméne." + "message": "Použiť nastavený doménový kôš." }, "useThisEmail": { "message": "Použiť tento e-mail" @@ -2991,7 +3050,8 @@ "message": "Ste si istí, že chcete použiť možnosť \"Nikdy\"? Táto predvoľba ukladá šifrovací kľúč od trezora priamo na zariadení. Ak použijete túto možnosť, mali by ste svoje zariadenie náležite zabezpečiť." }, "vault": { - "message": "Trezor" + "message": "Trezor", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Prihlásenie pomocou hlavného hesla" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias doména" }, - "importData": { - "message": "Import údajov", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Chyba importu" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Súbor sa uložil do zariadenia. Spravujte stiahnuté súbory zo zariadenia." }, + "importantNotice": { + "message": "Dôležité upozornenie" + }, + "setupTwoStepLogin": { + "message": "Nastaviť dvojstupňové prihlásenie" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden vám od februára 2025 pošle na e-mail vášho účtu kód na overenie prihlásenia z nových zariadení." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Ako alternatívny spôsob ochrany svojho účtu môžete nastaviť dvojstupňové prihlásenie alebo zmeniť e-mail na taký, ku ktorému máte prístup." + }, + "remindMeLater": { + "message": "Pripomenúť neskôr" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Máte zaručený prístup k e-mailu $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nie, nemám" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Áno, mám zaručený prístup k e-mailu" + }, + "turnOnTwoStepLogin": { + "message": "Zapnúť dvojstupňové prihlásenie" + }, + "changeAcctEmail": { + "message": "Zmeniť e-mail účtu" + }, + "passkeyLogin": { + "message": "Prihlásiť sa s prístupovým kľúčom?" + }, + "savePasskeyQuestion": { + "message": "Uložiť prístupový kľúč?" + }, + "saveNewPasskey": { + "message": "Uložiť ako nové prihlasovacie údaje" + }, + "savePasskeyNewLogin": { + "message": "Uložiť prístupový kľúč ako nové prihlásenie" + }, + "noMatchingLoginsForSite": { + "message": "Pre túto stránku sa nenašli prihlasovacie údaje" + }, + "overwritePasskey": { + "message": "Prepísať prístupový kľúč?" + }, + "unableToSavePasskey": { + "message": "Prístupový kľúč sa nepodarilo uložiť" + }, + "alreadyContainsPasskey": { + "message": "Táto položka už obsahuje prístupový kľúč. Naozaj chcete prepísať aktuálny prístupový kľúč?" + }, + "passkeyAlreadyExists": { + "message": "Pre túto aplikáciu už existuje prístupový kľúč." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Táto aplikácia nepodporuje duplikáty." + }, + "closeThisWindow": { + "message": "Zatvoriť toto okno" + }, "allowScreenshots": { "message": "Povoliť snímanie obrazovky" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "A ešte viac!" }, - "planDescPremium": { - "message": "Úplné online zabezpečenie" + "advancedOnlineSecurity": { + "message": "Pokročilá online ochrana" }, "upgradeToPremium": { "message": "Upgradovať na Prémium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Vaša organizácia už nepoužíva hlavné heslá na prihlásenie do Bitwardenu. Ak chcete pokračovať, overte organizáciu a doménu." + }, + "continueWithLogIn": { + "message": "Pokračujte prihlásením" + }, + "doNotContinue": { + "message": "Nepokračovať" + }, + "domain": { + "message": "Doména" + }, + "keyConnectorDomainTooltip": { + "message": "Táto doména bude ukladať šifrovacie kľúče vášho účtu, takže sa uistite, že jej dôverujete. Ak si nie ste istí, overte si to u správcu." + }, + "verifyYourOrganization": { + "message": "Na prihlásenie overte organizáciu" + }, + "organizationVerified": { + "message": "Organizácia je overená" + }, + "domainVerified": { + "message": "Doména je overená" + }, + "leaveOrganizationContent": { + "message": "Ak organizáciu neoveríte, váš prístup k nej bude zrušený." + }, + "leaveNow": { + "message": "Opustiť teraz" + }, + "verifyYourDomainToLogin": { + "message": "Na prihlásenie overte doménu" + }, + "verifyYourDomainDescription": { + "message": "Na pokračovanie prihlásením, overte túto doménu." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Na pokračovanie prihlásením, overte organizáciu a doménu." + }, "sessionTimeoutSettingsAction": { "message": "Akcia pri vypršaní časového limitu" }, "sessionTimeoutHeader": { "message": "Časový limit relácie" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Toto nastavenie spravuje vaša organizácia." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Vaša organizácia nastavila maximálny časový limit relácie na $HOURS$ hod. a $MINUTES$ min.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Vaša organizácia nastavila predvolený časový limit relácie na Pri uzamknutí systému." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Vaša organizácia nastavila predvolený časový limit relácie na Pri reštarte prehliadača." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximálny časový limit nesmie prekročiť $HOURS$ hod. a $MINUTES$ min.", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Pri reštarte" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Nastavte metódu odomknutia, aby ste zmenili akciu pri vypršaní časového limitu" + }, + "upgrade": { + "message": "Upgradovať" + }, + "leaveConfirmationDialogTitle": { + "message": "Naozaj chcete odísť?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Ak odmietnete, vaše osobné položky zostanú vo vašom účte, ale stratíte prístup k zdieľaným položkám a funkciám organizácie." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Ak chcete obnoviť prístup, obráťte sa na správcu." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Opustiť $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Ako môžem spravovať svoj trezor?" + }, + "transferItemsToOrganizationTitle": { + "message": "Prenos položiek do $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ vyžaduje, aby všetky položky boli vo vlastníctve organizácie z dôvodu bezpečnosti a dodržiavania predpisov. Ak chcete previesť vlastníctvo položiek, kliknite na tlačidlo Prijať.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Prijať prenos" + }, + "declineAndLeave": { + "message": "Zamietnuť a odísť" + }, + "whyAmISeeingThis": { + "message": "Prečo to vidím?" } } diff --git a/apps/desktop/src/locales/sl/messages.json b/apps/desktop/src/locales/sl/messages.json index 353c6858afa..b0acd957d68 100644 --- a/apps/desktop/src/locales/sl/messages.json +++ b/apps/desktop/src/locales/sl/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Informacije o elementu" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Več o tem" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Funkcija ni na voljo" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Sledite nam" }, - "syncVault": { - "message": "Sinhroniziraj trezor" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Spremeni glavno geslo" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Izvoz trezorja" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Format datoteke" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Vsi Sendsi", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Glavno geslo je bilo odstranjeno." }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index 1bc4a0ed016..0142a1bc719 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Додај прилог" }, + "itemsTransferred": { + "message": "Пренете ставке" + }, + "fixEncryption": { + "message": "Поправи шифровање" + }, + "fixEncryptionTooltip": { + "message": "Ова датотека користи застарели метод шифровања." + }, + "attachmentUpdated": { + "message": "Прилог је ажуриран" + }, "maxFileSizeSansPunctuation": { "message": "Максимална величина је 500МБ" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Дошло је до неочекиване грешке." }, + "unexpectedErrorShort": { + "message": "Неочекивана грешка" + }, + "closeThisBitwardenWindow": { + "message": "Затворите овај Bitwarden прозор и покушајте поново." + }, "itemInformation": { "message": "Инфо о ставци" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Сазнај више" }, + "migrationsFailed": { + "message": "Дошло је до грешке при ажурирању подешавања шифровања." + }, + "updateEncryptionSettingsTitle": { + "message": "Ажурирај своје поставке за шифровање" + }, + "updateEncryptionSettingsDesc": { + "message": "Нова препоручена подешавања шифрирања побољшаће вашу сигурност налога. Унесите своју главну лозинку за ажурирање." + }, + "confirmIdentityToContinue": { + "message": "Да бисте наставили потврдите ваш идентитет" + }, + "enterYourMasterPassword": { + "message": "Унети вашу главну лозинку" + }, + "updateSettings": { + "message": "Ажурирај подешавања" + }, "featureUnavailable": { "message": "Функција је недоступна" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Пратите нас" }, - "syncVault": { - "message": "Синхронизуј сеф" + "syncNow": { + "message": "Синхронизуј сада" }, "changeMasterPass": { "message": "Промени главну лозинку" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1ГБ шифровано складиште за прилоге." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ шифровано складиште за прилоге.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Приоритарне опције пријаве у два корака као што су YubiKey и Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Извоз од" }, - "exportVault": { - "message": "Извоз сефа" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Формат датотеке" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Контакт подаци" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Сва слања", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Главна лозинка уклоњена" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Главна лозинка више није потребна за чланове следеће организације. Молимо потврдите домен са администратором организације." - }, "organizationName": { "message": "Назив организације" }, @@ -2991,7 +3050,8 @@ "message": "Да ли сте сигурни да желите да користите опцију „Никад“? Ако поставите опције закључавања на „Никада“, на вашем уређају се чува кључ за шифровање сефа. Ако користите ову опцију, осигурајте да је уређај правилно заштићен." }, "vault": { - "message": "Сеф" + "message": "Сеф", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Пријавите се са главном лозинком" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Домен алијаса" }, - "importData": { - "message": "Увези податке", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Грешка при увозу" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Датотека је сачувана на уређају. Управљајте преузимањима са свог уређаја." }, + "importantNotice": { + "message": "Важно обавештење" + }, + "setupTwoStepLogin": { + "message": "Поставити дво-степенску пријаву" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden ће послати кôд на имејл вашег налога за верификовање пријављивања са нових уређаја почевши од фебруара 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Можете да подесите пријаву у два корака као алтернативни начин да заштитите свој налог или да промените свој имејл у један који можете да приступите." + }, + "remindMeLater": { + "message": "Подсети ме касније" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Да ли имате поуздан приступ својим имејлом, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Не, ненам" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Да, могу поуздано да приступим овим имејлом" + }, + "turnOnTwoStepLogin": { + "message": "Упалити дво-степенску пријаву" + }, + "changeAcctEmail": { + "message": "Променити имејл налога" + }, + "passkeyLogin": { + "message": "Пријавите се са приступним кључем?" + }, + "savePasskeyQuestion": { + "message": "Сачувати приступни кључ?" + }, + "saveNewPasskey": { + "message": "Сачувати као нову пријаву" + }, + "savePasskeyNewLogin": { + "message": "Сачувати приступни кључ као нову пријаву" + }, + "noMatchingLoginsForSite": { + "message": "Нема одговарајућих пријава за овај сајт" + }, + "overwritePasskey": { + "message": "Заменити приступни кључ?" + }, + "unableToSavePasskey": { + "message": "Није могуће сачувати приступни кључ" + }, + "alreadyContainsPasskey": { + "message": "Ова ставка већ садржи приступни кључ. Да ли сте сигурни да желите да замените тренутни приступни кључ?" + }, + "passkeyAlreadyExists": { + "message": "За ову апликацију већ постоји приступни кључ." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Ова апликација не подржава дупликате." + }, + "closeThisWindow": { + "message": "Затвори овај прозор" + }, "allowScreenshots": { "message": "Дозволи снимање екрана" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "И још више!" }, - "planDescPremium": { - "message": "Потпуна онлајн безбедност" + "advancedOnlineSecurity": { + "message": "Напредна онлајн безбедност" }, "upgradeToPremium": { "message": "Надоградите на Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Ваша организација више не користи главне лозинке за пријаву на Bitwarden. Да бисте наставили, верификујте организацију и домен." + }, + "continueWithLogIn": { + "message": "Наставити са пријавом" + }, + "doNotContinue": { + "message": "Не настави" + }, + "domain": { + "message": "Домен" + }, + "keyConnectorDomainTooltip": { + "message": "Овај домен ће чувати кључеве за шифровање вашег налога, па се уверите да му верујете. Ако нисте сигурни, проверите код свог администратора." + }, + "verifyYourOrganization": { + "message": "Верификујте своју организацију да бисте се пријавили" + }, + "organizationVerified": { + "message": "Организација верификована" + }, + "domainVerified": { + "message": "Домен верификован" + }, + "leaveOrganizationContent": { + "message": "Ако не верификујете своју организацију, ваш приступ организацији ће бити опозван." + }, + "leaveNow": { + "message": "Напусти сада" + }, + "verifyYourDomainToLogin": { + "message": "Верификујте домен да бисте се пријавили" + }, + "verifyYourDomainDescription": { + "message": "Да бисте наставили са пријављивањем, верификујте овај домен." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "Да бисте наставили са пријављивањем, верификујте организацију и домен." + }, "sessionTimeoutSettingsAction": { - "message": "Timeout action" + "message": "Акција тајмаута" }, "sessionTimeoutHeader": { - "message": "Session timeout" + "message": "Истек сесије" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Овим подешавањем управља ваша организација." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Ваша организација је подесила максимално временско ограничење сесије на $HOURS$ сати и $MINUTES$ минута.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Ваша организација је поставила подразумевано временско ограничење сесије на Блокирање система." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Ваша организација је поставила подразумевано временско ограничење сесије на При рестартовању." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Максимално временско ограничење не може да пређе $HOURS$ сат(а) и $MINUTES$ минут(а)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "На поновно покретање" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Подесите метод откључавања да бисте променили радњу временског ограничења" + }, + "upgrade": { + "message": "Надогради" + }, + "leaveConfirmationDialogTitle": { + "message": "Да ли сте сигурни да желите да напустите?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Ако одбијете, ваши лични предмети ће остати на вашем налогу, али ћете изгубити приступ дељеним ставкама и организационим функцијама." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Контактирајте свог администратора да бисте поново добили приступ." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Напустити $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Како да управљам својим сефом?" + }, + "transferItemsToOrganizationTitle": { + "message": "Премести ставке у $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ захтева да све ставке буду у власништву организације ради безбедности и усклађености. Кликните на прихвати да бисте пренели власништво над својим ставкама.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Прихвати трансфер" + }, + "declineAndLeave": { + "message": "Одбиј и напусти" + }, + "whyAmISeeingThis": { + "message": "Зашто видите ово?" } } diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json index 93d56419ae3..e19328075d1 100644 --- a/apps/desktop/src/locales/sv/messages.json +++ b/apps/desktop/src/locales/sv/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Lägg till bilaga" }, + "itemsTransferred": { + "message": "Objekt överförda" + }, + "fixEncryption": { + "message": "Fixa kryptering" + }, + "fixEncryptionTooltip": { + "message": "Denna fil använder en föråldrad krypteringsmetod." + }, + "attachmentUpdated": { + "message": "Bilaga uppdaterad" + }, "maxFileSizeSansPunctuation": { "message": "Maximal filstorlek är 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Ett oväntat fel har inträffat." }, + "unexpectedErrorShort": { + "message": "Oväntat fel" + }, + "closeThisBitwardenWindow": { + "message": "Stäng detta Bitwarden-fönster och försök igen." + }, "itemInformation": { "message": "Objektinformation" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Läs mer" }, + "migrationsFailed": { + "message": "Ett fel inträffade när krypteringsinställningarna skulle uppdateras." + }, + "updateEncryptionSettingsTitle": { + "message": "Uppdatera dina krypteringsinställningar" + }, + "updateEncryptionSettingsDesc": { + "message": "De nya rekommenderade krypteringsinställningarna kommer att förbättra säkerheten för ditt konto. Ange ditt huvudlösenord för att uppdatera nu." + }, + "confirmIdentityToContinue": { + "message": "Bekräfta din identitet för att fortsätta" + }, + "enterYourMasterPassword": { + "message": "Ange ditt huvudlösenord" + }, + "updateSettings": { + "message": "Uppdatera inställningar" + }, "featureUnavailable": { "message": "Funktion ej tillgänglig" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Följ oss" }, - "syncVault": { - "message": "Synkronisera valv" + "syncNow": { + "message": "Synkronisera nu" }, "changeMasterPass": { "message": "Ändra huvudlösenord" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB krypterad lagring." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ krypterad lagring för filbilagor.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Premium-alternativ för tvåstegsverifiering, såsom YubiKey och Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Exportera från" }, - "exportVault": { - "message": "Exportera valv" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Exportera", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Importera", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Filformat" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Kontaktinformation" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Alla Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Huvudlösenord togs bort" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Ett huvudlösenord krävs inte längre för medlemmar i följande organisation. Vänligen bekräfta domänen nedan med din organisationsadministratör." - }, "organizationName": { "message": "Organisationsnamn" }, @@ -2991,7 +3050,8 @@ "message": "Är du säker på att du vill använda alternativet ”Aldrig”? Att ställa in låsnings-alternativet till ”Aldrig” lagrar valvets krypteringsnyckel på datorn. Om du använder det här alternativet bör du se till att du håller datorn ordentligt skyddad." }, "vault": { - "message": "Valv" + "message": "Valv", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Logga in med huvudlösenord" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Aliasdomän" }, - "importData": { - "message": "Importera data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Fel vid import" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Fil sparad till enhet. Hantera nedladdningar från din enhet." }, + "importantNotice": { + "message": "Viktigt meddelande" + }, + "setupTwoStepLogin": { + "message": "Ställ in tvåstegsverifiering" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden kommer att skicka en kod till din e-postadress för ditt konto för att verifiera inloggningar från nya enheter med start i februari 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Du kan ställa in tvåstegsverifiering som ett alternativt sätt att skydda ditt konto eller ändra din e-post till en som du kan komma åt." + }, + "remindMeLater": { + "message": "Påminn mig senare" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Har du tillförlitlig åtkomst till din e-post, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nej, det har jag inte" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Ja, jag har tillförlitlig åtkomst till min e-post" + }, + "turnOnTwoStepLogin": { + "message": "Aktivera tvåstegsverifiering" + }, + "changeAcctEmail": { + "message": "Byt e-postadress för konto" + }, + "passkeyLogin": { + "message": "Logga in med inloggningsnyckel?" + }, + "savePasskeyQuestion": { + "message": "Spara inloggningsnyckel?" + }, + "saveNewPasskey": { + "message": "Spara som ny inloggning" + }, + "savePasskeyNewLogin": { + "message": "Spara inloggningsnyckel som ny inloggning" + }, + "noMatchingLoginsForSite": { + "message": "Inga matchande inloggningar för denna webbplats" + }, + "overwritePasskey": { + "message": "Skriv över inloggningsnyckel?" + }, + "unableToSavePasskey": { + "message": "Kunde inte spara inloggningsnyckel" + }, + "alreadyContainsPasskey": { + "message": "Detta objekt innehåller redan en inloggningsnyckel. Är du säker på att du vill skriva över den aktuella inloggningsnyckeln?" + }, + "passkeyAlreadyExists": { + "message": "En inloggningsnyckel finns redan för detta program." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Denna applikation har inte stöd för dubbletter." + }, + "closeThisWindow": { + "message": "Stäng detta fönster" + }, "allowScreenshots": { "message": "Tillåt skärmdump" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "och mer!" }, - "planDescPremium": { - "message": "Komplett säkerhet online" + "advancedOnlineSecurity": { + "message": "Avancerad säkerhet online" }, "upgradeToPremium": { "message": "Uppgradera till Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Din organisation använder inte längre huvudlösenord för att logga in på Bitwarden. För att fortsätta, verifiera organisationen och domänen." + }, + "continueWithLogIn": { + "message": "Fortsätt med inloggning" + }, + "doNotContinue": { + "message": "Fortsätt inte" + }, + "domain": { + "message": "Domän" + }, + "keyConnectorDomainTooltip": { + "message": "Denna domän kommer att lagra dina krypteringsnycklar, så se till att du litar på den. Om du inte är säker, kontrollera med din administratör." + }, + "verifyYourOrganization": { + "message": "Verifiera din organisation för att logga in" + }, + "organizationVerified": { + "message": "Organisation verifierad" + }, + "domainVerified": { + "message": "Domän verifierad" + }, + "leaveOrganizationContent": { + "message": "Om du inte verifierar din organisation kommer din åtkomst till organisationen att återkallas." + }, + "leaveNow": { + "message": "Lämna nu" + }, + "verifyYourDomainToLogin": { + "message": "Verifiera din domän för att logga in" + }, + "verifyYourDomainDescription": { + "message": "För att fortsätta med inloggning, verifiera denna domän." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "För att fortsätta logga in, verifiera organisationen och domänen." + }, "sessionTimeoutSettingsAction": { "message": "Tidsgränsåtgärd" }, "sessionTimeoutHeader": { "message": "Sessionstidsgräns" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Den här inställningen hanteras av din organisation." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Din organisation har ställt in maximal sessionstidsgräns till $HOURS$ timmar och $MINUTES$ minut(er).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Din organisation har ställt in tidsgräns för standardsession till Vid systemlåsning." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Din organisation har ställt in tidsgräns för standardsession till Vid omstart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximal tidsgräns får inte överstiga $HOURS$ timmar och $MINUTES$ minut(er)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Vid omstart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Ställ in en upplåsningsmetod för att ändra din tidsgränsåtgärd" + }, + "upgrade": { + "message": "Uppgradera" + }, + "leaveConfirmationDialogTitle": { + "message": "Är du säker på att du vill lämna?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Genom att avböja kommer dina personliga objekt att stanna på ditt konto, men du kommer att förlora åtkomst till delade objekt och organisationsfunktioner." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Kontakta administratören för att återfå åtkomst." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Lämna $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Hur hanterar jag mitt valv?" + }, + "transferItemsToOrganizationTitle": { + "message": "Överför objekt till $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ kräver att alla objekt ägs av organisationen för säkerhet och efterlevnad. Klicka på godkänn för att överföra ägarskapet för dina objekt.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Godkänn överföring" + }, + "declineAndLeave": { + "message": "Avböj och lämna" + }, + "whyAmISeeingThis": { + "message": "Varför ser jag det här?" } } diff --git a/apps/desktop/src/locales/ta/messages.json b/apps/desktop/src/locales/ta/messages.json index 2f9d12917d6..01f8f04f945 100644 --- a/apps/desktop/src/locales/ta/messages.json +++ b/apps/desktop/src/locales/ta/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "இணைப்பைச் சேர்" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "அதிகபட்ச கோப்பு அளவு 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "ஒரு எதிர்பாராத பிழை ஏற்பட்டது." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "உருப்படி தகவல்" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "மேலும் அறியவும்" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "வசதி கிடைக்கவில்லை" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "எங்களைப் பின்தொடரவும்" }, - "syncVault": { - "message": "பெட்டகத்தை ஒத்திசைக்கவும்" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "முதன்மை கடவுச்சொல்லை மாற்றவும்" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "கோப்பு இணைப்புகளுக்கு 1 GB குறியாக்கப்பட்ட சேமிப்பகம்." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "YubiKey மற்றும் Duo போன்ற பிரத்யேக இரண்டு-படி உள்நுழைவு விருப்பங்கள்." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "இருந்து ஏற்றுமதி" }, - "exportVault": { - "message": "பெட்டகத்தை ஏற்றுமதி செய்" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "கோப்பு வடிவம்" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "தொடர்புத் தகவல்" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "அனைத்து அனுப்புதல்களும்", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "முதன்மை கடவுச்சொல் நீக்கப்பட்டது" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "பின்வரும் அமைப்பின் உறுப்பினர்களுக்கு ஒரு முதன்மை கடவுச்சொல் இனி தேவையில்லை. கீழே உள்ள டொமைனை உங்கள் நிறுவன நிர்வாகியுடன் உறுதிப்படுத்தவும்." - }, "organizationName": { "message": "நிறுவனத்தின் பெயர்" }, @@ -2991,7 +3050,8 @@ "message": "\"ஒருபோதும் இல்லை\" விருப்பத்தைப் பயன்படுத்த விரும்புகிறீர்களா? உங்கள் பூட்டு விருப்பங்களை \"ஒருபோதும் இல்லை\" என அமைப்பது உங்கள் வால்ட்டின் குறியாக்க சாவியை உங்கள் சாதனத்தில் சேமிக்கிறது. இந்த விருப்பத்தைப் பயன்படுத்தினால், உங்கள் சாதனத்தை நீங்கள் சரியாகப் பாதுகாப்பதை உறுதி செய்ய வேண்டும்." }, "vault": { - "message": "வால்ட்" + "message": "வால்ட்", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "முதன்மை கடவுச்சொல்லுடன் உள்நுழைக" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "புனைப்பெயர் டொமைன்" }, - "importData": { - "message": "தரவை இறக்குமதி செய்", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "இறக்குமதி பிழை" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "கோப்பு சாதனத்தில் சேமிக்கப்பட்டது. உங்கள் சாதன பதிவிறக்கங்களிலிருந்து நிர்வகி." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "திரை பிடிப்பை அனுமதி" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/te/messages.json b/apps/desktop/src/locales/te/messages.json index d607bb8d097..2d0019a1f31 100644 --- a/apps/desktop/src/locales/te/messages.json +++ b/apps/desktop/src/locales/te/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "An unexpected error has occurred." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Item information" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Learn more" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow us" }, - "syncVault": { - "message": "Sync vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Change master password" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB encrypted storage for file attachments." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "All Sends", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/th/messages.json b/apps/desktop/src/locales/th/messages.json index d794ace629c..a9b08eda022 100644 --- a/apps/desktop/src/locales/th/messages.json +++ b/apps/desktop/src/locales/th/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Add attachment" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Maximum file size is 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "ข้อผิดพลาดที่ไม่คาดคิดได้เกิดขึ้น." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "ข้อมูลรายการ" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "เรียนรู้เพิ่มเติม" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Feature Unavailable" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Follow Us" }, - "syncVault": { - "message": "Sync Vault" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "เปลี่ยนรหัสผ่านหลัก" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 GB of encrypted file storage." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Proprietary two-step login options such as YubiKey and Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Export from" }, - "exportVault": { - "message": "Export Vault" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "File Format" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Contact information" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "ส่งทั้งหมด", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Master password removed" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." - }, "organizationName": { "message": "Organization name" }, @@ -2991,7 +3050,8 @@ "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." }, "vault": { - "message": "Vault" + "message": "Vault", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Log in with master password" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias domain" }, - "importData": { - "message": "Import data", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Import error" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Allow screen capture" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "And more!" }, - "planDescPremium": { - "message": "Complete online security" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Upgrade to Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index ac67b177cbf..fb867fba82c 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Dosya ekle" }, + "itemsTransferred": { + "message": "Kayıtlar aktarıldı" + }, + "fixEncryption": { + "message": "Şifrelemeyi düzelt" + }, + "fixEncryptionTooltip": { + "message": "Bu dosya eski bir şifreleme yöntemi kullanıyor." + }, + "attachmentUpdated": { + "message": "Ek güncellendi" + }, "maxFileSizeSansPunctuation": { "message": "Maksimum dosya boyutu 500 MB'dir" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Beklenmedik bir hata oluştu." }, + "unexpectedErrorShort": { + "message": "Beklenmeyen hata" + }, + "closeThisBitwardenWindow": { + "message": "Bu Bitwarden penceresini kapatıp yeniden deneyin." + }, "itemInformation": { "message": "Kayıt bilgileri" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Daha fazla bilgi al" }, + "migrationsFailed": { + "message": "Şifreleme ayarları güncellenirken bir hata oluştu." + }, + "updateEncryptionSettingsTitle": { + "message": "Şifreleme ayarlarınızı güncelleyin" + }, + "updateEncryptionSettingsDesc": { + "message": "Önerilen yeni şifreleme ayarları hesap güvenliğinizi artıracaktır. Şimdi güncellemek için ana parolanızı girin." + }, + "confirmIdentityToContinue": { + "message": "Devam etmek için kimliğinizi doğrulayın" + }, + "enterYourMasterPassword": { + "message": "Ana parolanızı girin" + }, + "updateSettings": { + "message": "Ayarları güncelle" + }, "featureUnavailable": { "message": "Özellik kullanılamıyor" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Bizi takip edin" }, - "syncVault": { - "message": "Kasayı eşitle" + "syncNow": { + "message": "Şimdi eşitle" }, "changeMasterPass": { "message": "Ana parolayı değiştir" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "Dosya ekleri için 1 GB şifrelenmiş depolama." }, + "premiumSignUpStorageV2": { + "message": "Dosya ekleri için $SIZE$ şifrelenmiş depolama.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "YubiKey ve Duo gibi marka bazlı iki aşamalı giriş seçenekleri." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Dışa aktarılacak konum" }, - "exportVault": { - "message": "Kasayı dışa aktar" + "exportNoun": { + "message": "Dışa aktar", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Dışa aktar", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "İçe aktar", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "İçe aktar", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Dosya biçimi" @@ -1761,7 +1819,7 @@ "message": "Hesap kısıtlı" }, "restrictCardTypeImport": { - "message": "Kart öge türleri içe aktarılamıyor" + "message": "Kart kayıt türleri içe aktarılamıyor" }, "restrictCardTypeImportDesc": { "message": "1 veya daha fazla kuruluş tarafından belirlenen bir ilke, kasalarınıza kart aktarmanızı engelliyor." @@ -1841,7 +1899,7 @@ "message": "Kilidi Windows Hello ile aç" }, "unlockWithPolkit": { - "message": "Sistem kimlik doğrulaması ile kilit açma" + "message": "Kilidi sistem kimlik doğrulamasıyla aç" }, "windowsHelloConsentMessage": { "message": "Bitwarden için doğrulayın." @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "İletişim bilgileri" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Tüm Send'ler", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Ana parola kaldırıldı" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Aşağıdaki organizasyonun üyeleri için artık ana parola gerekmemektedir. Lütfen alan adını organizasyon yöneticinizle doğrulayın." - }, "organizationName": { "message": "Kuruluş adı" }, @@ -2679,7 +2738,7 @@ } }, "exportingOrganizationVaultFromPasswordManagerWithDataOwnershipDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported.", + "message": "Yalnızca $ORGANIZATION$ ile ilişkili kuruluş kasası dışa aktarılacaktır.", "placeholders": { "organization": { "content": "$1", @@ -2688,7 +2747,7 @@ } }, "exportingOrganizationVaultFromAdminConsoleWithDataOwnershipDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. My items collections will not be included.", + "message": "Yalnızca $ORGANIZATION$ ile ilişkilendirilmiş kuruluş kasası dışa aktarılacaktır. Kayıtlarım koleksiyonları dahil edilmeyecek.", "placeholders": { "organization": { "content": "$1", @@ -2991,7 +3050,8 @@ "message": "\"Asla\" seçeneğini kullanmak istediğinizden emin misiniz? Kilit seçeneklerinizi \"Asla\" olarak ayarlarsanız kasanızın şifreleme anahtarı cihazınızda saklanacaktır. Bu seçeneği kullanırsanız cihazınızı çok iyi korumalısınız." }, "vault": { - "message": "Kasa" + "message": "Kasa", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Ana parola ile giriş yap" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Alias alan adı" }, - "importData": { - "message": "Verileri içe aktar", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "İçe aktarma hatası" }, @@ -3819,22 +3875,22 @@ "message": "Uyarı: Aracı Yönlendirme" }, "agentForwardingWarningText": { - "message": "Bu istek, oturum açtığınız uzak bir cihazdan gelir" + "message": "Bu istek, giriş yaptığınız uzak bir cihazdan geliyor" }, "sshkeyApprovalMessageInfix": { - "message": "erişim istiyor" + "message": "buraya erişmek istiyor:" }, "sshkeyApprovalMessageSuffix": { - "message": "amacıyla" + "message": "amaç:" }, "sshActionLogin": { - "message": "bir sunucuya kimlik doğrulamak" + "message": "sunucuda kimlik doğrulamak" }, "sshActionSign": { - "message": "bir iletiyi imzala" + "message": "ileti imzalamak" }, "sshActionGitSign": { - "message": "bir git commit'i imzala" + "message": "git commit'i imzalamak" }, "unknownApplication": { "message": "Bir uygulama" @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Dosya cihaza kaydedildi. Cihazınızın indirilenler klasöründen yönetebilirsiniz." }, + "importantNotice": { + "message": "Önemli uyarı" + }, + "setupTwoStepLogin": { + "message": "İki adımlı girişi ayarlayın" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Şubat 2025 itibarıyla Bitwarden, yeni cihazlardan yeni girişleri doğrulamanız için e-posta adresinize bir kod gönderecektir." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Hesabınızı korumanın alternatif bir yolu olarak iki adımlı girişi etkinleştirebilirsiniz. Aksi halde e-posta adresinizin doğru olduğundan emin olmalısınız." + }, + "remindMeLater": { + "message": "Daha sonra hatırlat" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "$EMAIL$ adresinize sağlıklı bir şekilde erişebiliyor musunuz?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Hayır, erişemiyorum" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Evet, e-postalarıma sağlıklı bir şekilde erişebiliyorum" + }, + "turnOnTwoStepLogin": { + "message": "İki adımlı girişi etkinleştir" + }, + "changeAcctEmail": { + "message": "Hesap e-postasını değiştir" + }, + "passkeyLogin": { + "message": "Geçiş anahtarı ile giriş yapılsın mı?" + }, + "savePasskeyQuestion": { + "message": "Geçiş anahtarı kaydedilsin mi?" + }, + "saveNewPasskey": { + "message": "Yeni hesap olarak kaydet" + }, + "savePasskeyNewLogin": { + "message": "Geçiş anahtarını yeni hesap olarak kaydet" + }, + "noMatchingLoginsForSite": { + "message": "Bu siteyle eşleşen hesap bulunamadı" + }, + "overwritePasskey": { + "message": "Geçiş anahtarının üzerine yazılsın mı?" + }, + "unableToSavePasskey": { + "message": "Geçiş anahtarı kaydedilemedi" + }, + "alreadyContainsPasskey": { + "message": "Bu kayıt zaten bir geçiş anahtarı içeriyor. Mevcut geçiş anahtarının üzerine yazmak istediğinizden emin misiniz?" + }, + "passkeyAlreadyExists": { + "message": "Bu uygulama için bir geçiş anahtarı zaten mevcut." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Bu uygulama yinelenen kayıtları desteklemiyor." + }, + "closeThisWindow": { + "message": "Bu pencereyi kapat" + }, "allowScreenshots": { "message": "Ekran kaydına izin ver" }, @@ -3861,7 +3986,7 @@ "message": "Bitwarden masaüstü uygulamasının ekran görüntülerinde yakalanmasına ve uzak masaüstü oturumlarında görüntülenmesine izin verin. Bunun devre dışı bırakılması bazı harici ekranlarda erişimi engelleyecektir." }, "confirmWindowStillVisibleTitle": { - "message": "Pencerenin hala görünür durumda olduğunu onayla" + "message": "Pencerenin hâlâ görünür durumda olduğunu onayla" }, "confirmWindowStillVisibleContent": { "message": "Lütfen pencerenin hala görünür olduğunu onaylayın." @@ -3980,7 +4105,7 @@ "message": "Bu ayar hakkında" }, "permitCipherDetailsDescription": { - "message": "Bitwarden will use saved login URIs to identify which icon or change password URL should be used to improve your experience. No information is collected or saved when you use this service." + "message": "Bitwarden, hangi simgenin veya parola değiştirme URL'sinin kullanılacağını belirlemek için kaydedilmiş hesap URI'larını kullanacaktır; bu da deneyiminizi iyileştirmeye yardımcı olur. Bu hizmeti kullandığınızda herhangi bir bilgi toplanmaz veya kaydedilmez." }, "assignToCollections": { "message": "Koleksiyonlara ata" @@ -4129,7 +4254,7 @@ "message": "Kısayolu yazın" }, "editAutotypeShortcutDescription": { - "message": "Include one or two of the following modifiers: Ctrl, Alt, Win, or Shift, and a letter." + "message": "Aşağıdaki değiştirici tuşlardan birini veya ikisini (Ctrl, Alt, Win ya da Shift) ve bir harf kullanın." }, "invalidShortcut": { "message": "Geçersiz kısayol" @@ -4148,7 +4273,7 @@ "message": "Onayla" }, "enableAutotypeShortcutPreview": { - "message": "Enable autotype shortcut (Feature Preview)" + "message": "Otomatik yazma kısayolunu etkinleştir (Özellik Önizlemesi)" }, "enableAutotypeShortcutDescription": { "message": "Verilerin yanlış yere doldurulmasını önlemek için kısayolu kullanmadan önce doğru alanda olduğunuzdan emin olun." @@ -4168,13 +4293,13 @@ "message": "Arşivden çıkar" }, "itemsInArchive": { - "message": "Items in archive" + "message": "Arşivdeki kayıtlar" }, "noItemsInArchive": { - "message": "No items in archive" + "message": "Arşivde kayıt yok" }, "noItemsInArchiveDesc": { - "message": "Archived items will appear here and will be excluded from general search results and autofill suggestions." + "message": "Arşivlenmiş kayıtlar burada görünecek ve genel arama sonuçları ile otomatik doldurma önerilerinden hariç tutulacaktır." }, "itemWasSentToArchive": { "message": "Kayıt arşive gönderildi" @@ -4183,10 +4308,10 @@ "message": "Kayıt arşivden çıkarıldı" }, "archiveItem": { - "message": "Archive item" + "message": "Kaydı arşivle" }, "archiveItemConfirmDesc": { - "message": "Archived items are excluded from general search results and autofill suggestions. Are you sure you want to archive this item?" + "message": "Arşivlenmiş kayıtlar genel arama sonuçları ve otomatik doldurma önerilerinden hariç tutulur. Bu kaydı arşivlemek istediğinizden emin misiniz?" }, "zipPostalCodeLabel": { "message": "ZIP / posta kodu" @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "Ve daha fazlası!" }, - "planDescPremium": { - "message": "Eksiksiz çevrimiçi güvenlik" + "advancedOnlineSecurity": { + "message": "Gelişmiş çevrimiçi güvenlik" }, "upgradeToPremium": { "message": "Premium'a yükselt" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Zaman aşımı eylemi" }, "sessionTimeoutHeader": { "message": "Oturum zaman aşımı" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Bu ayar kuruluşunuz tarafından yönetiliyor." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Kuruluşunuz maksimum kasa zaman aşımını $HOURS$ saat $MINUTES$ dakika olarak belirlemiş.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Kuruluşunuz varsayılan oturum zaman aşımını “Sistem kilitlenince” olarak ayarlamış." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Kuruluşunuz varsayılan oturum zaman aşımını “Yeniden başlatılınca” olarak ayarlamış." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maksimum zaman aşımı en fazla $HOURS$ saat $MINUTES$ dakika olabilir", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Yeniden başlatılınca" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Zaman aşımı eyleminizi değiştirmek için kilit açma yönteminizi ayarlayın" + }, + "upgrade": { + "message": "Yükselt" + }, + "leaveConfirmationDialogTitle": { + "message": "Ayrılmak istediğinizden emin misiniz?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Reddetmeniz halinde kişisel kayıtlarınız hesabınızda kalmaya devam edecek, ancak paylaşılan kayıtlara ve kuruluş özelliklerine erişiminizi kaybedeceksiniz." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Erişiminizi yeniden kazanmak için yöneticinizle iletişime geçin." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "$ORGANIZATION$ kuruluşundan ayrıl", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Kasamı nasıl yönetebilirim?" + }, + "transferItemsToOrganizationTitle": { + "message": "Kayıtları $ORGANIZATION$ kuruluşuna aktar", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$, güvenlik ve mevzuata uyum amacıyla tüm kayıtların kuruluşa ait olmasını zorunlu kılıyor. Kayıtlarınızın sahipliğini devretmek için \"Kabul et\"e tıklayın.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Aktarımı kabul et" + }, + "declineAndLeave": { + "message": "Reddet ve ayrıl" + }, + "whyAmISeeingThis": { + "message": "Bunu neden görüyorum?" } } diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index 7ed0710ca74..9f86087f883 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "Додати вкладення" }, + "itemsTransferred": { + "message": "Items transferred" + }, + "fixEncryption": { + "message": "Fix encryption" + }, + "fixEncryptionTooltip": { + "message": "This file is using an outdated encryption method." + }, + "attachmentUpdated": { + "message": "Attachment updated" + }, "maxFileSizeSansPunctuation": { "message": "Максимальний розмір файлу – 500 МБ" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Сталася неочікувана помилка." }, + "unexpectedErrorShort": { + "message": "Unexpected error" + }, + "closeThisBitwardenWindow": { + "message": "Close this Bitwarden window and try again." + }, "itemInformation": { "message": "Інформація про запис" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Докладніше" }, + "migrationsFailed": { + "message": "An error occurred updating the encryption settings." + }, + "updateEncryptionSettingsTitle": { + "message": "Update your encryption settings" + }, + "updateEncryptionSettingsDesc": { + "message": "The new recommended encryption settings will improve your account security. Enter your master password to update now." + }, + "confirmIdentityToContinue": { + "message": "Confirm your identity to continue" + }, + "enterYourMasterPassword": { + "message": "Enter your master password" + }, + "updateSettings": { + "message": "Update settings" + }, "featureUnavailable": { "message": "Функція недоступна" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Стежте за нами" }, - "syncVault": { - "message": "Синхронізувати сховище" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Змінити головний пароль" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1 ГБ зашифрованого сховища для файлів." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ encrypted storage for file attachments.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Додаткові можливості двоетапної авторизації, як-от YubiKey та Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Експортувати з" }, - "exportVault": { - "message": "Експортувати сховище" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Формат файлу" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Контактна інформація" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Усі відправлення", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Головний пароль вилучено" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Головний пароль більше не є обов'язковим для учасників зазначеної організації. Підтвердьте вказаний нижче домен з адміністратором вашої організації." - }, "organizationName": { "message": "Назва організації" }, @@ -2991,7 +3050,8 @@ "message": "Ви впевнені, що ніколи не хочете блокувати? Встановивши параметр блокування \"Ніколи\", ключ шифрування сховища зберігатиметься на вашому пристрої. Користуючись цим параметром, ви маєте бути впевнені в тому, що ваш пристрій надійно захищений." }, "vault": { - "message": "Сховище" + "message": "Сховище", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Увійти з головним паролем" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Псевдонім домену" }, - "importData": { - "message": "Імпортувати дані", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Помилка імпорту" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Файл збережено на пристрої. Ви можете його знайти у теці завантажень." }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" + }, + "passkeyLogin": { + "message": "Log in with passkey?" + }, + "savePasskeyQuestion": { + "message": "Save passkey?" + }, + "saveNewPasskey": { + "message": "Save as new login" + }, + "savePasskeyNewLogin": { + "message": "Save passkey as new login" + }, + "noMatchingLoginsForSite": { + "message": "No matching logins for this site" + }, + "overwritePasskey": { + "message": "Overwrite passkey?" + }, + "unableToSavePasskey": { + "message": "Unable to save passkey" + }, + "alreadyContainsPasskey": { + "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + }, + "passkeyAlreadyExists": { + "message": "A passkey already exists for this application." + }, + "applicationDoesNotSupportDuplicates": { + "message": "This application does not support duplicates." + }, + "closeThisWindow": { + "message": "Close this window" + }, "allowScreenshots": { "message": "Дозволити захоплення екрана" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "Інші можливості!" }, - "planDescPremium": { - "message": "Повна онлайн-безпека" + "advancedOnlineSecurity": { + "message": "Advanced online security" }, "upgradeToPremium": { "message": "Покращити до Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { "message": "Timeout action" }, "sessionTimeoutHeader": { "message": "Session timeout" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "This setting is managed by your organization." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Your organization has set the maximum session timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Your organization has set the default session timeout to On system lock." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Your organization has set the default session timeout to On restart." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Maximum timeout cannot exceed $HOURS$ hour(s) and $MINUTES$ minute(s)", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "On restart" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Set an unlock method to change your timeout action" + }, + "upgrade": { + "message": "Upgrade" + }, + "leaveConfirmationDialogTitle": { + "message": "Are you sure you want to leave?" + }, + "leaveConfirmationDialogContentOne": { + "message": "By declining, your personal items will stay in your account, but you'll lose access to shared items and organization features." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Contact your admin to regain access." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Leave $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "How do I manage my vault?" + }, + "transferItemsToOrganizationTitle": { + "message": "Transfer items to $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ is requiring all items to be owned by the organization for security and compliance. Click accept to transfer ownership of your items.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Accept transfer" + }, + "declineAndLeave": { + "message": "Decline and leave" + }, + "whyAmISeeingThis": { + "message": "Why am I seeing this?" } } diff --git a/apps/desktop/src/locales/vi/messages.json b/apps/desktop/src/locales/vi/messages.json index 8bf88aba458..2c248671fbb 100644 --- a/apps/desktop/src/locales/vi/messages.json +++ b/apps/desktop/src/locales/vi/messages.json @@ -70,7 +70,7 @@ } }, "noEditPermissions": { - "message": "You don't have permission to edit this item" + "message": "Bạn không có quyền chỉnh sửa mục này" }, "welcomeBack": { "message": "Chào mừng bạn trở lại" @@ -708,6 +708,18 @@ "addAttachment": { "message": "Thêm tệp đính kèm" }, + "itemsTransferred": { + "message": "Các mục đã chuyển" + }, + "fixEncryption": { + "message": "Sửa mã hóa" + }, + "fixEncryptionTooltip": { + "message": "Tệp này đang sử dụng phương pháp mã hóa lỗi thời." + }, + "attachmentUpdated": { + "message": "Tệp đính kèm đã được cập nhật" + }, "maxFileSizeSansPunctuation": { "message": "Kích thước tối đa của tập tin là 500MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "Đã xảy ra lỗi không mong muốn." }, + "unexpectedErrorShort": { + "message": "Lỗi bất thường" + }, + "closeThisBitwardenWindow": { + "message": "Đóng cửa sổ Bitwarden này rồi thử lại." + }, "itemInformation": { "message": "Thông tin mục" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "Tìm hiểu thêm" }, + "migrationsFailed": { + "message": "Đã xảy ra lỗi khi cập nhật cài đặt mã hóa." + }, + "updateEncryptionSettingsTitle": { + "message": "Cập nhật cài đặt mã hóa của bạn" + }, + "updateEncryptionSettingsDesc": { + "message": "Cài đặt mã hóa được khuyến nghị sẽ cải thiện bảo mật cho tài khoản của bạn. Nhập mật khẩu chính để cập nhật ngay." + }, + "confirmIdentityToContinue": { + "message": "Xác minh danh tính để tiếp tục" + }, + "enterYourMasterPassword": { + "message": "Nhập mật khẩu chính của bạn" + }, + "updateSettings": { + "message": "Cập nhật cài đặt" + }, "featureUnavailable": { "message": "Tính năng không có sẵn" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "Theo dõi chúng tôi" }, - "syncVault": { - "message": "Đồng bộ kho" + "syncNow": { + "message": "Sync now" }, "changeMasterPass": { "message": "Thay đổi mật khẩu chính" @@ -1295,7 +1331,7 @@ "message": "4 giờ" }, "onIdle": { - "message": "Khi hệ thống không hoạt động (rảnh rỗi)" + "message": "Khi hệ thống nhàn rỗi" }, "onSleep": { "message": "Khi hệ thống ngủ" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "1GB bộ nhớ lưu trữ được mã hóa cho các tệp đính kèm." }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ bộ nhớ lưu trữ được mã hóa cho các tệp đính kèm.", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "Các tùy chọn xác minh hai bước như YubiKey và Duo." }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "Xuất từ" }, - "exportVault": { - "message": "Xuất kho" + "exportNoun": { + "message": "Export", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "Export", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "Import", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "Import", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "Định dạng tập tin" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "Thông tin liên hệ" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "Tất cả Send", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "Đã xóa mật khẩu chính" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "Mật khẩu chính không còn được yêu cầu đối với các thành viên của tổ chức sau đây. Vui lòng xác nhận tên miền bên dưới với quản trị viên của tổ chức." - }, "organizationName": { "message": "Tên tổ chức" }, @@ -2991,7 +3050,8 @@ "message": "Bạn có chắc chắn muốn chọn \"Không bao giờ\" không? Lựa chọn này sẽ lưu khóa mã hóa kho của bạn trực tiếp trên thiết bị. Hãy nhớ bảo vệ thiết bị của bạn thật cẩn thận nếu bạn chọn tùy chọn này." }, "vault": { - "message": "Kho lưu trữ" + "message": "Kho lưu trữ", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "Đăng nhập bằng mật khẩu chính" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "Tên miền thay thế" }, - "importData": { - "message": "Nhập dữ liệu", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "Lỗi khi nhập" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "Tệp đã được lưu vào thiết bị. Quản lý từ phần Tải về trên thiết bị của bạn." }, + "importantNotice": { + "message": "Thông báo quan trọng" + }, + "setupTwoStepLogin": { + "message": "Thiết lập đăng nhập hai bước" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden sẽ gửi mã đến email tài khoản của bạn để xác minh thông tin đăng nhập từ thiết bị mới bắt đầu từ tháng 2 năm 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Bạn có thể thiết lập đăng nhập hai bước như một cách thay thế để bảo vệ tài khoản của mình hoặc thay đổi email thành email mà bạn có thể truy cập." + }, + "remindMeLater": { + "message": "Nhắc tôi sau" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Bạn có thể truy cập vào email $EMAIL$ không?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Không, tôi không có" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Có, tôi có quyền truy cập email này" + }, + "turnOnTwoStepLogin": { + "message": "Bật đăng nhập hai bước" + }, + "changeAcctEmail": { + "message": "Đổi email tài khoản" + }, + "passkeyLogin": { + "message": "Đăng nhập bằng mã khóa?" + }, + "savePasskeyQuestion": { + "message": "Lưu mã khóa?" + }, + "saveNewPasskey": { + "message": "Lưu như đăng nhập mới" + }, + "savePasskeyNewLogin": { + "message": "Lưu mã khoá như đăng nhập mới" + }, + "noMatchingLoginsForSite": { + "message": "Không có đăng nhập khớp với trang web này" + }, + "overwritePasskey": { + "message": "Ghi đè mã khoá?" + }, + "unableToSavePasskey": { + "message": "Không thể lưu mã khóa" + }, + "alreadyContainsPasskey": { + "message": "Mục này đã chứa mã khóa. Bạn có chắc muốn ghi đè mã khóa hiện tại không?" + }, + "passkeyAlreadyExists": { + "message": "Ứng dụng này đã có mã khoá." + }, + "applicationDoesNotSupportDuplicates": { + "message": "Ứng dụng này không hỗ trợ các mục trùng lặp." + }, + "closeThisWindow": { + "message": "Đóng cửa sổ này" + }, "allowScreenshots": { "message": "Cho phép chụp màn hình" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "Và nhiều hơn nữa!" }, - "planDescPremium": { - "message": "Bảo mật trực tuyến toàn diện" + "advancedOnlineSecurity": { + "message": "Bảo mật trực tuyến nâng cao" }, "upgradeToPremium": { "message": "Nâng cấp lên gói Cao cấp" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "Your organization is no longer using master passwords to log into Bitwarden. To continue, verify the organization and domain." + }, + "continueWithLogIn": { + "message": "Continue with log in" + }, + "doNotContinue": { + "message": "Do not continue" + }, + "domain": { + "message": "Domain" + }, + "keyConnectorDomainTooltip": { + "message": "This domain will store your account encryption keys, so make sure you trust it. If you're not sure, check with your admin." + }, + "verifyYourOrganization": { + "message": "Verify your organization to log in" + }, + "organizationVerified": { + "message": "Organization verified" + }, + "domainVerified": { + "message": "Domain verified" + }, + "leaveOrganizationContent": { + "message": "If you don't verify your organization, your access to the organization will be revoked." + }, + "leaveNow": { + "message": "Leave now" + }, + "verifyYourDomainToLogin": { + "message": "Verify your domain to log in" + }, + "verifyYourDomainDescription": { + "message": "To continue with log in, verify this domain." + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "To continue with log in, verify the organization and domain." + }, "sessionTimeoutSettingsAction": { - "message": "Timeout action" + "message": "Hành động sau khi đóng kho" }, "sessionTimeoutHeader": { - "message": "Session timeout" + "message": "Thời gian hết phiên" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "Cài đặt này do tổ chức của bạn quản lý." + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "Tổ chức của bạn đã đặt thời gian chờ phiên tối đa là $HOURS$ giờ và $MINUTES$ phút.", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "Tổ chức của bạn đã đặt thời gian chờ phiên mặc định là Mỗi khi khóa máy." + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "Tổ chức của bạn đã đặt thời gian chờ phiên mặc định là Khi khởi động lại." + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "Thời gian chờ tối đa không thể vượt quá $HOURS$ giờ và $MINUTES$ phút", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "Khi khởi động lại máy" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "Đặt phương thức mở khóa để thay đổi hành động khi hết thời gian chờ" + }, + "upgrade": { + "message": "Nâng cấp" + }, + "leaveConfirmationDialogTitle": { + "message": "Bạn có chắc chắn muốn rời đi không?" + }, + "leaveConfirmationDialogContentOne": { + "message": "Bằng việc từ chối, các mục cá nhân sẽ vẫn nằm trong tài khoản của bạn, nhưng bạn sẽ mất quyền truy cập vào các mục được chia sẻ và tính năng tổ chức." + }, + "leaveConfirmationDialogContentTwo": { + "message": "Liên hệ quản trị viên của bạn để lấy lại quyền truy cập." + }, + "leaveConfirmationDialogConfirmButton": { + "message": "Rời khỏi $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "Tôi quản lý kho của mình như thế nào?" + }, + "transferItemsToOrganizationTitle": { + "message": "Chuyển các mục đến $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ yêu cầu tất cả các mục phải thuộc sở hữu của tổ chức để đảm bảo an ninh và tuân thủ. Nhấp chấp nhận để chuyển quyền sở hữu các mục của bạn.", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "Chấp nhận chuyển" + }, + "declineAndLeave": { + "message": "Từ chối và rời đi" + }, + "whyAmISeeingThis": { + "message": "Tại sao tôi thấy điều này?" } } diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index 70711c7aa4e..7d1c1648bb6 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "添加附件" }, + "itemsTransferred": { + "message": "项目已传输" + }, + "fixEncryption": { + "message": "修复加密" + }, + "fixEncryptionTooltip": { + "message": "此文件正在使用过时的加密方式。" + }, + "attachmentUpdated": { + "message": "附件已更新" + }, "maxFileSizeSansPunctuation": { "message": "文件最大为 500 MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "发生意外错误。" }, + "unexpectedErrorShort": { + "message": "意外错误" + }, + "closeThisBitwardenWindow": { + "message": "关闭此 Bitwarden 窗口,然后重试。" + }, "itemInformation": { "message": "项目信息" }, @@ -927,7 +945,7 @@ "message": "验证码" }, "confirmIdentity": { - "message": "确认后继续。" + "message": "确认您的身份以继续。" }, "verificationCodeRequired": { "message": "必须填写验证码。" @@ -1093,6 +1111,24 @@ "learnMore": { "message": "进一步了解" }, + "migrationsFailed": { + "message": "更新加密设置时发生错误。" + }, + "updateEncryptionSettingsTitle": { + "message": "更新您的加密设置" + }, + "updateEncryptionSettingsDesc": { + "message": "新推荐的加密设置将提高您的账户安全性。输入您的主密码以立即更新。" + }, + "confirmIdentityToContinue": { + "message": "确认您的身份以继续" + }, + "enterYourMasterPassword": { + "message": "输入您的主密码" + }, + "updateSettings": { + "message": "更新设置" + }, "featureUnavailable": { "message": "功能不可用" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "关注我们" }, - "syncVault": { - "message": "同步密码库" + "syncNow": { + "message": "立即同步" }, "changeMasterPass": { "message": "修改主密码" @@ -1241,7 +1277,7 @@ } }, "twoStepLoginConfirmation": { - "message": "两步登录要求您从其他设备(例如安全密钥、验证器 App、短信、电话或者电子邮件)来验证您的登录,这能使您的账户更加安全。两步登录需要在 bitwarden.com 网页版密码库中设置。现在访问此网站吗?" + "message": "两步登录要求您从其他设备(例如安全密钥、验证器 App、短信、电话或者电子邮件)来验证您的登录,这能使您的账户更加安全。两步登录需要在 bitwarden.com 网页版密码库中设置。现在要访问此网站吗?" }, "twoStepLogin": { "message": "两步登录" @@ -1435,7 +1471,7 @@ "message": "有可用的更新" }, "updateAvailableDesc": { - "message": "发现更新。是否立即下载?" + "message": "发现更新。要立即下载吗?" }, "restart": { "message": "重启" @@ -1476,7 +1512,7 @@ "message": "管理会员资格" }, "premiumManageAlert": { - "message": "您可以在 bitwarden.com 网页版密码库管理您的会员资格。现在要访问吗?" + "message": "您可以在 bitwarden.com 网页版密码库管理您的会员资格。现在要访问此网站吗?" }, "premiumRefresh": { "message": "刷新会员资格" @@ -1488,7 +1524,16 @@ "message": "注册高级会员将获得:" }, "premiumSignUpStorage": { - "message": "1 GB 文件附件加密存储。" + "message": "1 GB 文件附件加密存储空间。" + }, + "premiumSignUpStorageV2": { + "message": "$SIZE$ 文件附件加密存储空间。", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } }, "premiumSignUpTwoStepOptions": { "message": "专有的两步登录选项,如 YubiKey 和 Duo。" @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "导出自" }, - "exportVault": { - "message": "导出密码库" + "exportNoun": { + "message": "导出", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "导出", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "导入", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "导入", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "文件格式" @@ -1835,7 +1893,7 @@ "message": "无效的 PIN 码。" }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "无效的 PIN 输入尝试次数过多,正在注销。" + "message": "无效的 PIN 输入尝试次数过多。正在注销。" }, "unlockWithWindowsHello": { "message": "使用 Windows Hello 解锁" @@ -2148,7 +2206,7 @@ "message": "启用浏览器集成时出错" }, "browserIntegrationErrorDesc": { - "message": "启用浏览器集成时出错。" + "message": "启用浏览器集成时发生错误。" }, "browserIntegrationWindowsStoreDesc": { "message": "很遗憾,Microsoft Store 版本目前不支持浏览器集成。" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "联系信息" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "所有的 Send", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "主密码已移除" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "以下组织的成员不再需要主密码。请与您的组织管理员确认下面的域名。" - }, "organizationName": { "message": "组织名称" }, @@ -2991,7 +3050,8 @@ "message": "确定要使用「从不」选项吗?将锁定选项设置为「从不」会将密码库的加密密钥存储在您的设备上。如果使用此选项,您必须确保您的设备安全。" }, "vault": { - "message": "密码库" + "message": "密码库", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "使用主密码登录" @@ -3048,7 +3108,7 @@ "message": "请求获得批准后,您将收到通知" }, "needAnotherOption": { - "message": "必须在 Bitwarden App 的设置中启用设备登录。需要其他登录选项吗?" + "message": "必须在 Bitwarden App 的设置中启用设备登录。需要其他选项吗?" }, "viewAllLogInOptions": { "message": "查看所有登录选项" @@ -3171,10 +3231,10 @@ "message": "检查您的电子邮箱" }, "followTheLinkInTheEmailSentTo": { - "message": "点击发送到电子邮件中的链接" + "message": "点击发送到" }, "andContinueCreatingYourAccount": { - "message": "然后继续创建您的账户。" + "message": "的电子邮件中的链接,然后继续创建您的账户。" }, "noEmail": { "message": "没有收到电子邮件吗?" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "别名域" }, - "importData": { - "message": "导入数据", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "导入出错" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "文件已保存到设备。可以在设备下载中进行管理。" }, + "importantNotice": { + "message": "重要通知" + }, + "setupTwoStepLogin": { + "message": "设置两步登录" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "从 2025 年 02 月起,Bitwarden 将向您的账户电子邮箱发送验证码,以验证来自新设备的登录。" + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "您可以设置两步登录作为保护账户的替代方法,或将您的电子邮箱更改为您可以访问的电子邮箱。" + }, + "remindMeLater": { + "message": "稍后提醒我" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "您可以正常访问您的电子邮箱 $EMAIL$ 吗?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "不,我不能" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "是的,我可以正常访问我的电子邮箱" + }, + "turnOnTwoStepLogin": { + "message": "启用两步登录" + }, + "changeAcctEmail": { + "message": "更改账户电子邮箱" + }, + "passkeyLogin": { + "message": "使用通行密钥登录吗?" + }, + "savePasskeyQuestion": { + "message": "保存通行密钥吗?" + }, + "saveNewPasskey": { + "message": "保存为新的登录" + }, + "savePasskeyNewLogin": { + "message": "将通行密钥保存为新的登录" + }, + "noMatchingLoginsForSite": { + "message": "此站点没有匹配的登录" + }, + "overwritePasskey": { + "message": "覆盖通行密钥吗?" + }, + "unableToSavePasskey": { + "message": "无法保存通行密钥" + }, + "alreadyContainsPasskey": { + "message": "此项目已包含一个通行密钥。确定要覆盖当前的通行密钥吗?" + }, + "passkeyAlreadyExists": { + "message": "此应用程序已存在一个通行密钥。" + }, + "applicationDoesNotSupportDuplicates": { + "message": "此应用程序不支持重复项。" + }, + "closeThisWindow": { + "message": "关闭此窗口" + }, "allowScreenshots": { "message": "允许屏幕截图" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "以及更多!" }, - "planDescPremium": { - "message": "全面的在线安全防护" + "advancedOnlineSecurity": { + "message": "高级在线安全防护" }, "upgradeToPremium": { "message": "升级为高级版" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "您的组织已不再使用主密码登录 Bitwarden。要继续,请验证组织和域名。" + }, + "continueWithLogIn": { + "message": "继续登录" + }, + "doNotContinue": { + "message": "不要继续" + }, + "domain": { + "message": "域名" + }, + "keyConnectorDomainTooltip": { + "message": "此域名将存储您的账户加密密钥,所以请确保您信任它。如果您不确定,请与您的管理员联系。" + }, + "verifyYourOrganization": { + "message": "验证您的组织以登录" + }, + "organizationVerified": { + "message": "组织已验证" + }, + "domainVerified": { + "message": "域名已验证" + }, + "leaveOrganizationContent": { + "message": "如果不验证您的组织,您对组织的访问权限将被撤销。" + }, + "leaveNow": { + "message": "立即退出" + }, + "verifyYourDomainToLogin": { + "message": "验证您的域名以登录" + }, + "verifyYourDomainDescription": { + "message": "要继续登录,请验证此域名。" + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "要继续登录,请验证组织和域名。" + }, "sessionTimeoutSettingsAction": { "message": "超时动作" }, "sessionTimeoutHeader": { "message": "会话超时" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "此设置由您的组织管理。" + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "您的组织已将最大会话超时设置为 $HOURS$ 小时 $MINUTES$ 分钟。", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "您的组织已将默认会话超时设置为「系统锁定时」。" + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "您的组织已将默认会话超时设置为「重启时」。" + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "最大超时不能超过 $HOURS$ 小时 $MINUTES$ 分钟", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "重启时" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "设置一个解锁方式以更改您的超时动作" + }, + "upgrade": { + "message": "升级" + }, + "leaveConfirmationDialogTitle": { + "message": "确定要退出吗?" + }, + "leaveConfirmationDialogContentOne": { + "message": "拒绝后,您的个人项目将保留在您的账户中,但您将失去对共享项目和组织功能的访问权限。" + }, + "leaveConfirmationDialogContentTwo": { + "message": "联系您的管理员以重新获取访问权限。" + }, + "leaveConfirmationDialogConfirmButton": { + "message": "退出 $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "我该如何管理我的密码库?" + }, + "transferItemsToOrganizationTitle": { + "message": "传输项目到 $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "出于安全和合规考虑,$ORGANIZATION$ 要求所有项目归组织所有。点击「接受」以传输您的项目的所有权。", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "接受传输" + }, + "declineAndLeave": { + "message": "拒绝并退出" + }, + "whyAmISeeingThis": { + "message": "为什么我会看到这个?" } } diff --git a/apps/desktop/src/locales/zh_TW/messages.json b/apps/desktop/src/locales/zh_TW/messages.json index 61fc00543ed..7b5b352d5cb 100644 --- a/apps/desktop/src/locales/zh_TW/messages.json +++ b/apps/desktop/src/locales/zh_TW/messages.json @@ -708,6 +708,18 @@ "addAttachment": { "message": "新增附件" }, + "itemsTransferred": { + "message": "項目已轉移" + }, + "fixEncryption": { + "message": "修正加密" + }, + "fixEncryptionTooltip": { + "message": "此檔案使用了過時的加密方式。" + }, + "attachmentUpdated": { + "message": "附件已更新" + }, "maxFileSizeSansPunctuation": { "message": "最大檔案大小為 500MB" }, @@ -908,6 +920,12 @@ "unexpectedError": { "message": "發生了未預期的錯誤。" }, + "unexpectedErrorShort": { + "message": "未預期的錯誤" + }, + "closeThisBitwardenWindow": { + "message": "關閉此 Bitwarden 視窗後再試一次。" + }, "itemInformation": { "message": "項目資訊" }, @@ -1093,6 +1111,24 @@ "learnMore": { "message": "了解更多" }, + "migrationsFailed": { + "message": "更新加密設定時發生錯誤。" + }, + "updateEncryptionSettingsTitle": { + "message": "更新您的加密設定" + }, + "updateEncryptionSettingsDesc": { + "message": "新的建議加密設定將提升您的帳戶安全性。請輸入主密碼以立即更新。" + }, + "confirmIdentityToContinue": { + "message": "請先確認身分後再繼續" + }, + "enterYourMasterPassword": { + "message": "輸入您的主密碼" + }, + "updateSettings": { + "message": "更新設定" + }, "featureUnavailable": { "message": "功能不可用" }, @@ -1162,8 +1198,8 @@ "followUs": { "message": "關注我們" }, - "syncVault": { - "message": "同步密碼庫" + "syncNow": { + "message": "立即同步" }, "changeMasterPass": { "message": "變更主密碼" @@ -1490,6 +1526,15 @@ "premiumSignUpStorage": { "message": "用於檔案附件的 1 GB 的加密檔案儲存空間。" }, + "premiumSignUpStorageV2": { + "message": "用於檔案附件的 $SIZE$ 加密儲存空間。", + "placeholders": { + "size": { + "content": "$1", + "example": "1 GB" + } + } + }, "premiumSignUpTwoStepOptions": { "message": "專有的兩步驟登入選項,例如 YubiKey 和 Duo。" }, @@ -1730,8 +1775,21 @@ "exportFrom": { "message": "匯出自" }, - "exportVault": { - "message": "匯出密碼庫" + "exportNoun": { + "message": "匯出", + "description": "The noun form of the word Export" + }, + "exportVerb": { + "message": "匯出", + "description": "The verb form of the word Export" + }, + "importNoun": { + "message": "匯入", + "description": "The noun form of the word Import" + }, + "importVerb": { + "message": "匯入", + "description": "The verb form of the word Import" }, "fileFormat": { "message": "檔案格式" @@ -2228,6 +2286,10 @@ "contactInfo": { "message": "聯絡資訊" }, + "send": { + "message": "Send", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "allSends": { "message": "所有 Send", "description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2588,9 +2650,6 @@ "removedMasterPassword": { "message": "主密碼已移除" }, - "removeMasterPasswordForOrganizationUserKeyConnector": { - "message": "以下組織的成員已不再需要主密碼。請與你的組織管理員確認下方的網域。" - }, "organizationName": { "message": "機構名稱" }, @@ -2991,7 +3050,8 @@ "message": "您確定要使用「永不」選項嗎?將鎖定選項設定為「永不」會將密碼庫的加密金鑰儲存在您的裝置上。如果使用此選項,應確保您的裝置是安全的。" }, "vault": { - "message": "密碼庫" + "message": "密碼庫", + "description": "'Vault' is a noun and refers to the Bitwarden Vault feature." }, "loginWithMasterPassword": { "message": "使用主密碼登入" @@ -3445,10 +3505,6 @@ "aliasDomain": { "message": "別名網域" }, - "importData": { - "message": "匯入資料", - "description": "Used for the desktop menu item and the header of the import dialog" - }, "importError": { "message": "匯入時發生錯誤" }, @@ -3854,6 +3910,75 @@ "fileSavedToDevice": { "message": "檔案已儲存到裝置。在您的裝置上管理下載檔案。" }, + "importantNotice": { + "message": "重要通知" + }, + "setupTwoStepLogin": { + "message": "啟動兩階段登入" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "從 2025 年 2 月開始,Bitwarden 會傳送代碼到您的帳號電子郵件中來驗證新裝置的登入。" + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "您可以啟動兩階段認證來保護您的帳號或更改您可以存取的電子郵件位址。" + }, + "remindMeLater": { + "message": "稍後再提醒我" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "您可以存取您的電子郵件位址 $EMAIL$ 嗎?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "不,我不行" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "是,我可以存取我的電子郵件位址" + }, + "turnOnTwoStepLogin": { + "message": "啟動兩階段登入" + }, + "changeAcctEmail": { + "message": "更改帳號電子郵件位址" + }, + "passkeyLogin": { + "message": "使用密碼金鑰登入?" + }, + "savePasskeyQuestion": { + "message": "儲存密碼金鑰?" + }, + "saveNewPasskey": { + "message": "儲存為新的登入資訊" + }, + "savePasskeyNewLogin": { + "message": "將密碼金鑰儲存為新的登入資訊" + }, + "noMatchingLoginsForSite": { + "message": "未找到此網站的登入資訊" + }, + "overwritePasskey": { + "message": "要覆寫密碼金鑰嗎?" + }, + "unableToSavePasskey": { + "message": "無法儲存通行金鑰" + }, + "alreadyContainsPasskey": { + "message": "該項目已包含一個密碼金鑰。您確定要覆寫目前的密碼金鑰嗎?" + }, + "passkeyAlreadyExists": { + "message": "用於這個應用程式的密碼金鑰已經存在。" + }, + "applicationDoesNotSupportDuplicates": { + "message": "此應用程式不支援重複項目。" + }, + "closeThisWindow": { + "message": "關閉此視窗" + }, "allowScreenshots": { "message": "允許螢幕擷取" }, @@ -4212,16 +4337,147 @@ "andMoreFeatures": { "message": "以及其他功能功能!" }, - "planDescPremium": { - "message": "完整的線上安全" + "advancedOnlineSecurity": { + "message": "進階線上安全防護" }, "upgradeToPremium": { "message": "升級到 Premium" }, + "removeMasterPasswordForOrgUserKeyConnector": { + "message": "您的組織已不再使用主密碼登入 Bitwarden。若要繼續,請驗證組織與網域。" + }, + "continueWithLogIn": { + "message": "繼續登入" + }, + "doNotContinue": { + "message": "不要繼續" + }, + "domain": { + "message": "網域" + }, + "keyConnectorDomainTooltip": { + "message": "此網域將儲存您帳號的加密金鑰,請確認您信任它。若不確定,請洽詢您的管理員。" + }, + "verifyYourOrganization": { + "message": "驗證您的組織以登入" + }, + "organizationVerified": { + "message": "組織已驗證" + }, + "domainVerified": { + "message": "已驗證網域" + }, + "leaveOrganizationContent": { + "message": "若您未驗證組織,將會被撤銷對該組織的存取權限。" + }, + "leaveNow": { + "message": "立即離開" + }, + "verifyYourDomainToLogin": { + "message": "驗證您的網域以登入" + }, + "verifyYourDomainDescription": { + "message": "若要繼續登入,請驗證此網域。" + }, + "confirmKeyConnectorOrganizationUserDescription": { + "message": "若要繼續登入,請驗證組織與網域。" + }, "sessionTimeoutSettingsAction": { "message": "逾時後動作" }, "sessionTimeoutHeader": { "message": "工作階段逾時" + }, + "sessionTimeoutSettingsManagedByOrganization": { + "message": "此設定由您的組織管理。" + }, + "sessionTimeoutSettingsPolicySetMaximumTimeoutToHoursMinutes": { + "message": "您的組織已將最長工作階段逾時設為 $HOURS$ 小時與 $MINUTES$ 分鐘。", + "placeholders": { + "hours": { + "content": "$1", + "example": "8" + }, + "minutes": { + "content": "$2", + "example": "2" + } + } + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnLocked": { + "message": "您的組織已將預設工作階段逾時設定為「在系統鎖定時」。" + }, + "sessionTimeoutSettingsPolicySetDefaultTimeoutToOnRestart": { + "message": "您的組織已將預設工作階段逾時設定為「在重新啟動時」。" + }, + "sessionTimeoutSettingsPolicyMaximumError": { + "message": "最長逾時時間不可超過 $HOURS$ 小時 $MINUTES$ 分鐘", + "placeholders": { + "hours": { + "content": "$1", + "example": "5" + }, + "minutes": { + "content": "$2", + "example": "5" + } + } + }, + "sessionTimeoutOnRestart": { + "message": "重新啟動時" + }, + "sessionTimeoutSettingsSetUnlockMethodToChangeTimeoutAction": { + "message": "設定一個解鎖方式來變更您的密碼庫逾時動作。" + }, + "upgrade": { + "message": "升級" + }, + "leaveConfirmationDialogTitle": { + "message": "確定要離開嗎?" + }, + "leaveConfirmationDialogContentOne": { + "message": "若選擇拒絕,您的個人項目將保留在帳號中,但您將失去對共用項目與組織功能的存取權。" + }, + "leaveConfirmationDialogContentTwo": { + "message": "請聯絡您的管理員以重新取得存取權限。" + }, + "leaveConfirmationDialogConfirmButton": { + "message": "離開 $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "howToManageMyVault": { + "message": "我要如何管理我的密碼庫?" + }, + "transferItemsToOrganizationTitle": { + "message": "將項目轉移至 $ORGANIZATION$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "transferItemsToOrganizationContent": { + "message": "$ORGANIZATION$ 為了安全性與合規性,要求所有項目皆由組織擁有。點擊接受即可轉移您項目的擁有權。", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + } + } + }, + "acceptTransfer": { + "message": "同意轉移" + }, + "declineAndLeave": { + "message": "拒絕並離開" + }, + "whyAmISeeingThis": { + "message": "為什麼我會看到此訊息?" } } diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index fbb83a1bf56..4734288f3c1 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -311,17 +311,8 @@ export class Main { this.windowMain, ); - app - .whenReady() - .then(() => { - this.mainDesktopAutotypeService.init(); - }) - .catch((reason) => { - this.logService.error("Error initializing Autotype.", reason); - }); - app.on("will-quit", () => { - this.mainDesktopAutotypeService.disableAutotype(); + this.mainDesktopAutotypeService.dispose(); }); } diff --git a/apps/desktop/src/main/menu/menu.file.ts b/apps/desktop/src/main/menu/menu.file.ts index a8cdb347a77..d5e8cb468f9 100644 --- a/apps/desktop/src/main/menu/menu.file.ts +++ b/apps/desktop/src/main/menu/menu.file.ts @@ -146,8 +146,8 @@ export class FileMenu extends FirstMenu implements IMenubarMenu { private get syncVault(): MenuItemConstructorOptions { return { - id: "syncVault", - label: this.localize("syncVault"), + id: "syncNow", + label: this.localize("syncNow"), click: () => this.sendMessage("syncVault"), enabled: this.hasAuthenticatedAccounts, }; @@ -155,8 +155,8 @@ export class FileMenu extends FirstMenu implements IMenubarMenu { private get importVault(): MenuItemConstructorOptions { return { - id: "importVault", - label: this.localize("importData"), + id: "import", + label: this.localize("importNoun"), click: () => this.sendMessage("importVault"), enabled: !this._isLocked, }; @@ -164,8 +164,8 @@ export class FileMenu extends FirstMenu implements IMenubarMenu { private get exportVault(): MenuItemConstructorOptions { return { - id: "exportVault", - label: this.localize("exportVault"), + id: "export", + label: this.localize("exportNoun"), click: () => this.sendMessage("exportVault"), enabled: !this._isLocked, }; diff --git a/apps/desktop/src/main/native-messaging.main.ts b/apps/desktop/src/main/native-messaging.main.ts index ba5d8616752..a0c17a115e0 100644 --- a/apps/desktop/src/main/native-messaging.main.ts +++ b/apps/desktop/src/main/native-messaging.main.ts @@ -14,7 +14,7 @@ import { isDev } from "../utils"; import { WindowMain } from "./window.main"; export class NativeMessagingMain { - private ipcServer: ipc.IpcServer | null; + private ipcServer: ipc.NativeIpcServer | null; private connected: number[] = []; constructor( @@ -78,7 +78,7 @@ export class NativeMessagingMain { this.ipcServer.stop(); } - this.ipcServer = await ipc.IpcServer.listen("bw", (error, msg) => { + this.ipcServer = await ipc.NativeIpcServer.listen("bw", (error, msg) => { switch (msg.kind) { case ipc.IpcMessageType.Connected: { this.connected.push(msg.clientId); @@ -314,6 +314,7 @@ export class NativeMessagingMain { "Microsoft Edge Canary": `${this.homedir()}/Library/Application\ Support/Microsoft\ Edge\ Canary/`, Vivaldi: `${this.homedir()}/Library/Application\ Support/Vivaldi/`, Zen: `${this.homedir()}/Library/Application\ Support/Zen/`, + Helium: `${this.homedir()}/Library/Application\ Support/net.imput.helium/`, }; /* eslint-enable no-useless-escape */ } diff --git a/apps/desktop/src/main/tray.main.ts b/apps/desktop/src/main/tray.main.ts index b7ddefe6e1b..81df6497ca8 100644 --- a/apps/desktop/src/main/tray.main.ts +++ b/apps/desktop/src/main/tray.main.ts @@ -53,9 +53,14 @@ export class TrayMain { }, { visible: isDev(), - label: "Fake Popup", + label: "Fake Popup Select", click: () => this.fakePopup(), }, + { + visible: isDev(), + label: "Fake Popup Create", + click: () => this.fakePopupCreate(), + }, { type: "separator" }, { label: this.i18nService.t("exit"), @@ -218,4 +223,8 @@ export class TrayMain { private async fakePopup() { await this.messagingService.send("loadurl", { url: "/passkeys", modal: true }); } + + private async fakePopupCreate() { + await this.messagingService.send("loadurl", { url: "/create-passkey", modal: true }); + } } diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index 0e234126ea3..bbdd2ad0a0f 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -100,10 +100,10 @@ export class WindowMain { applyMainWindowStyles(this.win, this.windowStates[mainWindowSizeKey]); // Because modal is used in front of another app, UX wise it makes sense to hide the main window when leaving modal mode. this.win.hide(); - } else if (!lastValue.isModalModeActive && newValue.isModalModeActive) { + } else if (newValue.isModalModeActive) { // Apply the popup modal styles this.logService.info("Applying popup modal styles", newValue.modalPosition); - applyPopupModalStyles(this.win, newValue.modalPosition); + applyPopupModalStyles(this.win, newValue.showTrafficButtons, newValue.modalPosition); this.win.show(); } }), @@ -273,7 +273,7 @@ export class WindowMain { this.win = new BrowserWindow({ width: this.windowStates[mainWindowSizeKey].width, height: this.windowStates[mainWindowSizeKey].height, - minWidth: 680, + minWidth: 600, minHeight: 500, x: this.windowStates[mainWindowSizeKey].x, y: this.windowStates[mainWindowSizeKey].y, diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json index 44fdb5c23b0..9d8eae15791 100644 --- a/apps/desktop/src/package-lock.json +++ b/apps/desktop/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/desktop", - "version": "2025.12.0", + "version": "2025.12.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "2025.12.0", + "version": "2025.12.1", "license": "GPL-3.0", "dependencies": { "@bitwarden/desktop-napi": "file:../desktop_native/napi" diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json index 4c396304f4a..2ac5d339a95 100644 --- a/apps/desktop/src/package.json +++ b/apps/desktop/src/package.json @@ -2,7 +2,7 @@ "name": "@bitwarden/desktop", "productName": "Bitwarden", "description": "A secure and free password manager for all of your devices.", - "version": "2025.12.0", + "version": "2025.12.1", "author": "Bitwarden Inc. (https://bitwarden.com)", "homepage": "https://bitwarden.com", "license": "GPL-3.0", diff --git a/apps/desktop/src/platform/components/approve-ssh-request.html b/apps/desktop/src/platform/components/approve-ssh-request.html index 55092788079..c691891487e 100644 --- a/apps/desktop/src/platform/components/approve-ssh-request.html +++ b/apps/desktop/src/platform/components/approve-ssh-request.html @@ -2,13 +2,11 @@
{{ "sshkeyApprovalTitle" | i18n }}
- + @if (params.isAgentForwarding) { + {{ 'agentForwardingWarningText' | i18n }} - + + } {{params.applicationName}} {{ "sshkeyApprovalMessageInfix" | i18n }} {{params.cipherName}} diff --git a/apps/desktop/src/platform/components/approve-ssh-request.ts b/apps/desktop/src/platform/components/approve-ssh-request.ts index 1741124774d..a2cae3d59e7 100644 --- a/apps/desktop/src/platform/components/approve-ssh-request.ts +++ b/apps/desktop/src/platform/components/approve-ssh-request.ts @@ -12,6 +12,7 @@ import { FormFieldModule, IconButtonModule, DialogService, + CalloutModule, } from "@bitwarden/components"; export interface ApproveSshRequestParams { @@ -35,6 +36,7 @@ export interface ApproveSshRequestParams { ReactiveFormsModule, AsyncActionsModule, FormFieldModule, + CalloutModule, ], }) export class ApproveSshRequestComponent { diff --git a/apps/desktop/src/platform/main/autofill/native-autofill.main.ts b/apps/desktop/src/platform/main/autofill/native-autofill.main.ts index 71cfcab84ba..c0d860d74db 100644 --- a/apps/desktop/src/platform/main/autofill/native-autofill.main.ts +++ b/apps/desktop/src/platform/main/autofill/native-autofill.main.ts @@ -7,6 +7,11 @@ import { WindowMain } from "../../../main/window.main"; import { CommandDefinition } from "./command"; +type BufferedMessage = { + channel: string; + data: any; +}; + export type RunCommandParams = { namespace: C["namespace"]; command: C["name"]; @@ -16,13 +21,44 @@ export type RunCommandParams = { export type RunCommandResult = C["output"]; export class NativeAutofillMain { - private ipcServer: autofill.IpcServer | null; + private ipcServer?: autofill.AutofillIpcServer; + private messageBuffer: BufferedMessage[] = []; + private listenerReady = false; constructor( private logService: LogService, private windowMain: WindowMain, ) {} + /** + * Safely sends a message to the renderer, buffering it if the server isn't ready yet + */ + private safeSend(channel: string, data: any) { + if (this.listenerReady && this.windowMain.win?.webContents) { + this.windowMain.win.webContents.send(channel, data); + } else { + this.messageBuffer.push({ channel, data }); + } + } + + /** + * Flushes all buffered messages to the renderer + */ + private flushMessageBuffer() { + if (!this.windowMain.win?.webContents) { + this.logService.error("Cannot flush message buffer - window not available"); + return; + } + + this.logService.info(`Flushing ${this.messageBuffer.length} buffered messages`); + + for (const { channel, data } of this.messageBuffer) { + this.windowMain.win.webContents.send(channel, data); + } + + this.messageBuffer = []; + } + async init() { ipcMain.handle( "autofill.runCommand", @@ -34,16 +70,16 @@ export class NativeAutofillMain { }, ); - this.ipcServer = await autofill.IpcServer.listen( + this.ipcServer = await autofill.AutofillIpcServer.listen( "af", // RegistrationCallback (error, clientId, sequenceNumber, request) => { if (error) { this.logService.error("autofill.IpcServer.registration", error); - this.ipcServer.completeError(clientId, sequenceNumber, String(error)); + this.ipcServer?.completeError(clientId, sequenceNumber, String(error)); return; } - this.windowMain.win.webContents.send("autofill.passkeyRegistration", { + this.safeSend("autofill.passkeyRegistration", { clientId, sequenceNumber, request, @@ -53,10 +89,10 @@ export class NativeAutofillMain { (error, clientId, sequenceNumber, request) => { if (error) { this.logService.error("autofill.IpcServer.assertion", error); - this.ipcServer.completeError(clientId, sequenceNumber, String(error)); + this.ipcServer?.completeError(clientId, sequenceNumber, String(error)); return; } - this.windowMain.win.webContents.send("autofill.passkeyAssertion", { + this.safeSend("autofill.passkeyAssertion", { clientId, sequenceNumber, request, @@ -66,33 +102,54 @@ export class NativeAutofillMain { (error, clientId, sequenceNumber, request) => { if (error) { this.logService.error("autofill.IpcServer.assertion", error); - this.ipcServer.completeError(clientId, sequenceNumber, String(error)); + this.ipcServer?.completeError(clientId, sequenceNumber, String(error)); return; } - this.windowMain.win.webContents.send("autofill.passkeyAssertionWithoutUserInterface", { + this.safeSend("autofill.passkeyAssertionWithoutUserInterface", { clientId, sequenceNumber, request, }); }, + // NativeStatusCallback + (error, clientId, sequenceNumber, status) => { + if (error) { + this.logService.error("autofill.IpcServer.nativeStatus", error); + this.ipcServer?.completeError(clientId, sequenceNumber, String(error)); + return; + } + this.safeSend("autofill.nativeStatus", { + clientId, + sequenceNumber, + status, + }); + }, ); + ipcMain.on("autofill.listenerReady", () => { + this.listenerReady = true; + this.logService.info( + `Listener is ready, flushing ${this.messageBuffer.length} buffered messages`, + ); + this.flushMessageBuffer(); + }); + ipcMain.on("autofill.completePasskeyRegistration", (event, data) => { - this.logService.warning("autofill.completePasskeyRegistration", data); + this.logService.debug("autofill.completePasskeyRegistration", data); const { clientId, sequenceNumber, response } = data; - this.ipcServer.completeRegistration(clientId, sequenceNumber, response); + this.ipcServer?.completeRegistration(clientId, sequenceNumber, response); }); ipcMain.on("autofill.completePasskeyAssertion", (event, data) => { - this.logService.warning("autofill.completePasskeyAssertion", data); + this.logService.debug("autofill.completePasskeyAssertion", data); const { clientId, sequenceNumber, response } = data; - this.ipcServer.completeAssertion(clientId, sequenceNumber, response); + this.ipcServer?.completeAssertion(clientId, sequenceNumber, response); }); ipcMain.on("autofill.completeError", (event, data) => { - this.logService.warning("autofill.completeError", data); + this.logService.debug("autofill.completeError", data); const { clientId, sequenceNumber, error } = data; - this.ipcServer.completeError(clientId, sequenceNumber, String(error)); + this.ipcServer?.completeError(clientId, sequenceNumber, String(error)); }); } diff --git a/apps/desktop/src/platform/models/domain/window-state.ts b/apps/desktop/src/platform/models/domain/window-state.ts index 0efc9a1efab..ab52531bb5d 100644 --- a/apps/desktop/src/platform/models/domain/window-state.ts +++ b/apps/desktop/src/platform/models/domain/window-state.ts @@ -14,5 +14,6 @@ export class WindowState { export class ModalModeState { isModalModeActive: boolean; + showTrafficButtons?: boolean; modalPosition?: { x: number; y: number }; // Modal position is often passed from the native UI } diff --git a/apps/desktop/src/platform/popup-modal-styles.ts b/apps/desktop/src/platform/popup-modal-styles.ts index 5c5619bd463..6ad00b44171 100644 --- a/apps/desktop/src/platform/popup-modal-styles.ts +++ b/apps/desktop/src/platform/popup-modal-styles.ts @@ -3,15 +3,19 @@ import { BrowserWindow } from "electron"; import { WindowState } from "./models/domain/window-state"; // change as needed, however limited by mainwindow minimum size -const popupWidth = 680; -const popupHeight = 500; +const popupWidth = 600; +const popupHeight = 600; type Position = { x: number; y: number }; -export function applyPopupModalStyles(window: BrowserWindow, position?: Position) { +export function applyPopupModalStyles( + window: BrowserWindow, + showTrafficButtons: boolean = true, + position?: Position, +) { window.unmaximize(); window.setSize(popupWidth, popupHeight); - window.setWindowButtonVisibility?.(false); + window.setWindowButtonVisibility?.(showTrafficButtons); window.setMenuBarVisibility?.(false); window.setResizable(false); window.setAlwaysOnTop(true); @@ -40,7 +44,7 @@ function positionWindow(window: BrowserWindow, position?: Position) { } export function applyMainWindowStyles(window: BrowserWindow, existingWindowState: WindowState) { - window.setMinimumSize(680, 500); + window.setMinimumSize(popupWidth, popupHeight); // need to guard against null/undefined values diff --git a/apps/desktop/src/platform/preload.ts b/apps/desktop/src/platform/preload.ts index 5af2fa571ec..5f643242a9c 100644 --- a/apps/desktop/src/platform/preload.ts +++ b/apps/desktop/src/platform/preload.ts @@ -17,6 +17,7 @@ import { isFlatpak, isMacAppStore, isSnapStore, + isWindowsPortable, isWindowsStore, } from "../utils"; @@ -108,8 +109,13 @@ const ephemeralStore = { }; const localhostCallbackService = { - openSsoPrompt: (codeChallenge: string, state: string, email: string): Promise => { - return ipcRenderer.invoke("openSsoPrompt", { codeChallenge, state, email }); + openSsoPrompt: ( + codeChallenge: string, + state: string, + email: string, + orgSsoIdentifier?: string, + ): Promise => { + return ipcRenderer.invoke("openSsoPrompt", { codeChallenge, state, email, orgSsoIdentifier }); }, }; @@ -128,6 +134,7 @@ export default { isDev: isDev(), isMacAppStore: isMacAppStore(), isWindowsStore: isWindowsStore(), + isWindowsPortable: isWindowsPortable(), isFlatpak: isFlatpak(), isSnapStore: isSnapStore(), isAppImage: isAppImage(), diff --git a/apps/desktop/src/platform/services/desktop-settings.service.ts b/apps/desktop/src/platform/services/desktop-settings.service.ts index c11f10646d7..d7c17433471 100644 --- a/apps/desktop/src/platform/services/desktop-settings.service.ts +++ b/apps/desktop/src/platform/services/desktop-settings.service.ts @@ -335,9 +335,14 @@ export class DesktopSettingsService { * Sets the modal mode of the application. Setting this changes the windows-size and other properties. * @param value `true` if the application is in modal mode, `false` if it is not. */ - async setModalMode(value: boolean, modalPosition?: { x: number; y: number }) { + async setModalMode( + value: boolean, + showTrafficButtons?: boolean, + modalPosition?: { x: number; y: number }, + ) { await this.modalModeState.update(() => ({ isModalModeActive: value, + showTrafficButtons, modalPosition, })); } diff --git a/apps/desktop/src/platform/services/electron-log.main.service.ts b/apps/desktop/src/platform/services/electron-log.main.service.ts index 947f4449271..e148f7a45c8 100644 --- a/apps/desktop/src/platform/services/electron-log.main.service.ts +++ b/apps/desktop/src/platform/services/electron-log.main.service.ts @@ -22,7 +22,7 @@ export class ElectronLogMainService extends BaseLogService { return; } - log.transports.file.level = "info"; + log.transports.file.level = isDev() ? "debug" : "info"; if (this.logDir != null) { log.transports.file.resolvePathFn = () => path.join(this.logDir, "app.log"); } diff --git a/apps/desktop/src/platform/services/sso-localhost-callback.service.ts b/apps/desktop/src/platform/services/sso-localhost-callback.service.ts index 75a84919b07..fdd9bc29237 100644 --- a/apps/desktop/src/platform/services/sso-localhost-callback.service.ts +++ b/apps/desktop/src/platform/services/sso-localhost-callback.service.ts @@ -25,20 +25,25 @@ export class SSOLocalhostCallbackService { private messagingService: MessageSender, private ssoUrlService: SsoUrlService, ) { - ipcMain.handle("openSsoPrompt", async (event, { codeChallenge, state, email }) => { - // Close any existing server before starting new one - if (this.currentServer) { - await this.closeCurrentServer(); - } + ipcMain.handle( + "openSsoPrompt", + async (event, { codeChallenge, state, email, orgSsoIdentifier }) => { + // Close any existing server before starting new one + if (this.currentServer) { + await this.closeCurrentServer(); + } - return this.openSsoPrompt(codeChallenge, state, email).then(({ ssoCode, recvState }) => { - this.messagingService.send("ssoCallback", { - code: ssoCode, - state: recvState, - redirectUri: this.ssoRedirectUri, - }); - }); - }); + return this.openSsoPrompt(codeChallenge, state, email, orgSsoIdentifier).then( + ({ ssoCode, recvState }) => { + this.messagingService.send("ssoCallback", { + code: ssoCode, + state: recvState, + redirectUri: this.ssoRedirectUri, + }); + }, + ); + }, + ); } private async closeCurrentServer(): Promise { @@ -58,6 +63,7 @@ export class SSOLocalhostCallbackService { codeChallenge: string, state: string, email: string, + orgSsoIdentifier?: string, ): Promise<{ ssoCode: string; recvState: string }> { const env = await firstValueFrom(this.environmentService.environment$); @@ -121,6 +127,7 @@ export class SSOLocalhostCallbackService { state, codeChallenge, email, + orgSsoIdentifier, ); // Set up error handler before attempting to listen diff --git a/apps/desktop/src/scss/migration.scss b/apps/desktop/src/scss/migration.scss new file mode 100644 index 00000000000..e3078158283 --- /dev/null +++ b/apps/desktop/src/scss/migration.scss @@ -0,0 +1,15 @@ +/** + * Desktop UI Migration + * + * These are temporary styles during the desktop ui migration. + **/ + +/** + * This removes any padding applied by the bit-layout to content. + * This should be revisited once the table is migrated, and again once drawers are migrated. + **/ +bit-layout { + #main-content { + padding: 0 0 0 0; + } +} diff --git a/apps/desktop/src/scss/styles.scss b/apps/desktop/src/scss/styles.scss index c579e6acdc0..b4082afd38c 100644 --- a/apps/desktop/src/scss/styles.scss +++ b/apps/desktop/src/scss/styles.scss @@ -15,5 +15,6 @@ @import "left-nav.scss"; @import "loading.scss"; @import "plugins.scss"; +@import "migration.scss"; @import "../../../../libs/angular/src/scss/icons.scss"; @import "../../../../libs/components/src/multi-select/scss/bw.theme"; diff --git a/apps/desktop/src/services/biometric-message-handler.service.spec.ts b/apps/desktop/src/services/biometric-message-handler.service.spec.ts index 49d346bfa3a..3b343fcc0fb 100644 --- a/apps/desktop/src/services/biometric-message-handler.service.spec.ts +++ b/apps/desktop/src/services/biometric-message-handler.service.spec.ts @@ -2,7 +2,7 @@ import { NgZone } from "@angular/core"; import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject, filter, firstValueFrom, of, take, timeout, timer } from "rxjs"; -import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; @@ -10,7 +10,7 @@ import { EncryptService } from "@bitwarden/common/key-management/crypto/abstract import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { FakeAccountService } from "@bitwarden/common/spec"; +import { mockAccountInfoWith, FakeAccountService } from "@bitwarden/common/spec"; import { CsprngArray } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { DialogService } from "@bitwarden/components"; @@ -23,17 +23,15 @@ import { BiometricMessageHandlerService } from "./biometric-message-handler.serv const SomeUser = "SomeUser" as UserId; const AnotherUser = "SomeOtherUser" as UserId; -const accounts: Record = { - [SomeUser]: { +const accounts = { + [SomeUser]: mockAccountInfoWith({ name: "some user", email: "some.user@example.com", - emailVerified: true, - }, - [AnotherUser]: { + }), + [AnotherUser]: mockAccountInfoWith({ name: "some other user", email: "some.other.user@example.com", - emailVerified: true, - }, + }), }; describe("BiometricMessageHandlerService", () => { diff --git a/apps/desktop/src/vault/app/vault/item-footer.component.ts b/apps/desktop/src/vault/app/vault/item-footer.component.ts index 0034bd9a43c..0ac12c928f2 100644 --- a/apps/desktop/src/vault/app/vault/item-footer.component.ts +++ b/apps/desktop/src/vault/app/vault/item-footer.component.ts @@ -225,7 +225,7 @@ export class ItemFooterComponent implements OnInit, OnChanges { switchMap((id) => combineLatest([ this.cipherArchiveService.userCanArchive$(id), - this.cipherArchiveService.hasArchiveFlagEnabled$(), + this.cipherArchiveService.hasArchiveFlagEnabled$, ]), ), ), diff --git a/apps/desktop/tailwind.config.js b/apps/desktop/tailwind.config.js index e67c0c38010..0c4ed8c5a7e 100644 --- a/apps/desktop/tailwind.config.js +++ b/apps/desktop/tailwind.config.js @@ -10,6 +10,7 @@ config.content = [ "../../libs/angular/src/**/*.{html,ts}", "../../libs/vault/src/**/*.{html,ts,mdx}", "../../libs/pricing/src/**/*.{html,ts}", + "../../libs/tools/send/send-ui/src/**/*.{html,ts}", ]; module.exports = config; diff --git a/apps/web/README.md b/apps/web/README.md index c5e03eebb59..0640d7199af 100644 --- a/apps/web/README.md +++ b/apps/web/README.md @@ -1,3 +1,5 @@ +# Bitwarden Web App +

diff --git a/apps/web/package.json b/apps/web/package.json index 344a78f2a2c..a5399de920e 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/web-vault", - "version": "2025.12.0", + "version": "2025.12.1", "scripts": { "build:oss": "webpack", "build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js", diff --git a/apps/web/src/app/admin-console/common/people-table-data-source.spec.ts b/apps/web/src/app/admin-console/common/people-table-data-source.spec.ts new file mode 100644 index 00000000000..e9cf87a114d --- /dev/null +++ b/apps/web/src/app/admin-console/common/people-table-data-source.spec.ts @@ -0,0 +1,130 @@ +import { TestBed } from "@angular/core/testing"; +import { ReplaySubject } from "rxjs"; + +import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; +import { + Environment, + EnvironmentService, +} from "@bitwarden/common/platform/abstractions/environment.service"; + +import { PeopleTableDataSource } from "./people-table-data-source"; + +interface MockUser { + id: string; + name: string; + email: string; + status: OrganizationUserStatusType; + checked?: boolean; +} + +class TestPeopleTableDataSource extends PeopleTableDataSource { + protected statusType = OrganizationUserStatusType; +} + +describe("PeopleTableDataSource", () => { + let dataSource: TestPeopleTableDataSource; + + const createMockUser = (id: string, checked: boolean = false): MockUser => ({ + id, + name: `User ${id}`, + email: `user${id}@example.com`, + status: OrganizationUserStatusType.Confirmed, + checked, + }); + + const createMockUsers = (count: number, checked: boolean = false): MockUser[] => { + return Array.from({ length: count }, (_, i) => createMockUser(`${i + 1}`, checked)); + }; + + beforeEach(() => { + const featureFlagSubject = new ReplaySubject(1); + featureFlagSubject.next(false); + + const environmentSubject = new ReplaySubject(1); + environmentSubject.next({ + isCloud: () => false, + } as Environment); + + const mockConfigService = { + getFeatureFlag$: jest.fn(() => featureFlagSubject.asObservable()), + } as any; + + const mockEnvironmentService = { + environment$: environmentSubject.asObservable(), + } as any; + + TestBed.configureTestingModule({ + providers: [ + { provide: ConfigService, useValue: mockConfigService }, + { provide: EnvironmentService, useValue: mockEnvironmentService }, + ], + }); + + dataSource = TestBed.runInInjectionContext( + () => new TestPeopleTableDataSource(mockConfigService, mockEnvironmentService), + ); + }); + + describe("limitAndUncheckExcess", () => { + it("should return all users when under limit", () => { + const users = createMockUsers(10, true); + dataSource.data = users; + + const result = dataSource.limitAndUncheckExcess(users, 500); + + expect(result).toHaveLength(10); + expect(result).toEqual(users); + expect(users.every((u) => u.checked)).toBe(true); + }); + + it("should limit users and uncheck excess", () => { + const users = createMockUsers(600, true); + dataSource.data = users; + + const result = dataSource.limitAndUncheckExcess(users, 500); + + expect(result).toHaveLength(500); + expect(result).toEqual(users.slice(0, 500)); + expect(users.slice(0, 500).every((u) => u.checked)).toBe(true); + expect(users.slice(500).every((u) => u.checked)).toBe(false); + }); + + it("should only affect users in the provided array", () => { + const allUsers = createMockUsers(1000, true); + dataSource.data = allUsers; + + // Pass only a subset (simulates filtering by status) + const subset = allUsers.slice(0, 600); + + const result = dataSource.limitAndUncheckExcess(subset, 500); + + expect(result).toHaveLength(500); + expect(subset.slice(0, 500).every((u) => u.checked)).toBe(true); + expect(subset.slice(500).every((u) => u.checked)).toBe(false); + // Users outside subset remain checked + expect(allUsers.slice(600).every((u) => u.checked)).toBe(true); + }); + }); + + describe("status counts", () => { + it("should correctly count users by status", () => { + const users: MockUser[] = [ + { ...createMockUser("1"), status: OrganizationUserStatusType.Invited }, + { ...createMockUser("2"), status: OrganizationUserStatusType.Invited }, + { ...createMockUser("3"), status: OrganizationUserStatusType.Accepted }, + { ...createMockUser("4"), status: OrganizationUserStatusType.Confirmed }, + { ...createMockUser("5"), status: OrganizationUserStatusType.Confirmed }, + { ...createMockUser("6"), status: OrganizationUserStatusType.Confirmed }, + { ...createMockUser("7"), status: OrganizationUserStatusType.Revoked }, + ]; + dataSource.data = users; + + expect(dataSource.invitedUserCount).toBe(2); + expect(dataSource.acceptedUserCount).toBe(1); + expect(dataSource.confirmedUserCount).toBe(3); + expect(dataSource.revokedUserCount).toBe(1); + expect(dataSource.activeUserCount).toBe(6); // All except revoked + }); + }); +}); diff --git a/apps/web/src/app/admin-console/common/people-table-data-source.ts b/apps/web/src/app/admin-console/common/people-table-data-source.ts index 4696f8a6738..9ac370d8c0d 100644 --- a/apps/web/src/app/admin-console/common/people-table-data-source.ts +++ b/apps/web/src/app/admin-console/common/people-table-data-source.ts @@ -1,14 +1,30 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore +import { computed, Signal } from "@angular/core"; +import { toSignal } from "@angular/core/rxjs-interop"; +import { map } from "rxjs"; + import { OrganizationUserStatusType, ProviderUserStatusType, } from "@bitwarden/common/admin-console/enums"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; +import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { TableDataSource } from "@bitwarden/components"; import { StatusType, UserViewTypes } from "./base-members.component"; -const MaxCheckedCount = 500; +/** + * Default maximum for most bulk operations (confirm, remove, delete, etc.) + */ +export const MaxCheckedCount = 500; + +/** + * Maximum for bulk reinvite operations when the IncreaseBulkReinviteLimitForCloud + * feature flag is enabled on cloud environments. + */ +export const CloudBulkReinviteLimit = 8000; /** * Returns true if the user matches the status, or where the status is `null`, if the user is active (not revoked). @@ -56,6 +72,20 @@ export abstract class PeopleTableDataSource extends Tab confirmedUserCount: number; revokedUserCount: number; + /** True when increased bulk limit feature is enabled (feature flag + cloud environment) */ + readonly isIncreasedBulkLimitEnabled: Signal; + + constructor(configService: ConfigService, environmentService: EnvironmentService) { + super(); + + const featureFlagEnabled = toSignal( + configService.getFeatureFlag$(FeatureFlag.IncreaseBulkReinviteLimitForCloud), + ); + const isCloud = toSignal(environmentService.environment$.pipe(map((env) => env.isCloud()))); + + this.isIncreasedBulkLimitEnabled = computed(() => featureFlagEnabled() && isCloud()); + } + override set data(data: T[]) { super.data = data; @@ -89,6 +119,14 @@ export abstract class PeopleTableDataSource extends Tab return this.data.filter((u) => (u as any).checked); } + /** + * Gets checked users in the order they appear in the filtered/sorted table view. + * Use this when enforcing limits to ensure visual consistency (top N visible rows stay checked). + */ + getCheckedUsersInVisibleOrder() { + return this.filteredData.filter((u) => (u as any).checked); + } + /** * Check all filtered users (i.e. those rows that are currently visible) * @param select check the filtered users (true) or uncheck the filtered users (false) @@ -101,8 +139,13 @@ export abstract class PeopleTableDataSource extends Tab const filteredUsers = this.filteredData; - const selectCount = - filteredUsers.length > MaxCheckedCount ? MaxCheckedCount : filteredUsers.length; + // When the increased bulk limit feature is enabled, allow checking all users. + // Individual bulk operations will enforce their specific limits. + // When disabled, enforce the legacy limit at check time. + const selectCount = this.isIncreasedBulkLimitEnabled() + ? filteredUsers.length + : Math.min(filteredUsers.length, MaxCheckedCount); + for (let i = 0; i < selectCount; i++) { this.checkUser(filteredUsers[i], select); } @@ -132,4 +175,41 @@ export abstract class PeopleTableDataSource extends Tab this.data = updatedData; } } + + /** + * Limits an array of users and unchecks those beyond the limit. + * Returns the limited array. + * + * @param users The array of users to limit + * @param limit The maximum number of users to keep + * @returns The users array limited to the specified count + */ + limitAndUncheckExcess(users: T[], limit: number): T[] { + if (users.length <= limit) { + return users; + } + + // Uncheck users beyond the limit + users.slice(limit).forEach((user) => this.checkUser(user, false)); + + return users.slice(0, limit); + } + + /** + * Gets checked users with optional limiting based on the IncreaseBulkReinviteLimitForCloud feature flag. + * + * When the feature flag is enabled: Returns checked users in visible order, limited to the specified count. + * When the feature flag is disabled: Returns all checked users without applying any limit. + * + * @param limit The maximum number of users to return (only applied when feature flag is enabled) + * @returns The checked users array + */ + getCheckedUsersWithLimit(limit: number): T[] { + if (this.isIncreasedBulkLimitEnabled()) { + const allUsers = this.getCheckedUsersInVisibleOrder(); + return this.limitAndUncheckExcess(allUsers, limit); + } else { + return this.getCheckedUsers(); + } + } } diff --git a/apps/web/src/app/admin-console/organizations/collections/vault-filter/vault-filter.component.ts b/apps/web/src/app/admin-console/organizations/collections/vault-filter/vault-filter.component.ts index 01e61f0ab28..a253bb87c50 100644 --- a/apps/web/src/app/admin-console/organizations/collections/vault-filter/vault-filter.component.ts +++ b/apps/web/src/app/admin-console/organizations/collections/vault-filter/vault-filter.component.ts @@ -11,6 +11,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { CipherArchiveService } from "@bitwarden/common/vault/abstractions/cipher-archive.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service"; import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node"; import { RestrictedItemTypesService } from "@bitwarden/common/vault/services/restricted-item-types.service"; import { DialogService, ToastService } from "@bitwarden/components"; @@ -59,6 +60,7 @@ export class VaultFilterComponent protected restrictedItemTypesService: RestrictedItemTypesService, protected cipherService: CipherService, protected cipherArchiveService: CipherArchiveService, + premiumUpgradePromptService: PremiumUpgradePromptService, ) { super( vaultFilterService, @@ -72,6 +74,7 @@ export class VaultFilterComponent restrictedItemTypesService, cipherService, cipherArchiveService, + premiumUpgradePromptService, ); } diff --git a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html index e84f78458d6..198cb3a47cd 100644 --- a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html +++ b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html @@ -2,12 +2,15 @@ - + + @if (canShowAccessIntelligenceTab(organization)) { + + } + diff --git a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.ts b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.ts index ee09143ed2f..b00e4d9840d 100644 --- a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.ts +++ b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.ts @@ -8,6 +8,7 @@ import { combineLatest, filter, map, Observable, switchMap, withLatestFrom } fro import { JslibModule } from "@bitwarden/angular/jslib.module"; import { AdminConsoleLogo } from "@bitwarden/assets/svg"; import { + canAccessAccessIntelligence, canAccessBillingTab, canAccessGroupsTab, canAccessMembersTab, @@ -172,6 +173,10 @@ export class OrganizationLayoutComponent implements OnInit { return canAccessBillingTab(organization); } + canShowAccessIntelligenceTab(organization: Organization): boolean { + return canAccessAccessIntelligence(organization); + } + getReportTabLabel(organization: Organization): string { return organization.useEvents ? "reporting" : "reports"; } diff --git a/apps/web/src/app/admin-console/organizations/members/members.component.ts b/apps/web/src/app/admin-console/organizations/members/members.component.ts index 59c4c4898ea..51a2a6dafc0 100644 --- a/apps/web/src/app/admin-console/organizations/members/members.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/members.component.ts @@ -33,6 +33,8 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { OrganizationMetadataServiceAbstraction } from "@bitwarden/common/billing/abstractions/organization-metadata.service.abstraction"; import { OrganizationBillingMetadataResponse } from "@bitwarden/common/billing/models/response/organization-billing-metadata.response"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; +import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; @@ -44,7 +46,11 @@ import { BillingConstraintService } from "@bitwarden/web-vault/app/billing/membe import { OrganizationWarningsService } from "@bitwarden/web-vault/app/billing/organizations/warnings/services"; import { BaseMembersComponent } from "../../common/base-members.component"; -import { PeopleTableDataSource } from "../../common/people-table-data-source"; +import { + CloudBulkReinviteLimit, + MaxCheckedCount, + PeopleTableDataSource, +} from "../../common/people-table-data-source"; import { OrganizationUserView } from "../core/views/organization-user.view"; import { AccountRecoveryDialogResultType } from "./components/account-recovery/account-recovery-dialog.component"; @@ -70,7 +76,7 @@ export class MembersComponent extends BaseMembersComponent userType = OrganizationUserType; userStatusType = OrganizationUserStatusType; memberTab = MemberDialogTab; - protected dataSource = new MembersTableDataSource(); + protected dataSource: MembersTableDataSource; readonly organization: Signal; status: OrganizationUserStatusType | undefined; @@ -113,6 +119,8 @@ export class MembersComponent extends BaseMembersComponent private policyService: PolicyService, private policyApiService: PolicyApiServiceAbstraction, private organizationMetadataService: OrganizationMetadataServiceAbstraction, + private configService: ConfigService, + private environmentService: EnvironmentService, ) { super( apiService, @@ -126,6 +134,8 @@ export class MembersComponent extends BaseMembersComponent toastService, ); + this.dataSource = new MembersTableDataSource(this.configService, this.environmentService); + const organization$ = this.route.params.pipe( concatMap((params) => this.userId$.pipe( @@ -356,10 +366,9 @@ export class MembersComponent extends BaseMembersComponent return; } - await this.memberDialogManager.openBulkRemoveDialog( - organization, - this.dataSource.getCheckedUsers(), - ); + const users = this.dataSource.getCheckedUsersWithLimit(MaxCheckedCount); + + await this.memberDialogManager.openBulkRemoveDialog(organization, users); this.organizationMetadataService.refreshMetadataCache(); await this.load(organization); } @@ -369,10 +378,9 @@ export class MembersComponent extends BaseMembersComponent return; } - await this.memberDialogManager.openBulkDeleteDialog( - organization, - this.dataSource.getCheckedUsers(), - ); + const users = this.dataSource.getCheckedUsersWithLimit(MaxCheckedCount); + + await this.memberDialogManager.openBulkDeleteDialog(organization, users); await this.load(organization); } @@ -389,11 +397,9 @@ export class MembersComponent extends BaseMembersComponent return; } - await this.memberDialogManager.openBulkRestoreRevokeDialog( - organization, - this.dataSource.getCheckedUsers(), - isRevoking, - ); + const users = this.dataSource.getCheckedUsersWithLimit(MaxCheckedCount); + + await this.memberDialogManager.openBulkRestoreRevokeDialog(organization, users, isRevoking); await this.load(organization); } @@ -402,8 +408,28 @@ export class MembersComponent extends BaseMembersComponent return; } - const users = this.dataSource.getCheckedUsers(); - const filteredUsers = users.filter((u) => u.status === OrganizationUserStatusType.Invited); + let users: OrganizationUserView[]; + if (this.dataSource.isIncreasedBulkLimitEnabled()) { + users = this.dataSource.getCheckedUsersInVisibleOrder(); + } else { + users = this.dataSource.getCheckedUsers(); + } + + const allInvitedUsers = users.filter((u) => u.status === OrganizationUserStatusType.Invited); + + // Capture the original count BEFORE enforcing the limit + const originalInvitedCount = allInvitedUsers.length; + + // When feature flag is enabled, limit invited users and uncheck the excess + let filteredUsers: OrganizationUserView[]; + if (this.dataSource.isIncreasedBulkLimitEnabled()) { + filteredUsers = this.dataSource.limitAndUncheckExcess( + allInvitedUsers, + CloudBulkReinviteLimit, + ); + } else { + filteredUsers = allInvitedUsers; + } if (filteredUsers.length <= 0) { this.toastService.showToast({ @@ -417,20 +443,44 @@ export class MembersComponent extends BaseMembersComponent try { const result = await this.memberActionsService.bulkReinvite( organization, - filteredUsers.map((user) => user.id), + filteredUsers.map((user) => user.id as UserId), ); if (!result.successful) { throw new Error(); } - // Bulk Status component open - await this.memberDialogManager.openBulkStatusDialog( - users, - filteredUsers, - Promise.resolve(result.successful), - this.i18nService.t("bulkReinviteMessage"), - ); + // When feature flag is enabled, show toast instead of dialog + if (this.dataSource.isIncreasedBulkLimitEnabled()) { + const selectedCount = originalInvitedCount; + const invitedCount = filteredUsers.length; + + if (selectedCount > CloudBulkReinviteLimit) { + const excludedCount = selectedCount - CloudBulkReinviteLimit; + this.toastService.showToast({ + variant: "success", + message: this.i18nService.t( + "bulkReinviteLimitedSuccessToast", + CloudBulkReinviteLimit.toLocaleString(), + selectedCount.toLocaleString(), + excludedCount.toLocaleString(), + ), + }); + } else { + this.toastService.showToast({ + variant: "success", + message: this.i18nService.t("bulkReinviteSuccessToast", invitedCount.toString()), + }); + } + } else { + // Feature flag disabled - show legacy dialog + await this.memberDialogManager.openBulkStatusDialog( + users, + filteredUsers, + Promise.resolve(result.successful), + this.i18nService.t("bulkReinviteMessage"), + ); + } } catch (e) { this.validationService.showError(e); } @@ -442,15 +492,14 @@ export class MembersComponent extends BaseMembersComponent return; } - await this.memberDialogManager.openBulkConfirmDialog( - organization, - this.dataSource.getCheckedUsers(), - ); + const users = this.dataSource.getCheckedUsersWithLimit(MaxCheckedCount); + + await this.memberDialogManager.openBulkConfirmDialog(organization, users); await this.load(organization); } async bulkEnableSM(organization: Organization) { - const users = this.dataSource.getCheckedUsers(); + const users = this.dataSource.getCheckedUsersWithLimit(MaxCheckedCount); await this.memberDialogManager.openBulkEnableSecretsManagerDialog(organization, users); diff --git a/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.spec.ts b/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.spec.ts index e856ab7afd1..80a330b0db1 100644 --- a/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.spec.ts +++ b/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.spec.ts @@ -4,6 +4,7 @@ import { of } from "rxjs"; import { OrganizationUserApiService, OrganizationUserBulkResponse, + OrganizationUserService, } from "@bitwarden/admin-console/common"; import { OrganizationUserType, @@ -22,9 +23,8 @@ import { newGuid } from "@bitwarden/guid"; import { KeyService } from "@bitwarden/key-management"; import { OrganizationUserView } from "../../../core/views/organization-user.view"; -import { OrganizationUserService } from "../organization-user/organization-user.service"; -import { MemberActionsService } from "./member-actions.service"; +import { REQUESTS_PER_BATCH, MemberActionsService } from "./member-actions.service"; describe("MemberActionsService", () => { let service: MemberActionsService; @@ -308,41 +308,308 @@ describe("MemberActionsService", () => { }); describe("bulkReinvite", () => { - const userIds = [newGuid(), newGuid(), newGuid()]; + const userIds = [newGuid() as UserId, newGuid() as UserId, newGuid() as UserId]; - it("should successfully reinvite multiple users", async () => { - const mockResponse = { - data: userIds.map((id) => ({ - id, - error: null, - })), - continuationToken: null, - } as ListResponse; - organizationUserApiService.postManyOrganizationUserReinvite.mockResolvedValue(mockResponse); - - const result = await service.bulkReinvite(mockOrganization, userIds); - - expect(result).toEqual({ - successful: mockResponse, - failed: [], + describe("when feature flag is false", () => { + beforeEach(() => { + configService.getFeatureFlag$.mockReturnValue(of(false)); + }); + + it("should successfully reinvite multiple users", async () => { + const mockResponse = new ListResponse( + { + data: userIds.map((id) => ({ + id, + error: null, + })), + continuationToken: null, + }, + OrganizationUserBulkResponse, + ); + + organizationUserApiService.postManyOrganizationUserReinvite.mockResolvedValue(mockResponse); + + const result = await service.bulkReinvite(mockOrganization, userIds); + + expect(result.failed).toEqual([]); + expect(result.successful).toBeDefined(); + expect(result.successful).toEqual(mockResponse); + expect(organizationUserApiService.postManyOrganizationUserReinvite).toHaveBeenCalledWith( + organizationId, + userIds, + ); + }); + + it("should handle bulk reinvite errors", async () => { + const errorMessage = "Bulk reinvite failed"; + organizationUserApiService.postManyOrganizationUserReinvite.mockRejectedValue( + new Error(errorMessage), + ); + + const result = await service.bulkReinvite(mockOrganization, userIds); + + expect(result.successful).toBeUndefined(); + expect(result.failed).toHaveLength(3); + expect(result.failed[0]).toEqual({ id: userIds[0], error: errorMessage }); }); - expect(organizationUserApiService.postManyOrganizationUserReinvite).toHaveBeenCalledWith( - organizationId, - userIds, - ); }); - it("should handle bulk reinvite errors", async () => { - const errorMessage = "Bulk reinvite failed"; - organizationUserApiService.postManyOrganizationUserReinvite.mockRejectedValue( - new Error(errorMessage), - ); + describe("when feature flag is true (batching behavior)", () => { + beforeEach(() => { + configService.getFeatureFlag$.mockReturnValue(of(true)); + }); + it("should process users in a single batch when count equals REQUESTS_PER_BATCH", async () => { + const userIdsBatch = Array.from({ length: REQUESTS_PER_BATCH }, () => newGuid() as UserId); + const mockResponse = new ListResponse( + { + data: userIdsBatch.map((id) => ({ + id, + error: null, + })), + continuationToken: null, + }, + OrganizationUserBulkResponse, + ); - const result = await service.bulkReinvite(mockOrganization, userIds); + organizationUserApiService.postManyOrganizationUserReinvite.mockResolvedValue(mockResponse); - expect(result.successful).toBeUndefined(); - expect(result.failed).toHaveLength(3); - expect(result.failed[0]).toEqual({ id: userIds[0], error: errorMessage }); + const result = await service.bulkReinvite(mockOrganization, userIdsBatch); + + expect(result.successful).toBeDefined(); + expect(result.successful?.response).toHaveLength(REQUESTS_PER_BATCH); + expect(result.failed).toHaveLength(0); + expect(organizationUserApiService.postManyOrganizationUserReinvite).toHaveBeenCalledTimes( + 1, + ); + expect(organizationUserApiService.postManyOrganizationUserReinvite).toHaveBeenCalledWith( + organizationId, + userIdsBatch, + ); + }); + + it("should process users in multiple batches when count exceeds REQUESTS_PER_BATCH", async () => { + const totalUsers = REQUESTS_PER_BATCH + 100; + const userIdsBatch = Array.from({ length: totalUsers }, () => newGuid() as UserId); + + const mockResponse1 = new ListResponse( + { + data: userIdsBatch.slice(0, REQUESTS_PER_BATCH).map((id) => ({ + id, + error: null, + })), + continuationToken: null, + }, + OrganizationUserBulkResponse, + ); + + const mockResponse2 = new ListResponse( + { + data: userIdsBatch.slice(REQUESTS_PER_BATCH).map((id) => ({ + id, + error: null, + })), + continuationToken: null, + }, + OrganizationUserBulkResponse, + ); + + organizationUserApiService.postManyOrganizationUserReinvite + .mockResolvedValueOnce(mockResponse1) + .mockResolvedValueOnce(mockResponse2); + + const result = await service.bulkReinvite(mockOrganization, userIdsBatch); + + expect(result.successful).toBeDefined(); + expect(result.successful?.response).toHaveLength(totalUsers); + expect(result.failed).toHaveLength(0); + expect(organizationUserApiService.postManyOrganizationUserReinvite).toHaveBeenCalledTimes( + 2, + ); + expect(organizationUserApiService.postManyOrganizationUserReinvite).toHaveBeenNthCalledWith( + 1, + organizationId, + userIdsBatch.slice(0, REQUESTS_PER_BATCH), + ); + expect(organizationUserApiService.postManyOrganizationUserReinvite).toHaveBeenNthCalledWith( + 2, + organizationId, + userIdsBatch.slice(REQUESTS_PER_BATCH), + ); + }); + + it("should aggregate results across multiple successful batches", async () => { + const totalUsers = REQUESTS_PER_BATCH + 50; + const userIdsBatch = Array.from({ length: totalUsers }, () => newGuid() as UserId); + + const mockResponse1 = new ListResponse( + { + data: userIdsBatch.slice(0, REQUESTS_PER_BATCH).map((id) => ({ + id, + error: null, + })), + continuationToken: null, + }, + OrganizationUserBulkResponse, + ); + + const mockResponse2 = new ListResponse( + { + data: userIdsBatch.slice(REQUESTS_PER_BATCH).map((id) => ({ + id, + error: null, + })), + continuationToken: null, + }, + OrganizationUserBulkResponse, + ); + + organizationUserApiService.postManyOrganizationUserReinvite + .mockResolvedValueOnce(mockResponse1) + .mockResolvedValueOnce(mockResponse2); + + const result = await service.bulkReinvite(mockOrganization, userIdsBatch); + + expect(result.successful).toBeDefined(); + expect(result.successful?.response).toHaveLength(totalUsers); + expect(result.successful?.response.slice(0, REQUESTS_PER_BATCH)).toEqual( + mockResponse1.data, + ); + expect(result.successful?.response.slice(REQUESTS_PER_BATCH)).toEqual(mockResponse2.data); + expect(result.failed).toHaveLength(0); + }); + + it("should handle mixed individual errors across multiple batches", async () => { + const totalUsers = REQUESTS_PER_BATCH + 4; + const userIdsBatch = Array.from({ length: totalUsers }, () => newGuid() as UserId); + + const mockResponse1 = new ListResponse( + { + data: userIdsBatch.slice(0, REQUESTS_PER_BATCH).map((id, index) => ({ + id, + error: index % 10 === 0 ? "Rate limit exceeded" : null, + })), + continuationToken: null, + }, + OrganizationUserBulkResponse, + ); + + const mockResponse2 = new ListResponse( + { + data: [ + { id: userIdsBatch[REQUESTS_PER_BATCH], error: null }, + { id: userIdsBatch[REQUESTS_PER_BATCH + 1], error: "Invalid email" }, + { id: userIdsBatch[REQUESTS_PER_BATCH + 2], error: null }, + { id: userIdsBatch[REQUESTS_PER_BATCH + 3], error: "User suspended" }, + ], + continuationToken: null, + }, + OrganizationUserBulkResponse, + ); + + organizationUserApiService.postManyOrganizationUserReinvite + .mockResolvedValueOnce(mockResponse1) + .mockResolvedValueOnce(mockResponse2); + + const result = await service.bulkReinvite(mockOrganization, userIdsBatch); + + // Count expected failures: every 10th index (0, 10, 20, ..., 490) in first batch + 2 explicit in second batch + // Indices 0 to REQUESTS_PER_BATCH-1 where index % 10 === 0: that's floor((BATCH_SIZE-1)/10) + 1 values + const expectedFailuresInBatch1 = Math.floor((REQUESTS_PER_BATCH - 1) / 10) + 1; + const expectedFailuresInBatch2 = 2; + const expectedTotalFailures = expectedFailuresInBatch1 + expectedFailuresInBatch2; + const expectedSuccesses = totalUsers - expectedTotalFailures; + + expect(result.successful).toBeDefined(); + expect(result.successful?.response).toHaveLength(expectedSuccesses); + expect(result.failed).toHaveLength(expectedTotalFailures); + expect(result.failed.some((f) => f.error === "Rate limit exceeded")).toBe(true); + expect(result.failed.some((f) => f.error === "Invalid email")).toBe(true); + expect(result.failed.some((f) => f.error === "User suspended")).toBe(true); + }); + + it("should aggregate all failures when all batches fail", async () => { + const totalUsers = REQUESTS_PER_BATCH + 100; + const userIdsBatch = Array.from({ length: totalUsers }, () => newGuid() as UserId); + const errorMessage = "All batches failed"; + + organizationUserApiService.postManyOrganizationUserReinvite.mockRejectedValue( + new Error(errorMessage), + ); + + const result = await service.bulkReinvite(mockOrganization, userIdsBatch); + + expect(result.successful).toBeUndefined(); + expect(result.failed).toHaveLength(totalUsers); + expect(result.failed.every((f) => f.error === errorMessage)).toBe(true); + expect(organizationUserApiService.postManyOrganizationUserReinvite).toHaveBeenCalledTimes( + 2, + ); + }); + + it("should handle empty data in batch response", async () => { + const totalUsers = REQUESTS_PER_BATCH + 50; + const userIdsBatch = Array.from({ length: totalUsers }, () => newGuid() as UserId); + + const mockResponse1 = new ListResponse( + { + data: userIdsBatch.slice(0, REQUESTS_PER_BATCH).map((id) => ({ + id, + error: null, + })), + continuationToken: null, + }, + OrganizationUserBulkResponse, + ); + + const mockResponse2 = new ListResponse( + { + data: [], + continuationToken: null, + }, + OrganizationUserBulkResponse, + ); + + organizationUserApiService.postManyOrganizationUserReinvite + .mockResolvedValueOnce(mockResponse1) + .mockResolvedValueOnce(mockResponse2); + + const result = await service.bulkReinvite(mockOrganization, userIdsBatch); + + expect(result.successful).toBeDefined(); + expect(result.successful?.response).toHaveLength(REQUESTS_PER_BATCH); + expect(result.failed).toHaveLength(0); + }); + + it("should process batches sequentially in order", async () => { + const totalUsers = REQUESTS_PER_BATCH * 2; + const userIdsBatch = Array.from({ length: totalUsers }, () => newGuid() as UserId); + const callOrder: number[] = []; + + organizationUserApiService.postManyOrganizationUserReinvite.mockImplementation( + async (orgId, ids) => { + const batchIndex = ids.includes(userIdsBatch[0]) ? 1 : 2; + callOrder.push(batchIndex); + + return new ListResponse( + { + data: ids.map((id) => ({ + id, + error: null, + })), + continuationToken: null, + }, + OrganizationUserBulkResponse, + ); + }, + ); + + await service.bulkReinvite(mockOrganization, userIdsBatch); + + expect(callOrder).toEqual([1, 2]); + expect(organizationUserApiService.postManyOrganizationUserReinvite).toHaveBeenCalledTimes( + 2, + ); + }); }); }); @@ -427,14 +694,6 @@ describe("MemberActionsService", () => { expect(result).toBe(false); }); - it("should not allow reset password when organization lacks public and private keys", () => { - const org = { ...mockOrganization, hasPublicAndPrivateKeys: false } as Organization; - - const result = service.allowResetPassword(mockOrgUser, org, resetPasswordEnabled); - - expect(result).toBe(false); - }); - it("should not allow reset password when user is not enrolled in reset password", () => { const user = { ...mockOrgUser, resetPasswordEnrolled: false } as OrganizationUserView; @@ -443,12 +702,6 @@ describe("MemberActionsService", () => { expect(result).toBe(false); }); - it("should not allow reset password when reset password is disabled", () => { - const result = service.allowResetPassword(mockOrgUser, mockOrganization, false); - - expect(result).toBe(false); - }); - it("should not allow reset password when user status is not confirmed", () => { const user = { ...mockOrgUser, diff --git a/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.ts b/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.ts index 5e19e26954e..f3774e3cb25 100644 --- a/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.ts +++ b/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.ts @@ -20,9 +20,12 @@ import { EncryptService } from "@bitwarden/common/key-management/crypto/abstract import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { KeyService } from "@bitwarden/key-management"; +import { UserId } from "@bitwarden/user-core"; import { OrganizationUserView } from "../../../core/views/organization-user.view"; +export const REQUESTS_PER_BATCH = 500; + export interface MemberActionResult { success: boolean; error?: string; @@ -162,20 +165,36 @@ export class MemberActionsService { } } - async bulkReinvite(organization: Organization, userIds: string[]): Promise { - try { - const result = await this.organizationUserApiService.postManyOrganizationUserReinvite( - organization.id, - userIds, - ); - return { successful: result, failed: [] }; - } catch (error) { - return { - failed: userIds.map((id) => ({ id, error: (error as Error).message ?? String(error) })), - }; + async bulkReinvite(organization: Organization, userIds: UserId[]): Promise { + const increaseBulkReinviteLimitForCloud = await firstValueFrom( + this.configService.getFeatureFlag$(FeatureFlag.IncreaseBulkReinviteLimitForCloud), + ); + if (increaseBulkReinviteLimitForCloud) { + return await this.vNextBulkReinvite(organization, userIds); + } else { + try { + const result = await this.organizationUserApiService.postManyOrganizationUserReinvite( + organization.id, + userIds, + ); + return { successful: result, failed: [] }; + } catch (error) { + return { + failed: userIds.map((id) => ({ id, error: (error as Error).message ?? String(error) })), + }; + } } } + async vNextBulkReinvite( + organization: Organization, + userIds: UserId[], + ): Promise { + return this.processBatchedOperation(userIds, REQUESTS_PER_BATCH, (batch) => + this.organizationUserApiService.postManyOrganizationUserReinvite(organization.id, batch), + ); + } + allowResetPassword( orgUser: OrganizationUserView, organization: Organization, @@ -207,4 +226,52 @@ export class MemberActionsService { orgUser.status === OrganizationUserStatusType.Confirmed ); } + + /** + * Processes user IDs in sequential batches and aggregates results. + * @param userIds - Array of user IDs to process + * @param batchSize - Number of IDs to process per batch + * @param processBatch - Async function that processes a single batch and returns the result + * @returns Aggregated bulk action result + */ + private async processBatchedOperation( + userIds: UserId[], + batchSize: number, + processBatch: (batch: string[]) => Promise>, + ): Promise { + const allSuccessful: OrganizationUserBulkResponse[] = []; + const allFailed: { id: string; error: string }[] = []; + + for (let i = 0; i < userIds.length; i += batchSize) { + const batch = userIds.slice(i, i + batchSize); + + try { + const result = await processBatch(batch); + + if (result?.data) { + for (const response of result.data) { + if (response.error) { + allFailed.push({ id: response.id, error: response.error }); + } else { + allSuccessful.push(response); + } + } + } + } catch (error) { + allFailed.push( + ...batch.map((id) => ({ id, error: (error as Error).message ?? String(error) })), + ); + } + } + + const successful = + allSuccessful.length > 0 + ? new ListResponse(allSuccessful, OrganizationUserBulkResponse) + : undefined; + + return { + successful, + failed: allFailed, + }; + } } diff --git a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts index df5e7e8a25c..88797f86650 100644 --- a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts +++ b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts @@ -35,13 +35,10 @@ import { OrganizationUserResetPasswordEntry } from "./organization-user-reset-pa @Injectable({ providedIn: "root", }) -export class OrganizationUserResetPasswordService - implements - UserKeyRotationKeyRecoveryProvider< - OrganizationUserResetPasswordWithIdRequest, - OrganizationUserResetPasswordEntry - > -{ +export class OrganizationUserResetPasswordService implements UserKeyRotationKeyRecoveryProvider< + OrganizationUserResetPasswordWithIdRequest, + OrganizationUserResetPasswordEntry +> { constructor( private keyService: KeyService, private encryptService: EncryptService, diff --git a/apps/web/src/app/admin-console/organizations/settings/organization-settings-routing.module.ts b/apps/web/src/app/admin-console/organizations/settings/organization-settings-routing.module.ts index a644086628c..2fb3703ee6b 100644 --- a/apps/web/src/app/admin-console/organizations/settings/organization-settings-routing.module.ts +++ b/apps/web/src/app/admin-console/organizations/settings/organization-settings-routing.module.ts @@ -57,7 +57,7 @@ const routes: Routes = [ ), canActivate: [organizationPermissionsGuard((org) => org.canAccessImport)], data: { - titleId: "importData", + titleId: "importNoun", }, }, { @@ -68,7 +68,7 @@ const routes: Routes = [ ), canActivate: [organizationPermissionsGuard((org) => org.canAccessExport)], data: { - titleId: "exportVault", + titleId: "exportNoun", }, }, ], diff --git a/apps/web/src/app/auth/core/services/login/web-login-component.service.ts b/apps/web/src/app/auth/core/services/login/web-login-component.service.ts index 5bea0908b0a..8c1bc4bd080 100644 --- a/apps/web/src/app/auth/core/services/login/web-login-component.service.ts +++ b/apps/web/src/app/auth/core/services/login/web-login-component.service.ts @@ -61,8 +61,11 @@ export class WebLoginComponentService email: string, state: string, codeChallenge: string, + orgSsoIdentifier?: string, ): Promise { - await this.router.navigate(["/sso"]); + await this.router.navigate(["/sso"], { + queryParams: { identifier: orgSsoIdentifier }, + }); return; } diff --git a/apps/web/src/app/auth/core/services/password-management/set-initial-password/web-set-initial-password.service.spec.ts b/apps/web/src/app/auth/core/services/password-management/set-initial-password/web-set-initial-password.service.spec.ts index 647c9ae83d9..1bbaa0ec236 100644 --- a/apps/web/src/app/auth/core/services/password-management/set-initial-password/web-set-initial-password.service.spec.ts +++ b/apps/web/src/app/auth/core/services/password-management/set-initial-password/web-set-initial-password.service.spec.ts @@ -16,6 +16,7 @@ import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-conso import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction"; import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request"; import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service"; +import { AccountCryptographicStateService } from "@bitwarden/common/key-management/account-cryptography/account-cryptographic-state.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; @@ -45,6 +46,7 @@ describe("WebSetInitialPasswordService", () => { let userDecryptionOptionsService: MockProxy; let organizationInviteService: MockProxy; let routerService: MockProxy; + let accountCryptographicStateService: MockProxy; beforeEach(() => { apiService = mock(); @@ -59,6 +61,7 @@ describe("WebSetInitialPasswordService", () => { userDecryptionOptionsService = mock(); organizationInviteService = mock(); routerService = mock(); + accountCryptographicStateService = mock(); sut = new WebSetInitialPasswordService( apiService, @@ -73,6 +76,7 @@ describe("WebSetInitialPasswordService", () => { userDecryptionOptionsService, organizationInviteService, routerService, + accountCryptographicStateService, ); }); diff --git a/apps/web/src/app/auth/core/services/password-management/set-initial-password/web-set-initial-password.service.ts b/apps/web/src/app/auth/core/services/password-management/set-initial-password/web-set-initial-password.service.ts index 19ddbf5e260..303b9148e8e 100644 --- a/apps/web/src/app/auth/core/services/password-management/set-initial-password/web-set-initial-password.service.ts +++ b/apps/web/src/app/auth/core/services/password-management/set-initial-password/web-set-initial-password.service.ts @@ -10,6 +10,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction"; import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service"; +import { AccountCryptographicStateService } from "@bitwarden/common/key-management/account-cryptography/account-cryptographic-state.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -34,6 +35,7 @@ export class WebSetInitialPasswordService protected userDecryptionOptionsService: InternalUserDecryptionOptionsServiceAbstraction, private organizationInviteService: OrganizationInviteService, private routerService: RouterService, + protected accountCryptographicStateService: AccountCryptographicStateService, ) { super( apiService, @@ -46,6 +48,7 @@ export class WebSetInitialPasswordService organizationApiService, organizationUserApiService, userDecryptionOptionsService, + accountCryptographicStateService, ); } diff --git a/apps/web/src/app/auth/core/services/webauthn-login/webauthn-login-admin.service.ts b/apps/web/src/app/auth/core/services/webauthn-login/webauthn-login-admin.service.ts index 7765d01f75c..3fc57e1a22c 100644 --- a/apps/web/src/app/auth/core/services/webauthn-login/webauthn-login-admin.service.ts +++ b/apps/web/src/app/auth/core/services/webauthn-login/webauthn-login-admin.service.ts @@ -39,9 +39,7 @@ import { WebAuthnLoginAdminApiService } from "./webauthn-login-admin-api.service /** * Service for managing WebAuthnLogin credentials. */ -export class WebauthnLoginAdminService - implements UserKeyRotationDataProvider -{ +export class WebauthnLoginAdminService implements UserKeyRotationDataProvider { static readonly MaxCredentialCount = 5; private navigatorCredentials: CredentialsContainer; diff --git a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts index b91bc932e83..80b1b27116b 100644 --- a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts +++ b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts @@ -45,13 +45,10 @@ import { EmergencyAccessGranteeDetailsResponse } from "../response/emergency-acc import { EmergencyAccessApiService } from "./emergency-access-api.service"; @Injectable() -export class EmergencyAccessService - implements - UserKeyRotationKeyRecoveryProvider< - EmergencyAccessWithIdRequest, - GranteeEmergencyAccessWithPublicKey - > -{ +export class EmergencyAccessService implements UserKeyRotationKeyRecoveryProvider< + EmergencyAccessWithIdRequest, + GranteeEmergencyAccessWithPublicKey +> { constructor( private emergencyAccessApiService: EmergencyAccessApiService, private apiService: ApiService, diff --git a/apps/web/src/app/auth/recover-delete.component.ts b/apps/web/src/app/auth/recover-delete.component.ts index 00b14f9a402..921d96270bf 100644 --- a/apps/web/src/app/auth/recover-delete.component.ts +++ b/apps/web/src/app/auth/recover-delete.component.ts @@ -1,21 +1,37 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Component } from "@angular/core"; -import { FormControl, FormGroup, Validators } from "@angular/forms"; -import { Router } from "@angular/router"; +import { FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms"; +import { Router, RouterLink } from "@angular/router"; +import { JslibModule } from "@bitwarden/angular/jslib.module"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { DeleteRecoverRequest } from "@bitwarden/common/models/request/delete-recover.request"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { ToastService } from "@bitwarden/components"; +import { + AsyncActionsModule, + ButtonModule, + FormFieldModule, + ToastService, + TypographyModule, +} from "@bitwarden/components"; +import { I18nPipe } from "@bitwarden/ui-common"; // FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "app-recover-delete", templateUrl: "recover-delete.component.html", - standalone: false, + imports: [ + ReactiveFormsModule, + RouterLink, + JslibModule, + AsyncActionsModule, + ButtonModule, + FormFieldModule, + I18nPipe, + TypographyModule, + ], }) export class RecoverDeleteComponent { protected recoverDeleteForm = new FormGroup({ @@ -29,7 +45,6 @@ export class RecoverDeleteComponent { constructor( private router: Router, private apiService: ApiService, - private platformUtilsService: PlatformUtilsService, private i18nService: I18nService, private toastService: ToastService, ) {} diff --git a/apps/web/src/app/auth/recover-two-factor.component.spec.ts b/apps/web/src/app/auth/recover-two-factor.component.spec.ts index c3792cfd3f3..b7a68ff9f07 100644 --- a/apps/web/src/app/auth/recover-two-factor.component.spec.ts +++ b/apps/web/src/app/auth/recover-two-factor.component.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { Router } from "@angular/router"; +import { Router, provideRouter } from "@angular/router"; import { mock, MockProxy } from "jest-mock-extended"; import { @@ -7,69 +7,49 @@ import { LoginSuccessHandlerService, PasswordLoginCredentials, } from "@bitwarden/auth/common"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; import { ToastService } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; -import { I18nPipe } from "@bitwarden/ui-common"; import { RecoverTwoFactorComponent } from "./recover-two-factor.component"; describe("RecoverTwoFactorComponent", () => { let component: RecoverTwoFactorComponent; let fixture: ComponentFixture; - - // Mock Services let mockRouter: MockProxy; - let mockApiService: MockProxy; - let mockPlatformUtilsService: MockProxy; let mockI18nService: MockProxy; - let mockKeyService: MockProxy; let mockLoginStrategyService: MockProxy; let mockToastService: MockProxy; - let mockConfigService: MockProxy; let mockLoginSuccessHandlerService: MockProxy; let mockLogService: MockProxy; let mockValidationService: MockProxy; - beforeEach(() => { - mockRouter = mock(); - mockApiService = mock(); - mockPlatformUtilsService = mock(); + beforeEach(async () => { mockI18nService = mock(); - mockKeyService = mock(); mockLoginStrategyService = mock(); mockToastService = mock(); - mockConfigService = mock(); mockLoginSuccessHandlerService = mock(); mockLogService = mock(); mockValidationService = mock(); - TestBed.configureTestingModule({ - declarations: [RecoverTwoFactorComponent], + await TestBed.configureTestingModule({ + imports: [RecoverTwoFactorComponent], providers: [ - { provide: Router, useValue: mockRouter }, - { provide: ApiService, useValue: mockApiService }, - { provide: PlatformUtilsService, mockPlatformUtilsService }, + provideRouter([]), { provide: I18nService, useValue: mockI18nService }, - { provide: KeyService, useValue: mockKeyService }, { provide: LoginStrategyServiceAbstraction, useValue: mockLoginStrategyService }, { provide: ToastService, useValue: mockToastService }, - { provide: ConfigService, useValue: mockConfigService }, { provide: LoginSuccessHandlerService, useValue: mockLoginSuccessHandlerService }, { provide: LogService, useValue: mockLogService }, { provide: ValidationService, useValue: mockValidationService }, ], - imports: [I18nPipe], - // FIXME(PM-18598): Replace unknownElements and unknownProperties with actual imports - errorOnUnknownElements: false, - }); + }).compileComponents(); + + mockRouter = TestBed.inject(Router) as MockProxy; + jest.spyOn(mockRouter, "navigate"); fixture = TestBed.createComponent(RecoverTwoFactorComponent); component = fixture.componentInstance; diff --git a/apps/web/src/app/auth/recover-two-factor.component.ts b/apps/web/src/app/auth/recover-two-factor.component.ts index 9c033b88a75..5d160e4ed91 100644 --- a/apps/web/src/app/auth/recover-two-factor.component.ts +++ b/apps/web/src/app/auth/recover-two-factor.component.ts @@ -1,8 +1,9 @@ import { Component, DestroyRef, OnInit } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { FormControl, FormGroup, Validators } from "@angular/forms"; -import { Router } from "@angular/router"; +import { FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms"; +import { Router, RouterLink } from "@angular/router"; +import { JslibModule } from "@bitwarden/angular/jslib.module"; import { LoginStrategyServiceAbstraction, PasswordLoginCredentials, @@ -14,14 +15,32 @@ import { ErrorResponse } from "@bitwarden/common/models/response/error.response" import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; -import { ToastService } from "@bitwarden/components"; +import { + AsyncActionsModule, + ButtonModule, + FormFieldModule, + LinkModule, + ToastService, + TypographyModule, +} from "@bitwarden/components"; +import { I18nPipe } from "@bitwarden/ui-common"; // FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "app-recover-two-factor", templateUrl: "recover-two-factor.component.html", - standalone: false, + imports: [ + ReactiveFormsModule, + RouterLink, + JslibModule, + AsyncActionsModule, + ButtonModule, + FormFieldModule, + I18nPipe, + LinkModule, + TypographyModule, + ], }) export class RecoverTwoFactorComponent implements OnInit { formGroup = new FormGroup({ @@ -108,7 +127,7 @@ export class RecoverTwoFactorComponent implements OnInit { message: this.i18nService.t("twoStepRecoverDisabled"), }); - await this.loginSuccessHandlerService.run(authResult.userId); + await this.loginSuccessHandlerService.run(authResult.userId, this.masterPassword); await this.router.navigate(["/settings/security/two-factor"]); } catch (error: unknown) { diff --git a/apps/web/src/app/auth/settings/emergency-access/view/emergency-access-view.component.html b/apps/web/src/app/auth/settings/emergency-access/view/emergency-access-view.component.html index 20cc50c4d59..4aaac6aaa52 100644 --- a/apps/web/src/app/auth/settings/emergency-access/view/emergency-access-view.component.html +++ b/apps/web/src/app/auth/settings/emergency-access/view/emergency-access-view.component.html @@ -19,7 +19,7 @@ >