Skip to content

Commit

Permalink
Merge branch 'main' into ps/dynamically-load-macos-passkey
Browse files Browse the repository at this point in the history
  • Loading branch information
dani-garcia authored Jan 16, 2025
2 parents cdfff73 + 9a6f00e commit 18d2d56
Show file tree
Hide file tree
Showing 48 changed files with 2,077 additions and 522 deletions.
2 changes: 1 addition & 1 deletion .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"enabledManagers": ["cargo", "github-actions", "npm"],
"packageRules": [
{
"groupName": "github action dependencies",
"groupName": "github-action minor",
"matchManagers": ["github-actions"],
"matchUpdateTypes": ["minor"]
},
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@bitwarden/desktop",
"description": "A secure and free password manager for all of your devices.",
"version": "2025.1.2",
"version": "2025.1.3",
"keywords": [
"bitwarden",
"password",
Expand Down Expand Up @@ -35,7 +35,7 @@
"clean:dist": "rimraf ./dist",
"pack:dir": "npm run clean:dist && electron-builder --dir -p never",
"pack:lin:flatpak": "npm run clean:dist && electron-builder --dir -p never && flatpak-builder --repo=build/.repo build/.flatpak ./resources/com.bitwarden.desktop.devel.yaml --install-deps-from=flathub --force-clean && flatpak build-bundle ./build/.repo/ ./dist/com.bitwarden.desktop.flatpak com.bitwarden.desktop",
"pack:lin": "npm run clean:dist && electron-builder --linux --x64 -p never && export SNAP_FILE=$(realpath ./dist/bitwarden_*.snap) && unsquashfs -d ./dist/tmp-snap/ $SNAP_FILE && mkdir -p ./dist/tmp-snap/meta/polkit/ && cp ./resources/com.bitwarden.desktop.policy ./dist/tmp-snap/meta/polkit/polkit.com.bitwarden.desktop.policy && rm $SNAP_FILE && mksquashfs ./dist/tmp-snap/ $SNAP_FILE -noappend -comp lzo -no-fragments && rm -rf ./dist/tmp-snap/",
"pack:lin": "npm run clean:dist && electron-builder --linux --x64 -p never && export SNAP_FILE=$(realpath ./dist/bitwarden_*.snap) && unsquashfs -d ./dist/tmp-snap/ $SNAP_FILE && mkdir -p ./dist/tmp-snap/meta/polkit/ && cp ./resources/com.bitwarden.desktop.policy ./dist/tmp-snap/meta/polkit/polkit.com.bitwarden.desktop.policy && rm $SNAP_FILE && snapcraft pack ./dist/tmp-snap/ && mv ./*.snap ./dist/ && rm -rf ./dist/tmp-snap/",
"pack:mac": "npm run clean:dist && 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",
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/desktop/src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@bitwarden/desktop",
"productName": "Bitwarden",
"description": "A secure and free password manager for all of your devices.",
"version": "2025.1.2",
"version": "2025.1.3",
"author": "Bitwarden Inc. <[email protected]> (https://bitwarden.com)",
"homepage": "https://bitwarden.com",
"license": "GPL-3.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,7 @@ export class OrganizationLayoutComponent implements OnInit {
filter((org) => org != null),
);

this.canAccessExport$ = combineLatest([
this.organization$,
this.configService.getFeatureFlag$(FeatureFlag.PM11360RemoveProviderExportPermission),
]).pipe(map(([org, removeProviderExport]) => org.canAccessExport(removeProviderExport)));
this.canAccessExport$ = this.organization$.pipe(map((org) => org.canAccessExport));

this.showPaymentAndHistory$ = this.organization$.pipe(
map(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { inject, NgModule } from "@angular/core";
import { CanMatchFn, RouterModule, Routes } from "@angular/router";
import { map } from "rxjs";
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";

import { canAccessSettingsTab } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";

import { organizationPermissionsGuard } from "../../organizations/guards/org-permissions.guard";
import { organizationRedirectGuard } from "../../organizations/guards/org-redirect.guard";
Expand All @@ -16,11 +11,6 @@ import { PoliciesComponent } from "../../organizations/policies";
import { AccountComponent } from "./account.component";
import { TwoFactorSetupComponent } from "./two-factor-setup.component";

const removeProviderExportPermission$: CanMatchFn = () =>
inject(ConfigService)
.getFeatureFlag$(FeatureFlag.PM11360RemoveProviderExportPermission)
.pipe(map((removeProviderExport) => removeProviderExport === true));

const routes: Routes = [
{
path: "",
Expand Down Expand Up @@ -68,27 +58,13 @@ const routes: Routes = [
titleId: "importData",
},
},

// Export routing is temporarily duplicated to set the flag value passed into org.canAccessExport
{
path: "export",
loadComponent: () =>
import("../tools/vault-export/org-vault-export.component").then(
(mod) => mod.OrganizationVaultExportComponent,
),
canMatch: [removeProviderExportPermission$], // if this matches, the flag is ON
canActivate: [organizationPermissionsGuard((org) => org.canAccessExport(true))],
data: {
titleId: "exportVault",
},
},
{
path: "export",
loadComponent: () =>
import("../tools/vault-export/org-vault-export.component").then(
(mod) => mod.OrganizationVaultExportComponent,
),
canActivate: [organizationPermissionsGuard((org) => org.canAccessExport(false))],
canActivate: [organizationPermissionsGuard((org) => org.canAccessExport)],
data: {
titleId: "exportVault",
},
Expand Down Expand Up @@ -118,7 +94,8 @@ function getSettingsRoute(organization: Organization) {
if (organization.canManageDeviceApprovals) {
return "device-approvals";
}
return undefined;

return "/";
}

@NgModule({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ export const SMAvailable: Story = {
canManageUsers: false,
canAccessSecretsManager: true,
enabled: true,
canAccessExport: (_) => false,
},
] as Organization[],
mockProviders: [],
Expand All @@ -173,7 +172,6 @@ export const SMAndACAvailable: Story = {
canManageUsers: true,
canAccessSecretsManager: true,
enabled: true,
canAccessExport: (_) => false,
},
] as Organization[],
mockProviders: [],
Expand All @@ -189,7 +187,6 @@ export const WithAllOptions: Story = {
canManageUsers: true,
canAccessSecretsManager: true,
enabled: true,
canAccessExport: (_) => false,
},
] as Organization[],
mockProviders: [{ id: "provider-a" }] as Provider[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ export const WithSM: Story = {
canManageUsers: false,
canAccessSecretsManager: true,
enabled: true,
canAccessExport: (_) => false,
},
] as Organization[],
mockProviders: [],
Expand All @@ -192,7 +191,6 @@ export const WithSMAndAC: Story = {
canManageUsers: true,
canAccessSecretsManager: true,
enabled: true,
canAccessExport: (_) => false,
},
] as Organization[],
mockProviders: [],
Expand All @@ -208,7 +206,6 @@ export const WithAllOptions: Story = {
canManageUsers: true,
canAccessSecretsManager: true,
enabled: true,
canAccessExport: (_) => false,
},
] as Organization[],
mockProviders: [{ id: "provider-a" }] as Provider[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ describe("ProductSwitcherService", () => {
id: "1234",
canAccessSecretsManager: true,
enabled: true,
canAccessExport: (_) => true,
},
] as Organization[]);

Expand Down Expand Up @@ -232,14 +231,12 @@ describe("ProductSwitcherService", () => {
canAccessSecretsManager: true,
enabled: true,
name: "Org 2",
canAccessExport: (_) => true,
},
{
id: "4243",
canAccessSecretsManager: true,
enabled: true,
name: "Org 32",
canAccessExport: (_) => true,
},
] as Organization[]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export type ApplicationHealthReportDetail = {
atRiskMemberDetails: MemberDetailsFlat[];
};

export type ApplicationHealthReportDetailWithCriticalFlag = ApplicationHealthReportDetail & {
isMarkedAsCritical: boolean;
};

/**
* Breaks the cipher health info out by uri and passes
* along the password health and member info
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { mock } from "jest-mock-extended";

import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { OrganizationId } from "@bitwarden/common/types/guid";

import { CriticalAppsApiService } from "./critical-apps-api.service";
import {
PasswordHealthReportApplicationId,
PasswordHealthReportApplicationsRequest,
PasswordHealthReportApplicationsResponse,
} from "./critical-apps.service";

describe("CriticalAppsApiService", () => {
let service: CriticalAppsApiService;
const apiService = mock<ApiService>();

beforeEach(() => {
service = new CriticalAppsApiService(apiService);
});

it("should be created", () => {
expect(service).toBeTruthy();
});

it("should call apiService.send with correct parameters for SaveCriticalApps", (done) => {
const requests: PasswordHealthReportApplicationsRequest[] = [
{ organizationId: "org1" as OrganizationId, url: "test one" },
{ organizationId: "org1" as OrganizationId, url: "test two" },
];
const response: PasswordHealthReportApplicationsResponse[] = [
{
id: "1" as PasswordHealthReportApplicationId,
organizationId: "org1" as OrganizationId,
uri: "test one",
},
{
id: "2" as PasswordHealthReportApplicationId,
organizationId: "org1" as OrganizationId,
uri: "test two",
},
];

apiService.send.mockReturnValue(Promise.resolve(response));

service.saveCriticalApps(requests).subscribe((result) => {
expect(result).toEqual(response);
expect(apiService.send).toHaveBeenCalledWith(
"POST",
"/reports/password-health-report-applications/",
requests,
true,
true,
);
done();
});
});

it("should call apiService.send with correct parameters for GetCriticalApps", (done) => {
const orgId: OrganizationId = "org1" as OrganizationId;
const response: PasswordHealthReportApplicationsResponse[] = [
{ id: "1" as PasswordHealthReportApplicationId, organizationId: orgId, uri: "test one" },
{ id: "2" as PasswordHealthReportApplicationId, organizationId: orgId, uri: "test two" },
];

apiService.send.mockReturnValue(Promise.resolve(response));

service.getCriticalApps(orgId).subscribe((result) => {
expect(result).toEqual(response);
expect(apiService.send).toHaveBeenCalledWith(
"GET",
`/reports/password-health-report-applications/${orgId.toString()}`,
null,
true,
true,
);
done();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { from, Observable } from "rxjs";

import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { OrganizationId } from "@bitwarden/common/types/guid";

import {
PasswordHealthReportApplicationsRequest,
PasswordHealthReportApplicationsResponse,
} from "./critical-apps.service";

export class CriticalAppsApiService {
constructor(private apiService: ApiService) {}

saveCriticalApps(
requests: PasswordHealthReportApplicationsRequest[],
): Observable<PasswordHealthReportApplicationsResponse[]> {
const dbResponse = this.apiService.send(
"POST",
"/reports/password-health-report-applications/",
requests,
true,
true,
);

return from(dbResponse as Promise<PasswordHealthReportApplicationsResponse[]>);
}

getCriticalApps(orgId: OrganizationId): Observable<PasswordHealthReportApplicationsResponse[]> {
const dbResponse = this.apiService.send(
"GET",
`/reports/password-health-report-applications/${orgId.toString()}`,
null,
true,
true,
);

return from(dbResponse as Promise<PasswordHealthReportApplicationsResponse[]>);
}
}
Loading

0 comments on commit 18d2d56

Please sign in to comment.