Add email address generator: 3 styles, 14 domains, inline menu, /email command, tests

This commit is contained in:
kromskii2 committed 2026-09-10 15:15:19 +07:00
1 parent 20c3fb1c06
commit 3b92e317d0
4 files changed
+158 -2

No files matched your search

+36
View File
@@ -100,3 +100,39 @@ export function strength(password) {
return { bits, level, bar };
}
/* ---------- Email (почтовые адреса) ---------- */
export const EMAIL_DOMAINS = [
'gmail.com','googlemail.com','mail.ru','yandex.ru','ya.ru','outlook.com',
'hotmail.com','yahoo.com','icloud.com','proton.me','protonmail.com','bk.ru','inbox.ru','list.ru',
];
const EMAIL_WORDS = [
'swift','dark','cyber','frost','neon','lunar','solar','storm','raven','wolf',
'fox','pixel','turbo','quantum','echo','vortex','nova','pulse','drift','orbit',
'lynx','onyx','zephyr','flux','ember','cobalt','delta','omega','prime','crux',
];
const LOCAL_RANDOM = 'abcdefghijkmnpqrstuvwxyz';
/**
* Стили local-части: random | pronounceable | wordnum
* @param {object} opts { style, domain, withNumber, length }
*/
export function generateEmail(opts = {}) {
const { style = 'random', domain = 'gmail.com', withNumber = true, length = 8 } = opts;
const n = Math.min(Math.max(Number(length) || 8, 4), 24);
let local;
if (style === 'pronounceable') {
local = pronounceablePassword(n).toLowerCase();
} else if (style === 'wordnum') {
local = pick(EMAIL_WORDS) + '.' + pick(EMAIL_WORDS) + String(crypto.randomInt(10, 100));
} else {
local = Array.from({ length: n }, () => pick(LOCAL_RANDOM)).join('');
}
if (withNumber && !new RegExp('[0-9]').test(local)) local += String(crypto.randomInt(10, 1000));
const dom = EMAIL_DOMAINS.includes(domain) ? domain : EMAIL_DOMAINS[0];
return local.toLowerCase() + '@' + dom;
}