App Password Name:
diff --git a/src/app/account-security/app-passwords.component.spec.ts b/src/app/account-security/app-passwords.component.spec.ts
new file mode 100644
index 000000000..272b6449f
--- /dev/null
+++ b/src/app/account-security/app-passwords.component.spec.ts
@@ -0,0 +1,119 @@
+// --------- BEGIN RUNBOX LICENSE ---------
+// Copyright (C) 2016-2026 Runbox Solutions AS (runbox.com).
+//
+// This file is part of Runbox 7.
+//
+// Runbox 7 is free software: You can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the
+// Free Software Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// Runbox 7 is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Runbox 7. If not, see .
+// ---------- END RUNBOX LICENSE ----------
+
+import { CommonModule } from '@angular/common';
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule } from '@angular/forms';
+import { of } from 'rxjs';
+import { MatLegacyDialog as MatDialog } from '@angular/material/legacy-dialog';
+import { MatLegacySnackBar as MatSnackBar } from '@angular/material/legacy-snack-bar';
+
+import { AppPasswordsComponent } from './app-passwords.component';
+import { MobileQueryService } from '../mobile-query.service';
+import { RMM } from '../rmm';
+
+describe('AppPasswordsComponent', () => {
+ let fixture: ComponentFixture;
+
+ type RmmMock = {
+ me: {
+ load: jasmine.Spy;
+ };
+ account_security: {
+ user_password: string;
+ tfa: {
+ get: jasmine.Spy;
+ settings: {
+ is_app_pass_enabled: boolean;
+ };
+ };
+ app_pass: {
+ list: jasmine.Spy;
+ create: jasmine.Spy;
+ update: jasmine.Spy;
+ is_busy: boolean;
+ password: Record;
+ results: unknown[];
+ };
+ };
+ };
+
+ let rmmMock: RmmMock;
+
+ beforeEach(async () => {
+ rmmMock = {
+ me: {
+ load: jasmine.createSpy('load'),
+ },
+ account_security: {
+ user_password: 'secret',
+ tfa: {
+ get: jasmine.createSpy('get'),
+ settings: {
+ is_app_pass_enabled: true,
+ },
+ },
+ app_pass: {
+ list: jasmine.createSpy('list'),
+ create: jasmine.createSpy('create').and.returnValue(of({ status: 'ok' })),
+ update: jasmine.createSpy('update').and.returnValue(of({ status: 'ok' })),
+ is_busy: false,
+ password: {},
+ results: [],
+ },
+ },
+ };
+
+ await TestBed.configureTestingModule({
+ declarations: [AppPasswordsComponent],
+ imports: [CommonModule, FormsModule],
+ providers: [
+ { provide: RMM, useValue: rmmMock },
+ { provide: MatSnackBar, useValue: { open: jasmine.createSpy('open') } },
+ {
+ provide: MatDialog,
+ useValue: { open: jasmine.createSpy('open').and.returnValue({ afterClosed: () => of(null) }) },
+ },
+ { provide: MobileQueryService, useValue: { matches: false } },
+ ],
+ schemas: [NO_ERRORS_SCHEMA],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(AppPasswordsComponent);
+ });
+
+ it('shows a warning when the main app password switch is disabled', () => {
+ rmmMock.account_security.tfa.settings.is_app_pass_enabled = false;
+
+ fixture.detectChanges();
+
+ expect(fixture.nativeElement.textContent).toContain('App Passwords are currently disabled.');
+ expect(fixture.nativeElement.textContent)
+ .toContain('New app passwords will not work until you enable the main switch above.');
+ });
+
+ it('does not show the warning when app passwords are enabled', () => {
+ rmmMock.account_security.tfa.settings.is_app_pass_enabled = true;
+
+ fixture.detectChanges();
+
+ expect(fixture.nativeElement.textContent).not.toContain('App Passwords are currently disabled.');
+ });
+});
diff --git a/src/app/account-security/app-passwords.component.ts b/src/app/account-security/app-passwords.component.ts
index 4fa012f12..bf3c20761 100644
--- a/src/app/account-security/app-passwords.component.ts
+++ b/src/app/account-security/app-passwords.component.ts
@@ -52,6 +52,10 @@ export class AppPasswordsComponent implements OnInit {
}
}
+ get isAppPasswordFeatureDisabled(): boolean {
+ return this.rmm.account_security.tfa.settings.is_app_pass_enabled === false;
+ }
+
app_pass_create() {
if (!this.rmm.account_security.user_password) {
this.show_modal_password();
diff --git a/src/app/changelog/changes.ts b/src/app/changelog/changes.ts
index 125deeb28..60c688220 100644
--- a/src/app/changelog/changes.ts
+++ b/src/app/changelog/changes.ts
@@ -71,11 +71,571 @@ export class ChangelogEntry {
// BEGIN:AUTOGENERATED
const changes = [
[
- "2b05c475",
- "1747382829",
+ "0cf08e23",
+ "1774632844",
+ "fix",
+ "account-security",
+ "warn when app passwords are disabled"
+ ],
+ [
+ "e42d70ad",
+ "1772635017",
+ "fix",
+ "tests",
+ "Format date according to local TZ in tests"
+ ],
+ [
+ "3e26a8f9",
+ "1772634692",
+ "test",
+ "draftdesk",
+ "check for double line break in draftdesk unit tests"
+ ],
+ [
+ "13471db2",
+ "1772634692",
+ "fix",
+ "compose",
+ "add double line break at top of replies"
+ ],
+ [
+ "ae85bb70",
+ "1771944794",
+ "refactor",
+ "cleanup",
+ "remove extra newline"
+ ],
+ [
+ "7a82a35a",
+ "1770942956",
+ "fix",
+ "stability",
+ "revert removal of fonts"
+ ],
+ [
+ "16279fab",
+ "1770875924",
+ "fix",
+ "stability",
+ "address castaway review comments for PR #1765"
+ ],
+ [
+ "5efd36f2",
+ "1770215427",
+ "refactor",
+ "rxjs",
+ "remove unused take import in test"
+ ],
+ [
+ "08d1476b",
+ "1770214776",
+ "refactor",
+ "cleanup",
+ "remove unused imports"
+ ],
+ [
+ "aeed9e93",
+ "1770214767",
+ "refactor",
+ "rxjs",
+ "remove redundant pipe take 1s on firstValueFrom"
+ ],
+ [
+ "995f055a",
+ "1770214759",
+ "refactor",
+ "cleanup",
+ "remove code that turned out to be unnecessary"
+ ],
+ [
+ "1b5feaae",
+ "1770214753",
+ "fix",
+ "build",
+ "gen-env"
+ ],
+ [
+ "a9730ff0",
+ "1770214747",
+ "build",
+ "deps",
+ "update package lock json"
+ ],
+ [
+ "47e1c3bd",
+ "1770214747",
+ "style",
+ "cleanup",
+ "remove obsolete CSS styles"
+ ],
+ [
+ "796fecff",
+ "1770214746",
+ "refactor",
+ "cleanup",
+ "remove unused code and constants"
+ ],
+ [
+ "3ea607c5",
+ "1770214746",
+ "fix",
+ "stability",
+ "gate service worker registration"
+ ],
+ [
+ "6718dd69",
+ "1770214714",
+ "ci",
+ "tooling",
+ "update ESLint configuration"
+ ],
+ [
+ "a38da338",
+ "1770214713",
+ "feat",
+ "migration",
+ "migrate to RxJS 7"
+ ],
+ [
+ "99b6b322",
+ "1770214713",
+ "refactor",
+ "2fa",
+ "Change 2FA unlock code description"
+ ],
+ [
+ "15d5b4f1",
+ "1769272608",
+ "style",
+ "account-upgrades",
+ "amend text regarding sub-accounts"
+ ],
+ [
+ "9f4c2fb3",
+ "1769009210",
+ "refactor",
+ "2fa",
+ "Change 2FA unlock code description"
+ ],
+ [
+ "f2d51985",
+ "1768489312",
+ "fix",
+ "cart",
+ "Fix add/remove cart item"
+ ],
+ [
+ "3bc39da0",
+ "1768480595",
+ "feat",
+ "upgrades",
+ "Show recommended plans with addons if needed to downgrade"
+ ],
+ [
+ "eaf16ee2",
+ "1768388642",
+ "refactor",
+ "upgrades",
+ "Ensure currency calculations are correct"
+ ],
+ [
+ "1b76a7d4",
+ "1767483281",
+ "fix",
+ "mailviewer",
+ "intercept `mailto:` links and open a compose window"
+ ],
+ [
+ "b52c415a",
+ "1765455095",
+ "fix",
+ "notifications",
+ "Check Notifcation API exists when showing button"
+ ],
+ [
+ "ad665a71",
+ "1764772951",
+ "fix",
+ "plans",
+ "Enable downgrade to Micro including Email Hosting"
+ ],
+ [
+ "840522fb",
+ "1764245620",
+ "style",
+ "payment",
+ "Change \"pending\" to \"incomplete\"."
+ ],
+ [
+ "9ada126e",
+ "1764175688",
+ "fix",
+ "stripe",
+ "Fail early if stripe submission errors"
+ ],
+ [
+ "757de0ed",
+ "1762962071",
+ "fix",
+ "stripe",
+ "Improve on-page status updates for Stripe payments"
+ ],
+ [
+ "35cb13aa",
+ "1761061904",
+ "fix",
+ "notification",
+ "notification permission on click"
+ ],
+ [
+ "524e9134",
+ "1760020202",
+ "style",
+ "payment",
+ "Correct image source URLs."
+ ],
+ [
+ "42c6b9d2",
+ "1759989960",
+ "style",
+ "payment",
+ "Move shopping cart style back to main stylesheet for it to work."
+ ],
+ [
+ "2154f5a8",
+ "1759989960",
+ "style",
+ "payment",
+ "Include missing SCSS file."
+ ],
+ [
+ "07f415a6",
+ "1759989960",
+ "style",
+ "payment",
+ "Add Apple Pay logo and imrpove formatting."
+ ],
+ [
+ "09968dc8",
+ "1759916636",
+ "feat",
+ "dkim",
+ "Display all users domains"
+ ],
+ [
+ "a6316817",
+ "1759692383",
+ "style",
+ "payment",
+ "Minor textual correction."
+ ],
+ [
+ "89bf44f6",
+ "1759692157",
+ "style",
+ "payment",
+ "Add cryptocurrency logos."
+ ],
+ [
+ "2cc33c58",
+ "1759689457",
+ "style",
+ "payment",
+ "Bundle Stripe and PayPal, and improve layout."
+ ],
+ [
+ "89de7403",
+ "1759202407",
+ "style",
+ "payment",
+ "Add note about number of email aliases on sub-accounts."
+ ],
+ [
+ "a04b4700",
+ "1759144876",
+ "fix",
+ "mailviewer",
+ "Show images with ngsw bypass"
+ ],
+ [
+ "0eb7556f",
+ "1757937300",
+ "fix",
+ "2fa",
+ "Show QR codes for 2FA generation"
+ ],
+ [
+ "440fbdfc",
+ "1756825896",
+ "fix",
+ "sentry",
+ "Downgrade client to make it work with sentry server"
+ ],
+ [
+ "10e135be",
+ "1756794090",
+ "style",
+ "payment",
+ "Fix typo."
+ ],
+ [
+ "7ebeca44",
+ "1756335277",
+ "style",
+ "settings",
+ "Moved and updated link to documentation."
+ ],
+ [
+ "a1faab26",
+ "1756305250",
+ "fix",
+ "paymentcards",
+ "Make add card dialog fit on screen"
+ ],
+ [
+ "50b8e5db",
+ "1755783796",
"feat",
"worker",
- "Add sentry to xapian worker scope"
+ "Improve Sentry integration"
+ ],
+ [
+ "db8ccdef",
+ "1754909871",
+ "fix",
+ "stripe",
+ "Allow dialog to scroll (make Submit reachable)"
+ ],
+ [
+ "4bdcff06",
+ "1751829714",
+ "style",
+ "dkim",
+ "Add note about format."
+ ],
+ [
+ "7d6ddd10",
+ "1751477343",
+ "fix",
+ "cart",
+ "Renewing a subscription now sets a quantity of 1"
+ ],
+ [
+ "1eebaa8a",
+ "1751367740",
+ "fix",
+ "commit-lint",
+ "allow hyphen in commit subject"
+ ],
+ [
+ "67c0a118",
+ "1751367409",
+ "fix",
+ "login",
+ "make login inputs required"
+ ],
+ [
+ "29eb8869",
+ "1751367360",
+ "fix",
+ "side-menu",
+ "make buttons keyboard navigable"
+ ],
+ [
+ "8d22da9f",
+ "1751363648",
+ "fix",
+ "upgrades",
+ "Highlight correct \"current sub\" in plans table"
+ ],
+ [
+ "d40892f9",
+ "1751296588",
+ "build",
+ "lint",
+ "Remove typos from commit-lint tags"
+ ],
+ [
+ "e7be3886",
+ "1751296588",
+ "fix",
+ "upgrades",
+ "Indicate which plans would put the user over quota"
+ ],
+ [
+ "ea501342",
+ "1751291013",
+ "fix",
+ "subscriptions",
+ "Only warn about close-quota for Disk/File quotas"
+ ],
+ [
+ "1a198352",
+ "1751277492",
+ "fix",
+ "upgrades",
+ "Prevent two subscriptions being bought at once"
+ ],
+ [
+ "9e4d014c",
+ "1750951971",
+ "fix",
+ "mailviewer",
+ "Text/HTML views blank when attachment has odd types"
+ ],
+ [
+ "290ebe7e",
+ "1750694678",
+ "fix",
+ "upgrades",
+ "Remove ability to buy plans when over usage"
+ ],
+ [
+ "8b4ad27a",
+ "1750691421",
+ "fix",
+ "upgrades",
+ "Checks quota usage for plan upgrades table"
+ ],
+ [
+ "77657d08",
+ "1750691117",
+ "build",
+ "lint",
+ "Fix allowed commit-message tags"
+ ],
+ [
+ "19ee3d5f",
+ "1750410342",
+ "style",
+ "upgrades",
+ "Improve formatting of recommended plans and other fixes."
+ ],
+ [
+ "e53115a7",
+ "1750354119",
+ "fix",
+ "upgrades",
+ "Compare user's quotas when displaying plans"
+ ],
+ [
+ "6d14aa2b",
+ "1750088797",
+ "fix",
+ "renewals",
+ "Removes confusing Yes/No for renewal checkboxes"
+ ],
+ [
+ "b2d769b7",
+ "1750084083",
+ "fix",
+ "mailviewer",
+ "Fixes attachment display with HTML (again)"
+ ],
+ [
+ "4a4e08e2",
+ "1749740369",
+ "fix",
+ "mailviewer",
+ "Only show attachments that are not inline in HTML"
+ ],
+ [
+ "1beabc35",
+ "1749571399",
+ "fix",
+ "folderlist",
+ "place dir expander button above the anchor overlay"
+ ],
+ [
+ "1e5cee80",
+ "1749544633",
+ "fix",
+ "github",
+ "make checkout of fork work in commit lint workflow"
+ ],
+ [
+ "8d0d3cde",
+ "1749227244",
+ "style",
+ "mail",
+ "Make Allow and Block Sender descriptions consistent."
+ ],
+ [
+ "652e3748",
+ "1749031846",
+ "build",
+ "ci",
+ "Remove redundant cache action"
+ ],
+ [
+ "9a0189bb",
+ "1749031810",
+ "build",
+ "ci",
+ "prevent improper commit formatting from being merged into master"
+ ],
+ [
+ "6cfc7dd4",
+ "1748872985",
+ "fix",
+ "details",
+ "show alternative email resend on email change"
+ ],
+ [
+ "0036ce78",
+ "1748517484",
+ "fix",
+ "payments",
+ "Handle post stripe 3d secure correctly"
+ ],
+ [
+ "ea2c77ca",
+ "1747908332",
+ "fix",
+ "build",
+ "Remove unused dependencies (revert)"
+ ],
+ [
+ "2ef0626f",
+ "1747734901",
+ "build",
+ "deps",
+ "Remove unused dependencies"
+ ],
+ [
+ "183d42ad",
+ "1747729699",
+ "build",
+ "deps",
+ "Remove unused dependencies"
+ ],
+ [
+ "90d46835",
+ "1747328794",
+ "fix",
+ "payments",
+ "Renew or create products after Stripe payment"
+ ],
+ [
+ "9b2580c3",
+ "1747302470",
+ "fix",
+ "folderlist",
+ "Make folder buttons keyboard navigable"
+ ],
+ [
+ "51cb8dfe",
+ "1747297115",
+ "feat",
+ "login",
+ "Add autcomplete attrs in accordance with WCAG guidelines"
+ ],
+ [
+ "403f7367",
+ "1747296965",
+ "fix",
+ "login",
+ "Fix user not sent with login req even when field is filled"
],
[
"111120bd",