Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Continuing refinement of the web pages for handling email subscriptions. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | email-alerts |
Files: | files | file ages | folders |
SHA3-256: |
84d0d853177588ebccad753a0379b029 |
User & Date: | drh 2018-06-21 22:37:58.494 |
Context
2018-06-21
| ||
23:01 | Add the "fossil email inbound" command, though it currently does not analyze the inbound emails - it just stores the emails in a directory for later human viewing. ... (check-in: 775e529b user: drh tags: email-alerts) | |
22:37 | Continuing refinement of the web pages for handling email subscriptions. ... (check-in: 84d0d853 user: drh tags: email-alerts) | |
21:02 | Add the /subscribers page. Fix minor issues. All pages still need improvement. ... (check-in: e015c103 user: drh tags: email-alerts) | |
Changes
Changes to src/email.c.
︙ | ︙ | |||
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | */ void email_schema(void){ if( !db_table_exists("repository", "subscriber") ){ db_multi_exec(zEmailInit/*works-like:""*/); } } /* ** WEBPAGE: setup_email ** ** Administrative page for configuring and controlling email notification */ void setup_email(void){ static const char *const azSendMethods[] = { "off", "Disabled", "pipe", "Pipe to a command", "db", "Store in a database", "file", "Store in a directory" }; login_check_credentials(); if( !g.perm.Setup ){ login_needed(0); return; } db_begin_transaction(); | > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | | | | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | */ void email_schema(void){ if( !db_table_exists("repository", "subscriber") ){ db_multi_exec(zEmailInit/*works-like:""*/); } } /* ** Return true if email alerts are active. */ int email_enabled(void){ if( !db_table_exists("repository", "subscriber") ) return 0; if( fossil_strcmp(db_get("email-send-method","off"),"off")==0 ) return 0; return 1; } /* ** Insert a "Subscriber List" submenu link if the current user ** is an administrator. */ void email_subscriber_list_link(void){ if( g.perm.Admin ){ style_submenu_element("Subscriber List","%R/subscribers"); } } /* ** WEBPAGE: setup_email ** ** Administrative page for configuring and controlling email notification */ void setup_email(void){ static const char *const azSendMethods[] = { "off", "Disabled", "pipe", "Pipe to a command", "db", "Store in a database", "file", "Store in a directory" }; login_check_credentials(); if( !g.perm.Setup ){ login_needed(0); return; } db_begin_transaction(); email_subscriber_list_link(); style_header("Email Notification Setup"); @ <form action="%R/setup_email" method="post"><div> @ <input type="submit" name="submit" value="Apply Changes" /><hr> login_insert_csrf_secret(); multiple_choice_attribute("Email Send Method", "email-send-method", "esm", "off", count(azSendMethods)/2, azSendMethods); @ <p>How to send email. The "Pipe to a command" @ method is the usual choice in production. @ (Property: "email-send-method")</p> @ <hr> entry_attribute("Command To Pipe Email To", 80, "email-send-command", "ecmd", "sendmail -t", 0); @ <p>When the send method is "pipe to a command", this is the command @ that is run. Email messages are piped into the standard input of this @ command. The command is expected to extract the sender address, @ recepient addresses, and subject from the header of the piped email @ text. (Property: "email-send-command")</p> entry_attribute("Database In Which To Store Email", 60, "email-send-db", "esdb", "", 0); @ <p>When the send method is "store in a databaes", each email message is @ stored in an SQLite database file with the name given here. @ (Property: "email-send-db")</p> entry_attribute("Directory In Which To Store Email", 60, "email-send-dir", "esdir", "", 0); @ <p>When the send method is "store in a directory", each email message is @ stored as a separate file in the directory shown here. @ (Property: "email-send-dir")</p> @ <hr> entry_attribute("\"From\" email address", 40, "email-self", "eself", "", 0); @ <p>This is the email from which email notifications are sent. 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("Administrator email address", 40, "email-admin", "eadmin", "", 0); @ <p>This is the email for the human administrator for the system. @ Abuse and trouble reports are send here. @ (Property: "email-admin")</p> @ <hr> @ <p><input type="submit" name="submit" value="Apply Changes" /></p> @ </div></form> db_end_transaction(0); |
︙ | ︙ | |||
564 565 566 567 568 569 570 | } if( login_is_individual() && db_exists("SELECT 1 FROM subscriber WHERE suname=%Q",g.zLogin) ){ /* This person is already signed up for email alerts. Jump ** to the screen that lets them edit their alert preferences. */ | | > | 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 | } if( login_is_individual() && db_exists("SELECT 1 FROM subscriber WHERE suname=%Q",g.zLogin) ){ /* This person is already signed up for email alerts. Jump ** to the screen that lets them edit their alert preferences. */ cgi_redirectf("%R/alerts"); return; } email_subscriber_list_link(); needCaptcha = !login_is_individual(); if( P("submit") && cgi_csrf_safe(1) && subscribe_error_check(&eErr,&zErr,needCaptcha) ){ /* A validated request for a new subscription has been received. */ char ssub[20]; |
︙ | ︙ | |||
680 681 682 683 684 685 686 | @ <label><input type="checkbox" name="dnc" %s(PCK("dnc"))> \ @ Do not call</label><br> } @ </td> @ </tr> @ <tr> @ <td></td> | > > > > | > | 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 | @ <label><input type="checkbox" name="dnc" %s(PCK("dnc"))> \ @ Do not call</label><br> } @ </td> @ </tr> @ <tr> @ <td></td> if( needCaptcha && !email_enabled() ){ @ <td><input type="submit" name="submit" value="Submit" disabled> @ (Email current disabled)</td> }else{ @ <td><input type="submit" name="submit" value="Submit"></td> } @ </tr> @ </table> if( needCaptcha ){ @ <div class="captcha"><table class="captcha"><tr><td><pre> @ %h(zCaptcha) @ </pre> @ Enter the 8 characters above in the "Security Code" box |
︙ | ︙ | |||
737 738 739 740 741 742 743 744 745 746 747 748 749 750 | zName = db_text(0, "SELECT hex(subscriberCode) FROM subscriber" " WHERE suname=%Q", g.zLogin); } if( zName==0 || !validate16(zName, -1) ){ cgi_redirect("subscribe"); return; } if( P("submit")!=0 && cgi_csrf_safe(1) ){ int sdonotcall = PB("sdonotcall"); int sdigest = PB("sdigest"); char ssub[10]; int nsub = 0; const char *suname = 0; if( PB("sa") ) ssub[nsub++] = 'a'; | > | 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 | zName = db_text(0, "SELECT hex(subscriberCode) FROM subscriber" " WHERE suname=%Q", g.zLogin); } if( zName==0 || !validate16(zName, -1) ){ cgi_redirect("subscribe"); return; } email_subscriber_list_link(); if( P("submit")!=0 && cgi_csrf_safe(1) ){ int sdonotcall = PB("sdonotcall"); int sdigest = PB("sdigest"); char ssub[10]; int nsub = 0; const char *suname = 0; if( PB("sa") ) ssub[nsub++] = 'a'; |
︙ | ︙ | |||
905 906 907 908 909 910 911 | style_header("Subscriber List"); blob_init(&sql, 0, 0); blob_append_sql(&sql, "SELECT hex(subscriberCode)," " semail," " ssub," " suname," | | > | > > > > > > > | > | | | 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 | style_header("Subscriber List"); blob_init(&sql, 0, 0); blob_append_sql(&sql, "SELECT hex(subscriberCode)," " semail," " ssub," " suname," " sverified," " sdigest" " FROM subscriber" ); db_prepare_blob(&q, &sql); @ <table border="1"> @ <tr> @ <th>Email @ <th>Events @ <th>Digest-Only? @ <th>User @ <th>Verified? @ </tr> while( db_step(&q)==SQLITE_ROW ){ @ <tr> @ <td><a href='%R/alerts/%s(db_column_text(&q,0))'>\ @ %h(db_column_text(&q,1))</a></td> @ <td>%h(db_column_text(&q,2))</td> @ <td>%s(db_column_int(&q,5)?"digest":"")</td> @ <td>%h(db_column_text(&q,3))</td> @ <td>%s(db_column_int(&q,4)?"yes":"pending")</td> @ </tr> } @ </table> db_finalize(&q); style_footer(); } |
Changes to src/login.c.
︙ | ︙ | |||
728 729 730 731 732 733 734 735 736 737 738 739 740 741 | } @ </div> free(zCaptcha); } @ </form> } if( g.zLogin && g.perm.Password ){ @ <hr /> @ <p>Change Password for user <b>%h(g.zLogin)</b>:</p> form_begin(0, "%R/login"); @ <table> @ <tr><td class="form_label">Old Password:</td> @ <td><input type="password" name="p" size="30" /></td></tr> @ <tr><td class="form_label">New Password:</td> | > > > > > | 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 | } @ </div> free(zCaptcha); } @ </form> } if( g.zLogin && g.perm.Password ){ if( email_enabled() ){ @ <hr> @ <p>Configure <a href="%R/alerts">Email Alerts</a> @ for user <b>%h(g.zLogin)</b></p> } @ <hr /> @ <p>Change Password for user <b>%h(g.zLogin)</b>:</p> form_begin(0, "%R/login"); @ <table> @ <tr><td class="form_label">Old Password:</td> @ <td><input type="password" name="p" size="30" /></td></tr> @ <tr><td class="form_label">New Password:</td> |
︙ | ︙ |
Changes to src/setup.c.
︙ | ︙ | |||
1020 1021 1022 1023 1024 1025 1026 | login_verify_csrf_secret(); db_set(zVar, zQ, 0); admin_log("Set entry_attribute %Q to: %.*s%s", zVar, 20, zQ, (nZQ>20 ? "..." : "")); zVal = zQ; } @ <input type="text" id="%s(zQParm)" name="%s(zQParm)" value="%h(zVal)" \ | | | | 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 | login_verify_csrf_secret(); db_set(zVar, zQ, 0); admin_log("Set entry_attribute %Q to: %.*s%s", zVar, 20, zQ, (nZQ>20 ? "..." : "")); zVal = zQ; } @ <input type="text" id="%s(zQParm)" name="%s(zQParm)" value="%h(zVal)" \ @ size="%d(width)" \ if( disabled ){ @ disabled="disabled" \ } @ /> <b>%s(zLabel)</b> } /* ** Generate a text box for an attribute. */ |
︙ | ︙ |