diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json index 34264765..11e555bc 100644 --- a/src/locales/en/messages.json +++ b/src/locales/en/messages.json @@ -441,6 +441,19 @@ "sync": { "message": "Sync" }, + "duplicateEmails": { + "message": "Emails must be unique. Multiple entries pulled with the following emails:", + "desription": "Error message displayed when duplicate email addresses are synced. Followed by a list of duplicate emails." + }, + "andMore": { + "message": "and $NUMBER$ more...", + "placeholders": { + "NUMBER": { + "content": "$1", + "example": "10" + } + } + }, "ldapEncrypted": { "message": "This server uses an encrypted connection" }, diff --git a/src/services/sync.service.ts b/src/services/sync.service.ts index 10cbda53..ce59e880 100644 --- a/src/services/sync.service.ts +++ b/src/services/sync.service.ts @@ -55,6 +55,14 @@ export class SyncService { this.flattenUsersToGroups(groups, groups); } + const duplicateEmails = this.findDuplicateUserEmails(users); + if (duplicateEmails.length > 0) { + const emailsMessage = duplicateEmails.length < 4 ? + duplicateEmails.join('\n') : + duplicateEmails.slice(0, 3).join('\n') + '\n' + this.i18nService.t('andMore', `${duplicateEmails.length - 3}`); + throw new Error(this.i18nService.t('duplicateEmails') + '\n' + emailsMessage); + } + if (test || (!syncConfig.overwriteExisting && (groups == null || groups.length === 0) && (users == null || users.length === 0))) { if (!test) { @@ -108,6 +116,19 @@ export class SyncService { } } + private findDuplicateUserEmails(users: UserEntry[]) { + const duplicatedEmails = new Array(); + users.reduce((agg, user) => { + if (agg.includes(user.email) && !duplicatedEmails.includes(user.email)) { + duplicatedEmails.push(user.email); + } else { + agg.push(user.email); + } + return agg; + }, new Array()); + return duplicatedEmails; + } + private filterUnsupportedUsers(users: UserEntry[]): UserEntry[] { return users == null ? null : users.filter(u => u.email?.length <= 256); }