From 66a914badfd65046ce5969163e957ef8f919f5a8 Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Fri, 28 Mar 2025 15:50:30 -0400 Subject: [PATCH 1/4] [PM-19654] add hideIcon option to extension anon layout (#14045) --- .../extension-anon-layout-wrapper.component.html | 1 + .../extension-anon-layout-wrapper.component.ts | 10 ++++++++++ .../extension-anon-layout-wrapper.stories.ts | 2 ++ .../anon-layout/anon-layout.component.html | 2 +- .../angular/anon-layout/anon-layout.component.ts | 1 + .../angular/anon-layout/anon-layout.stories.ts | 16 ++++++++++++++++ 6 files changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html index 88a3b1c3076..54cb5203a87 100644 --- a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html +++ b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html @@ -21,6 +21,7 @@ [hideLogo]="true" [maxWidth]="maxWidth" [hideFooter]="hideFooter" + [hideIcon]="hideIcon" > diff --git a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts index 10ef65d0654..51dbb6503d7 100644 --- a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts +++ b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts @@ -26,6 +26,7 @@ export interface ExtensionAnonLayoutWrapperData extends AnonLayoutWrapperData { showBackButton?: boolean; showLogo?: boolean; hideFooter?: boolean; + hideIcon?: boolean; } @Component({ @@ -48,6 +49,7 @@ export class ExtensionAnonLayoutWrapperComponent implements OnInit, OnDestroy { protected showAcctSwitcher: boolean; protected showBackButton: boolean; protected showLogo: boolean = true; + protected hideIcon: boolean = false; protected pageTitle: string; protected pageSubtitle: string; @@ -129,6 +131,10 @@ export class ExtensionAnonLayoutWrapperComponent implements OnInit, OnDestroy { if (firstChildRouteData["showLogo"] !== undefined) { this.showLogo = Boolean(firstChildRouteData["showLogo"]); } + + if (firstChildRouteData["hideIcon"] !== undefined) { + this.hideIcon = Boolean(firstChildRouteData["hideIcon"]); + } } private listenForServiceDataChanges() { @@ -180,6 +186,10 @@ export class ExtensionAnonLayoutWrapperComponent implements OnInit, OnDestroy { if (data.showLogo !== undefined) { this.showLogo = data.showLogo; } + + if (data.hideIcon !== undefined) { + this.hideIcon = data.hideIcon; + } } private handleStringOrTranslation(value: string | Translation): string { diff --git a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts index 841eefda0ad..a0990485d49 100644 --- a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts +++ b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts @@ -242,6 +242,7 @@ const initialData: ExtensionAnonLayoutWrapperData = { showAcctSwitcher: true, showBackButton: true, showLogo: true, + hideIcon: false, }; const changedData: ExtensionAnonLayoutWrapperData = { @@ -255,6 +256,7 @@ const changedData: ExtensionAnonLayoutWrapperData = { showAcctSwitcher: false, showBackButton: false, showLogo: false, + hideIcon: false, }; @Component({ diff --git a/libs/auth/src/angular/anon-layout/anon-layout.component.html b/libs/auth/src/angular/anon-layout/anon-layout.component.html index 4120ea59002..f31a5500b43 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout.component.html +++ b/libs/auth/src/angular/anon-layout/anon-layout.component.html @@ -17,7 +17,7 @@ class="tw-text-center tw-mb-4 sm:tw-mb-6" [ngClass]="{ 'tw-max-w-md tw-mx-auto': titleAreaMaxWidth === 'md' }" > -
+
diff --git a/libs/auth/src/angular/anon-layout/anon-layout.component.ts b/libs/auth/src/angular/anon-layout/anon-layout.component.ts index 05ddb9614f1..1ca4ccd2432 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout.component.ts +++ b/libs/auth/src/angular/anon-layout/anon-layout.component.ts @@ -39,6 +39,7 @@ export class AnonLayoutComponent implements OnInit, OnChanges { @Input() showReadonlyHostname: boolean; @Input() hideLogo: boolean = false; @Input() hideFooter: boolean = false; + @Input() hideIcon: boolean = false; /** * Max width of the title area content diff --git a/libs/auth/src/angular/anon-layout/anon-layout.stories.ts b/libs/auth/src/angular/anon-layout/anon-layout.stories.ts index c7e15d9dcfa..34d561d5210 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout.stories.ts +++ b/libs/auth/src/angular/anon-layout/anon-layout.stories.ts @@ -163,6 +163,22 @@ export const WithCustomIcon: Story = { }), }; +export const HideIcon: Story = { + render: (args) => ({ + props: args, + template: + // Projected content (the
) and styling is just a sample and can be replaced with any content/styling. + ` + +
+
Primary Projected Content Area (customizable)
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Necessitatibus illum vero, placeat recusandae esse ratione eius minima veniam nemo, quas beatae! Impedit molestiae alias sapiente explicabo. Sapiente corporis ipsa numquam?
+
+
+ `, + }), +}; + export const HideLogo: Story = { render: (args) => ({ props: args, From 907abc9dae3ecb5b994d9e6d852d60576ec64bdb Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Sun, 30 Mar 2025 15:49:52 -0400 Subject: [PATCH 2/4] Complete feature flag grouping by team (#14054) * Completed feature flag grouping * Added organization of default value section. * Clarified comment. --- libs/common/src/enums/feature-flag.enum.ts | 52 +++++++++++++--------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index c5119cd5206..1907f6539c5 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -2,6 +2,8 @@ * Feature flags. * * Flags MUST be short lived and SHALL be removed once enabled. + * + * Flags should be grouped by team to have visibility of ownership and cleanup. */ export enum FeatureFlag { /* Admin Console Team */ @@ -9,6 +11,11 @@ export enum FeatureFlag { VerifiedSsoDomainEndpoint = "pm-12337-refactor-sso-details-endpoint", LimitItemDeletion = "pm-15493-restrict-item-deletion-to-can-manage-permission", SsoExternalIdVisibility = "pm-18630-sso-external-id-visibility", + AccountDeprovisioningBanner = "pm-17120-account-deprovisioning-admin-console-banner", + + /* Auth */ + PM9112_DeviceApprovalPersistence = "pm-9112-device-approval-persistence", + UnauthenticatedExtensionUIRefresh = "unauth-ui-refresh", /* Autofill */ BlockBrowserInjectionsByDomain = "block-browser-injections-by-domain", @@ -21,6 +28,18 @@ export enum FeatureFlag { NotificationBarAddLoginImprovements = "notification-bar-add-login-improvements", NotificationRefresh = "notification-refresh", UseTreeWalkerApiForPageDetailsCollection = "use-tree-walker-api-for-page-details-collection", + MacOsNativeCredentialSync = "macos-native-credential-sync", + + /* Billing */ + TrialPaymentOptional = "PM-8163-trial-payment", + PM15179_AddExistingOrgsFromProviderPortal = "pm-15179-add-existing-orgs-from-provider-portal", + PM12276_BreadcrumbEventLogs = "pm-12276-breadcrumbing-for-business-features", + PM18794_ProviderPaymentMethod = "pm-18794-provider-payment-method", + + /* Key Management */ + PrivateKeyRegeneration = "pm-12241-private-key-regeneration", + UserKeyRotationV2 = "userkey-rotation-v2", + PM4154_BulkEncryptionService = "PM-4154-bulk-encryption-service", /* Tools */ ItemShare = "item-share", @@ -36,21 +55,7 @@ export enum FeatureFlag { NewDeviceVerificationPermanentDismiss = "new-device-permanent-dismiss", VaultBulkManagementAction = "vault-bulk-management-action", SecurityTasks = "security-tasks", - - /* Auth */ - PM9112_DeviceApprovalPersistence = "pm-9112-device-approval-persistence", - - UserKeyRotationV2 = "userkey-rotation-v2", - PM4154_BulkEncryptionService = "PM-4154-bulk-encryption-service", - UnauthenticatedExtensionUIRefresh = "unauth-ui-refresh", CipherKeyEncryption = "cipher-key-encryption", - TrialPaymentOptional = "PM-8163-trial-payment", - MacOsNativeCredentialSync = "macos-native-credential-sync", - PrivateKeyRegeneration = "pm-12241-private-key-regeneration", - AccountDeprovisioningBanner = "pm-17120-account-deprovisioning-admin-console-banner", - PM15179_AddExistingOrgsFromProviderPortal = "pm-15179-add-existing-orgs-from-provider-portal", - PM12276_BreadcrumbEventLogs = "pm-12276-breadcrumbing-for-business-features", - PM18794_ProviderPaymentMethod = "pm-18794-provider-payment-method", } export type AllowedFeatureFlagTypes = boolean | number | string; @@ -63,6 +68,8 @@ const FALSE = false as boolean; * * DO NOT enable previously disabled flags, REMOVE them instead. * We support true as a value as we prefer flags to "enable" not "disable". + * + * Flags should be grouped by team to have visibility of ownership and cleanup. */ export const DefaultFeatureFlagValue = { /* Admin Console Team */ @@ -70,6 +77,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.VerifiedSsoDomainEndpoint]: FALSE, [FeatureFlag.LimitItemDeletion]: FALSE, [FeatureFlag.SsoExternalIdVisibility]: FALSE, + [FeatureFlag.AccountDeprovisioningBanner]: FALSE, /* Autofill */ [FeatureFlag.BlockBrowserInjectionsByDomain]: FALSE, @@ -82,6 +90,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.NotificationBarAddLoginImprovements]: FALSE, [FeatureFlag.NotificationRefresh]: FALSE, [FeatureFlag.UseTreeWalkerApiForPageDetailsCollection]: FALSE, + [FeatureFlag.MacOsNativeCredentialSync]: FALSE, /* Tools */ [FeatureFlag.ItemShare]: FALSE, @@ -97,21 +106,22 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.NewDeviceVerificationPermanentDismiss]: FALSE, [FeatureFlag.VaultBulkManagementAction]: FALSE, [FeatureFlag.SecurityTasks]: FALSE, + [FeatureFlag.CipherKeyEncryption]: FALSE, /* Auth */ [FeatureFlag.PM9112_DeviceApprovalPersistence]: FALSE, - - [FeatureFlag.UserKeyRotationV2]: FALSE, - [FeatureFlag.PM4154_BulkEncryptionService]: FALSE, [FeatureFlag.UnauthenticatedExtensionUIRefresh]: FALSE, - [FeatureFlag.CipherKeyEncryption]: FALSE, + + /* Billing */ [FeatureFlag.TrialPaymentOptional]: FALSE, - [FeatureFlag.MacOsNativeCredentialSync]: FALSE, - [FeatureFlag.PrivateKeyRegeneration]: FALSE, - [FeatureFlag.AccountDeprovisioningBanner]: FALSE, [FeatureFlag.PM15179_AddExistingOrgsFromProviderPortal]: FALSE, [FeatureFlag.PM12276_BreadcrumbEventLogs]: FALSE, [FeatureFlag.PM18794_ProviderPaymentMethod]: FALSE, + + /* Key Management */ + [FeatureFlag.PrivateKeyRegeneration]: FALSE, + [FeatureFlag.UserKeyRotationV2]: FALSE, + [FeatureFlag.PM4154_BulkEncryptionService]: FALSE, } satisfies Record; export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue; From 56672a3568da7ef0a79de6d18f0ab6a6baab47b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ch=C4=99ci=C5=84ski?= Date: Mon, 31 Mar 2025 12:59:47 +0200 Subject: [PATCH 3/4] [BRE-714] Enhance TestFlight desktop publishing (#13871) * Update TestFlight deployment to use Fastlane for app uploads * Update TestFlight deployment to use Fastlane for app uploads * Fix * Fix create secret for fastlane * Fix create secret for fastlane * Fix create secret for fastlane * Install gsed to use sed on macos runner * Create test file * Fix test * Use actual token * Add TestFlight distribution option for QA testing * Update .github/workflows/build-desktop.yml Co-authored-by: MtnBurrit0 <77340197+mimartin12@users.noreply.github.com> * Add if to secret construction for fastlane --------- Co-authored-by: MtnBurrit0 <77340197+mimartin12@users.noreply.github.com> --- .github/workflows/build-desktop.yml | 42 ++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 48ecca540e8..72b60da97a1 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -33,6 +33,10 @@ on: description: "Custom SDK branch" required: false type: string + testflight_distribute: + description: "Force distribute to TestFlight regardless of branch (useful for QA testing on feature branches)" + type: boolean + default: true defaults: run: @@ -1208,21 +1212,45 @@ jobs: path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg if-no-files-found: error + - name: Create secrets for Fastlane + if: | + github.event_name != 'pull_request_target' + && (inputs.testflight_distribute || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc-desktop') + run: | + brew install gsed + + KEY_WITHOUT_NEWLINES=$(gsed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g' ~/private_keys/AuthKey_6TV9MKN3GP.p8) + + cat << EOF > ~/secrets/appstoreconnect-fastlane.json + { + "issuer_id": "${{ secrets.APP_STORE_CONNECT_TEAM_ISSUER }}", + "key_id": "6TV9MKN3GP", + "key": "$KEY_WITHOUT_NEWLINES" + } + EOF + - name: Deploy to TestFlight id: testflight-deploy if: | github.event_name != 'pull_request_target' - && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc-desktop') + && (inputs.testflight_distribute || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc-desktop') env: APP_STORE_CONNECT_TEAM_ISSUER: ${{ secrets.APP_STORE_CONNECT_TEAM_ISSUER }} APP_STORE_CONNECT_AUTH_KEY: 6TV9MKN3GP + BRANCH: ${{ github.ref }} run: | - xcrun altool \ - --upload-app \ - --type macos \ - --file "$(find ./dist/mas-universal/Bitwarden*.pkg)" \ - --apiKey $APP_STORE_CONNECT_AUTH_KEY \ - --apiIssuer $APP_STORE_CONNECT_TEAM_ISSUER + + GIT_CHANGE="$(git show -s --format=%s)" + + BRANCH=$(echo $BRANCH | sed 's/refs\/heads\///') + + CHANGELOG="$BRANCH: $GIT_CHANGE" + + fastlane pilot upload \ + --app_identifier "com.bitwarden.desktop" \ + --changelog "$CHANGELOG" \ + --api_key_path $HOME/secrets/appstoreconnect-fastlane.json \ + --pkg "$(find ./dist/mas-universal/Bitwarden*.pkg)" - name: Post message to a Slack channel id: slack-message From 51bfbcf09056775e60fd24b11e37570e46835e85 Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Mon, 31 Mar 2025 09:11:47 -0400 Subject: [PATCH 4/4] chore(UI Refresh): [PM-19679] Remove unauth-ui-refresh flag from clients * Completed feature flag grouping * Added organization of default value section. * Clarified comment. * Removed flag * Removed merge error that duplicated comment. --- libs/common/src/enums/feature-flag.enum.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 1907f6539c5..798053c09d0 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -15,7 +15,6 @@ export enum FeatureFlag { /* Auth */ PM9112_DeviceApprovalPersistence = "pm-9112-device-approval-persistence", - UnauthenticatedExtensionUIRefresh = "unauth-ui-refresh", /* Autofill */ BlockBrowserInjectionsByDomain = "block-browser-injections-by-domain", @@ -110,7 +109,6 @@ export const DefaultFeatureFlagValue = { /* Auth */ [FeatureFlag.PM9112_DeviceApprovalPersistence]: FALSE, - [FeatureFlag.UnauthenticatedExtensionUIRefresh]: FALSE, /* Billing */ [FeatureFlag.TrialPaymentOptional]: FALSE,