mirror of
https://github.com/bitwarden/browser
synced 2026-02-11 05:53:42 +00:00
Merge branch 'main' into ac/pm-17168/revoking-user-is-not-synced-immediately-via-push-notification
This commit is contained in:
@@ -47,6 +47,6 @@
|
||||
|
||||
<div
|
||||
*ngIf="showOverlay"
|
||||
class="tw-absolute tw-w-full tw-h-full tw-bg-background-alt tw-inset-0 tw-bg-opacity-80 tw-z-50"
|
||||
class="tw-absolute tw-size-full tw-bg-background-alt tw-inset-0 tw-bg-opacity-80 tw-z-50"
|
||||
></div>
|
||||
</ng-container>
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
<ng-content select="[slot=above-scroll-area]"></ng-content>
|
||||
</div>
|
||||
<div
|
||||
class="tw-max-w-screen-sm tw-mx-auto tw-overflow-y-auto tw-flex tw-flex-col tw-w-full tw-h-full tw-styled-scrollbar"
|
||||
class="tw-max-w-screen-sm tw-mx-auto tw-overflow-y-auto tw-flex tw-flex-col tw-size-full tw-styled-scrollbar"
|
||||
data-testid="popup-layout-scroll-region"
|
||||
(scroll)="handleScroll($event)"
|
||||
[ngClass]="{ 'tw-invisible': loading }"
|
||||
>
|
||||
<div
|
||||
class="tw-max-w-screen-sm tw-mx-auto tw-flex-1 tw-flex tw-flex-col tw-h-full tw-w-full"
|
||||
class="tw-max-w-screen-sm tw-mx-auto tw-flex-1 tw-flex tw-flex-col tw-size-full"
|
||||
[ngClass]="{ 'tw-p-3 bit-compact:tw-p-2': !disablePadding }"
|
||||
>
|
||||
<ng-content></ng-content>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</p>
|
||||
<div
|
||||
*ngIf="showBadge$ | async"
|
||||
class="tw-flex tw-items-center tw-justify-center tw-z-10 tw-absolute tw-rounded-full tw-h-[15px] tw-w-[15px] tw-top-[1px] tw-right-[1px] tw-text-notification-600 tw-text-[8px] tw-border-notification-600 tw-border-[0.5px] tw-border-solid tw-bg-notification-100 tw-leading-normal"
|
||||
class="tw-flex tw-items-center tw-justify-center tw-z-10 tw-absolute tw-rounded-full tw-size-[15px] tw-top-[1px] tw-right-[1px] tw-text-notification-600 tw-text-[8px] tw-border-notification-600 tw-border-[0.5px] tw-border-solid tw-bg-notification-100 tw-leading-normal"
|
||||
data-testid="filter-badge"
|
||||
>
|
||||
{{ numberOfAppliedFilters$ | async }}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<div
|
||||
class="tw-flex tw-h-32 tw-bg-secondary-100 tw-items-center tw-justify-center tw-pb-2 tw-px-6 lg:tw-pb-4 lg:tw-px-12"
|
||||
>
|
||||
<div class="tw-flex tw-items-center tw-justify-center tw-h-28 tw-w-28 lg:tw-w-40">
|
||||
<div class="tw-flex tw-items-center tw-justify-center tw-size-28 lg:tw-w-40">
|
||||
<img
|
||||
#imageEle
|
||||
[src]="image"
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="tw-p-5">
|
||||
<h3 class="tw-text-main tw-text-lg tw-font-semibold">{{ name }}</h3>
|
||||
<a
|
||||
class="tw-block tw-mb-0 tw-font-bold hover:tw-no-underline focus:tw-outline-none after:tw-content-[''] after:tw-block after:tw-absolute after:tw-w-full after:tw-h-full after:tw-left-0 after:tw-top-0"
|
||||
class="tw-block tw-mb-0 tw-font-bold hover:tw-no-underline focus:tw-outline-none after:tw-content-[''] after:tw-block after:tw-absolute after:tw-size-full after:tw-left-0 after:tw-top-0"
|
||||
[href]="linkURL"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
'!tw-outline-[3px] tw-outline-primary-600 hover:tw-outline-[3px] hover:tw-outline-primary-600':
|
||||
customColorSelected,
|
||||
}"
|
||||
class="tw-relative tw-flex tw-h-24 tw-w-24 tw-cursor-pointer tw-place-content-center tw-content-center tw-justify-center tw-rounded-full tw-border tw-border-solid tw-border-secondary-600 tw-outline tw-outline-0 tw-outline-offset-1 hover:tw-outline-1 hover:tw-outline-primary-300 focus:tw-outline-2 focus:tw-outline-primary-600"
|
||||
class="tw-relative tw-flex tw-size-24 tw-cursor-pointer tw-place-content-center tw-rounded-full tw-border tw-border-solid tw-border-secondary-600 tw-outline tw-outline-0 tw-outline-offset-1 hover:tw-outline-1 hover:tw-outline-primary-300 focus:tw-outline-2 focus:tw-outline-primary-600"
|
||||
[style.background-color]="customColor$ | async"
|
||||
>
|
||||
<i
|
||||
@@ -37,7 +37,7 @@
|
||||
></i>
|
||||
<input
|
||||
tabindex="-1"
|
||||
class="tw-absolute tw-bottom-0 tw-right-0 tw-h-px tw-w-px tw-border-none tw-bg-transparent tw-opacity-0"
|
||||
class="tw-absolute tw-bottom-0 tw-right-0 tw-size-px tw-border-none tw-bg-transparent tw-opacity-0"
|
||||
#colorPicker
|
||||
type="color"
|
||||
[ngModel]="customColor$ | async"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<button
|
||||
[bitPopoverTriggerFor]="infoPopover"
|
||||
type="button"
|
||||
class="tw-border-none tw-bg-transparent tw-text-primary-600 tw-flex tw-items-center tw-h-4 tw-w-4"
|
||||
class="tw-border-none tw-bg-transparent tw-text-primary-600 tw-flex tw-items-center tw-size-4"
|
||||
[position]="'right-start'"
|
||||
>
|
||||
<i class="bwi bwi-question-circle" aria-hidden="true"></i>
|
||||
@@ -15,7 +15,7 @@
|
||||
</bit-popover>
|
||||
<i
|
||||
*ngIf="asyncActionLoading"
|
||||
class="bwi bwi-spinner bwi-spin tw-flex tw-items-center tw-h-4 tw-w-4"
|
||||
class="bwi bwi-spinner bwi-spin tw-flex tw-items-center tw-size-4"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="tw-mb-1 tw-items-center" *ngIf="annualPlan !== null">
|
||||
<label class="tw- tw-block tw-text-main" for="annual">
|
||||
<input
|
||||
class="tw-h-4 tw-w-4 tw-align-middle"
|
||||
class="tw-size-4 tw-align-middle"
|
||||
id="annual"
|
||||
name="cadence"
|
||||
type="radio"
|
||||
@@ -34,7 +34,7 @@
|
||||
<div class="tw-mb-1 tw-items-center" *ngIf="monthlyPlan !== null">
|
||||
<label class="tw- tw-block tw-text-main" for="monthly">
|
||||
<input
|
||||
class="tw-h-4 tw-w-4 tw-align-middle"
|
||||
class="tw-size-4 tw-align-middle"
|
||||
id="monthly"
|
||||
name="cadence"
|
||||
type="radio"
|
||||
|
||||
@@ -39,7 +39,13 @@
|
||||
<th bitCell bitSortable="organizationId" *ngIf="!isAdminConsoleActive">
|
||||
{{ "owner" | i18n }}
|
||||
</th>
|
||||
<th bitCell class="tw-text-right" bitSortable="score" default>
|
||||
<th
|
||||
bitCell
|
||||
class="tw-text-right"
|
||||
bitSortable="score"
|
||||
default
|
||||
(sortChange)="onSortChange('score', $event)"
|
||||
>
|
||||
{{ "weakness" | i18n }}
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
@@ -59,6 +59,7 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen
|
||||
this.weakPasswordCiphers = [];
|
||||
this.filterStatus = [0];
|
||||
this.findWeakPasswords(allCiphers);
|
||||
this.weakPasswordCiphers = this.sortCiphers(this.weakPasswordCiphers, "score", false);
|
||||
}
|
||||
|
||||
protected findWeakPasswords(ciphers: CipherView[]): void {
|
||||
@@ -112,6 +113,29 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen
|
||||
this.filterCiphersByOrg(this.weakPasswordCiphers);
|
||||
}
|
||||
|
||||
onSortChange(field: string, event: Event) {
|
||||
const target = event.target as HTMLInputElement;
|
||||
const ascending = target.checked;
|
||||
this.weakPasswordCiphers = this.sortCiphers(this.weakPasswordCiphers, field, ascending);
|
||||
}
|
||||
|
||||
protected sortCiphers(
|
||||
ciphers: ReportResult[],
|
||||
field: string,
|
||||
ascending: boolean,
|
||||
): ReportResult[] {
|
||||
return ciphers.sort((a, b) => {
|
||||
const aValue = a[field as keyof ReportResult];
|
||||
const bValue = b[field as keyof ReportResult];
|
||||
|
||||
if (aValue === bValue) {
|
||||
return 0;
|
||||
}
|
||||
const comparison = aValue > bValue ? 1 : -1;
|
||||
return ascending ? comparison : -comparison;
|
||||
});
|
||||
}
|
||||
|
||||
protected canManageCipher(c: CipherView): boolean {
|
||||
// this will only ever be false from the org view;
|
||||
return true;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[src]="data.image"
|
||||
[appFallbackSrc]="data.fallbackImage"
|
||||
*ngIf="data.imageEnabled && data.image"
|
||||
class="tw-h-6 tw-w-6 tw-rounded-md"
|
||||
class="tw-size-6 tw-rounded-md"
|
||||
alt=""
|
||||
decoding="async"
|
||||
loading="lazy"
|
||||
|
||||
@@ -8,7 +8,6 @@ import { ApiService } from "../../abstractions/api.service";
|
||||
import { AccountService } from "../../auth/abstractions/account.service";
|
||||
import { AuthService } from "../../auth/abstractions/auth.service";
|
||||
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
|
||||
import { getUserId } from "../../auth/services/account.service";
|
||||
import {
|
||||
SyncCipherNotification,
|
||||
SyncFolderNotification,
|
||||
@@ -59,7 +58,7 @@ export abstract class CoreSyncService implements SyncService {
|
||||
abstract fullSync(forceSync: boolean, allowThrowOnError?: boolean): Promise<boolean>;
|
||||
|
||||
async getLastSync(): Promise<Date> {
|
||||
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
||||
const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id)));
|
||||
if (userId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
|
||||
import {
|
||||
CollectionService,
|
||||
@@ -34,7 +34,6 @@ import { InternalMasterPasswordServiceAbstraction } from "../../auth/abstraction
|
||||
import { TokenService } from "../../auth/abstractions/token.service";
|
||||
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
|
||||
import { ForceSetPasswordReason } from "../../auth/models/domain/force-set-password-reason";
|
||||
import { getUserId } from "../../auth/services/account.service";
|
||||
import { DomainSettingsService } from "../../autofill/services/domain-settings.service";
|
||||
import { BillingAccountProfileStateService } from "../../billing/abstractions";
|
||||
import { DomainsResponse } from "../../models/response/domains.response";
|
||||
@@ -108,7 +107,7 @@ export class DefaultSyncService extends CoreSyncService {
|
||||
|
||||
@sequentialize(() => "fullSync")
|
||||
override async fullSync(forceSync: boolean, allowThrowOnError = false): Promise<boolean> {
|
||||
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
||||
const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id)));
|
||||
this.syncStarted();
|
||||
const authStatus = await firstValueFrom(this.authService.authStatusFor$(userId));
|
||||
if (authStatus === AuthenticationStatus.LoggedOut) {
|
||||
|
||||
@@ -35,10 +35,7 @@
|
||||
'tw-min-h-60': loading,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
*ngIf="loading"
|
||||
class="tw-absolute tw-flex tw-h-full tw-w-full tw-items-center tw-justify-center"
|
||||
>
|
||||
<div *ngIf="loading" class="tw-absolute tw-flex tw-size-full tw-items-center tw-justify-center">
|
||||
<i class="bwi bwi-spinner bwi-spin bwi-lg" [attr.aria-label]="'loading' | i18n"></i>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
</ng-template>
|
||||
|
||||
<div *ngIf="!readOnly; else readOnlyView" class="tw-w-full tw-relative tw-group/bit-form-field">
|
||||
<div class="tw-absolute tw-w-full tw-h-full tw-top-0 tw-pointer-events-none tw-z-20">
|
||||
<div class="tw-w-full tw-h-full tw-flex">
|
||||
<div class="tw-absolute tw-size-full tw-top-0 tw-pointer-events-none tw-z-20">
|
||||
<div class="tw-size-full tw-flex">
|
||||
<div
|
||||
class="tw-min-w-3 tw-border-r-0 group-focus-within/bit-form-field:tw-border-r-0 !tw-rounded-l-lg"
|
||||
[ngClass]="inputBorderClasses"
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<div
|
||||
*ngIf="data.open"
|
||||
(click)="sideNavService.toggle()"
|
||||
class="tw-pointer-events-auto tw-h-full tw-w-full"
|
||||
class="tw-pointer-events-auto tw-size-full"
|
||||
></div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#btn
|
||||
type="button"
|
||||
role="tab"
|
||||
class="tw-h-6 tw-w-6 tw-p-0 tw-flex tw-items-center tw-justify-center tw-border-2 tw-border-solid tw-rounded-full tw-transition tw-bg-transparent tw-border-transparent focus-visible:tw-outline-none focus-visible:tw-border-primary-600"
|
||||
class="tw-size-6 tw-p-0 tw-flex tw-items-center tw-justify-center tw-border-2 tw-border-solid tw-rounded-full tw-transition tw-bg-transparent tw-border-transparent focus-visible:tw-outline-none focus-visible:tw-border-primary-600"
|
||||
[ngClass]="dynamicClasses"
|
||||
[attr.aria-selected]="isActive"
|
||||
[attr.tabindex]="isActive ? 0 : -1"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
bitTypography="helper"
|
||||
>{{ totpSec }}</span
|
||||
>
|
||||
<svg class="tw-w-7 tw-h-7" transform="rotate(-90)">
|
||||
<svg class="tw-size-7" transform="rotate(-90)">
|
||||
<g>
|
||||
<circle
|
||||
class="tw-fill-none"
|
||||
|
||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -147,7 +147,7 @@
|
||||
"eslint-plugin-rxjs": "5.0.3",
|
||||
"eslint-plugin-rxjs-angular": "2.0.1",
|
||||
"eslint-plugin-storybook": "0.11.2",
|
||||
"eslint-plugin-tailwindcss": "3.17.5",
|
||||
"eslint-plugin-tailwindcss": "3.18.0",
|
||||
"html-loader": "5.1.0",
|
||||
"html-webpack-injector": "1.1.4",
|
||||
"html-webpack-plugin": "5.6.3",
|
||||
@@ -16209,9 +16209,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-tailwindcss": {
|
||||
"version": "3.17.5",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-tailwindcss/-/eslint-plugin-tailwindcss-3.17.5.tgz",
|
||||
"integrity": "sha512-8Mi7p7dm+mO1dHgRHHFdPu4RDTBk69Cn4P0B40vRQR+MrguUpwmKwhZy1kqYe3Km8/4nb+cyrCF+5SodOEmaow==",
|
||||
"version": "3.18.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-tailwindcss/-/eslint-plugin-tailwindcss-3.18.0.tgz",
|
||||
"integrity": "sha512-PQDU4ZMzFH0eb2DrfHPpbgo87Zgg2EXSMOj1NSfzdZm+aJzpuwGerfowMIaVehSREEa0idbf/eoNYAOHSJoDAQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
"eslint-plugin-rxjs": "5.0.3",
|
||||
"eslint-plugin-rxjs-angular": "2.0.1",
|
||||
"eslint-plugin-storybook": "0.11.2",
|
||||
"eslint-plugin-tailwindcss": "3.17.5",
|
||||
"eslint-plugin-tailwindcss": "3.18.0",
|
||||
"html-loader": "5.1.0",
|
||||
"html-webpack-injector": "1.1.4",
|
||||
"html-webpack-plugin": "5.6.3",
|
||||
|
||||
Reference in New Issue
Block a user