Move login screen to new forms framework

This commit is contained in:
2019-03-31 22:33:22 +02:00
parent e4e965516f
commit 86921e9b3b
7 changed files with 99 additions and 89 deletions

View File

@@ -103,7 +103,7 @@ body{
font-family: "Lato Thin", sans-serif;
font-weight: bold;
font-size: 1.8em;
transition: box-shadow 2s;
transition: box-shadow 5s;
}
.navigation a:hover {
background: linear-gradient(var(--highlight_color), var(--highlight_color_dark));

View File

@@ -1,69 +0,0 @@
{{define "login"}}
<!DOCTYPE html>
<html>
<head>
{{template "meta_tags" "Login"}}
{{template "user_style" .}}
<script type="text/javascript">var apiEndpoint = '{{.APIEndpoint}}';</script>
</head>
<body>
<div id='body' class="body">
{{template "menu" .}}
<h1>Log in to your PixelDrain account</h1>
<div id="submit_result"></div>
<form onSubmit="return submitForm();" class="highlight_dark border_top border_bottom">
<table class="form">
<tr class="form">
<td>Username / e-mail</td>
<td><input id="username" name="username" type="text" autocomplete="username" value="" class="form_input"/></td>
</tr>
<tr class="form">
<td>Password</td>
<td><input id="password" name="password" type="password" autocomplete="current-password" class="form_input"/></td>
</tr>
<tr class="form">
<td colspan=2 style="text-align: right;"><input type="submit" value="Login" class="button_highlight"/></td>
</tr>
</table>
</form>
<br/>
If you don't have a PixelDrain account yet, you can <a href="/register">register here</a>. No e-mail address is required.<br/>
{{template "footer"}}
</div>
<script type="text/javascript">
function submitForm(){
var req = new XMLHttpRequest();
req.onreadystatechange = function(){
if (this.readyState === 4) {
var response = JSON.parse(req.responseText);
var resultDiv = document.getElementById("submit_result");
if (response.success) {
resultDiv.className = "border_top border_bottom highlight_green";
resultDiv.innerHTML = 'Success! Proceeding to user portal...<br/>'
+'<a href="/user">Click here if you are not redirected automatically</a>';
window.location.href = "/user";
} else {
resultDiv.className = "border_top border_bottom highlight_red";
resultDiv.innerHTML = response.message;
}
console.log(response);
}
}
var data = new FormData();
data.append("username", document.getElementById("username").value);
data.append("password", document.getElementById("password").value);
req.open("POST", apiEndpoint+"/user/login", true);
req.send(data);
return false;
}
</script>
{{template "analytics"}}
</body>
</html>
{{end}}

View File

@@ -8,18 +8,18 @@
<div id='body' class="body">
{{template "menu" .}}
<h1>Please confirm that you want to log out of your Pixeldrain account</h1>
<h1>Please confirm that you want to log out of your pixeldrain account</h1>
<form method="POST" action="/logout" class="highlight_light border_top border_bottom">
<input type="submit" value="I want to log out of pixeldrain on this computer" class="button_highlight"/>
</form>
<br/>
<h2>Why do I need to confirm my logout?</h2>
<p>
We need you to confirm your action here so we can be sure that
you really requested a logout. If we didn't do this, anyone (or
any website) would be able to send you to this page and you
would automatically get logged out of Pixeldrain, which would be
very annoying.
We need you to confirm your action so we can be sure that you
really requested a logout. If we didn't do this, anyone (or any
website) would be able to send you to this page and you would
automatically get logged out of pixeldrain, which would be very
annoying.
</p>
<p>
To prevent this from happening we're verifying that you actually

View File

@@ -12,11 +12,10 @@
<h1 class="highlight_middle border_bottom">Welcome home, {{.Username}}!</h1>
<!--<a href="/user/settings">Change user settings</a><br/>-->
<h2>Actions</h2>
<ul>
<li><a href="/user/logout">Log out</a></li>
<li><a href="/user/change_password">Change my password</a></li>
<li><a href="/logout">Log out</a></li>
</ul>
<h2>Your most recently uploaded files:</h2>

View File

@@ -29,6 +29,9 @@ type Form struct {
// Used for letting the browser know which user is logged in
Username string
// Actions to perform when the form is rendered
Extra ExtraActions
}
// Field is a single input field in a form
@@ -54,11 +57,22 @@ type Field struct {
Type FieldType
// Only used when Type = `captcha`. When using reCaptcha the field name has
// to be `recaptcha_response`
// Only used when Type == FieldTypeCaptcha
CaptchaSiteKey string
}
// ExtraActions contains extra actions to performs when rendering the form
type ExtraActions struct {
// Redirects the browser to a different URL with a HTTP 303: See Other
// status. This is useful for redirecting the user to a different page if
// the form submission was successful
RedirectTo string
// A cookie to install in the browser when the form is rendered. Useful for
// setting / destroying user sessions or configurations
SetCookie *http.Cookie
}
// FieldType defines the type a form field has and how it should be rendered
type FieldType string
@@ -82,15 +96,17 @@ func (f *Form) ReadInput(r *http.Request) (success bool) {
}
f.Submitted = true
var val string
for i, field := range f.Fields {
val = r.FormValue(field.Name)
field.EnteredValue = val
field.EnteredValue = r.FormValue(field.Name)
if field.DefaultValue == "" {
field.DefaultValue = val
field.DefaultValue = field.EnteredValue
}
if field.Type == FieldTypeCaptcha && field.EnteredValue == "" {
field.EnteredValue = r.FormValue("g-recaptcha-response")
}
f.Fields[i] = field // Update the new values in the array
}

