1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-19 10:54:00 +00:00

Merge branch 'main' into PM-20040-all-tasks-complete-banner

This commit is contained in:
jng
2025-08-15 15:54:26 -04:00
5 changed files with 73 additions and 7 deletions

View File

@@ -1,4 +1,5 @@
name: Autofill BIT checks
run-name: Autofill BIT checks on ${{ github.event.workflow_run.head_branch }} build
on:
workflow_run:
@@ -11,10 +12,23 @@ jobs:
name: Check files
runs-on: ubuntu-22.04
permissions:
actions: read
actions: write
contents: read
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Check for job requirements
if: ${{ !(github.event.workflow_run.pull_requests && github.event.workflow_run.pull_requests.length > 0 && github.event.workflow_run.head_branch) }}
env:
GH_TOKEN: ${{ github.token }}
run: |
gh run cancel ${{ github.run_id }}
gh run watch ${{ github.run_id }}
- name: Log in to Azure
uses: bitwarden/gh-actions/azure-login@main
with:
@@ -42,11 +56,6 @@ jobs:
repositories: browser-interactions-testing
permission-actions: write
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Get changed files
id: changed-files
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2

View File

@@ -1757,6 +1757,54 @@ describe("CollectAutofillContentService", () => {
expect(parsedText).toEqual("Hello! This is a test string.");
});
it("preserves extended Latin letters like Š and ć", () => {
const text = "Šifra ćevapčići korisnika";
const result = collectAutofillContentService["trimAndRemoveNonPrintableText"](text);
expect(result).toEqual("Šifra ćevapčići korisnika");
});
it("removes zero-width and control characters", () => {
const text = "Hello\u200B\u200C\u200D\u2060World\x00\x1F!";
const result = collectAutofillContentService["trimAndRemoveNonPrintableText"](text);
expect(result).toEqual("Hello World !");
});
it("removes leading and trailing whitespace", () => {
const text = " padded text with spaces ";
const result = collectAutofillContentService["trimAndRemoveNonPrintableText"](text);
expect(result).toEqual("padded text with spaces");
});
it("replaces multiple whitespaces (tabs, newlines, spaces) with one space", () => {
const text = "one\t\ntwo \n three\t\tfour";
const result = collectAutofillContentService["trimAndRemoveNonPrintableText"](text);
expect(result).toEqual("one two three four");
});
it("preserves emoji and symbols", () => {
const text = "Text with emoji 🐍🚀 and ©®✓ symbols";
const result = collectAutofillContentService["trimAndRemoveNonPrintableText"](text);
expect(result).toEqual("Text with emoji 🐍🚀 and ©®✓ symbols");
});
it("handles RTL and LTR marks", () => {
const text = "abc\u200F\u202Edеf";
const result = collectAutofillContentService["trimAndRemoveNonPrintableText"](text);
expect(result).toEqual("abc dеf");
});
it("handles mathematical unicode letters", () => {
const text = "Unicode math: 𝒜𝒷𝒸𝒹";
const result = collectAutofillContentService["trimAndRemoveNonPrintableText"](text);
expect(result).toEqual("Unicode math: 𝒜𝒷𝒸𝒹");
});
it("removes only invisible non-printables, keeps Japanese", () => {
const text = "これは\u200Bテストです";
const result = collectAutofillContentService["trimAndRemoveNonPrintableText"](text);
expect(result).toEqual("これは テストです");
});
});
describe("recursivelyGetTextFromPreviousSiblings", () => {

View File

@@ -713,7 +713,7 @@ export class CollectAutofillContentService implements CollectAutofillContentServ
*/
private trimAndRemoveNonPrintableText(textContent: string): string {
return (textContent || "")
.replace(/[^\x20-\x7E]+|\s+/g, " ") // Strip out non-primitive characters and replace multiple spaces with a single space
.replace(/\p{C}+|\s+/gu, " ") // Strip out non-printable characters and replace multiple spaces with a single space
.trim(); // Trim leading and trailing whitespace
}

View File

@@ -36,6 +36,7 @@
[ngClass]="{ 'tw-hidden': passwordRevealed }"
readonly
bitInput
#passwordInput
type="password"
[value]="cipher.login.password"
aria-readonly="true"

View File

@@ -3,12 +3,14 @@
import { CommonModule, DatePipe } from "@angular/common";
import {
Component,
ElementRef,
EventEmitter,
inject,
Input,
OnChanges,
Output,
SimpleChanges,
ViewChild,
} from "@angular/core";
import { Observable, switchMap } from "rxjs";
@@ -61,6 +63,8 @@ export class LoginCredentialsViewComponent implements OnChanges {
@Input() activeUserId: UserId;
@Input() hadPendingChangePasswordTask: boolean;
@Output() handleChangePassword = new EventEmitter<void>();
@ViewChild("passwordInput")
private passwordInput!: ElementRef<HTMLInputElement>;
isPremium$: Observable<boolean> = this.accountService.activeAccount$.pipe(
switchMap((account) =>
@@ -92,6 +96,10 @@ export class LoginCredentialsViewComponent implements OnChanges {
ngOnChanges(changes: SimpleChanges): void {
if (changes["cipher"]) {
if (this.passwordInput?.nativeElement) {
// Reset password input type in case it's been toggled
this.passwordInput.nativeElement.type = "password";
}
this.passwordRevealed = false;
this.showPasswordCount = false;
}