import { test } from 'node:test'; import assert from 'node:assert/strict'; import { analyzeLink, hostFromText, registrableDomain } from './linkSafety'; test('visible text that names another site is a mismatch', () => { const r = analyzeLink('https://matrix.lotusguild.org/login', 'https://evil.example/login'); assert.equal(r?.mismatch, true); assert.equal(r?.shownHost, 'matrix.lotusguild.org'); assert.equal(r?.realHost, 'evil.example'); }); test('honest links are not flagged: same registrable domain, plain words, non-http', () => { assert.equal( analyzeLink('youtube.com/watch?v=1', 'https://www.youtube.com/watch?v=1')?.mismatch, false, ); assert.equal(analyzeLink('bbc.co.uk', 'https://news.bbc.co.uk/x')?.mismatch, false); assert.equal(analyzeLink('click here', 'https://evil.example')?.mismatch, false); assert.equal(analyzeLink('evil.example', 'mailto:someone@evil.example'), null); assert.equal(analyzeLink('elsewhere.org', 'https://matrix.to/#/#room:x'), null); assert.equal( analyzeLink('lotusguild.org', 'https://chat.lotusguild.org/home/!r:x')?.mismatch, false, ); }); test('registrable domain handles two-label suffixes', () => { assert.equal(registrableDomain('news.bbc.co.uk'), 'bbc.co.uk'); assert.equal(registrableDomain('www.example.com'), 'example.com'); assert.equal(registrableDomain('example.com'), 'example.com'); }); test('hostFromText only accepts URL/host-shaped text; IDN becomes punycode', () => { assert.equal(hostFromText('Visit https://a.example/path'), null); assert.equal(hostFromText('a.example/path'), 'a.example'); assert.equal(hostFromText('user@a.example:8448/x'), 'a.example'); assert.equal(hostFromText('pаypal.com'), 'xn--pypal-4ve.com'); // Cyrillic а assert.equal(analyzeLink('paypal.com', 'https://xn--pypal-4ve.com/')?.punycode, true); assert.equal(analyzeLink('paypal.com', 'https://xn--pypal-4ve.com/')?.mismatch, true); });