#include "trackname.h"
#include "charset.h"
#include "dcgi.h"
+#include "url.h"
+#include "mime.h"
+#include "sendmail.h"
char *login_cookie;
static void header_cookie(struct sink *output) {
struct dynstr d[1];
- char *s;
+ struct url u;
+ memset(&u, 0, sizeof u);
+ dynstr_init(d);
+ parse_url(config->url, &u);
if(login_cookie) {
- dynstr_init(d);
- for(s = login_cookie; *s; ++s) {
- if(*s == '"')
- dynstr_append(d, '\\');
- dynstr_append(d, *s);
- }
- dynstr_terminate(d);
- byte_xasprintf(&s, "disorder=\"%s\"", d->vec); /* TODO domain, path, expiry */
- cgi_header(output, "Set-Cookie", s);
- } else
+ dynstr_append_string(d, "disorder=");
+ dynstr_append_string(d, quote822(login_cookie, 0));
+ } else {
/* Force browser to discard cookie */
- cgi_header(output, "Set-Cookie", "disorder=none;Max-Age=0");
+ dynstr_append_string(d, "disorder=none;Max-Age=0");
+ }
+ if(u.path) {
+ /* The default domain matches the request host, so we need not override
+ * that. But the default path only goes up to the rightmost /, which would
+ * cause the browser to expose the cookie to other CGI programs on the same
+ * web server. */
+ dynstr_append_string(d, ";Path=");
+ dynstr_append_string(d, quote822(u.path, 0));
+ }
+ dynstr_terminate(d);
+ cgi_header(output, "Set-Cookie", d->vec);
}
static void redirect(struct sink *output) {
}
/* We have a new cookie */
header_cookie(output->sink);
- if((back = cgi_get("back")) && back)
+ cgi_set_option("status", "loginok");
+ if((back = cgi_get("back")) && *back)
/* Redirect back to somewhere or other */
redirect(output->sink);
else
/* Reconnect as guest */
disorder_cgi_login(ds, output);
/* Back to the login page */
+ cgi_set_option("status", "logoutok");
expand_template(ds, output, "login");
}
static void act_register(cgi_sink *output,
dcgi_state *ds) {
const char *username, *password, *email;
- char *confirm;
+ char *confirm, *content_type;
+ const char *text, *encoding, *charset;
username = cgi_get("username");
password = cgi_get("password");
expand_template(ds, output, "login");
return;
}
+ /* Send the user a mail */
+ /* TODO templatize this */
+ byte_xasprintf((char **)&text,
+ "Welcome to DisOrder. To active your login, please visit this URL:\n"
+ "\n"
+ "%s?c=%s\n", config->url, urlencodestring(confirm));
+ if(!(text = mime_encode_text(text, &charset, &encoding)))
+ fatal(0, "cannot encode email");
+ byte_xasprintf(&content_type, "text/plain;charset=%s",
+ quote822(charset, 0));
+ sendmail("", config->mail_sender, email, "Welcome to DisOrder",
+ encoding, content_type, text); /* TODO error checking */
/* We'll go back to the login page with a suitable message */
- cgi_set_option("registered", "registeredok");
+ cgi_set_option("status", "registered");
+ expand_template(ds, output, "login");
+}
+
+static void act_confirm(cgi_sink *output,
+ dcgi_state *ds) {
+ const char *confirmation;
+
+ if(!(confirmation = cgi_get("c"))) {
+ cgi_set_option("error", "noconfirm");
+ expand_template(ds, output, "login");
+ }
+ if(disorder_confirm(ds->g->client, confirmation)) {
+ cgi_set_option("error", "badconfirm");
+ expand_template(ds, output, "login");
+ }
+ cgi_set_option("status", "confirmed");
expand_template(ds, output, "login");
}
const char *name;
void (*handler)(cgi_sink *output, dcgi_state *ds);
} actions[] = {
+ { "confirm", act_confirm },
{ "disable", act_disable },
{ "enable", act_enable },
{ "login", act_login },
void disorder_cgi(cgi_sink *output, dcgi_state *ds) {
const char *action = cgi_get("action");
- if(!action) action = "playing";
+ if(!action) {
+ /* We allow URLs which are just confirm=... in order to keep confirmation
+ * URLs, which are user-facing, as short as possible. */
+ if(cgi_get("c"))
+ action = "confirm";
+ else
+ action = "playing";
+ }
perform_action(output, ds, action);
}