mirror of
https://github.com/bitwarden/browser
synced 2026-02-07 12:13:45 +00:00
Merge branch 'main' into autofill/pm-5189-fix-issues-present-with-inline-menu-rendering-in-iframes
This commit is contained in:
@@ -324,6 +324,26 @@
|
||||
"rules": {
|
||||
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/bit-common/*", "src/**/*"] }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["apps/**/*.ts"],
|
||||
"rules": {
|
||||
// Catches static imports
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"patterns": ["biwarden_license/**", "@bitwarden/bit-common/*", "@bitwarden/bit-web/*"]
|
||||
}
|
||||
],
|
||||
// Catches dynamic imports, e.g. in routing modules where modules are lazy-loaded
|
||||
"no-restricted-syntax": [
|
||||
"error",
|
||||
{
|
||||
"message": "Don't import Bitwarden licensed code into OSS code.",
|
||||
"selector": "ImportExpression > Literal.source[value=/.*(bitwarden_license|bit-common|bit-web).*/]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*ngIf="showBackButton"
|
||||
[title]="'back' | i18n"
|
||||
[ariaLabel]="'back' | i18n"
|
||||
(click)="back()"
|
||||
[bitAction]="backAction"
|
||||
></button>
|
||||
<h1 bitTypography="h3" class="!tw-mb-0.5 tw-text-headers">{{ pageTitle }}</h1>
|
||||
</div>
|
||||
|
||||
@@ -3,13 +3,18 @@ import { CommonModule, Location } from "@angular/common";
|
||||
import { Component, Input } from "@angular/core";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { IconButtonModule, TypographyModule } from "@bitwarden/components";
|
||||
import {
|
||||
AsyncActionsModule,
|
||||
FunctionReturningAwaitable,
|
||||
IconButtonModule,
|
||||
TypographyModule,
|
||||
} from "@bitwarden/components";
|
||||
|
||||
@Component({
|
||||
selector: "popup-header",
|
||||
templateUrl: "popup-header.component.html",
|
||||
standalone: true,
|
||||
imports: [TypographyModule, CommonModule, IconButtonModule, JslibModule],
|
||||
imports: [TypographyModule, CommonModule, IconButtonModule, JslibModule, AsyncActionsModule],
|
||||
})
|
||||
export class PopupHeaderComponent {
|
||||
/** Display the back button, which uses Location.back() to go back one page in history */
|
||||
@@ -26,9 +31,15 @@ export class PopupHeaderComponent {
|
||||
/** Title string that will be inserted as an h1 */
|
||||
@Input({ required: true }) pageTitle: string;
|
||||
|
||||
constructor(private location: Location) {}
|
||||
|
||||
back() {
|
||||
/**
|
||||
* Async action that occurs when clicking the back button
|
||||
*
|
||||
* If unset, will call `location.back()`
|
||||
**/
|
||||
@Input()
|
||||
backAction: FunctionReturningAwaitable = async () => {
|
||||
this.location.back();
|
||||
}
|
||||
};
|
||||
|
||||
constructor(private location: Location) {}
|
||||
}
|
||||
|
||||
@@ -32,17 +32,17 @@ import { OrganizationInvite } from "./organization-invite";
|
||||
// We're storing the organization invite for 2 reasons:
|
||||
// 1. If the org requires a MP policy check, we need to keep track that the user has already been redirected when they return.
|
||||
// 2. The MP policy check happens on login/register flows, we need to store the token to retrieve the policies then.
|
||||
export const ORGANIZATION_INVITE = new KeyDefinition<OrganizationInvite>(
|
||||
export const ORGANIZATION_INVITE = new KeyDefinition<OrganizationInvite | null>(
|
||||
ORGANIZATION_INVITE_DISK,
|
||||
"organizationInvite",
|
||||
{
|
||||
deserializer: (invite) => OrganizationInvite.fromJSON(invite),
|
||||
deserializer: (invite) => (invite ? OrganizationInvite.fromJSON(invite) : null),
|
||||
},
|
||||
);
|
||||
|
||||
@Injectable()
|
||||
export class AcceptOrganizationInviteService {
|
||||
private organizationInvitationState: GlobalState<OrganizationInvite>;
|
||||
private organizationInvitationState: GlobalState<OrganizationInvite | null>;
|
||||
private orgNameSubject: BehaviorSubject<string> = new BehaviorSubject<string>(null);
|
||||
private policyCache: Policy[];
|
||||
|
||||
@@ -66,7 +66,7 @@ export class AcceptOrganizationInviteService {
|
||||
}
|
||||
|
||||
/** Returns the currently stored organization invite */
|
||||
async getOrganizationInvite(): Promise<OrganizationInvite> {
|
||||
async getOrganizationInvite(): Promise<OrganizationInvite | null> {
|
||||
return await firstValueFrom(this.organizationInvitationState.state$);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,11 +11,19 @@ export class OrganizationInvite {
|
||||
organizationUserId: string;
|
||||
token: string;
|
||||
|
||||
static fromJSON(json: Jsonify<OrganizationInvite>) {
|
||||
static fromJSON(json: Jsonify<OrganizationInvite>): OrganizationInvite | null {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Object.assign(new OrganizationInvite(), json);
|
||||
}
|
||||
|
||||
static fromParams(params: Params): OrganizationInvite {
|
||||
static fromParams(params: Params): OrganizationInvite | null {
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Object.assign(new OrganizationInvite(), {
|
||||
email: params.email,
|
||||
initOrganization: params.initOrganization?.toLocaleLowerCase() === "true",
|
||||
|
||||
@@ -43,7 +43,7 @@ export class ApproveCommand {
|
||||
|
||||
const request = pendingRequests.find((r) => r.id == id);
|
||||
if (request == null) {
|
||||
return Response.error("Invalid request id");
|
||||
return Response.error("The request id is invalid.");
|
||||
}
|
||||
|
||||
await this.organizationAuthRequestService.approvePendingRequest(organizationId, request);
|
||||
|
||||
@@ -38,10 +38,16 @@ export class DenyCommand {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.organizationAuthRequestService.denyPendingRequests(organizationId, id);
|
||||
await this.organizationAuthRequestService.denyPendingRequest(organizationId, id);
|
||||
return Response.success();
|
||||
} catch (e) {
|
||||
return Response.error(e);
|
||||
} catch (error) {
|
||||
if (error?.statusCode === 404) {
|
||||
return Response.error(
|
||||
"The request id is invalid or you do not have permission to update it.",
|
||||
);
|
||||
}
|
||||
|
||||
return Response.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,4 +61,14 @@ export class OrganizationAuthRequestApiService {
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
async denyPendingRequest(organizationId: string, requestId: string): Promise<void> {
|
||||
await this.apiService.send(
|
||||
"POST",
|
||||
`/organizations/${organizationId}/auth-requests/${requestId}`,
|
||||
new AdminAuthRequestUpdateRequest(false),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,10 @@ export class OrganizationAuthRequestService {
|
||||
);
|
||||
}
|
||||
|
||||
async denyPendingRequest(organizationId: string, requestId: string) {
|
||||
await this.organizationAuthRequestApiService.denyPendingRequest(organizationId, requestId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of the user key that has been encrypted with the provided device's public key.
|
||||
* @param organizationId
|
||||
|
||||
@@ -36,7 +36,7 @@ export const CACHE_EXPIRATION_KEY = new KeyDefinition<Date | null>(
|
||||
* foreground instance to send out the notification.
|
||||
* TODO: Move to Auth Request service.
|
||||
*/
|
||||
export const AUTH_REQUEST_PUSH_NOTIFICATION_KEY = new KeyDefinition<string>(
|
||||
export const AUTH_REQUEST_PUSH_NOTIFICATION_KEY = new KeyDefinition<string | null>(
|
||||
LOGIN_STRATEGY_MEMORY,
|
||||
"authRequestPushNotification",
|
||||
{
|
||||
|
||||
@@ -28,13 +28,18 @@ import {
|
||||
} from "../models/request/update-devices-trust.request";
|
||||
|
||||
/** Uses disk storage so that the device key can persist after log out and tab removal. */
|
||||
export const DEVICE_KEY = new UserKeyDefinition<DeviceKey>(DEVICE_TRUST_DISK_LOCAL, "deviceKey", {
|
||||
deserializer: (deviceKey) => SymmetricCryptoKey.fromJSON(deviceKey) as DeviceKey,
|
||||
clearOn: [], // Device key is needed to log back into device, so we can't clear it automatically during lock or logout
|
||||
});
|
||||
export const DEVICE_KEY = new UserKeyDefinition<DeviceKey | null>(
|
||||
DEVICE_TRUST_DISK_LOCAL,
|
||||
"deviceKey",
|
||||
{
|
||||
deserializer: (deviceKey) =>
|
||||
deviceKey ? (SymmetricCryptoKey.fromJSON(deviceKey) as DeviceKey) : null,
|
||||
clearOn: [], // Device key is needed to log back into device, so we can't clear it automatically during lock or logout
|
||||
},
|
||||
);
|
||||
|
||||
/** Uses disk storage so that the shouldTrustDevice bool can persist across login. */
|
||||
export const SHOULD_TRUST_DEVICE = new UserKeyDefinition<boolean>(
|
||||
export const SHOULD_TRUST_DEVICE = new UserKeyDefinition<boolean | null>(
|
||||
DEVICE_TRUST_DISK_LOCAL,
|
||||
"shouldTrustDevice",
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ import { KeyConnectorUserKeyRequest } from "../models/request/key-connector-user
|
||||
import { SetKeyConnectorKeyRequest } from "../models/request/set-key-connector-key.request";
|
||||
import { IdentityTokenResponse } from "../models/response/identity-token.response";
|
||||
|
||||
export const USES_KEY_CONNECTOR = new UserKeyDefinition<boolean>(
|
||||
export const USES_KEY_CONNECTOR = new UserKeyDefinition<boolean | null>(
|
||||
KEY_CONNECTOR_DISK,
|
||||
"usesKeyConnector",
|
||||
{
|
||||
@@ -38,7 +38,7 @@ export const USES_KEY_CONNECTOR = new UserKeyDefinition<boolean>(
|
||||
},
|
||||
);
|
||||
|
||||
export const CONVERT_ACCOUNT_TO_KEY_CONNECTOR = new UserKeyDefinition<boolean>(
|
||||
export const CONVERT_ACCOUNT_TO_KEY_CONNECTOR = new UserKeyDefinition<boolean | null>(
|
||||
KEY_CONNECTOR_DISK,
|
||||
"convertAccountToKeyConnector",
|
||||
{
|
||||
|
||||
@@ -35,4 +35,4 @@ export * from "./tabs";
|
||||
export * from "./toast";
|
||||
export * from "./toggle-group";
|
||||
export * from "./typography";
|
||||
export * from "./utils/i18n-mock.service";
|
||||
export * from "./utils";
|
||||
|
||||
2
libs/components/src/utils/index.ts
Normal file
2
libs/components/src/utils/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./function-to-observable";
|
||||
export * from "./i18n-mock.service";
|
||||
Reference in New Issue
Block a user