1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

[PM-16790] introduce extension service (#13590)

This commit is contained in:
✨ Audrey ✨
2025-03-06 11:32:42 -05:00
committed by GitHub
parent 6f4a1ea37f
commit 9761588a2a
19 changed files with 461 additions and 39 deletions

View File

@@ -1,10 +1,13 @@
import { AlgorithmsByType as ABT } from "./data";
import { CredentialType, CredentialAlgorithm } from "./type";
// `CredentialAlgorithm` is defined in terms of `ABT`; supplying
// type information in the barrel file breaks a circular dependency.
/** Credential generation algorithms grouped by purpose. */
export const AlgorithmsByType: Record<CredentialType, ReadonlyArray<CredentialAlgorithm>> = ABT;
export { Profile, Type } from "./data";
export { GeneratorMetadata } from "./generator-metadata";
export { ProfileContext, CoreProfileMetadata, ProfileMetadata } from "./profile-metadata";
export { GeneratorProfile, CredentialAlgorithm, CredentialType } from "./type";
export { isForwarderProfile, isForwarderExtensionId } from "./util";
export { isForwarderProfile, toVendorId, isForwarderExtensionId } from "./util";

View File

@@ -1,6 +1,6 @@
import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { SiteId } from "@bitwarden/common/tools/extension";
import { ExtensionProfileMetadata } from "@bitwarden/common/tools/extension/type";
import { ObjectKey } from "@bitwarden/common/tools/state/object-key";
import { Constraints } from "@bitwarden/common/tools/types";
@@ -61,13 +61,7 @@ export type CoreProfileMetadata<Options> = {
* manager. Extension profiles store their data
* using the extension system.
*/
export type ExtensionProfileMetadata<Options, Site extends SiteId> = {
/** distinguishes profile metadata types */
type: "extension";
/** The extension site described by this metadata */
site: Site;
export type ForwarderProfileMetadata<Options> = ExtensionProfileMetadata<Options, "forwarder"> & {
constraints: ProfileConstraints<Options>;
};
@@ -77,4 +71,4 @@ export type ExtensionProfileMetadata<Options, Site extends SiteId> = {
*/
export type ProfileMetadata<Options> =
| CoreProfileMetadata<Options>
| ExtensionProfileMetadata<Options, "forwarder">;
| ForwarderProfileMetadata<Options>;

View File

@@ -1,7 +1,12 @@
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { GENERATOR_DISK } from "@bitwarden/common/platform/state";
import { VendorId } from "@bitwarden/common/tools/extension";
import { PrivateClassifier } from "@bitwarden/common/tools/private-classifier";
import { IdentityConstraint } from "@bitwarden/common/tools/state/identity-state-constraint";
import { ObjectKey } from "@bitwarden/common/tools/state/object-key";
import { Algorithm, AlgorithmsByType } from "./data";
import { ProfileMetadata } from "./profile-metadata";
import { ProfileContext, ProfileMetadata } from "./profile-metadata";
import {
isPasswordAlgorithm,
isUsernameAlgorithm,
@@ -12,6 +17,19 @@ import {
isForwarderProfile,
} from "./util";
const SomeStorage: ObjectKey<object> = {
target: "object",
key: "arbitrary",
state: GENERATOR_DISK,
classifier: new PrivateClassifier(),
format: "classified",
options: { clearOn: [], deserializer: (value) => value },
};
function createConstraints(policies: Policy[], context: ProfileContext<object>) {
return new IdentityConstraint();
}
describe("credential generator metadata utility functions", () => {
describe("isPasswordAlgorithm", () => {
it("returns `true` when the algorithm is a password algorithm", () => {
@@ -151,10 +169,10 @@ describe("credential generator metadata utility functions", () => {
it("returns `true` when the profile's type is `core`", () => {
const profile: ProfileMetadata<object> = {
type: "core",
storage: null,
storage: SomeStorage,
constraints: {
default: {},
create: () => null,
create: createConstraints,
},
};
@@ -165,9 +183,10 @@ describe("credential generator metadata utility functions", () => {
const profile: ProfileMetadata<object> = {
type: "extension",
site: "forwarder",
storage: SomeStorage,
constraints: {
default: {},
create: () => null,
create: createConstraints,
},
};
@@ -179,10 +198,10 @@ describe("credential generator metadata utility functions", () => {
it("returns `false` when the profile's type is `core`", () => {
const profile: ProfileMetadata<object> = {
type: "core",
storage: null,
storage: SomeStorage,
constraints: {
default: {},
create: () => null,
create: createConstraints,
},
};
@@ -193,9 +212,10 @@ describe("credential generator metadata utility functions", () => {
const profile: ProfileMetadata<object> = {
type: "extension",
site: "forwarder",
storage: SomeStorage,
constraints: {
default: {},
create: () => null,
create: createConstraints,
},
};
@@ -206,9 +226,10 @@ describe("credential generator metadata utility functions", () => {
const profile: ProfileMetadata<object> = {
type: "extension",
site: "not-a-forwarder" as any,
storage: SomeStorage,
constraints: {
default: {},
create: () => null,
create: createConstraints,
},
};

View File

@@ -1,5 +1,7 @@
import { VendorId } from "@bitwarden/common/tools/extension";
import { AlgorithmsByType } from "./data";
import { CoreProfileMetadata, ExtensionProfileMetadata, ProfileMetadata } from "./profile-metadata";
import { CoreProfileMetadata, ForwarderProfileMetadata, ProfileMetadata } from "./profile-metadata";
import {
CredentialAlgorithm,
EmailAlgorithm,
@@ -29,6 +31,17 @@ export function isForwarderExtensionId(
return algorithm && typeof algorithm === "object" && "forwarder" in algorithm;
}
/** Extract a `VendorId` from a `CredentialAlgorithm`.
* @param algorithm the algorithm containing the vendor id
* @returns the vendor id if the algorithm identifies a forwarder extension.
* Otherwise, undefined.
*/
export function toVendorId(algorithm: CredentialAlgorithm): VendorId | undefined {
if (isForwarderExtensionId(algorithm)) {
return algorithm.forwarder as VendorId;
}
}
/** Returns true when the input algorithm is an email algorithm. */
export function isEmailAlgorithm(algorithm: CredentialAlgorithm): algorithm is EmailAlgorithm {
return AlgorithmsByType.email.includes(algorithm as any) || isForwarderExtensionId(algorithm);
@@ -55,6 +68,6 @@ export function isCoreProfile<Options>(
/** Returns true when the input describes a forwarder extension profile. */
export function isForwarderProfile<Options>(
value: ProfileMetadata<Options>,
): value is ExtensionProfileMetadata<Options, "forwarder"> {
): value is ForwarderProfileMetadata<Options> {
return value.type === "extension" && value.site === "forwarder";
}