duck-mail.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // content/duck-mail.js — Content script for DuckDuckGo Email Protection autofill settings
  2. console.log('[MultiPage:duck-mail] Content script loaded on', location.href);
  3. chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  4. if (message.type !== 'FETCH_DUCK_EMAIL') return;
  5. resetStopState();
  6. fetchDuckEmail(message.payload).then(result => {
  7. sendResponse(result);
  8. }).catch(err => {
  9. if (isStopError(err)) {
  10. log('Duck Mail: Stopped by user.', 'warn');
  11. sendResponse({ stopped: true, error: err.message });
  12. return;
  13. }
  14. sendResponse({ error: err.message });
  15. });
  16. return true;
  17. });
  18. async function fetchDuckEmail(payload = {}) {
  19. const { generateNew = true } = payload;
  20. log(`Duck Mail: ${generateNew ? 'Generating' : 'Reading'} private address...`);
  21. await waitForElement(
  22. 'input.AutofillSettingsPanel__PrivateDuckAddressValue, button.AutofillSettingsPanel__GeneratorButton',
  23. 15000
  24. );
  25. const getAddressInput = () => document.querySelector('input.AutofillSettingsPanel__PrivateDuckAddressValue');
  26. const getGeneratorButton = () => document.querySelector('button.AutofillSettingsPanel__GeneratorButton')
  27. || Array.from(document.querySelectorAll('button')).find(btn => /generate private duck address/i.test(btn.textContent || ''));
  28. const readEmail = () => {
  29. const value = getAddressInput()?.value?.trim() || '';
  30. return value.includes('@duck.com') ? value : '';
  31. };
  32. const waitForEmailValue = async (previousValue = '') => {
  33. for (let i = 0; i < 100; i++) {
  34. const nextValue = readEmail();
  35. if (nextValue && nextValue !== previousValue) {
  36. return nextValue;
  37. }
  38. await sleep(150);
  39. }
  40. throw new Error('Timed out waiting for Duck address to appear.');
  41. };
  42. const currentEmail = readEmail();
  43. if (currentEmail && !generateNew) {
  44. log(`Duck Mail: Found existing address ${currentEmail}`);
  45. return { email: currentEmail, generated: false };
  46. }
  47. await humanPause(500, 1300);
  48. const generatorButton = getGeneratorButton();
  49. if (!generatorButton) {
  50. if (currentEmail) {
  51. log(`Duck Mail: Reusing existing address ${currentEmail}`, 'warn');
  52. return { email: currentEmail, generated: false };
  53. }
  54. throw new Error('Could not find "Generate Private Duck Address" button.');
  55. }
  56. generatorButton.click();
  57. log('Duck Mail: Clicked "Generate Private Duck Address"');
  58. const nextEmail = await waitForEmailValue(currentEmail);
  59. log(`Duck Mail: Ready address ${nextEmail}`, 'ok');
  60. return { email: nextEmail, generated: true };
  61. }