@brilab-mailer/disposable 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # disposable
2
+
3
+ ## Source: [ivolo/disposable-email-domains](https://github.com/ivolo/disposable-email-domains) — list of disposable email domains used in this library
4
+
5
+ This library was generated with [Nx](https://nx.dev).
6
+
7
+ ## Building
8
+
9
+ Run `nx build disposable` to build the library.
@@ -0,0 +1,401 @@
1
+ [
2
+ "0x01.gq",
3
+ "0x01.tk",
4
+ "10mail.org",
5
+ "10mail.tk",
6
+ "33m.co",
7
+ "33mail.com",
8
+ "3dxtras.com",
9
+ "3utilities.com",
10
+ "567map.xyz",
11
+ "8191.at",
12
+ "aa.am",
13
+ "accountsite.me",
14
+ "acmetoy.com",
15
+ "acusupply.com",
16
+ "adultvidlite.com",
17
+ "aji.kr",
18
+ "anonaddy.com",
19
+ "anonaddy.me",
20
+ "anonbox.net",
21
+ "anyalias.com",
22
+ "asanatest1.us",
23
+ "azzawajalla.store",
24
+ "bajetesik.store",
25
+ "band-freier.de",
26
+ "bandband1.com",
27
+ "bangmadid.store",
28
+ "batikbantul.com",
29
+ "bccto.me",
30
+ "bebekpenyet.buzz",
31
+ "bei.kr",
32
+ "bel.kr",
33
+ "beo.kr",
34
+ "bfo.kr",
35
+ "bgsaddrmwn.me",
36
+ "bho.kr",
37
+ "biasaelho.space",
38
+ "biz.st",
39
+ "biz.tm",
40
+ "bko.kr",
41
+ "blacksong.pw",
42
+ "blueauramassage.com",
43
+ "bounceme.net",
44
+ "bum.net",
45
+ "buwosok.tech",
46
+ "buzzndaraiangop2wae.buzz",
47
+ "byui.me",
48
+ "caboodle.buzz",
49
+ "cad.edu.gr",
50
+ "cempue.online",
51
+ "chickenkiller.com",
52
+ "choirul.host",
53
+ "cid.kr",
54
+ "ciran.xyz",
55
+ "cko.kr",
56
+ "cloudns.asia",
57
+ "cloudns.cc",
58
+ "cloudns.cx",
59
+ "cloudns.nz",
60
+ "com.com",
61
+ "coms.hk",
62
+ "comx.cf",
63
+ "craigslist.org",
64
+ "creo.site",
65
+ "creo.tips",
66
+ "creou.dev",
67
+ "crowdpress.it",
68
+ "cu.cc",
69
+ "cua77.xyz",
70
+ "d3vs.net",
71
+ "dadosa.xyz",
72
+ "danuarte.online",
73
+ "darrels.site",
74
+ "daseus.online",
75
+ "dayatan.host",
76
+ "dbo.kr",
77
+ "ddns.net",
78
+ "ddnsfree.com",
79
+ "deail.com",
80
+ "dedyn.io",
81
+ "defaultdomain.ml",
82
+ "discard-email.cf",
83
+ "dko.kr",
84
+ "dlink.cf",
85
+ "dlink.gq",
86
+ "dlyemail.com",
87
+ "dmtc.dev",
88
+ "dmtc.edu.pl",
89
+ "dmtc.press",
90
+ "dns-cloud.net",
91
+ "dns.navy",
92
+ "dnsabr.com",
93
+ "dnses.ro",
94
+ "doy.kr",
95
+ "drope.ml",
96
+ "dropmail.me",
97
+ "dynu.net",
98
+ "dzalaev-advokat.ru",
99
+ "e4ward.com",
100
+ "ediantenan.site",
101
+ "edu.auction",
102
+ "efo.kr",
103
+ "eho.kr",
104
+ "ely.kr",
105
+ "email-temp.com",
106
+ "emailfake.com",
107
+ "emailfake.ml",
108
+ "emailfreedom.ml",
109
+ "emlhub.com",
110
+ "emlpro.com",
111
+ "emltmp.com",
112
+ "emy.kr",
113
+ "enu.kr",
114
+ "eny.kr",
115
+ "epizy.com",
116
+ "escritossad.net",
117
+ "ese.kr",
118
+ "esy.es",
119
+ "ewa.kr",
120
+ "exi.kr",
121
+ "ezyro.com",
122
+ "fackme.gq",
123
+ "fassagforpresident.ga",
124
+ "firste.ml",
125
+ "flu.cc",
126
+ "foy.kr",
127
+ "fr.nf",
128
+ "freeml.net",
129
+ "gadzooks.buzz",
130
+ "gettrials.com",
131
+ "giize.com",
132
+ "gmail.gr.com",
133
+ "gmeil.me",
134
+ "gok.kr",
135
+ "gotdns.ch",
136
+ "gpa.lu",
137
+ "grigio.cf",
138
+ "guardmail.cf",
139
+ "haddo.eu",
140
+ "heliohost.org",
141
+ "higogoya.com",
142
+ "historial.store",
143
+ "hitechinfo.com",
144
+ "hix.kr",
145
+ "hiz.kr",
146
+ "hmail.us",
147
+ "hopto.org",
148
+ "hostingarif.me",
149
+ "idn.vn",
150
+ "iesco.info",
151
+ "igg.biz",
152
+ "ignorelist.com",
153
+ "iki.kr",
154
+ "ilovemyniggers.club",
155
+ "imouto.pro",
156
+ "info.tm",
157
+ "infos.st",
158
+ "irr.kr",
159
+ "isgre.at",
160
+ "it2-mail.tk",
161
+ "jil.kr",
162
+ "jindmail.club",
163
+ "jto.kr",
164
+ "junnuok.com",
165
+ "justemail.ml",
166
+ "kadokawa.top",
167
+ "kantal.buzz",
168
+ "keitin.site",
169
+ "kentel.buzz",
170
+ "kerl.cf",
171
+ "kerl.gq",
172
+ "kikwet.com",
173
+ "kondomeus.site",
174
+ "kozow.com",
175
+ "kranjingan.store",
176
+ "kranjingan.tech",
177
+ "kranjingans.tech",
178
+ "kro.kr",
179
+ "lal.kr",
180
+ "laste.ml",
181
+ "lbe.kr",
182
+ "legundi.site",
183
+ "lei.kr",
184
+ "likevip.net",
185
+ "liopers.link",
186
+ "lko.co.kr",
187
+ "lko.kr",
188
+ "ll47.net",
189
+ "lofteone.ru",
190
+ "lom.kr",
191
+ "longdz.site",
192
+ "longmusic.com",
193
+ "lostandalone.com",
194
+ "loudcannabisapp.com",
195
+ "loy.kr",
196
+ "loyalherceghalom.ml",
197
+ "luk2.com",
198
+ "luksarcenter.ru",
199
+ "luo.kr",
200
+ "lyrics-lagu.me",
201
+ "mail-temp.com",
202
+ "mail0.ga",
203
+ "mailinator.com",
204
+ "mailr.eu",
205
+ "marrone.cf",
206
+ "mbe.kr",
207
+ "mblimbingan.space",
208
+ "mebelnovation.ru",
209
+ "mefound.com",
210
+ "mintemail.com",
211
+ "mishmash.buzz",
212
+ "mko.kr",
213
+ "mlo.kr",
214
+ "mooo.com",
215
+ "motifasidiri.website",
216
+ "mp-j.cf",
217
+ "mp-j.ga",
218
+ "mp-j.gq",
219
+ "mp-j.ml",
220
+ "mp-j.tk",
221
+ "mr-meshkat.com",
222
+ "mrossi.cf",
223
+ "mrossi.gq",
224
+ "mrossi.ml",
225
+ "ms1.email",
226
+ "msdc.co",
227
+ "muabanwin.net",
228
+ "museumplanet.com",
229
+ "my.id",
230
+ "my3mail.cf",
231
+ "my3mail.ga",
232
+ "my3mail.gq",
233
+ "my3mail.ml",
234
+ "my3mail.tk",
235
+ "myddns.me",
236
+ "myeslbookclub.com",
237
+ "mymy.cf",
238
+ "mysafe.ml",
239
+ "mzon.store",
240
+ "n-e.kr",
241
+ "nafko.cf",
242
+ "nctu.me",
243
+ "netmail.tk",
244
+ "netricity.nl",
245
+ "new-mgmt.ga",
246
+ "ngalasmoen.xyz",
247
+ "ngguwokulon.online",
248
+ "njambon.space",
249
+ "nko.kr",
250
+ "now.im",
251
+ "npv.kr",
252
+ "nuo.co.kr",
253
+ "nuo.kr",
254
+ "nut.cc",
255
+ "o-r.kr",
256
+ "oazis.site",
257
+ "obo.kr",
258
+ "ocry.com",
259
+ "office.gy",
260
+ "okezone.bid",
261
+ "one.pl",
262
+ "onlysext.com",
263
+ "oovy.org",
264
+ "oppoesrt.online",
265
+ "orangotango.ml",
266
+ "otherinbox.com",
267
+ "ourhobby.com",
268
+ "owa.kr",
269
+ "owh.ooo",
270
+ "oyu.kr",
271
+ "p-e.kr",
272
+ "pafnuty.com",
273
+ "pandies.space",
274
+ "paqeh.online",
275
+ "pe.hu",
276
+ "petinggiean.tech",
277
+ "peyekkolipi.buzz",
278
+ "poderosamulher.com",
279
+ "poistaa.com",
280
+ "porco.cf",
281
+ "poy.kr",
282
+ "prapto.host",
283
+ "probatelawarizona.com",
284
+ "ptcu.dev",
285
+ "pubgm.website",
286
+ "qbi.kr",
287
+ "qc.to",
288
+ "r-e.kr",
289
+ "ragel.me",
290
+ "rao.kr",
291
+ "reilis.site",
292
+ "rf.gd",
293
+ "ringen.host",
294
+ "rko.kr",
295
+ "rosso.ml",
296
+ "row.kr",
297
+ "rr.nu",
298
+ "rshagor.xyz",
299
+ "s-ly.me",
300
+ "safe-mail.gq",
301
+ "sagun.info",
302
+ "samsueng.site",
303
+ "saucent.online",
304
+ "sborra.tk",
305
+ "schwarzmail.ga",
306
+ "seluang.com",
307
+ "sempak.link",
308
+ "sendaljepit.site",
309
+ "sendangagung.online",
310
+ "servegame.com",
311
+ "shp7.cn",
312
+ "siambretta.com",
313
+ "skodaauto.cf",
314
+ "soju.buzz",
315
+ "solidplai.us",
316
+ "somee.com",
317
+ "spamtrap.ro",
318
+ "spymail.one",
319
+ "ssanphone.me",
320
+ "standeight.com",
321
+ "statuspage.ga",
322
+ "steakbeef.site",
323
+ "stonedogdigital.com",
324
+ "stop-my-spam.pp.ua",
325
+ "storeyee.com",
326
+ "sumanan.site",
327
+ "supere.ml",
328
+ "svblog.com",
329
+ "sytes.net",
330
+ "tandy.co",
331
+ "tangtingtung.tech",
332
+ "teml.net",
333
+ "tempembus.buzz",
334
+ "tempremail.cf",
335
+ "tempremail.tk",
336
+ "tgwrzqr.top",
337
+ "thepieter.com",
338
+ "theworkpc.com",
339
+ "thinktimessolve.info",
340
+ "thumoi.com",
341
+ "tko.co.kr",
342
+ "tko.kr",
343
+ "tmo.kr",
344
+ "tmpeml.com",
345
+ "toh.info",
346
+ "toi.kr",
347
+ "tomcrusenono.host",
348
+ "topikurrohman.xyz",
349
+ "tourbalitravel.com",
350
+ "traveldesk.com",
351
+ "tricakesi.store",
352
+ "trillianpro.com",
353
+ "twilightparadox.com",
354
+ "tyrex.cf",
355
+ "uha.kr",
356
+ "uk.to",
357
+ "uko.kr",
358
+ "umy.kr",
359
+ "unaux.com",
360
+ "undo.it",
361
+ "uny.kr",
362
+ "uola.org",
363
+ "upy.kr",
364
+ "urbanban.com",
365
+ "us.to",
366
+ "usa.cc",
367
+ "uu.gl",
368
+ "uvy.kr",
369
+ "uyu.kr",
370
+ "vay.kr",
371
+ "vba.kr",
372
+ "veo.kr",
373
+ "viola.gq",
374
+ "vivoheroes.xyz",
375
+ "vkbags.in",
376
+ "vo.uk",
377
+ "volvo-xc.tk",
378
+ "vuforia.us",
379
+ "wakultimbo.buzz",
380
+ "web.id",
381
+ "weprof.it",
382
+ "werkuldino.buzz",
383
+ "wil.kr",
384
+ "wingkobabat.buzz",
385
+ "x24hr.com",
386
+ "xiaomie.store",
387
+ "xo.uk",
388
+ "xxi2.com",
389
+ "yarien.eu",
390
+ "yawahid.host",
391
+ "ye.vc",
392
+ "yertxenor.tk",
393
+ "yomail.info",
394
+ "yopmail.com",
395
+ "yoqoyyum.space",
396
+ "youdontcare.com",
397
+ "zalvisual.us",
398
+ "zapto.org",
399
+ "ze.cx",
400
+ "zeroe.ml"
401
+ ]
@@ -0,0 +1 @@
1
+ 3b3e9d56e2f98f19f3d7ddf76cd09615531b69616b8aa20520c2aa3bc9bf9bb8
package/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { DisposableMatcher } from './matcher.js';
2
+ export declare function isDisposableEmail(email: string): boolean;
3
+ export declare function isDisposableDomain(domain: string): boolean;
4
+ export { DisposableMatcher };
5
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AA2BjD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
package/index.js ADDED
@@ -0,0 +1,31 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { fileURLToPath } from 'node:url';
3
+ import path from 'node:path';
4
+ import { DisposableMatcher } from './matcher.js';
5
+ function loadWildcardJson() {
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+ // dist/index.js -> ../data/wildcard.json (because "data" is shipped)
9
+ const p = path.join(__dirname, '..', 'data', 'wildcard.json');
10
+ const raw = readFileSync(p, 'utf8');
11
+ const json = JSON.parse(raw);
12
+ if (Array.isArray(json))
13
+ return json;
14
+ // In case format changes in the future
15
+ if (json && typeof json === 'object') {
16
+ const anyJson = json;
17
+ if (Array.isArray(anyJson.wildcard))
18
+ return anyJson.wildcard;
19
+ if (Array.isArray(anyJson.domains))
20
+ return anyJson.domains;
21
+ }
22
+ throw new Error('Unsupported wildcard.json format');
23
+ }
24
+ const matcher = new DisposableMatcher(loadWildcardJson());
25
+ export function isDisposableEmail(email) {
26
+ return matcher.isDisposable(email);
27
+ }
28
+ export function isDisposableDomain(domain) {
29
+ return matcher.isDisposable(domain);
30
+ }
31
+ export { DisposableMatcher };
package/matcher.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ export type WildcardEntry = string;
2
+ /**
3
+ * Matches disposable domains from a list that can include wildcard entries.
4
+ * Supported patterns:
5
+ * - "example.com" (exact)
6
+ * - "*.example.com" (any subdomain OR the root; see notes below)
7
+ *
8
+ * NOTE: For practicality, we treat "*.example.com" as matching both:
9
+ * - example.com
10
+ * - anything.example.com
11
+ */
12
+ export declare class DisposableMatcher {
13
+ private readonly exact;
14
+ private readonly suffixes;
15
+ constructor(entries: WildcardEntry[]);
16
+ isDisposable(emailOrDomain: string): boolean;
17
+ }
18
+ //# sourceMappingURL=matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.d.ts","sourceRoot":"","sources":["../src/matcher.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAcnC;;;;;;;;;GASG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;gBAE7B,OAAO,EAAE,aAAa,EAAE;IAgBpC,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO;CAa7C"}
package/matcher.js ADDED
@@ -0,0 +1,53 @@
1
+ function normalizeDomain(d) {
2
+ return d.trim().toLowerCase().replace(/\.$/, '');
3
+ }
4
+ function extractDomain(emailOrDomain) {
5
+ const v = emailOrDomain.trim();
6
+ const at = v.lastIndexOf('@');
7
+ const domain = at >= 0 ? v.slice(at + 1) : v;
8
+ const norm = normalizeDomain(domain);
9
+ return norm ? norm : null;
10
+ }
11
+ /**
12
+ * Matches disposable domains from a list that can include wildcard entries.
13
+ * Supported patterns:
14
+ * - "example.com" (exact)
15
+ * - "*.example.com" (any subdomain OR the root; see notes below)
16
+ *
17
+ * NOTE: For practicality, we treat "*.example.com" as matching both:
18
+ * - example.com
19
+ * - anything.example.com
20
+ */
21
+ export class DisposableMatcher {
22
+ exact = new Set();
23
+ suffixes = [];
24
+ constructor(entries) {
25
+ for (const raw of entries) {
26
+ const e = normalizeDomain(raw);
27
+ if (!e)
28
+ continue;
29
+ if (e.startsWith('*.')) {
30
+ this.suffixes.push(e.slice(2));
31
+ }
32
+ else {
33
+ this.exact.add(e);
34
+ }
35
+ }
36
+ // check longer suffixes first (micro-optimization)
37
+ this.suffixes.sort((a, b) => b.length - a.length);
38
+ }
39
+ isDisposable(emailOrDomain) {
40
+ const domain = extractDomain(emailOrDomain);
41
+ if (!domain)
42
+ return false;
43
+ if (this.exact.has(domain))
44
+ return true;
45
+ for (const s of this.suffixes) {
46
+ if (domain === s)
47
+ return true;
48
+ if (domain.endsWith('.' + s))
49
+ return true;
50
+ }
51
+ return false;
52
+ }
53
+ }
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@brilab-mailer/disposable",
3
+ "version": "0.0.1",
4
+ "description": "Fast disposable email/domain detection with bundled wildcard list and optional postinstall refresh.",
5
+ "author": "Bohdan Radchenko <radchenkobs@gmail.com>",
6
+ "type": "module",
7
+ "main": "./index.js",
8
+ "module": "./index.js",
9
+ "types": "./index.d.ts",
10
+ "exports": {
11
+ "./package.json": "./package.json",
12
+ ".": {
13
+ "types": "./index.d.ts",
14
+ "import": "./index.js",
15
+ "default": "./index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "**/*",
20
+ "!**/*.tsbuildinfo",
21
+ "data",
22
+ "scripts"
23
+ ],
24
+ "license": "MIT",
25
+ "keywords": [
26
+ "email",
27
+ "disposable",
28
+ "validation",
29
+ "domain",
30
+ "blocklist"
31
+ ],
32
+ "publishConfig": {
33
+ "access": "public",
34
+ "directory": "dist"
35
+ },
36
+ "scripts": {
37
+ "postinstall": "node scripts/postinstall.cjs"
38
+ }
39
+ }
@@ -0,0 +1,62 @@
1
+ /* eslint-disable no-console */
2
+ const fs = require('node:fs');
3
+ const path = require('node:path');
4
+ const https = require('node:https');
5
+ const crypto = require('node:crypto');
6
+
7
+ const URL =
8
+ 'https://raw.githubusercontent.com/ivolo/disposable-email-domains/master/wildcard.json';
9
+
10
+ const DATA_DIR = path.join(__dirname, '..', 'data');
11
+ const TARGET_JSON = path.join(DATA_DIR, 'wildcard.json');
12
+ const TARGET_SHA = path.join(DATA_DIR, 'wildcard.sha256');
13
+
14
+ const HARD_FAIL = process.env.DISPOSABLE_DOMAINS_HARD_FAIL === '1';
15
+ const TIMEOUT_MS = Number(process.env.DISPOSABLE_DOMAINS_TIMEOUT_MS || 2500);
16
+
17
+ function sha256(buf) {
18
+ return crypto.createHash('sha256').update(buf).digest('hex');
19
+ }
20
+
21
+ function fetch(url) {
22
+ return new Promise((resolve, reject) => {
23
+ const req = https.get(url, { timeout: TIMEOUT_MS }, (res) => {
24
+ if (res.statusCode !== 200) {
25
+ reject(new Error(`HTTP ${res.statusCode}`));
26
+ res.resume();
27
+ return;
28
+ }
29
+ const chunks = [];
30
+ res.on('data', (c) => chunks.push(c));
31
+ res.on('end', () => resolve(Buffer.concat(chunks)));
32
+ });
33
+ req.on('timeout', () => req.destroy(new Error('timeout')));
34
+ req.on('error', reject);
35
+ });
36
+ }
37
+
38
+ (async () => {
39
+ try {
40
+ fs.mkdirSync(DATA_DIR, { recursive: true });
41
+
42
+ const buf = await fetch(URL);
43
+
44
+ // basic sanity check (avoid saving HTML/errors)
45
+ const parsed = JSON.parse(buf.toString('utf8'));
46
+ if (!Array.isArray(parsed) || parsed.length < 100) {
47
+ throw new Error('Unexpected JSON format/size');
48
+ }
49
+
50
+ fs.writeFileSync(TARGET_JSON, buf);
51
+ fs.writeFileSync(TARGET_SHA, sha256(buf), 'utf8');
52
+
53
+ console.log(
54
+ `[disposable-domain-kit] updated wildcard.json (${parsed.length} entries)`
55
+ );
56
+ } catch (e) {
57
+ console.warn(
58
+ `[disposable-domain-kit] could not update list, using bundled snapshot. reason: ${e.message}`
59
+ );
60
+ if (HARD_FAIL) process.exit(1);
61
+ }
62
+ })();