}
+// Generate a pre-authorized subscribe/unsubscribe URL for a particular email address for a particular room.
+// This can be used as the second part of a double-opt-in or double-opt-out process.
+// It can also be used to generate a "one click unsubscribe" link.
+void generate_one_click_url(char *target_buf, char *base_url, char *action, char *roomname, char *emailaddr) {
+
+ // We need a URL-safe representation of the room name
+ char encoded_roomname[ROOMNAMELEN+10];
+ urlesc(encoded_roomname, sizeof(encoded_roomname), roomname);
+
+ // The confirmation token pre-authorizes the generated URL. It is hashed by the host key so it can't be guessed.
+ char confirmation_token[128];
+ generate_confirmation_token(confirmation_token, sizeof confirmation_token, roomname, emailaddr);
+
+ // Write to the buffer
+ snprintf(target_buf, SIZ, "%s?cmd=%s&email=%s&room=%s&token=%s",
+ base_url,
+ action,
+ emailaddr,
+ encoded_roomname,
+ confirmation_token
+ );
+}
+
+
// This generates an email with a link the user clicks to confirm a list subscription.
void send_subscribe_confirmation_email(char *roomname, char *emailaddr, char *url, char *confirmation_token) {
- // We need a URL-safe representation of the room name
- char urlroom[ROOMNAMELEN+10];
- urlesc(urlroom, sizeof(urlroom), roomname);
+
+ char confirm_subscribe_url[SIZ];
+ generate_one_click_url(confirm_subscribe_url, url, "confirm_subscribe", roomname, emailaddr);
char from_address[1024];
snprintf(from_address, sizeof from_address, "noreply@%s", CtdlGetConfigStr("c_fqdn"));
"<%s> to the <%s> mailing list.\n"
"\n"
"Please go here to confirm this request:\n"
- "%s?cmd=confirm_subscribe&email=%s&room=%s&token=%s\n"
+ "%s\n"
"\n"
"If this request has been submitted in error and you do not\n"
"wish to receive the <%s> mailing list, simply do nothing,\n"
"--__ctdlmultipart__\n"
"Content-type: text/html\n"
"\n"
- "<html><body><p>Someone (probably you) has submitted a request to subscribe "
- "<strong>%s</strong> to the <strong>%s</strong> mailing list.</p>"
- "<p>Please go here to confirm this request:</p>"
- "<p><a href=\"%s?cmd=confirm_subscribe&email=%s&room=%s&token=%s\">"
- "%s?cmd=confirm_subscribe&email=%s&room=%s&token=%s</a></p>"
- "<p>If this request has been submitted in error and you do not "
- "wish to receive the <strong>%s<strong> mailing list, simply do nothing, "
- "and you will not receive any further mailings.</p>"
+ "<html><body><p>Someone (probably you) has submitted a request to subscribe\n"
+ "<strong>%s</strong> to the <strong>%s</strong> mailing list.</p>\n"
+ "<p>Please go here to confirm this request:</p>\n"
+ "<p><a href=\"%s\">%s</a></p>\n"
+ "<p>If this request has been submitted in error and you do not\n"
+ "wish to receive the <strong>%s</strong> mailing list, simply do nothing,\n"
+ "and you will not receive any further mailings.</p>\n"
"</body></html>\n"
"\n"
"--__ctdlmultipart__--\n"
,
- emailaddr, roomname,
- url, emailaddr, urlroom, confirmation_token,
- roomname
- ,
- emailaddr, roomname,
- url, emailaddr, urlroom, confirmation_token,
- url, emailaddr, urlroom, confirmation_token,
- roomname
+ emailaddr, roomname, confirm_subscribe_url, roomname,
+ emailaddr, roomname, confirm_subscribe_url, confirm_subscribe_url, roomname
);
quickie_message("Citadel", from_address, emailaddr, NULL, emailtext, FMT_RFC822, "Please confirm your list subscription");
// This generates an email with a link the user clicks to confirm a list unsubscription.
void send_unsubscribe_confirmation_email(char *roomname, char *emailaddr, char *url, char *confirmation_token) {
- // We need a URL-safe representation of the room name
- char urlroom[ROOMNAMELEN+10];
- urlesc(urlroom, sizeof(urlroom), roomname);
+
+ char confirm_unsubscribe_url[SIZ];
+ generate_one_click_url(confirm_unsubscribe_url, url, "confirm_unsubscribe", roomname, emailaddr);
char from_address[1024];
snprintf(from_address, sizeof from_address, "noreply@%s", CtdlGetConfigStr("c_fqdn"));
"<%s> from the <%s> mailing list.\n"
"\n"
"Please go here to confirm this request:\n"
- "%s?cmd=confirm_unsubscribe&email=%s&room=%s&token=%s\n"
+ "%s\n"
"\n"
"If this request has been submitted in error and you still\n"
"wish to receive the <%s> mailing list, simply do nothing,\n"
"--__ctdlmultipart__\n"
"Content-type: text/html\n"
"\n"
- "<html><body><p>Someone (probably you) has submitted a request to unsubscribe "
- "<strong>%s</strong> from the <strong>%s</strong> mailing list.</p>"
- "<p>Please go here to confirm this request:</p>"
- "<p><a href=\"%s?cmd=confirm_unsubscribe&email=%s&room=%s&token=%s\">"
- "%s?cmd=confirm_unsubscribe&email=%s&room=%s&token=%s</a></p>"
- "<p>If this request has been submitted in error and you still "
- "wish to receive the <strong>%s<strong> mailing list, simply do nothing, "
- "and you will remain subscribed.</p>"
+ "<html><body><p>Someone (probably you) has submitted a request to unsubscribe\n"
+ "<strong>%s</strong> from the <strong>%s</strong> mailing list.</p>\n"
+ "<p>Please go here to confirm this request:</p>\n"
+ "<p><a href=\"%s\">%s</a></p>\n"
+ "<p>If this request has been submitted in error and you still\n"
+ "wish to receive the <strong>%s</strong> mailing list, simply do nothing,\n"
+ "and you will remain subscribed.</p>\n"
"</body></html>\n"
"\n"
"--__ctdlmultipart__--\n"
,
- emailaddr, roomname,
- url, emailaddr, urlroom, confirmation_token,
- roomname
- ,
- emailaddr, roomname,
- url, emailaddr, urlroom, confirmation_token,
- url, emailaddr, urlroom, confirmation_token,
- roomname
+ emailaddr, roomname, confirm_unsubscribe_url, roomname,
+ emailaddr, roomname, confirm_unsubscribe_url, confirm_unsubscribe_url, roomname
);
quickie_message("Citadel", from_address, emailaddr, NULL, emailtext, FMT_RFC822, "Please confirm your list unsubscription");