feat(email): expand email client detection & add Outlook edition helper (#819)

* feat(email): significantly expanded email client detection to support 40+ new user agents, including Alpine, Canary Mail, FairEmail, ProtonMail Bridge, Tutanota, and The Bat!
feat(helpers): added getOutlookEdition() utility to interpret raw version strings into specific Outlook editions (e.g., distinguishing Outlook 2016 MSI vs. Click-to-Run/365).

chore(enums): added comprehensive BrowserName.Email enums for all newly supported clients.
chore(types): added TypeScript definitions for the new getOutlookEdition helper.

test(email): added comprehensive test suite covering 60+ email client user agent strings.

test(helpers): added unit tests for getOutlookEdition covering Windows (MSI/C2R) and Mac variants.

* chore: Some small updates for business logic around K-9, Yahoo Mail, Outlook

* test: Edgecase alignment and fixes
chore(deps): npm vulnerability fix in package-lock.json
chore: Updated dist builds

* Revert accidentally-removed additional code and comments

* Correct comment syntax in ua-parser-extensions.js

Fix comment formatting and clean up code.

* chore: build fix
This commit is contained in:
Casey Grimes
2026-01-11 23:34:59 -05:00
committed by GitHub
parent 1696b87b58
commit bab55a28df
11 changed files with 899 additions and 200 deletions

View File

@@ -22,6 +22,19 @@ const INAPP = 'inapp';
const MEDIAPLAYER = 'mediaplayer';
const LIBRARY = 'library';
// Helper to normalize specific email client names
const normalizeEmailName = function (str) {
const map = {
'YahooMobile': 'Yahoo Mail',
'YahooMail': 'Yahoo Mail',
'K-9': 'K-9 Mail',
'K-9 Mail': 'K-9 Mail',
'Zdesktop': 'Zimbra',
'zdesktop': 'Zimbra'
};
return map[str] || str;
};
//////////////////////
// COMMAND LINE APPS
/////////////////////
@@ -229,25 +242,55 @@ const ExtraDevices = Object.freeze({
]
});
///////////////
//////////////
// EMAIL APPS
//////////////
const Emails = Object.freeze({
browser : [
[
// Evolution / Kontact/KMail[2] / [Microsoft/Mac] Outlook / Thunderbird
// Airmail / BlueMail / DaumMail / eMClient / Foxmail / NaverMailApp / Polymail
// ProtonMail / SparkDesktop / Sparrow / Yahoo! Mail / Zimbra / ZohoMail-Desktop
/((?:air|blue|daum|fox|poly|proton)mail|emclient|evolution|kmail2?|kontact|(?:microsoft |mac)?outlook(?:-express)?|navermailapp|(?!chrom.+)sparrow|sparkdesktop|thunderbird|yahoo|zohomail-desktop)(?:m.+ail; |[\/ ])([\w\.]+)/i,
// 1. Specific Android Mail Rule
[/(android)\/([\w\.-]+email)/i],
[NAME, VERSION, [TYPE, EMAIL]],
// Apple's Mail
/(mail)\/([\w\.]+) cf/i
], [NAME, VERSION, [TYPE, EMAIL]], [
// 2. Standard Email Clients
[
new RegExp(
'(' +
// Clients ending in 'mail' (Case 1: Prefix + optional space + [e]mail)
// Covers: AirMail, Claws Mail, FairEmail, SamsungEmail, Yahoo Mail, etc.
'(?:air|aqua|blue|claws|daum|fair|fox|k-9|mac|nylas|pegasus|poco|poly|proton|samsung|squirrel|yahoo) ?e?mail(?:-desktop| app| bridge)?|' +
// Standalone / Specific Names
'microsoft outlook|r2mail2|spicebird|turnpike|yahoomobile|' +
// Microsoft & Outlook Variants
'(?:microsoft )?outlook(?:-express)?|macoutlook|windows-live-mail|' +
// Specific Clients
'alpine|balsa|barca|canary|emclient|eudora|evolution|geary|gnus|' +
'horde::imp|incredimail|kmail2?|kontact|lotus-notes|' +
'mail(?:bird|mate|spring)|mutt|navermailapp|newton|nine|postbox|' +
'rainloop|roundcube webmail|spar(?:row|kdesktop)|sylpheed|' +
'the bat!|thunderbird|trojita|tutanota-desktop|wanderlust|' +
'zdesktop|zohomail-desktop' +
')' +
// Separator
'(?:m.+ail; |[\\/ ])' +
// Version (Updated to allow hyphens for Turnpike)
'([\\w\\.-]+)',
'i'
)
],
[
[NAME, normalizeEmailName],
VERSION,
[TYPE, EMAIL]
],
// 3. Apple Mail Context
[/(mail)\/([\w\.]+) cf/i],
[NAME, VERSION, [TYPE, EMAIL]],
// Zimbra
/zdesktop\/([\w\.]+)/i
], [VERSION, [NAME, 'Zimbra'], [TYPE, EMAIL]]
// 4. Zimbra Server
[/(zimbra)\/([\w\.-]+)/i],
[NAME, VERSION, [TYPE, EMAIL]]
]
});
@@ -451,4 +494,4 @@ module.exports = {
Libraries,
MediaPlayers,
Vehicles
};
};