public HttpResponseMessage CreatePwdToken(ConfirmationCreateTokenModel model)
        {
            Api api = Api.INSTANCE;

            if (model.confirmation_url == null || model.email == null)
            {
                return(ApiResponse.Json(HttpStatusCode.OK, new RegistrationError()
                {
                    error = "password_reset_failed",
                    error_description = "missing_fields"
                }));
            }

            // verify email syntax
            // To do: check if email address is disposable.
            try
            {
                var addr = new System.Net.Mail.MailAddress(model.email);
            }
            catch
            {
                return(ApiResponse.Json(HttpStatusCode.OK, new RegistrationError()
                {
                    error = "password_reset_failed",
                    error_description = "email_invalid"
                }));
            }

            using (var da = api.DAFactory.Get)
            {
                var user = da.Users.GetByEmail(model.email);

                if (user == null)
                {
                    return(ApiResponse.Json(HttpStatusCode.OK, new RegistrationError()
                    {
                        error = "password_reset_failed",
                        error_description = "email_invalid"
                    }));
                }

                EmailConfirmation confirm = da.EmailConfirmations.GetByEmail(model.email, ConfirmationType.password);

                // already awaiting a confirmation
                // to-do: resend?
                if (confirm != null)
                {
                    return(ApiResponse.Json(HttpStatusCode.OK, new RegistrationError()
                    {
                        error = "registration_failed",
                        error_description = "confirmation_pending"
                    }));
                }

                uint expires = Epoch.Now + EMAIL_CONFIRMATION_EXPIRE;

                // create new email confirmation
                string token = da.EmailConfirmations.Create(new EmailConfirmation
                {
                    type    = ConfirmationType.password,
                    email   = model.email,
                    expires = expires
                });

                // send confirmation email with generated token
                bool sent = api.SendPasswordResetMail(model.email, user.username, token, model.confirmation_url, expires);

                if (sent)
                {
                    return(ApiResponse.Json(HttpStatusCode.OK, new
                    {
                        status = "success"
                    }));
                }

                return(ApiResponse.Json(HttpStatusCode.OK, new
                {
                    // success but email shitfaced
                    status = "email_failed"
                }));
            }
        }
        public HttpResponseMessage CreateToken(ConfirmationCreateTokenModel model)
        {
            Api api = Api.INSTANCE;

            // smtp needs to be configured for this
            if (!api.Config.SmtpEnabled)
            {
                return(ApiResponse.Json(HttpStatusCode.OK, new RegistrationError()
                {
                    error = "registration_failed",
                    error_description = "smtp_disabled"
                }));
            }

            if (model.confirmation_url == null || model.email == null)
            {
                return(ApiResponse.Json(HttpStatusCode.OK, new RegistrationError()
                {
                    error = "registration_failed",
                    error_description = "missing_fields"
                }));
            }

            // verify email syntax
            // To do: check if email address is disposable.
            try
            {
                var addr = new System.Net.Mail.MailAddress(model.email);
            }
            catch
            {
                return(ApiResponse.Json(HttpStatusCode.OK, new RegistrationError()
                {
                    error = "registration_failed",
                    error_description = "email_invalid"
                }));
            }

            using (var da = api.DAFactory.Get)
            {
                // email is taken
                if (da.Users.GetByEmail(model.email) != null)
                {
                    return(ApiResponse.Json(HttpStatusCode.OK, new RegistrationError()
                    {
                        error = "registration_failed",
                        error_description = "email_taken"
                    }));
                }

                EmailConfirmation confirm = da.EmailConfirmations.GetByEmail(model.email, ConfirmationType.email);

                // already waiting for confirmation
                if (confirm != null)
                {
                    return(ApiResponse.Json(HttpStatusCode.OK, new RegistrationError()
                    {
                        error = "registration_failed",
                        error_description = "confirmation_pending"
                    }));
                }

                uint expires = Epoch.Now + EMAIL_CONFIRMATION_EXPIRE;

                // create new email confirmation
                string token = da.EmailConfirmations.Create(new EmailConfirmation
                {
                    type    = ConfirmationType.email,
                    email   = model.email,
                    expires = expires
                });

                // send email with recently generated token
                bool sent = api.SendEmailConfirmationMail(model.email, token, model.confirmation_url, expires);

                if (sent)
                {
                    return(ApiResponse.Json(HttpStatusCode.OK, new
                    {
                        status = "success"
                    }));
                }

                return(ApiResponse.Json(HttpStatusCode.OK, new
                {
                    status = "email_failed"
                }));
            }
        }