Fossil SCM
Enhance the /register page so that it also does email subscriptions if that is enabled for self-registered users.
Commit
2e308280444314cc181e8fb3cc90fedecdcfd2b98d313d608a5b73e53e554b56
Parent
bc303c0ec006ab3…
2 files changed
+10
-2
+78
-2
+10
-2
| --- src/email.c | ||
| +++ src/email.c | ||
| @@ -1104,10 +1104,19 @@ | ||
| 1104 | 1104 | @ |
| 1105 | 1105 | @ If you do not want to subscribe, you can simply ignore this message. |
| 1106 | 1106 | @ You will not be contacted again. |
| 1107 | 1107 | @ |
| 1108 | 1108 | ; |
| 1109 | + | |
| 1110 | +/* | |
| 1111 | +** Append the text of an email confirmation message to the given | |
| 1112 | +** Blob. The security code is in zCode. | |
| 1113 | +*/ | |
| 1114 | +void email_append_confirmation_message(Blob *pMsg, const char *zCode){ | |
| 1115 | + blob_appendf(pMsg, zConfirmMsg/*works-like:"%s%s%s"*/, | |
| 1116 | + g.zBaseURL, g.zBaseURL, zCode); | |
| 1117 | +} | |
| 1109 | 1118 | |
| 1110 | 1119 | /* |
| 1111 | 1120 | ** WEBPAGE: subscribe |
| 1112 | 1121 | ** |
| 1113 | 1122 | ** Allow users to subscribe to email notifications. |
| @@ -1206,12 +1215,11 @@ | ||
| 1206 | 1215 | EmailSender *pSender = email_sender_new(0,0); |
| 1207 | 1216 | blob_init(&hdr,0,0); |
| 1208 | 1217 | blob_init(&body,0,0); |
| 1209 | 1218 | blob_appendf(&hdr, "To: <%s>\n", zEAddr); |
| 1210 | 1219 | blob_appendf(&hdr, "Subject: Subscription verification\n"); |
| 1211 | - blob_appendf(&body, zConfirmMsg/*works-like:"%s%s%s"*/, | |
| 1212 | - g.zBaseURL, g.zBaseURL, zCode); | |
| 1220 | + email_append_confirmation_message(&body, zCode); | |
| 1213 | 1221 | email_send(pSender, &hdr, &body); |
| 1214 | 1222 | style_header("Email Alert Verification"); |
| 1215 | 1223 | if( pSender->zErr ){ |
| 1216 | 1224 | @ <h1>Internal Error</h1> |
| 1217 | 1225 | @ <p>The following internal error was encountered while trying |
| 1218 | 1226 |
| --- src/email.c | |
| +++ src/email.c | |
| @@ -1104,10 +1104,19 @@ | |
| 1104 | @ |
| 1105 | @ If you do not want to subscribe, you can simply ignore this message. |
| 1106 | @ You will not be contacted again. |
| 1107 | @ |
| 1108 | ; |
| 1109 | |
| 1110 | /* |
| 1111 | ** WEBPAGE: subscribe |
| 1112 | ** |
| 1113 | ** Allow users to subscribe to email notifications. |
| @@ -1206,12 +1215,11 @@ | |
| 1206 | EmailSender *pSender = email_sender_new(0,0); |
| 1207 | blob_init(&hdr,0,0); |
| 1208 | blob_init(&body,0,0); |
| 1209 | blob_appendf(&hdr, "To: <%s>\n", zEAddr); |
| 1210 | blob_appendf(&hdr, "Subject: Subscription verification\n"); |
| 1211 | blob_appendf(&body, zConfirmMsg/*works-like:"%s%s%s"*/, |
| 1212 | g.zBaseURL, g.zBaseURL, zCode); |
| 1213 | email_send(pSender, &hdr, &body); |
| 1214 | style_header("Email Alert Verification"); |
| 1215 | if( pSender->zErr ){ |
| 1216 | @ <h1>Internal Error</h1> |
| 1217 | @ <p>The following internal error was encountered while trying |
| 1218 |
| --- src/email.c | |
| +++ src/email.c | |
| @@ -1104,10 +1104,19 @@ | |
| 1104 | @ |
| 1105 | @ If you do not want to subscribe, you can simply ignore this message. |
| 1106 | @ You will not be contacted again. |
| 1107 | @ |
| 1108 | ; |
| 1109 | |
| 1110 | /* |
| 1111 | ** Append the text of an email confirmation message to the given |
| 1112 | ** Blob. The security code is in zCode. |
| 1113 | */ |
| 1114 | void email_append_confirmation_message(Blob *pMsg, const char *zCode){ |
| 1115 | blob_appendf(pMsg, zConfirmMsg/*works-like:"%s%s%s"*/, |
| 1116 | g.zBaseURL, g.zBaseURL, zCode); |
| 1117 | } |
| 1118 | |
| 1119 | /* |
| 1120 | ** WEBPAGE: subscribe |
| 1121 | ** |
| 1122 | ** Allow users to subscribe to email notifications. |
| @@ -1206,12 +1215,11 @@ | |
| 1215 | EmailSender *pSender = email_sender_new(0,0); |
| 1216 | blob_init(&hdr,0,0); |
| 1217 | blob_init(&body,0,0); |
| 1218 | blob_appendf(&hdr, "To: <%s>\n", zEAddr); |
| 1219 | blob_appendf(&hdr, "Subject: Subscription verification\n"); |
| 1220 | email_append_confirmation_message(&body, zCode); |
| 1221 | email_send(pSender, &hdr, &body); |
| 1222 | style_header("Email Alert Verification"); |
| 1223 | if( pSender->zErr ){ |
| 1224 | @ <h1>Internal Error</h1> |
| 1225 | @ <p>The following internal error was encountered while trying |
| 1226 |
+78
-2
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -1496,19 +1496,27 @@ | ||
| 1496 | 1496 | unsigned int uSeed; |
| 1497 | 1497 | const char *zDecoded; |
| 1498 | 1498 | char *zCaptcha; |
| 1499 | 1499 | int iErrLine = -1; |
| 1500 | 1500 | const char *zErr = 0; |
| 1501 | + char *zPerms; /* Permissions for the default user */ | |
| 1502 | + int canDoAlerts = 0; /* True if receiving email alerts is possible */ | |
| 1501 | 1503 | if( !db_get_boolean("self-register", 0) ){ |
| 1502 | 1504 | style_header("Registration not possible"); |
| 1503 | 1505 | @ <p>This project does not allow user self-registration. Please contact the |
| 1504 | 1506 | @ project administrator to obtain an account.</p> |
| 1505 | 1507 | style_footer(); |
| 1506 | 1508 | return; |
| 1507 | 1509 | } |
| 1510 | + zPerms = db_get("default-perms","u"); | |
| 1508 | 1511 | |
| 1509 | - style_header("Register"); | |
| 1512 | + /* Prompt the user for email alerts if this repository is configured for | |
| 1513 | + ** email alerts and if the default permissions include "7" */ | |
| 1514 | + canDoAlerts = email_tables_exist() && db_int(0, | |
| 1515 | + "SELECT fullcap(%Q) GLOB '*7*'", zPerms | |
| 1516 | + ); | |
| 1517 | + | |
| 1510 | 1518 | zUserID = PDT("u",""); |
| 1511 | 1519 | zPasswd = PDT("p",""); |
| 1512 | 1520 | zConfirm = PDT("cp",""); |
| 1513 | 1521 | zEAddr = PDT("ea",""); |
| 1514 | 1522 | zDName = PDT("dn",""); |
| @@ -1554,23 +1562,82 @@ | ||
| 1554 | 1562 | blob_init(&sql, 0, 0); |
| 1555 | 1563 | blob_append_sql(&sql, |
| 1556 | 1564 | "INSERT INTO user(login,pw,cap,info,mtime)\n" |
| 1557 | 1565 | "VALUES(%Q,%Q,%Q," |
| 1558 | 1566 | "'%q <%q>\nself-register from ip %q on '||datetime('now'),now())", |
| 1559 | - zUserID, zPass, db_get("default-perms","u"), zDName, zEAddr, g.zIpAddr); | |
| 1567 | + zUserID, zPass, zPerms, zDName, zEAddr, g.zIpAddr); | |
| 1560 | 1568 | fossil_free(zPass); |
| 1561 | 1569 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1562 | 1570 | uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUserID); |
| 1563 | 1571 | login_set_user_cookie(zUserID, uid, NULL); |
| 1572 | + if( canDoAlerts && atoi(PD("alerts","1"))!=0 ){ | |
| 1573 | + /* Also make the new user a subscriber. */ | |
| 1574 | + Blob hdr, body; | |
| 1575 | + EmailSender *pSender; | |
| 1576 | + sqlite3_int64 id; /* New subscriber Id */ | |
| 1577 | + const char *zCode; /* New subscriber code (in hex) */ | |
| 1578 | + const char *zGoto = P("g"); | |
| 1579 | + int nsub = 0; | |
| 1580 | + char ssub[20]; | |
| 1581 | + ssub[nsub++] = 'a'; | |
| 1582 | + if( g.perm.Read ) ssub[nsub++] = 'c'; | |
| 1583 | + if( g.perm.RdForum ) ssub[nsub++] = 'f'; | |
| 1584 | + if( g.perm.RdTkt ) ssub[nsub++] = 't'; | |
| 1585 | + if( g.perm.RdWiki ) ssub[nsub++] = 'w'; | |
| 1586 | + ssub[nsub] = 0; | |
| 1587 | + db_multi_exec( | |
| 1588 | + "INSERT INTO subscriber(semail,suname," | |
| 1589 | + " sverified,sdonotcall,sdigest,ssub,sctime,mtime,smip)" | |
| 1590 | + "VALUES(%Q,%Q,%d,0,%d,%Q,now(),now(),%Q)", | |
| 1591 | + /* semail */ zEAddr, | |
| 1592 | + /* suname */ zUserID, | |
| 1593 | + /* sverified */ 0, | |
| 1594 | + /* sdigest */ 0, | |
| 1595 | + /* ssub */ ssub, | |
| 1596 | + /* smip */ g.zIpAddr | |
| 1597 | + ); | |
| 1598 | + id = db_last_insert_rowid(); | |
| 1599 | + zCode = db_text(0, | |
| 1600 | + "SELECT hex(subscriberCode) FROM subscriber WHERE subscriberId=%lld", | |
| 1601 | + id); | |
| 1602 | + /* A verification email */ | |
| 1603 | + pSender = email_sender_new(0,0); | |
| 1604 | + blob_init(&hdr,0,0); | |
| 1605 | + blob_init(&body,0,0); | |
| 1606 | + blob_appendf(&hdr, "To: <%s>\n", zEAddr); | |
| 1607 | + blob_appendf(&hdr, "Subject: Subscription verification\n"); | |
| 1608 | + email_append_confirmation_message(&body, zCode); | |
| 1609 | + email_send(pSender, &hdr, &body); | |
| 1610 | + style_header("Email Verification"); | |
| 1611 | + if( pSender->zErr ){ | |
| 1612 | + @ <h1>Internal Error</h1> | |
| 1613 | + @ <p>The following internal error was encountered while trying | |
| 1614 | + @ to send the confirmation email: | |
| 1615 | + @ <blockquote><pre> | |
| 1616 | + @ %h(pSender->zErr) | |
| 1617 | + @ </pre></blockquote> | |
| 1618 | + }else{ | |
| 1619 | + @ <p>An email has been sent to "%h(zEAddr)". That email contains a | |
| 1620 | + @ hyperlink that you must click on in order to activate your | |
| 1621 | + @ subscription.</p> | |
| 1622 | + } | |
| 1623 | + email_sender_free(pSender); | |
| 1624 | + if( zGoto ){ | |
| 1625 | + @ <p><a href='%h(zGoto)'>Continue</a> | |
| 1626 | + } | |
| 1627 | + style_footer(); | |
| 1628 | + return; | |
| 1629 | + } | |
| 1564 | 1630 | redirect_to_g(); |
| 1565 | 1631 | } |
| 1566 | 1632 | |
| 1567 | 1633 | /* Prepare the captcha. */ |
| 1568 | 1634 | uSeed = captcha_seed(); |
| 1569 | 1635 | zDecoded = captcha_decode(uSeed); |
| 1570 | 1636 | zCaptcha = captcha_render(zDecoded); |
| 1571 | 1637 | |
| 1638 | + style_header("Register"); | |
| 1572 | 1639 | /* Print out the registration form. */ |
| 1573 | 1640 | form_begin(0, "%R/register"); |
| 1574 | 1641 | if( P("g") ){ |
| 1575 | 1642 | @ <input type="hidden" name="g" value="%h(P("g"))" /> |
| 1576 | 1643 | } |
| @@ -1595,10 +1662,19 @@ | ||
| 1595 | 1662 | @ <td><input type="text" name="ea" value="%h(zEAddr)" size="30"></td> |
| 1596 | 1663 | if( iErrLine==3 ){ |
| 1597 | 1664 | @ <td><span class='loginError'>← %h(zErr)</span></td> |
| 1598 | 1665 | } |
| 1599 | 1666 | @ </tr> |
| 1667 | + if( canDoAlerts ){ | |
| 1668 | + int a = atoi(PD("alerts","1")); | |
| 1669 | + @ <tr> | |
| 1670 | + @ <td class="form_label" align="right">Receive Email Alerts?</td> | |
| 1671 | + @ <td><select size='1' name='alerts'> | |
| 1672 | + @ <option value="1" %s(a?"selected":"")>Yes</option> | |
| 1673 | + @ <option value="0" %s(!a?"selected":"")>No</option> | |
| 1674 | + @ </select></td></tr> | |
| 1675 | + } | |
| 1600 | 1676 | @ <tr> |
| 1601 | 1677 | @ <td class="form_label" align="right">Password:</td> |
| 1602 | 1678 | @ <td><input type="password" name="p" value="%h(zPasswd)" size="30"></td> |
| 1603 | 1679 | if( iErrLine==4 ){ |
| 1604 | 1680 | @ <td><span class='loginError'>← %h(zErr)</span></td> |
| 1605 | 1681 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -1496,19 +1496,27 @@ | |
| 1496 | unsigned int uSeed; |
| 1497 | const char *zDecoded; |
| 1498 | char *zCaptcha; |
| 1499 | int iErrLine = -1; |
| 1500 | const char *zErr = 0; |
| 1501 | if( !db_get_boolean("self-register", 0) ){ |
| 1502 | style_header("Registration not possible"); |
| 1503 | @ <p>This project does not allow user self-registration. Please contact the |
| 1504 | @ project administrator to obtain an account.</p> |
| 1505 | style_footer(); |
| 1506 | return; |
| 1507 | } |
| 1508 | |
| 1509 | style_header("Register"); |
| 1510 | zUserID = PDT("u",""); |
| 1511 | zPasswd = PDT("p",""); |
| 1512 | zConfirm = PDT("cp",""); |
| 1513 | zEAddr = PDT("ea",""); |
| 1514 | zDName = PDT("dn",""); |
| @@ -1554,23 +1562,82 @@ | |
| 1554 | blob_init(&sql, 0, 0); |
| 1555 | blob_append_sql(&sql, |
| 1556 | "INSERT INTO user(login,pw,cap,info,mtime)\n" |
| 1557 | "VALUES(%Q,%Q,%Q," |
| 1558 | "'%q <%q>\nself-register from ip %q on '||datetime('now'),now())", |
| 1559 | zUserID, zPass, db_get("default-perms","u"), zDName, zEAddr, g.zIpAddr); |
| 1560 | fossil_free(zPass); |
| 1561 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1562 | uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUserID); |
| 1563 | login_set_user_cookie(zUserID, uid, NULL); |
| 1564 | redirect_to_g(); |
| 1565 | } |
| 1566 | |
| 1567 | /* Prepare the captcha. */ |
| 1568 | uSeed = captcha_seed(); |
| 1569 | zDecoded = captcha_decode(uSeed); |
| 1570 | zCaptcha = captcha_render(zDecoded); |
| 1571 | |
| 1572 | /* Print out the registration form. */ |
| 1573 | form_begin(0, "%R/register"); |
| 1574 | if( P("g") ){ |
| 1575 | @ <input type="hidden" name="g" value="%h(P("g"))" /> |
| 1576 | } |
| @@ -1595,10 +1662,19 @@ | |
| 1595 | @ <td><input type="text" name="ea" value="%h(zEAddr)" size="30"></td> |
| 1596 | if( iErrLine==3 ){ |
| 1597 | @ <td><span class='loginError'>← %h(zErr)</span></td> |
| 1598 | } |
| 1599 | @ </tr> |
| 1600 | @ <tr> |
| 1601 | @ <td class="form_label" align="right">Password:</td> |
| 1602 | @ <td><input type="password" name="p" value="%h(zPasswd)" size="30"></td> |
| 1603 | if( iErrLine==4 ){ |
| 1604 | @ <td><span class='loginError'>← %h(zErr)</span></td> |
| 1605 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -1496,19 +1496,27 @@ | |
| 1496 | unsigned int uSeed; |
| 1497 | const char *zDecoded; |
| 1498 | char *zCaptcha; |
| 1499 | int iErrLine = -1; |
| 1500 | const char *zErr = 0; |
| 1501 | char *zPerms; /* Permissions for the default user */ |
| 1502 | int canDoAlerts = 0; /* True if receiving email alerts is possible */ |
| 1503 | if( !db_get_boolean("self-register", 0) ){ |
| 1504 | style_header("Registration not possible"); |
| 1505 | @ <p>This project does not allow user self-registration. Please contact the |
| 1506 | @ project administrator to obtain an account.</p> |
| 1507 | style_footer(); |
| 1508 | return; |
| 1509 | } |
| 1510 | zPerms = db_get("default-perms","u"); |
| 1511 | |
| 1512 | /* Prompt the user for email alerts if this repository is configured for |
| 1513 | ** email alerts and if the default permissions include "7" */ |
| 1514 | canDoAlerts = email_tables_exist() && db_int(0, |
| 1515 | "SELECT fullcap(%Q) GLOB '*7*'", zPerms |
| 1516 | ); |
| 1517 | |
| 1518 | zUserID = PDT("u",""); |
| 1519 | zPasswd = PDT("p",""); |
| 1520 | zConfirm = PDT("cp",""); |
| 1521 | zEAddr = PDT("ea",""); |
| 1522 | zDName = PDT("dn",""); |
| @@ -1554,23 +1562,82 @@ | |
| 1562 | blob_init(&sql, 0, 0); |
| 1563 | blob_append_sql(&sql, |
| 1564 | "INSERT INTO user(login,pw,cap,info,mtime)\n" |
| 1565 | "VALUES(%Q,%Q,%Q," |
| 1566 | "'%q <%q>\nself-register from ip %q on '||datetime('now'),now())", |
| 1567 | zUserID, zPass, zPerms, zDName, zEAddr, g.zIpAddr); |
| 1568 | fossil_free(zPass); |
| 1569 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1570 | uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUserID); |
| 1571 | login_set_user_cookie(zUserID, uid, NULL); |
| 1572 | if( canDoAlerts && atoi(PD("alerts","1"))!=0 ){ |
| 1573 | /* Also make the new user a subscriber. */ |
| 1574 | Blob hdr, body; |
| 1575 | EmailSender *pSender; |
| 1576 | sqlite3_int64 id; /* New subscriber Id */ |
| 1577 | const char *zCode; /* New subscriber code (in hex) */ |
| 1578 | const char *zGoto = P("g"); |
| 1579 | int nsub = 0; |
| 1580 | char ssub[20]; |
| 1581 | ssub[nsub++] = 'a'; |
| 1582 | if( g.perm.Read ) ssub[nsub++] = 'c'; |
| 1583 | if( g.perm.RdForum ) ssub[nsub++] = 'f'; |
| 1584 | if( g.perm.RdTkt ) ssub[nsub++] = 't'; |
| 1585 | if( g.perm.RdWiki ) ssub[nsub++] = 'w'; |
| 1586 | ssub[nsub] = 0; |
| 1587 | db_multi_exec( |
| 1588 | "INSERT INTO subscriber(semail,suname," |
| 1589 | " sverified,sdonotcall,sdigest,ssub,sctime,mtime,smip)" |
| 1590 | "VALUES(%Q,%Q,%d,0,%d,%Q,now(),now(),%Q)", |
| 1591 | /* semail */ zEAddr, |
| 1592 | /* suname */ zUserID, |
| 1593 | /* sverified */ 0, |
| 1594 | /* sdigest */ 0, |
| 1595 | /* ssub */ ssub, |
| 1596 | /* smip */ g.zIpAddr |
| 1597 | ); |
| 1598 | id = db_last_insert_rowid(); |
| 1599 | zCode = db_text(0, |
| 1600 | "SELECT hex(subscriberCode) FROM subscriber WHERE subscriberId=%lld", |
| 1601 | id); |
| 1602 | /* A verification email */ |
| 1603 | pSender = email_sender_new(0,0); |
| 1604 | blob_init(&hdr,0,0); |
| 1605 | blob_init(&body,0,0); |
| 1606 | blob_appendf(&hdr, "To: <%s>\n", zEAddr); |
| 1607 | blob_appendf(&hdr, "Subject: Subscription verification\n"); |
| 1608 | email_append_confirmation_message(&body, zCode); |
| 1609 | email_send(pSender, &hdr, &body); |
| 1610 | style_header("Email Verification"); |
| 1611 | if( pSender->zErr ){ |
| 1612 | @ <h1>Internal Error</h1> |
| 1613 | @ <p>The following internal error was encountered while trying |
| 1614 | @ to send the confirmation email: |
| 1615 | @ <blockquote><pre> |
| 1616 | @ %h(pSender->zErr) |
| 1617 | @ </pre></blockquote> |
| 1618 | }else{ |
| 1619 | @ <p>An email has been sent to "%h(zEAddr)". That email contains a |
| 1620 | @ hyperlink that you must click on in order to activate your |
| 1621 | @ subscription.</p> |
| 1622 | } |
| 1623 | email_sender_free(pSender); |
| 1624 | if( zGoto ){ |
| 1625 | @ <p><a href='%h(zGoto)'>Continue</a> |
| 1626 | } |
| 1627 | style_footer(); |
| 1628 | return; |
| 1629 | } |
| 1630 | redirect_to_g(); |
| 1631 | } |
| 1632 | |
| 1633 | /* Prepare the captcha. */ |
| 1634 | uSeed = captcha_seed(); |
| 1635 | zDecoded = captcha_decode(uSeed); |
| 1636 | zCaptcha = captcha_render(zDecoded); |
| 1637 | |
| 1638 | style_header("Register"); |
| 1639 | /* Print out the registration form. */ |
| 1640 | form_begin(0, "%R/register"); |
| 1641 | if( P("g") ){ |
| 1642 | @ <input type="hidden" name="g" value="%h(P("g"))" /> |
| 1643 | } |
| @@ -1595,10 +1662,19 @@ | |
| 1662 | @ <td><input type="text" name="ea" value="%h(zEAddr)" size="30"></td> |
| 1663 | if( iErrLine==3 ){ |
| 1664 | @ <td><span class='loginError'>← %h(zErr)</span></td> |
| 1665 | } |
| 1666 | @ </tr> |
| 1667 | if( canDoAlerts ){ |
| 1668 | int a = atoi(PD("alerts","1")); |
| 1669 | @ <tr> |
| 1670 | @ <td class="form_label" align="right">Receive Email Alerts?</td> |
| 1671 | @ <td><select size='1' name='alerts'> |
| 1672 | @ <option value="1" %s(a?"selected":"")>Yes</option> |
| 1673 | @ <option value="0" %s(!a?"selected":"")>No</option> |
| 1674 | @ </select></td></tr> |
| 1675 | } |
| 1676 | @ <tr> |
| 1677 | @ <td class="form_label" align="right">Password:</td> |
| 1678 | @ <td><input type="password" name="p" value="%h(zPasswd)" size="30"></td> |
| 1679 | if( iErrLine==4 ){ |
| 1680 | @ <td><span class='loginError'>← %h(zErr)</span></td> |
| 1681 |