Private/Protect-SFNationalId.ps1

function Protect-SFNationalId {
    [CmdletBinding()]
    [OutputType([System.Collections.IDictionary])]
    param (
        [Parameter(Mandatory)]
        [System.Collections.IDictionary]$Data,

        [Parameter(Mandatory)]
        [string]$HashProfile
    )

    if ($HashProfile -cne 'CheckID-v1') {
        throw "Unsupported national ID hash profile '$HashProfile'."
    }

    if (-not $Data.Contains('nationalIdNav') -or $null -eq $Data['nationalIdNav']) {
        return $Data
    }

    $nationalIdNav = $Data['nationalIdNav']
    if ($nationalIdNav -isnot [System.Collections.IDictionary]) {
        throw 'nationalIdNav must be an object when NationalIdHashProfile is enabled.'
    }

    if (-not $nationalIdNav.Contains('results') -or $null -eq $nationalIdNav['results']) {
        return $Data
    }

    $nationalIds = @($nationalIdNav['results'])
    foreach ($nationalId in $nationalIds) {
        if ($nationalId -isnot [System.Collections.IDictionary]) {
            throw 'Every nationalIdNav/results entry must be an object when NationalIdHashProfile is enabled.'
        }
    }

    $primaryNationalIds = @($nationalIds | Where-Object { $_.Contains('isPrimary') -and $_['isPrimary'] -eq $true })
    if ($primaryNationalIds.Count -gt 1) {
        throw "Expected at most one primary national ID, but found $($primaryNationalIds.Count)."
    }

    if ($primaryNationalIds.Count -eq 1 -and
        $primaryNationalIds[0].Contains('nationalId') -and
        $null -ne $primaryNationalIds[0]['nationalId']) {
        if ($primaryNationalIds[0]['nationalId'] -isnot [string]) {
            throw 'The primary nationalId must be a string so its exact representation can be hashed.'
        }

        $ninHash = ConvertTo-SFCheckIdV1Hash -Value $primaryNationalIds[0]['nationalId']

        if ($Data.Contains('_fortytwo') -and $Data['_fortytwo'] -isnot [System.Collections.IDictionary]) {
            throw "Connector data property '_fortytwo' must be an object when NationalIdHashProfile is enabled."
        }
        if (-not $Data.Contains('_fortytwo')) {
            $Data['_fortytwo'] = @{}
        }

        $Data['_fortytwo']['ninHash'] = $ninHash
        $Data['_fortytwo']['ninHashProfile'] = $HashProfile
    }

    # No raw national ID may be persisted, including non-primary values.
    foreach ($nationalId in $nationalIds) {
        [void]$nationalId.Remove('nationalId')
    }

    return $Data
}