diff --git a/libs/common/src/models/domain/domain-service.ts b/libs/common/src/models/domain/domain-service.ts index a6b5ecfdaa..bfbe45450d 100644 --- a/libs/common/src/models/domain/domain-service.ts +++ b/libs/common/src/models/domain/domain-service.ts @@ -1,3 +1,5 @@ +import { UriMatchType } from "@bitwarden/sdk-internal"; + /* See full documentation at: https://bitwarden.com/help/uri-match-detection/#match-detection-options @@ -23,3 +25,28 @@ export type UriMatchStrategySetting = (typeof UriMatchStrategy)[keyof typeof Uri // using uniqueness properties of object shape over Set for ease of state storability export type NeverDomains = { [id: string]: null | { bannerIsDismissed?: boolean } }; export type EquivalentDomains = string[][]; + +/** + * Normalizes UriMatchStrategySetting for SDK mapping. + * @param value - The URI match strategy from user data + * @returns Valid UriMatchType or undefined if invalid + */ +export function normalizeUriMatchStrategyForSdk( + value: UriMatchStrategySetting | undefined, +): UriMatchType | undefined { + if (value == null) { + return undefined; + } + + switch (value) { + case 0: // Domain + case 1: // Host + case 2: // StartsWith + case 3: // Exact + case 4: // RegularExpression + case 5: // Never + return value; + default: + return undefined; + } +} diff --git a/libs/common/src/vault/enums/cipher-reprompt-type.ts b/libs/common/src/vault/enums/cipher-reprompt-type.ts index 91b05399d3..30d99e9800 100644 --- a/libs/common/src/vault/enums/cipher-reprompt-type.ts +++ b/libs/common/src/vault/enums/cipher-reprompt-type.ts @@ -1,3 +1,5 @@ +import { CipherRepromptType as SdkCipherRepromptType } from "@bitwarden/sdk-internal"; + import { UnionOfValues } from "../types/union-of-values"; export const CipherRepromptType = { @@ -6,3 +8,20 @@ export const CipherRepromptType = { } as const; export type CipherRepromptType = UnionOfValues; + +/** + * Normalizes a CipherRepromptType value to ensure compatibility with the SDK. + * @param value - The cipher reprompt type from user data + * @returns Valid CipherRepromptType, defaults to CipherRepromptType.None if unrecognized + */ +export function normalizeCipherRepromptTypeForSdk( + value: CipherRepromptType, +): SdkCipherRepromptType { + switch (value) { + case CipherRepromptType.None: + case CipherRepromptType.Password: + return value; + default: + return CipherRepromptType.None; + } +} diff --git a/libs/common/src/vault/enums/field-type.enum.ts b/libs/common/src/vault/enums/field-type.enum.ts index 0e8e2aaca3..3d819adbba 100644 --- a/libs/common/src/vault/enums/field-type.enum.ts +++ b/libs/common/src/vault/enums/field-type.enum.ts @@ -1,3 +1,5 @@ +import { FieldType as SdkFieldType } from "@bitwarden/sdk-internal"; + const _FieldType = Object.freeze({ Text: 0, Hidden: 1, @@ -10,3 +12,20 @@ type _FieldType = typeof _FieldType; export type FieldType = _FieldType[keyof _FieldType]; export const FieldType: Record = _FieldType; + +/** + * Normalizes a FieldType value to ensure compatibility with the SDK. + * @param value - The field type from user data + * @returns Valid FieldType, defaults to FieldType.Text if unrecognized + */ +export function normalizeFieldTypeForSdk(value: FieldType): SdkFieldType { + switch (value) { + case FieldType.Text: + case FieldType.Hidden: + case FieldType.Boolean: + case FieldType.Linked: + return value; + default: + return FieldType.Text; + } +} diff --git a/libs/common/src/vault/enums/linked-id-type.enum.ts b/libs/common/src/vault/enums/linked-id-type.enum.ts index 20ef15e620..38b852f94a 100644 --- a/libs/common/src/vault/enums/linked-id-type.enum.ts +++ b/libs/common/src/vault/enums/linked-id-type.enum.ts @@ -1,3 +1,5 @@ +import { LinkedIdType as SdkLinkedIdType } from "@bitwarden/sdk-internal"; + import { UnionOfValues } from "../types/union-of-values"; export type LinkedIdType = LoginLinkedId | CardLinkedId | IdentityLinkedId; @@ -46,3 +48,25 @@ export const IdentityLinkedId = { } as const; export type IdentityLinkedId = UnionOfValues; + +/** + * Normalizes a LinkedIdType value to ensure compatibility with the SDK. + * @param value - The linked ID type from user data + * @returns Valid LinkedIdType or undefined if unrecognized + */ +export function normalizeLinkedIdTypeForSdk( + value: LinkedIdType | undefined, +): SdkLinkedIdType | undefined { + if (value == null) { + return undefined; + } + + // Check all valid LinkedId numeric values (100-418) + const allValidValues = [ + ...Object.values(LoginLinkedId), + ...Object.values(CardLinkedId), + ...Object.values(IdentityLinkedId), + ]; + + return allValidValues.includes(value) ? value : undefined; +} diff --git a/libs/common/src/vault/enums/secure-note-type.enum.ts b/libs/common/src/vault/enums/secure-note-type.enum.ts index bb5838d028..348841c7df 100644 --- a/libs/common/src/vault/enums/secure-note-type.enum.ts +++ b/libs/common/src/vault/enums/secure-note-type.enum.ts @@ -1,3 +1,5 @@ +import { SecureNoteType as SdkSecureNoteType } from "@bitwarden/sdk-internal"; + import { UnionOfValues } from "../types/union-of-values"; export const SecureNoteType = { @@ -5,3 +7,12 @@ export const SecureNoteType = { } as const; export type SecureNoteType = UnionOfValues; + +/** + * Normalizes a SecureNoteType value to ensure compatibility with the SDK. + * @param value - The secure note type from user data + * @returns Valid SecureNoteType, defaults to SecureNoteType.Generic if unrecognized + */ +export function normalizeSecureNoteTypeForSdk(value: SecureNoteType): SdkSecureNoteType { + return SecureNoteType.Generic; +} diff --git a/libs/common/src/vault/models/domain/cipher.ts b/libs/common/src/vault/models/domain/cipher.ts index bbbf6a6a05..abddb73422 100644 --- a/libs/common/src/vault/models/domain/cipher.ts +++ b/libs/common/src/vault/models/domain/cipher.ts @@ -9,7 +9,10 @@ import { Utils } from "../../../platform/misc/utils"; import Domain from "../../../platform/models/domain/domain-base"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; import { InitializerKey } from "../../../platform/services/cryptography/initializer-key"; -import { CipherRepromptType } from "../../enums/cipher-reprompt-type"; +import { + CipherRepromptType, + normalizeCipherRepromptTypeForSdk, +} from "../../enums/cipher-reprompt-type"; import { CipherType } from "../../enums/cipher-type"; import { conditionalEncString, encStringFrom } from "../../utils/domain-utils"; import { CipherPermissionsApi } from "../api/cipher-permissions.api"; @@ -414,10 +417,7 @@ export class Cipher extends Domain implements Decryptable { creationDate: this.creationDate.toISOString(), deletedDate: this.deletedDate?.toISOString(), archivedDate: this.archivedDate?.toISOString(), - reprompt: - this.reprompt === CipherRepromptType.Password - ? CipherRepromptType.Password - : CipherRepromptType.None, + reprompt: normalizeCipherRepromptTypeForSdk(this.reprompt), // Initialize all cipher-type-specific properties as undefined login: undefined, identity: undefined, diff --git a/libs/common/src/vault/models/domain/field.ts b/libs/common/src/vault/models/domain/field.ts index 2ee3a9af8a..adec926351 100644 --- a/libs/common/src/vault/models/domain/field.ts +++ b/libs/common/src/vault/models/domain/field.ts @@ -1,11 +1,16 @@ import { Jsonify } from "type-fest"; -import { Field as SdkField, LinkedIdType as SdkLinkedIdType } from "@bitwarden/sdk-internal"; +import { Field as SdkField } from "@bitwarden/sdk-internal"; import { EncString } from "../../../key-management/crypto/models/enc-string"; import Domain from "../../../platform/models/domain/domain-base"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; -import { FieldType, LinkedIdType } from "../../enums"; +import { + FieldType, + LinkedIdType, + normalizeFieldTypeForSdk, + normalizeLinkedIdTypeForSdk, +} from "../../enums"; import { conditionalEncString, encStringFrom } from "../../utils/domain-utils"; import { FieldData } from "../data/field.data"; import { FieldView } from "../view/field.view"; @@ -77,9 +82,8 @@ export class Field extends Domain { return { name: this.name?.toSdk(), value: this.value?.toSdk(), - type: this.type, - // Safe type cast: client and SDK LinkedIdType enums have identical values - linkedId: this.linkedId as unknown as SdkLinkedIdType, + type: normalizeFieldTypeForSdk(this.type), + linkedId: normalizeLinkedIdTypeForSdk(this.linkedId), }; } diff --git a/libs/common/src/vault/models/domain/login-uri.ts b/libs/common/src/vault/models/domain/login-uri.ts index cac487747f..42acca25d6 100644 --- a/libs/common/src/vault/models/domain/login-uri.ts +++ b/libs/common/src/vault/models/domain/login-uri.ts @@ -3,7 +3,10 @@ import { Jsonify } from "type-fest"; import { LoginUri as SdkLoginUri } from "@bitwarden/sdk-internal"; import { EncString } from "../../../key-management/crypto/models/enc-string"; -import { UriMatchStrategySetting } from "../../../models/domain/domain-service"; +import { + normalizeUriMatchStrategyForSdk, + UriMatchStrategySetting, +} from "../../../models/domain/domain-service"; import { Utils } from "../../../platform/misc/utils"; import Domain from "../../../platform/models/domain/domain-base"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; @@ -91,7 +94,7 @@ export class LoginUri extends Domain { return { uri: this.uri?.toSdk(), uriChecksum: this.uriChecksum?.toSdk(), - match: this.match, + match: normalizeUriMatchStrategyForSdk(this.match), }; } diff --git a/libs/common/src/vault/models/domain/secure-note.ts b/libs/common/src/vault/models/domain/secure-note.ts index fb568f482b..688d34830d 100644 --- a/libs/common/src/vault/models/domain/secure-note.ts +++ b/libs/common/src/vault/models/domain/secure-note.ts @@ -3,7 +3,7 @@ import { Jsonify } from "type-fest"; import { SecureNote as SdkSecureNote } from "@bitwarden/sdk-internal"; import Domain from "../../../platform/models/domain/domain-base"; -import { SecureNoteType } from "../../enums"; +import { normalizeSecureNoteTypeForSdk, SecureNoteType } from "../../enums"; import { SecureNoteData } from "../data/secure-note.data"; import { SecureNoteView } from "../view/secure-note.view"; @@ -46,7 +46,7 @@ export class SecureNote extends Domain { */ toSdkSecureNote(): SdkSecureNote { return { - type: this.type, + type: normalizeSecureNoteTypeForSdk(this.type), }; }