All files / lib/Interfaces/Credential PasskeyCustomFieldInterface.js

100% Statements 25/25
100% Branches 26/26
100% Functions 5/5
100% Lines 25/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71  10x 10x 10x 10x 10x 10x   10x   10x   112x           35x 2x   33x 33x                         17x 17x 4x 4x     1x     16x           5x 3x   2x             9x 2x   7x              
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PASSKEY_CUSTOM_FIELD_LABEL = exports.PASSKEY_CUSTOM_FIELD_TYPE = void 0;
exports.isPasskeyData = isPasskeyData;
exports.parsePasskeyValue = parsePasskeyValue;
exports.isPasskeyCustomField = isPasskeyCustomField;
exports.createPasskeyCustomField = createPasskeyCustomField;
/** Custom-field `field_type` used for software passkeys. */
exports.PASSKEY_CUSTOM_FIELD_TYPE = 'passkey';
/** Fixed label for passkey custom fields (hide in credential editors). */
exports.PASSKEY_CUSTOM_FIELD_LABEL = 'Passkey';
function isNonEmptyString(value) {
    return typeof value === 'string' && value.length > 0;
}
/**
 * Type guard for a parsed passkey payload (object form).
 */
function isPasskeyData(value) {
    if (value === null || typeof value !== 'object') {
        return false;
    }
    const data = value;
    return data.v === 1
        && isNonEmptyString(data.domain)
        && isNonEmptyString(data.credentialId)
        && typeof data.userName === 'string'
        && typeof data.userDisplayName === 'string'
        && isNonEmptyString(data.userId)
        && isNonEmptyString(data.key)
        && (data.rpId === undefined || typeof data.rpId === 'string');
}
/**
 * Normalize a custom-field value that may be a PasskeyData object or a JSON string.
 */
function parsePasskeyValue(value) {
    let candidate = value;
    if (typeof candidate === 'string') {
        try {
            candidate = JSON.parse(candidate);
        }
        catch {
            return null;
        }
    }
    return isPasskeyData(candidate) ? candidate : null;
}
/**
 * True when the custom field is a secret passkey field with a valid v1 payload.
 */
function isPasskeyCustomField(field) {
    if (!field || field.field_type !== exports.PASSKEY_CUSTOM_FIELD_TYPE || field.secret !== true) {
        return false;
    }
    return parsePasskeyValue(field.value) !== null;
}
/**
 * Build a secret passkey custom field ready to store on a credential.
 * @throws Error when `passkey` is not a valid {@link PasskeyData} v1 object
 */
function createPasskeyCustomField(passkey) {
    if (!isPasskeyData(passkey)) {
        throw new Error('Invalid passkey data: expected a complete PasskeyData v1 object');
    }
    return {
        label: exports.PASSKEY_CUSTOM_FIELD_LABEL,
        secret: true,
        field_type: exports.PASSKEY_CUSTOM_FIELD_TYPE,
        value: { ...passkey }
    };
}