Revert "fix displayed email extraction boundaries"
This reverts commit daf703164a.
This commit is contained in:
@@ -259,112 +259,6 @@ function getActionText(el) {
|
|||||||
.trim();
|
.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasEmailTokenBoundary(text, start, end) {
|
|
||||||
const before = start > 0 ? text[start - 1] : '';
|
|
||||||
const after = end < text.length ? text[end] : '';
|
|
||||||
return (!before || !/[A-Z0-9._%+-]/i.test(before))
|
|
||||||
&& (!after || !/[A-Z0-9_%+-]/i.test(after));
|
|
||||||
}
|
|
||||||
|
|
||||||
function isValidEmailCandidate(value = '') {
|
|
||||||
const candidate = String(value || '').trim();
|
|
||||||
const atIndex = candidate.lastIndexOf('@');
|
|
||||||
if (atIndex <= 0 || atIndex !== candidate.indexOf('@')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const local = candidate.slice(0, atIndex);
|
|
||||||
const domain = candidate.slice(atIndex + 1);
|
|
||||||
if (!local || !domain || local.startsWith('.') || local.endsWith('.') || local.includes('..')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!/^[A-Z0-9._%+-]+$/i.test(local)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const labels = domain.split('.');
|
|
||||||
if (labels.length < 2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (const label of labels) {
|
|
||||||
if (!/^[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?$/i.test(label)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const tld = labels[labels.length - 1];
|
|
||||||
return /^[A-Z]{2,63}$/i.test(tld) && !/[a-z][A-Z]/.test(tld);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getEmailFromTextFragment(value = '') {
|
|
||||||
const text = String(value || '').replace(/\s+/g, ' ').trim();
|
|
||||||
if (!text) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
const pattern = /[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,63}/ig;
|
|
||||||
for (const match of text.matchAll(pattern)) {
|
|
||||||
const candidate = String(match[0] || '');
|
|
||||||
const start = Number(match.index || 0);
|
|
||||||
const end = start + candidate.length;
|
|
||||||
if (hasEmailTokenBoundary(text, start, end) && isValidEmailCandidate(candidate)) {
|
|
||||||
return candidate.toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getVisibleTextNodeEmail() {
|
|
||||||
if (typeof document?.createTreeWalker !== 'function' || !document.body) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
const showText = typeof NodeFilter !== 'undefined' ? NodeFilter.SHOW_TEXT : 4;
|
|
||||||
const walker = document.createTreeWalker(document.body, showText);
|
|
||||||
let node = walker.nextNode();
|
|
||||||
while (node) {
|
|
||||||
const parent = node.parentElement || node.parentNode || null;
|
|
||||||
const text = String(node.nodeValue || '').trim();
|
|
||||||
if (text && (!parent || typeof isVisibleElement !== 'function' || isVisibleElement(parent))) {
|
|
||||||
const email = getEmailFromTextFragment(text);
|
|
||||||
if (email) {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
node = walker.nextNode();
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDisplayedEmailFromDocument() {
|
|
||||||
const fieldCandidates = Array.from(document.querySelectorAll?.('input, textarea') || []);
|
|
||||||
for (const field of fieldCandidates) {
|
|
||||||
const email = getEmailFromTextFragment(field?.value || field?.getAttribute?.('value') || '');
|
|
||||||
if (email) {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const attributeCandidates = Array.from(document.querySelectorAll?.('[aria-label], [title]') || []);
|
|
||||||
for (const el of attributeCandidates) {
|
|
||||||
if (typeof isVisibleElement === 'function' && !isVisibleElement(el)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const email = getEmailFromTextFragment([
|
|
||||||
el?.getAttribute?.('aria-label'),
|
|
||||||
el?.getAttribute?.('title'),
|
|
||||||
].filter(Boolean).join(' '));
|
|
||||||
if (email) {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const textNodeEmail = getVisibleTextNodeEmail();
|
|
||||||
if (textNodeEmail) {
|
|
||||||
return textNodeEmail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function isActionEnabled(el) {
|
function isActionEnabled(el) {
|
||||||
return Boolean(el)
|
return Boolean(el)
|
||||||
&& !el.disabled
|
&& !el.disabled
|
||||||
@@ -821,7 +715,11 @@ function findSignupEntryTrigger(options = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getSignupPasswordDisplayedEmail() {
|
function getSignupPasswordDisplayedEmail() {
|
||||||
return getDisplayedEmailFromDocument();
|
const text = (document.body?.innerText || document.body?.textContent || '')
|
||||||
|
.replace(/\s+/g, ' ')
|
||||||
|
.trim();
|
||||||
|
const matches = text.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/ig);
|
||||||
|
return matches?.[0] ? String(matches[0]).trim().toLowerCase() : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function inspectSignupEntryState() {
|
function inspectSignupEntryState() {
|
||||||
@@ -3130,7 +3028,9 @@ function getPageTextSnapshot() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getLoginVerificationDisplayedEmail() {
|
function getLoginVerificationDisplayedEmail() {
|
||||||
return getDisplayedEmailFromDocument();
|
const pageText = getPageTextSnapshot();
|
||||||
|
const matches = pageText.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/ig) || [];
|
||||||
|
return matches[0] ? String(matches[0]).trim().toLowerCase() : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPhoneVerificationDisplayedPhone() {
|
function getPhoneVerificationDisplayedPhone() {
|
||||||
|
|||||||
@@ -51,12 +51,6 @@ function extractFunction(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bundle = [
|
const bundle = [
|
||||||
extractFunction('hasEmailTokenBoundary'),
|
|
||||||
extractFunction('isValidEmailCandidate'),
|
|
||||||
extractFunction('getEmailFromTextFragment'),
|
|
||||||
extractFunction('getVisibleTextNodeEmail'),
|
|
||||||
extractFunction('getDisplayedEmailFromDocument'),
|
|
||||||
extractFunction('getSignupPasswordDisplayedEmail'),
|
|
||||||
extractFunction('getPageTextSnapshot'),
|
extractFunction('getPageTextSnapshot'),
|
||||||
extractFunction('getLoginVerificationDisplayedEmail'),
|
extractFunction('getLoginVerificationDisplayedEmail'),
|
||||||
extractFunction('getPhoneVerificationDisplayedPhone'),
|
extractFunction('getPhoneVerificationDisplayedPhone'),
|
||||||
@@ -80,39 +74,9 @@ const document = {
|
|||||||
innerText: ${JSON.stringify(overrides.pageText || '')},
|
innerText: ${JSON.stringify(overrides.pageText || '')},
|
||||||
textContent: ${JSON.stringify(overrides.pageText || '')},
|
textContent: ${JSON.stringify(overrides.pageText || '')},
|
||||||
},
|
},
|
||||||
querySelectorAll(selector) {
|
|
||||||
if (selector === 'input, textarea') {
|
|
||||||
return ${JSON.stringify(overrides.fields || [])};
|
|
||||||
}
|
|
||||||
if (selector === '[aria-label], [title]') {
|
|
||||||
return ${JSON.stringify(overrides.attributeElements || [])};
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
querySelector() {
|
querySelector() {
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
createTreeWalker() {
|
|
||||||
const textNodeValues = ${JSON.stringify(
|
|
||||||
Object.prototype.hasOwnProperty.call(overrides, 'textNodes')
|
|
||||||
? overrides.textNodes
|
|
||||||
: [overrides.pageText || '']
|
|
||||||
)};
|
|
||||||
const nodes = textNodeValues.map((text) => ({
|
|
||||||
nodeValue: text,
|
|
||||||
parentElement: {
|
|
||||||
getBoundingClientRect() {
|
|
||||||
return { width: 1, height: 1 };
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
let index = 0;
|
|
||||||
return {
|
|
||||||
nextNode() {
|
|
||||||
return nodes[index++] || null;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function getLoginTimeoutErrorPageState() {
|
function getLoginTimeoutErrorPageState() {
|
||||||
@@ -185,8 +149,6 @@ return {
|
|||||||
inspectLoginAuthState,
|
inspectLoginAuthState,
|
||||||
isPhoneVerificationPageReady,
|
isPhoneVerificationPageReady,
|
||||||
normalizeStep6Snapshot,
|
normalizeStep6Snapshot,
|
||||||
getSignupPasswordDisplayedEmail,
|
|
||||||
getLoginVerificationDisplayedEmail,
|
|
||||||
};
|
};
|
||||||
`)();
|
`)();
|
||||||
}
|
}
|
||||||
@@ -217,49 +179,6 @@ return {
|
|||||||
assert.strictEqual(snapshot.displayedEmail, 'display.user@example.com');
|
assert.strictEqual(snapshot.displayedEmail, 'display.user@example.com');
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
const api = createApi({
|
|
||||||
verificationTarget: { id: 'otp' },
|
|
||||||
pageText: 'We emailed a code to skater-twine-carve@duck.comChange',
|
|
||||||
textNodes: ['We emailed a code to ', 'skater-twine-carve@duck.com', 'Change'],
|
|
||||||
});
|
|
||||||
|
|
||||||
const snapshot = api.inspectLoginAuthState();
|
|
||||||
assert.strictEqual(snapshot.displayedEmail, 'skater-twine-carve@duck.com');
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const api = createApi({
|
|
||||||
verificationTarget: { id: 'otp' },
|
|
||||||
pageText: 'We emailed a code to skater-twine-carve@duck.comChange',
|
|
||||||
textNodes: ['We emailed a code to skater-twine-carve@duck.comChange'],
|
|
||||||
});
|
|
||||||
|
|
||||||
const snapshot = api.inspectLoginAuthState();
|
|
||||||
assert.strictEqual(snapshot.displayedEmail, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const api = createApi({
|
|
||||||
pageText: 'Create your account skater-twine-carve@duck.comChange',
|
|
||||||
textNodes: ['Create your account ', 'skater-twine-carve@duck.com', 'Change'],
|
|
||||||
});
|
|
||||||
|
|
||||||
assert.strictEqual(api.getSignupPasswordDisplayedEmail(), 'skater-twine-carve@duck.com');
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const api = createApi({
|
|
||||||
verificationTarget: { id: 'otp' },
|
|
||||||
pageText: 'We emailed a code to skater-twine-carve@duck.comChange',
|
|
||||||
textNodes: ['We emailed a code to skater-twine-carve@duck.comChange'],
|
|
||||||
fields: [{ value: 'skater-twine-carve@duck.com' }],
|
|
||||||
});
|
|
||||||
|
|
||||||
const snapshot = api.inspectLoginAuthState();
|
|
||||||
assert.strictEqual(snapshot.displayedEmail, 'skater-twine-carve@duck.com');
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const api = createApi({
|
const api = createApi({
|
||||||
pathname: '/email-verification',
|
pathname: '/email-verification',
|
||||||
|
|||||||
Reference in New Issue
Block a user