Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | For email notifications abound events from a single user (such as individual forum post notifications) make the From: address be a "noreply" hash based on the users human-readable name or handle. Always include a Return-Path: field in the header that is the email-self setting, to be used by MTUs that need to bounce the message. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
475c9d11e9028f9b060b3b57c0b15e67 |
User & Date: | drh 2018-08-16 18:56:55.028 |
Context
2018-08-16
| ||
19:51 | Do not put "Return-Path:" headers in notification emails to be sent. That is a violation of standards as only the receiving SMTP server should add the Return-Path header. Instead, include a custom X-Fossil-From: header that downstream software can use (if desired) to set the envelope header of the message. ... (check-in: 731836b8 user: drh tags: trunk) | |
18:56 | For email notifications abound events from a single user (such as individual forum post notifications) make the From: address be a "noreply" hash based on the users human-readable name or handle. Always include a Return-Path: field in the header that is the email-self setting, to be used by MTUs that need to bounce the message. ... (check-in: 475c9d11 user: drh tags: trunk) | |
16:45 | Do not show posts that are awaiting moderation to users without moderator privilege unless they are the same user that generated the post in the first place. ... (check-in: 16c42a08 user: drh tags: trunk) | |
Changes
Changes to src/email.c.
︙ | ︙ | |||
236 237 238 239 240 241 242 | @ <p><b>Required.</b> @ This is URL used as the basename for hyperlinks included in @ email alert text. Omit the trailing "/". @ Suggested value: "%h(g.zBaseURL)" @ (Property: "email-url")</p> @ <hr> | | | > > > | | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | @ <p><b>Required.</b> @ This is URL used as the basename for hyperlinks included in @ email alert text. Omit the trailing "/". @ Suggested value: "%h(g.zBaseURL)" @ (Property: "email-url")</p> @ <hr> entry_attribute("\"Return-Path\" email address", 20, "email-self", "eself", "", 0); @ <p><b>Required.</b> @ This is the email to which email notification bounces should be sent. @ In cases where the email notification does not align with a specific @ Fossil login account (for example, digest messages), this is also @ the "From:" address of the email notification. @ The system administrator should arrange for emails sent to this address @ to be handed off to the "fossil email incoming" command so that Fossil @ can handle bounces. (Property: "email-self")</p> @ <hr> entry_attribute("Repository Nickname", 16, "email-subname", "enn", "", 0); @ <p><b>Required.</b> |
︙ | ︙ | |||
667 668 669 670 671 672 673 674 675 676 677 678 679 680 | if( z ){ z++; }else{ z = (char*)zAddr; } return z; } /* ** Extract all To: header values from the email header supplied. ** Store them in the array list. */ void email_header_to(Blob *pMsg, int *pnTo, char ***pazTo){ int nTo = 0; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 | if( z ){ z++; }else{ z = (char*)zAddr; } return z; } /* ** Return a pointer to a fake email mailbox name that corresponds ** to human-readable name zFromName. The fake mailbox name is based ** on a hash. No huge problems arise if there is a hash collisions, ** but it is still better if collisions can be avoided. ** ** The returned string is held in a static buffer and is overwritten ** by each subsequent call to this routine. */ static char *email_mailbox_name(const char *zFromName){ static char zHash[20]; unsigned int x = 0; int n = 0; while( zFromName[0] ){ n++; x = x*1103515245 + 12345 + ((unsigned char*)zFromName)[0]; zFromName++; } sqlite3_snprintf(sizeof(zHash), zHash, "noreply%x%08x", n, x); return zHash; } /* ** COMMAND: test-mailbox-hashname ** ** Usage: %fossil test-mailbox-hashname HUMAN-NAME ... ** ** Return the mailbox hash name corresponding to each human-readable ** name on the command line. This is a test interface for the ** email_mailbox_name() function. */ void email_test_mailbox_hashname(void){ int i; for(i=2; i<g.argc; i++){ fossil_print("%30s: %s\n", g.argv[i], email_mailbox_name(g.argv[i])); } } /* ** Extract all To: header values from the email header supplied. ** Store them in the array list. */ void email_header_to(Blob *pMsg, int *pnTo, char ***pazTo){ int nTo = 0; |
︙ | ︙ | |||
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 | ** in the header. Likewise, the header must contains a "Subject:" line. ** The header might also include fields like "Message-Id:" or ** "In-Reply-To:". ** ** This routine will add fields to the header as follows: ** ** From: ** Date: ** Message-Id: ** Content-Type: ** Content-Transfer-Encoding: ** MIME-Version: ** ** The caller maintains ownership of the input Blobs. This routine will ** read the Blobs and send them onward to the email system, but it will ** not free them. */ void email_send( EmailSender *p, /* Emailer context */ Blob *pHdr, /* Email header (incomplete) */ Blob *pBody, /* Email body */ const char *zFromName /* Optional human-readable name of sender */ ){ | > > > > > > > > | 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 | ** in the header. Likewise, the header must contains a "Subject:" line. ** The header might also include fields like "Message-Id:" or ** "In-Reply-To:". ** ** This routine will add fields to the header as follows: ** ** From: ** Return-Path: ** Date: ** Message-Id: ** Content-Type: ** Content-Transfer-Encoding: ** MIME-Version: ** ** The caller maintains ownership of the input Blobs. This routine will ** read the Blobs and send them onward to the email system, but it will ** not free them. ** ** If the zFromName argument is not NULL, then it should be a human-readable ** name or handle for the sender. In that case, "From:" becomes a made-up ** email address based on a hash of zFromName and the domain of email-self, ** and an additional "Reply-To:" field is inserted with the email-self ** address. If zFromName is a NULL pointer, then both "From:" and ** Return-Path: are set to the email-self value. */ void email_send( EmailSender *p, /* Emailer context */ Blob *pHdr, /* Email header (incomplete) */ Blob *pBody, /* Email body */ const char *zFromName /* Optional human-readable name of sender */ ){ |
︙ | ︙ | |||
747 748 749 750 751 752 753 | } }else{ blob_init(&all, 0, 0); pOut = &all; } blob_append(pOut, blob_buffer(pHdr), blob_size(pHdr)); if( zFromName ){ | | > > | 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 | } }else{ blob_init(&all, 0, 0); pOut = &all; } blob_append(pOut, blob_buffer(pHdr), blob_size(pHdr)); if( zFromName ){ blob_appendf(pOut, "From: %s <%s@%s>\r\n", zFromName, email_mailbox_name(zFromName), email_hostname(p->zFrom)); }else{ blob_appendf(pOut, "From: <%s>\r\n", p->zFrom); } blob_appendf(pOut, "Return-Path: <%s>\r\n", p->zFrom); blob_appendf(pOut, "Date: %z\r\n", cgi_rfc822_datestamp(time(0))); if( strstr(blob_str(pHdr), "\r\nMessage-Id:")==0 ){ /* Message-id format: "<$(date)x$(random).$(from)>" where $(date) is ** the current unix-time in hex, $(random) is a 64-bit random number, ** and $(from) is the sender. */ sqlite3_randomness(sizeof(r1), &r1); r2 = time(0); |
︙ | ︙ |