Skip to content

Conversation

yesenkaya
Copy link

Implemented advanced handling for EmailAddresses (proxy addresses) updates. The script now intelligently merges existing proxy addresses with new values, ensuring all prior addresses are retained while correctly formatting new entries. It specifically manages the casing, setting the primary address with an 'SMTP:' prefix (uppercase) and all secondary addresses with an 'smtp:' prefix (lowercase).

@JeroenBL JeroenBL added the needs-review Indicates that the PR is ready and waiting for review label Jul 8, 2025
@rscholtelubberink rscholtelubberink added the current-sprint PRs to be addressed within the current sprint label Jul 25, 2025
Copy link
Collaborator

@rschouten97 rschouten97 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yesenkaya The change itself looks good, nice added feature!
However there are some things which seem client specific and some changes I can't quite place, please address the comments on this.

"Update"
],
"MappingMode": "Complex",
"Value": "\"// Please enter the mapping logic to generate the mailNickname.\\r\\n// This must result in a unique alias to be used for email addresses for this user.\\r\\n// This will most likely be equal to the part before the '@' sign of the UserPrincipleName.\\r\\n// Please make sure that the result is not formatted like an email address.\\r\\nfunction generateMailNickname() {\\r\\n let firstName = Person.Name.NickName;\\r\\n let middleName = Person.Name.FamilyNamePrefix;\\r\\n if (typeof middleName !== 'undefined' && middleName) {\\r\\n if(middleName.split(' ').length == 1){\\r\\n middleName = middleName;\\r\\n } else {\\r\\n middleName = middleName.match(/\\\\b(\\\\w)/g).join('')\\r\\n }\\r\\n }\\r\\n let lastName = Person.Name.FamilyName;\\r\\n let middleNamePartner = Person.Name.FamilyNamePartnerPrefix;\\r\\n if (typeof middleNamePartner !== 'undefined' && middleNamePartner) {\\r\\n if(middleNamePartner.split(' ').length == 1){\\r\\n middleNamePartner = middleNamePartner;\\r\\n } else {\\r\\n middleNamePartner = middleNamePartner.match(/\\\\b(\\\\w)/g).join('')\\r\\n }\\r\\n }\\r\\n let lastNamePartner = Person.Name.FamilyNamePartner;\\r\\n let convention = Person.Name.Convention;\\r\\n\\r\\n const suffix = Iteration <= (firstName.length - 1) ? '' : (Iteration - (firstName.length - 2));\\r\\n\\r\\n // Eerste keuze\\t B\\tJanine.vd.boele\\r\\n // \\t BP\\tJanine.vd.boele\\r\\n // \\t P\\tJanine.de.vries\\r\\n // \\t PB Janine.de.vries\\r\\n // Indien in gebruik\\t B\\tJ.vd.boele\\r\\n // \\t BP\\tJ.vd.boele\\r\\n // \\t P\\tJ.de.vries\\r\\n // \\t PB\\tJ.de.vries\\r\\n // Indien ook in gebruik\\tB\\tJa.vd.boele\\r\\n // \\t BP\\tJa.vd.boele\\r\\n // \\t P\\tJa.de.vries\\r\\n // \\t PB\\tJa.de.vries\\r\\n\\r\\n let mailNickname = '';\\r\\n if (Iteration === 0) {\\r\\n mailNickname = firstName + '.';\\r\\n }else if(Iteration === 1) {\\r\\n mailNickname = firstName.charAt(0)+ '.';\\r\\n } else {\\r\\n mailNickname = firstName.substring(0, (Iteration)) + '.';\\r\\n }\\r\\n\\r\\n switch (convention) {\\r\\n case \\\"B\\\":\\r\\n case \\\"BP\\\":\\r\\n if (typeof middleName !== 'undefined' && middleName) { mailNickname = mailNickname + middleName + '.'}\\r\\n mailNickname = mailNickname + lastName;\\r\\n break;\\r\\n case \\\"P\\\":\\r\\n case \\\"PB\\\":\\r\\n if (typeof middleNamePartner !== 'undefined' && middleNamePartner) { mailNickname = mailNickname + middleNamePartner + '.'}\\r\\n mailNickname = mailNickname + lastNamePartner;\\r\\n break;\\r\\n default:\\r\\n if (typeof middleName !== 'undefined' && middleName) { mailNickname = mailNickname + middleName + '.'}\\r\\n mailNickname = mailNickname + lastName;\\r\\n break;\\r\\n }\\r\\n\\r\\n //Convert to lower case\\r\\n mailNickname = mailNickname.toLowerCase();\\r\\n\\r\\n //Remove diacritical chars\\r\\n mailNickname = deleteDiacriticalMarks(mailNickname);\\r\\n\\r\\n //Remove blank chars and \\\"'\\\"\\r\\n mailNickname = mailNickname.replace(/[^0-9a-zA-Z.-]/g, '');\\r\\n\\r\\n // use the iterator if needed\\r\\n mailNickname = mailNickname + suffix; \\r\\n\\r\\n // return mailNickname;\\r\\n return mailNickname;\\r\\n}\\r\\n\\r\\nfunction getValue() {\\r\\n const nickName = generateMailNickname();\\r\\n let domain = \\\"\\\"\\r\\n\\r\\n if (Person.PrimaryContract.Custom.allOECodes.indexOf('\\\"3-DVD\\\"') !== -1) {\\r\\n domain = 'devalckdealmakers.nl';\\r\\n } else{\\r\\n domain = 'bentacera.nl';\\r\\n }\\r\\n\\r\\n\\treturn [\\r\\n \\\"SMTP:\\\" + nickName + '@' + domain,\\r\\n \\\"smtp:\\\" + nickName.replace(/\\\\./g, '') + '@' + domain\\r\\n ]\\r\\n\\t\\r\\n}\\r\\n\\r\\ngetValue();\"",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still contains client specific data. Please change this to one of the templates/examples found here: https://github.com/Tools4everBV/HelloID-Lib-Prov-HelperFunctions/tree/main/Javascript/Target/ProxyAddresses