View File

@@ -3,6 +3,7 @@ package webcontroller
import (
"html/template"
"net/http"
"time"
"fornaxian.com/pixeldrain-web/pixelapi"
"fornaxian.com/pixeldrain-web/webcontroller/forms"
@@ -99,7 +100,7 @@ func (wc *WebController) registerForm(td *TemplateData, r *http.Request) (f form
"website with fake accounts",
Separator: true,
Type: forms.FieldTypeCaptcha,
CaptchaSiteKey: wc.captchaSiteKey,
CaptchaSiteKey: wc.captchaKey(),
},
},
BackLink: "/",
@@ -114,7 +115,7 @@ func (wc *WebController) registerForm(td *TemplateData, r *http.Request) (f form
"password in both password fields"}
return f
}
log.Debug("capt: %s", f.FieldVal("recaptcha_response"))
resp, err := td.PixelAPI.UserRegister(
f.FieldVal("username"),
f.FieldVal("e-mail"),
@@ -145,6 +146,57 @@ func (wc *WebController) registerForm(td *TemplateData, r *http.Request) (f form
return f
}
func (wc *WebController) loginForm(td *TemplateData, r *http.Request) (f forms.Form) {
td.Title = "Login"
f = forms.Form{
Name: "login",
Title: "Log in to your pixeldrain account",
Fields: []forms.Field{
{
Name: "username",
Label: "Username / e-mail",
Type: forms.FieldTypeUsername,
}, {
Name: "password",
Label: "Password",
Type: forms.FieldTypeCurrentPassword,
},
},
BackLink: "/",
SubmitLabel: "Login",
PostFormHTML: template.HTML(
`<br/>If you don't have a pixeldrain account yet, you can ` +
`<a href="/register">register here</a>. No e-mail address is ` +
`required.<br/>`,
),
}
if f.ReadInput(r) {
loginResp, err := td.PixelAPI.UserLogin(f.FieldVal("username"), f.FieldVal("password"), false)
if err != nil {
if apiErr, ok := err.(pixelapi.Error); ok {
f.SubmitMessages = []template.HTML{template.HTML(apiErr.Message)}
} else {
log.Error("%s", err)
f.SubmitMessages = []template.HTML{"Internal Server Error"}
}
} else {
log.Debug("key %s", loginResp.APIKey)
// Request was a success
f.SubmitSuccess = true
f.SubmitMessages = []template.HTML{"Success!"}
f.Extra.SetCookie = &http.Cookie{
Name: "pd_auth_key",
Value: loginResp.APIKey,
Path: "/",
Expires: time.Now().AddDate(50, 0, 0),
}
f.Extra.RedirectTo = "/user"
}
}
return f
}
func (wc *WebController) passwordForm(td *TemplateData, r *http.Request) (f forms.Form) {
td.Title = "Change Password"
f = forms.Form{

View File

@@ -64,7 +64,9 @@ func New(r *httprouter.Router, prefix string, conf *conf.PixelWebConfig) *WebCon
r.GET(p+"/register_old" /* */, wc.serveRegister)
r.GET(p+"/register" /* */, wc.serveForm(wc.registerForm, false))
r.POST(p+"/register" /* */, wc.serveForm(wc.registerForm, false))
r.GET(p+"/login" /* */, wc.serveTemplate("login", false))
r.GET(p+"/login" /* */, wc.serveForm(wc.loginForm, false))
r.POST(p+"/login" /* */, wc.serveForm(wc.loginForm, false))
// r.GET(p+"/login" /* */, wc.serveTemplate("login", false))
r.GET(p+"/logout" /* */, wc.serveTemplate("logout", true))
r.POST(p+"/logout" /* */, wc.serveLogout)
r.GET(p+"/user" /* */, wc.serveTemplate("user_home", true))
@@ -133,8 +135,18 @@ func (wc *WebController) serveForm(
td.Form.Username = td.Username
// Execute the extra actions if any
if td.Form.Extra.SetCookie != nil {
http.SetCookie(w, td.Form.Extra.SetCookie)
}
if td.Form.Extra.RedirectTo != "" {
http.Redirect(w, r, td.Form.Extra.RedirectTo, http.StatusSeeOther)
log.Debug("redirect: %s", td.Form.Extra.RedirectTo)
return // Don't need to render a form if the user is redirected
}
// Remove the recaptcha field if captcha is disabled
if wc.captchaSiteKey == "none" {
if wc.captchaKey() == "none" {
for i, field := range td.Form.Fields {
if field.Type == forms.FieldTypeCaptcha {
td.Form.Fields = append(