| ︙ | | | ︙ | |
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
@ --
@ CREATE TABLE repository.pending_alert(
@ eventid TEXT PRIMARY KEY, -- Object that changed
@ sentSep BOOLEAN DEFAULT false, -- individual alert sent
@ sentDigest BOOLEAN DEFAULT false, -- digest alert sent
@ sentMod BOOLEAN DEFAULT false -- pending moderation alert sent
@ ) WITHOUT ROWID;
@
@ -- Obsolete table. No longer used.
@ DROP TABLE IF EXISTS repository.alert_bounce;
;
/*
** Return true if the email notification tables exist.
*/
|
|
|
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
@ --
@ CREATE TABLE repository.pending_alert(
@ eventid TEXT PRIMARY KEY, -- Object that changed
@ sentSep BOOLEAN DEFAULT false, -- individual alert sent
@ sentDigest BOOLEAN DEFAULT false, -- digest alert sent
@ sentMod BOOLEAN DEFAULT false -- pending moderation alert sent
@ ) WITHOUT ROWID;
@
@ -- Obsolete table. No longer used.
@ DROP TABLE IF EXISTS repository.alert_bounce;
;
/*
** Return true if the email notification tables exist.
*/
|
| ︙ | | | ︙ | |
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
|
*/
void email_header_to(Blob *pMsg, int *pnTo, char ***pazTo){
int nTo = 0;
char **azTo = 0;
Blob v;
char *z, *zAddr;
int i;
email_header_value(pMsg, "to", &v);
z = blob_str(&v);
for(i=0; z[i]; i++){
if( z[i]=='<' && (zAddr = email_copy_addr(&z[i+1],'>'))!=0 ){
azTo = fossil_realloc(azTo, sizeof(azTo[0])*(nTo+1) );
azTo[nTo++] = zAddr;
}
}
*pnTo = nTo;
*pazTo = azTo;
}
/*
** Free a list of To addresses obtained from a prior call to
** email_header_to()
*/
void email_header_to_free(int nTo, char **azTo){
int i;
for(i=0; i<nTo; i++) fossil_free(azTo[i]);
fossil_free(azTo);
}
|
|
|
|
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
|
*/
void email_header_to(Blob *pMsg, int *pnTo, char ***pazTo){
int nTo = 0;
char **azTo = 0;
Blob v;
char *z, *zAddr;
int i;
email_header_value(pMsg, "to", &v);
z = blob_str(&v);
for(i=0; z[i]; i++){
if( z[i]=='<' && (zAddr = email_copy_addr(&z[i+1],'>'))!=0 ){
azTo = fossil_realloc(azTo, sizeof(azTo[0])*(nTo+1) );
azTo[nTo++] = zAddr;
}
}
*pnTo = nTo;
*pazTo = azTo;
}
/*
** Free a list of To addresses obtained from a prior call to
** email_header_to()
*/
void email_header_to_free(int nTo, char **azTo){
int i;
for(i=0; i<nTo; i++) fossil_free(azTo[i]);
fossil_free(azTo);
}
|
| ︙ | | | ︙ | |
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
|
** From:
** Date:
** Message-Id:
** Content-Type:
** Content-Transfer-Encoding:
** MIME-Version:
** Sender:
**
** 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.
**
** The Message-Id: field is added if there is not already a Message-Id
** in the pHdr parameter.
**
** 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 "Sender:" field is inserted with the email-self
** address. Downstream software might use the Sender header to set
** the envelope-from address of the email. If zFromName is a NULL pointer,
** then the "From:" is set to the email-self value and Sender is
** omitted.
*/
void alert_send(
AlertSender *p, /* Emailer context */
Blob *pHdr, /* Email header (incomplete) */
Blob *pBody, /* Email body */
|
|
|
|
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
|
** From:
** Date:
** Message-Id:
** Content-Type:
** Content-Transfer-Encoding:
** MIME-Version:
** Sender:
**
** 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.
**
** The Message-Id: field is added if there is not already a Message-Id
** in the pHdr parameter.
**
** 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 "Sender:" field is inserted with the email-self
** address. Downstream software might use the Sender header to set
** the envelope-from address of the email. If zFromName is a NULL pointer,
** then the "From:" is set to the email-self value and Sender is
** omitted.
*/
void alert_send(
AlertSender *p, /* Emailer context */
Blob *pHdr, /* Email header (incomplete) */
Blob *pBody, /* Email body */
|
| ︙ | | | ︙ | |
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
|
** the basename for hyperlinks included in email alert text.
** Omit the trailing "/". If the repository is not intended to be
** a long-running server and will not be sending email notifications,
** then leave this setting blank.
*/
/*
** SETTING: email-admin width=40
** This is the email address for the human administrator for the system.
** Abuse and trouble reports and password reset requests are send here.
*/
/*
** SETTING: email-subname width=16
** This is a short name used to identifies the repository in the Subject:
** line of email alerts. Traditionally this name is included in square
** brackets. Examples: "[fossil-src]", "[sqlite-src]".
|
|
|
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
|
** the basename for hyperlinks included in email alert text.
** Omit the trailing "/". If the repository is not intended to be
** a long-running server and will not be sending email notifications,
** then leave this setting blank.
*/
/*
** SETTING: email-admin width=40
** This is the email address for the human administrator for the system.
** Abuse and trouble reports and password reset requests are send here.
*/
/*
** SETTING: email-subname width=16
** This is a short name used to identifies the repository in the Subject:
** line of email alerts. Traditionally this name is included in square
** brackets. Examples: "[fossil-src]", "[sqlite-src]".
|
| ︙ | | | ︙ | |
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
|
** a subscription is less than email-renew-cutoff, then now new emails
** are sent to the subscriber.
**
** email-renew-warning is the time (in days since 1970-01-01) when the
** last batch of "your subscription is about to expire" emails were
** sent out.
**
** email-renew-cutoff is normally 7 days behind email-renew-warning.
*/
/*
** SETTING: email-send-method width=5 default=off sensitive
** Determine the method used to send email. Allowed values are
** "off", "relay", "pipe", "dir", "db", and "stdout". The "off" value
** means no email is ever sent. The "relay" value means emails are sent
** to an Mail Sending Agent using SMTP located at email-send-relayhost.
** The "pipe" value means email messages are piped into a command
** determined by the email-send-command setting. The "dir" value means
** emails are written to individual files in a directory determined
** by the email-send-dir setting. The "db" value means that emails
** are added to an SQLite database named by the* email-send-db setting.
** The "stdout" value writes email text to standard output, for debugging.
*/
/*
|
|
|
|
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
|
** a subscription is less than email-renew-cutoff, then now new emails
** are sent to the subscriber.
**
** email-renew-warning is the time (in days since 1970-01-01) when the
** last batch of "your subscription is about to expire" emails were
** sent out.
**
** email-renew-cutoff is normally 7 days behind email-renew-warning.
*/
/*
** SETTING: email-send-method width=5 default=off sensitive
** Determine the method used to send email. Allowed values are
** "off", "relay", "pipe", "dir", "db", and "stdout". The "off" value
** means no email is ever sent. The "relay" value means emails are sent
** to an Mail Sending Agent using SMTP located at email-send-relayhost.
** The "pipe" value means email messages are piped into a command
** determined by the email-send-command setting. The "dir" value means
** emails are written to individual files in a directory determined
** by the email-send-dir setting. The "db" value means that emails
** are added to an SQLite database named by the* email-send-db setting.
** The "stdout" value writes email text to standard output, for debugging.
*/
/*
|
| ︙ | | | ︙ | |
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
|
** SMTP server configured as a Mail Submission Agent listening on the
** designated host and port and all times.
*/
/*
** COMMAND: alerts*
**
** Usage: %fossil alerts SUBCOMMAND ARGS...
**
** Subcommands:
**
** pending Show all pending alerts. Useful for debugging.
**
** reset Hard reset of all email notification tables
|
|
|
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
|
** SMTP server configured as a Mail Submission Agent listening on the
** designated host and port and all times.
*/
/*
** COMMAND: alerts*
**
** Usage: %fossil alerts SUBCOMMAND ARGS...
**
** Subcommands:
**
** pending Show all pending alerts. Useful for debugging.
**
** reset Hard reset of all email notification tables
|
| ︙ | | | ︙ | |
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
|
uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zLogin);
}
style_set_current_feature("alerts");
if( zEmail==0 ){
style_header("Unsubscribe Fail");
@ <p>Unable to locate a subscriber with the requested key</p>
}else{
db_multi_exec(
"DELETE FROM subscriber WHERE subscriberId=%d", sid
);
style_header("Unsubscribed");
@ <p>The "%h(zEmail)" email address has been unsubscribed from all
@ notifications. All subscription records for "%h(zEmail)" have
@ been purged. No further emails will be sent to "%h(zEmail)".</p>
|
<
|
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
|
uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zLogin);
}
style_set_current_feature("alerts");
if( zEmail==0 ){
style_header("Unsubscribe Fail");
@ <p>Unable to locate a subscriber with the requested key</p>
}else{
db_multi_exec(
"DELETE FROM subscriber WHERE subscriberId=%d", sid
);
style_header("Unsubscribed");
@ <p>The "%h(zEmail)" email address has been unsubscribed from all
@ notifications. All subscription records for "%h(zEmail)" have
@ been purged. No further emails will be sent to "%h(zEmail)".</p>
|
| ︙ | | | ︙ | |
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
|
** email and clicks on the link in the email. When a
** compilete subscriberCode is seen on the name= query parameter,
** that constitutes verification of the email address.
**
** * The sid= query parameter contains an integer subscriberId.
** This only works for the administrator. It allows the
** administrator to edit any subscription.
**
** * The user is logged into an account other than "nobody" or
** "anonymous". In that case the notification settings
** associated with that account can be edited without needing
** to know the subscriber code.
**
** * The name= query parameter contains a 32-digit prefix of
** subscriber code. (Subscriber codes are normally 64 hex digits
|
|
|
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
|
** email and clicks on the link in the email. When a
** compilete subscriberCode is seen on the name= query parameter,
** that constitutes verification of the email address.
**
** * The sid= query parameter contains an integer subscriberId.
** This only works for the administrator. It allows the
** administrator to edit any subscription.
**
** * The user is logged into an account other than "nobody" or
** "anonymous". In that case the notification settings
** associated with that account can be edited without needing
** to know the subscriber code.
**
** * The name= query parameter contains a 32-digit prefix of
** subscriber code. (Subscriber codes are normally 64 hex digits
|
| ︙ | | | ︙ | |
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
|
if( !PB("dodelete") ){
eErr = 9;
zErr = mprintf("Select this checkbox and press \"Unsubscribe\" again to"
" unsubscribe");
}else{
alert_unsubscribe(sid);
db_commit_transaction();
return;
}
}
style_set_current_feature("alerts");
style_header("Update Subscription");
db_prepare(&q,
"SELECT"
" semail," /* 0 */
|
|
|
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
|
if( !PB("dodelete") ){
eErr = 9;
zErr = mprintf("Select this checkbox and press \"Unsubscribe\" again to"
" unsubscribe");
}else{
alert_unsubscribe(sid);
db_commit_transaction();
return;
}
}
style_set_current_feature("alerts");
style_header("Update Subscription");
db_prepare(&q,
"SELECT"
" semail," /* 0 */
|
| ︙ | | | ︙ | |
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
|
style_finish_page();
}
/* This is the message that gets sent to describe how to change
** or modify a subscription
*/
static const char zUnsubMsg[] =
@ To changes your subscription settings at %s visit this link:
@
@ %s/alerts/%s
@
@ To completely unsubscribe from %s, visit the following link:
@
@ %s/unsubscribe/%s
|
|
|
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
|
style_finish_page();
}
/* This is the message that gets sent to describe how to change
** or modify a subscription
*/
static const char zUnsubMsg[] =
@ To changes your subscription settings at %s visit this link:
@
@ %s/alerts/%s
@
@ To completely unsubscribe from %s, visit the following link:
@
@ %s/unsubscribe/%s
|
| ︙ | | | ︙ | |
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
|
const char *zEAddr;
char *zCode = 0;
int sid = 0;
if( zName==0 ) zName = P("scode");
/* If a valid subscriber code is supplied, then either present the user
** with a comformation, or if already confirmed, unsubscribe immediately.
*/
if( zName
&& (sid = db_int(0, "SELECT subscriberId FROM subscriber"
" WHERE subscriberCode=hextoblob(%Q)", zName))!=0
){
char *zUnsubName = mprintf("confirm%04x", sid);
if( P(zUnsubName)!=0 ){
alert_unsubscribe(sid);
}else if( P("manage")!=0 ){
|
|
|
|
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
|
const char *zEAddr;
char *zCode = 0;
int sid = 0;
if( zName==0 ) zName = P("scode");
/* If a valid subscriber code is supplied, then either present the user
** with a confirmation, or if already confirmed, unsubscribe immediately.
*/
if( zName
&& (sid = db_int(0, "SELECT subscriberId FROM subscriber"
" WHERE subscriberCode=hextoblob(%Q)", zName))!=0
){
char *zUnsubName = mprintf("confirm%04x", sid);
if( P(zUnsubName)!=0 ){
alert_unsubscribe(sid);
}else if( P("manage")!=0 ){
|
| ︙ | | | ︙ | |
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
|
}else{
@ <p>An email has been sent to "%h(zEAddr)" that explains how to
@ unsubscribe and/or modify your subscription settings</p>
}
alert_sender_free(pSender);
style_finish_page();
return;
}
/* Non-logged-in users have to enter an email address to which is
** sent a message containing the unsubscribe link.
*/
style_header("Unsubscribe Request");
@ <p>Fill out the form below to request an email message that will
@ explain how to unsubscribe and/or change your subscription settings.</p>
|
|
|
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
|
}else{
@ <p>An email has been sent to "%h(zEAddr)" that explains how to
@ unsubscribe and/or modify your subscription settings</p>
}
alert_sender_free(pSender);
style_finish_page();
return;
}
/* Non-logged-in users have to enter an email address to which is
** sent a message containing the unsubscribe link.
*/
style_header("Unsubscribe Request");
@ <p>Fill out the form below to request an email message that will
@ explain how to unsubscribe and/or change your subscription settings.</p>
|
| ︙ | | | ︙ | |
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
|
zUuid = db_column_text(&q, 1);
zTitle = db_column_text(&q, 3);
if( p->needMod ){
blob_appendf(&p->hdr, "Subject: %s Pending Moderation: %s\r\n",
zSub, zTitle);
}else{
blob_appendf(&p->hdr, "Subject: %s %s\r\n", zSub, zTitle);
blob_appendf(&p->hdr, "Message-Id: <%.32s@%s>\r\n",
zUuid, alert_hostname(zFrom));
zIrt = db_column_text(&q, 4);
if( zIrt && zIrt[0] ){
blob_appendf(&p->hdr, "In-Reply-To: <%.32s@%s>\r\n",
zIrt, alert_hostname(zFrom));
}
}
|
|
|
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
|
zUuid = db_column_text(&q, 1);
zTitle = db_column_text(&q, 3);
if( p->needMod ){
blob_appendf(&p->hdr, "Subject: %s Pending Moderation: %s\r\n",
zSub, zTitle);
}else{
blob_appendf(&p->hdr, "Subject: %s %s\r\n", zSub, zTitle);
blob_appendf(&p->hdr, "Message-Id: <%.32s@%s>\r\n",
zUuid, alert_hostname(zFrom));
zIrt = db_column_text(&q, 4);
if( zIrt && zIrt[0] ){
blob_appendf(&p->hdr, "In-Reply-To: <%.32s@%s>\r\n",
zIrt, alert_hostname(zFrom));
}
}
|
| ︙ | | | ︙ | |
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
|
" AND length(sdigest)>0",
iNewWarn, iOldWarn
);
while( db_step(&q)==SQLITE_ROW ){
Blob hdr, body;
blob_init(&hdr, 0, 0);
blob_init(&body, 0, 0);
alert_renewal_msg(&hdr, &body,
db_column_text(&q,0),
db_column_int(&q,1),
db_column_text(&q,2),
db_column_text(&q,3),
zRepoName, zUrl);
alert_send(pSender,&hdr,&body,0);
blob_reset(&hdr);
|
|
|
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
|
" AND length(sdigest)>0",
iNewWarn, iOldWarn
);
while( db_step(&q)==SQLITE_ROW ){
Blob hdr, body;
blob_init(&hdr, 0, 0);
blob_init(&body, 0, 0);
alert_renewal_msg(&hdr, &body,
db_column_text(&q,0),
db_column_int(&q,1),
db_column_text(&q,2),
db_column_text(&q,3),
zRepoName, zUrl);
alert_send(pSender,&hdr,&body,0);
blob_reset(&hdr);
|
| ︙ | | | ︙ | |
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
|
style_set_current_feature("alerts");
if( zAdminEmail==0 || zAdminEmail[0]==0 ){
style_header("Outbound Email Disabled");
@ <p>Outbound email is disabled on this repository
style_finish_page();
return;
}
if( P("submit")!=0
&& P("subject")!=0
&& P("msg")!=0
&& P("from")!=0
&& cgi_csrf_safe(2)
&& captcha_is_correct(0)
){
Blob hdr, body;
|
|
|
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
|
style_set_current_feature("alerts");
if( zAdminEmail==0 || zAdminEmail[0]==0 ){
style_header("Outbound Email Disabled");
@ <p>Outbound email is disabled on this repository
style_finish_page();
return;
}
if( P("submit")!=0
&& P("subject")!=0
&& P("msg")!=0
&& P("from")!=0
&& cgi_csrf_safe(2)
&& captcha_is_correct(0)
){
Blob hdr, body;
|
| ︙ | | | ︙ | |