throw 'Multiple primary SMTP addresses found in the mapped properties. Please ensure only one is set.'
}

# Verwijder SPO adressen uit de gemergde lijst
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure all comments are in english.

}

# Verwijder SPO adressen uit de gemergde lijst
$mergedEmailAddresses = $mergedEmailAddresses | Where-Object { $_ -notmatch '^SPO:SPO_' }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we removing SPO addresses here? While I understand they might be system-generated and not typically used for communication, there could be cases where a client relies on them.

By default, I think we should aim to preserve all existing email addresses unless there's a clear reason to exclude them, especially if we're only intending to update the primary SMTP and aliases.

That said, if there's a strong use case or precedent for excluding SPO addresses (e.g., to prevent sync issues or clutter), we should document that and make it the default behavior. Otherwise, maybe consider making this filtering optional or configurable?

}

Write-Information "Changed properties: $($accountChangedPropertiesObject | ConvertTo-Json)"
#Write-Information "Changed properties: $($accountChangedPropertiesObject | ConvertTo-Json)"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why has this become outcommented? It is there to provide information in the preview or retry context.


$outputContext.Data = $correlatedAccount | Select-Object $outputContext.Data.PsObject.Properties.Name
$outputContext.PreviousData = $correlatedAccount | Select-Object $outputContext.Data.PsObject.Properties.Name
$outputContext.Data = $actionContext.Data
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why has this changed? Was there a specific reason for it? The previous code should work as well right?
We aim to only make changes if something doesn't work (correctly).

$outputContext.Data = $correlatedAccount | Select-Object $outputContext.Data.PsObject.Properties.Name
$outputContext.PreviousData = $correlatedAccount | Select-Object $outputContext.Data.PsObject.Properties.Name
$outputContext.Data = $actionContext.Data
$outputContext.PreviousData = $actionContext.Data
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why has this changed? Was there a specific reason for it? The previous code should work as well right?
We aim to only make changes if something doesn't work (correctly).

@rschouten97 rschouten97 assigned yesenkaya and unassigned rschouten97 Aug 18, 2025
@rschouten97 rschouten97 added pending-author-update PR is waiting for the author to make necessary modifications or updates and removed needs-review Indicates that the PR is ready and waiting for review labels Aug 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
current-sprint PRs to be addressed within the current sprint pending-author-update PR is waiting for the author to make necessary modifications or updates
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants