Move login screen to new forms framework
This commit is contained in:
@@ -103,7 +103,7 @@ body{
|
|||||||
font-family: "Lato Thin", sans-serif;
|
font-family: "Lato Thin", sans-serif;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 1.8em;
|
font-size: 1.8em;
|
||||||
transition: box-shadow 2s;
|
transition: box-shadow 5s;
|
||||||
}
|
}
|
||||||
.navigation a:hover {
|
.navigation a:hover {
|
||||||
background: linear-gradient(var(--highlight_color), var(--highlight_color_dark));
|
background: linear-gradient(var(--highlight_color), var(--highlight_color_dark));
|
||||||
|
@@ -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}}
|
|
@@ -8,18 +8,18 @@
|
|||||||
<div id='body' class="body">
|
<div id='body' class="body">
|
||||||
{{template "menu" .}}
|
{{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">
|
<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"/>
|
<input type="submit" value="I want to log out of pixeldrain on this computer" class="button_highlight"/>
|
||||||
</form>
|
</form>
|
||||||
<br/>
|
<br/>
|
||||||
<h2>Why do I need to confirm my logout?</h2>
|
<h2>Why do I need to confirm my logout?</h2>
|
||||||
<p>
|
<p>
|
||||||
We need you to confirm your action here so we can be sure that
|
We need you to confirm your action so we can be sure that you
|
||||||
you really requested a logout. If we didn't do this, anyone (or
|
really requested a logout. If we didn't do this, anyone (or any
|
||||||
any website) would be able to send you to this page and you
|
website) would be able to send you to this page and you would
|
||||||
would automatically get logged out of Pixeldrain, which would be
|
automatically get logged out of pixeldrain, which would be very
|
||||||
very annoying.
|
annoying.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
To prevent this from happening we're verifying that you actually
|
To prevent this from happening we're verifying that you actually
|
||||||
|
@@ -12,11 +12,10 @@
|
|||||||
|
|
||||||
<h1 class="highlight_middle border_bottom">Welcome home, {{.Username}}!</h1>
|
<h1 class="highlight_middle border_bottom">Welcome home, {{.Username}}!</h1>
|
||||||
|
|
||||||
<!--<a href="/user/settings">Change user settings</a><br/>-->
|
|
||||||
<h2>Actions</h2>
|
<h2>Actions</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/user/logout">Log out</a></li>
|
|
||||||
<li><a href="/user/change_password">Change my password</a></li>
|
<li><a href="/user/change_password">Change my password</a></li>
|
||||||
|
<li><a href="/logout">Log out</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>Your most recently uploaded files:</h2>
|
<h2>Your most recently uploaded files:</h2>
|
||||||
|
@@ -29,6 +29,9 @@ type Form struct {
|
|||||||
|
|
||||||
// Used for letting the browser know which user is logged in
|
// Used for letting the browser know which user is logged in
|
||||||
Username string
|
Username string
|
||||||
|
|
||||||
|
// Actions to perform when the form is rendered
|
||||||
|
Extra ExtraActions
|
||||||
}
|
}
|
||||||
|
|
||||||
// Field is a single input field in a form
|
// Field is a single input field in a form
|
||||||
@@ -54,11 +57,22 @@ type Field struct {
|
|||||||
|
|
||||||
Type FieldType
|
Type FieldType
|
||||||
|
|
||||||
// Only used when Type = `captcha`. When using reCaptcha the field name has
|
// Only used when Type == FieldTypeCaptcha
|
||||||
// to be `recaptcha_response`
|
|
||||||
CaptchaSiteKey string
|
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
|
// FieldType defines the type a form field has and how it should be rendered
|
||||||
type FieldType string
|
type FieldType string
|
||||||
|
|
||||||
@@ -82,15 +96,17 @@ func (f *Form) ReadInput(r *http.Request) (success bool) {
|
|||||||
}
|
}
|
||||||
f.Submitted = true
|
f.Submitted = true
|
||||||
|
|
||||||
var val string
|
|
||||||
|
|
||||||
for i, field := range f.Fields {
|
for i, field := range f.Fields {
|
||||||
val = r.FormValue(field.Name)
|
field.EnteredValue = r.FormValue(field.Name)
|
||||||
field.EnteredValue = val
|
|
||||||
|
|
||||||
if field.DefaultValue == "" {
|
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
|
f.Fields[i] = field // Update the new values in the array
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@ package webcontroller
|
|||||||
import (
|
import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"fornaxian.com/pixeldrain-web/pixelapi"
|
"fornaxian.com/pixeldrain-web/pixelapi"
|
||||||
"fornaxian.com/pixeldrain-web/webcontroller/forms"
|
"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",
|
"website with fake accounts",
|
||||||
Separator: true,
|
Separator: true,
|
||||||
Type: forms.FieldTypeCaptcha,
|
Type: forms.FieldTypeCaptcha,
|
||||||
CaptchaSiteKey: wc.captchaSiteKey,
|
CaptchaSiteKey: wc.captchaKey(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
BackLink: "/",
|
BackLink: "/",
|
||||||
@@ -114,7 +115,7 @@ func (wc *WebController) registerForm(td *TemplateData, r *http.Request) (f form
|
|||||||
"password in both password fields"}
|
"password in both password fields"}
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
log.Debug("capt: %s", f.FieldVal("recaptcha_response"))
|
||||||
resp, err := td.PixelAPI.UserRegister(
|
resp, err := td.PixelAPI.UserRegister(
|
||||||
f.FieldVal("username"),
|
f.FieldVal("username"),
|
||||||
f.FieldVal("e-mail"),
|
f.FieldVal("e-mail"),
|
||||||
@@ -145,6 +146,57 @@ func (wc *WebController) registerForm(td *TemplateData, r *http.Request) (f form
|
|||||||
return f
|
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) {
|
func (wc *WebController) passwordForm(td *TemplateData, r *http.Request) (f forms.Form) {
|
||||||
td.Title = "Change Password"
|
td.Title = "Change Password"
|
||||||
f = forms.Form{
|
f = forms.Form{
|
||||||
|
@@ -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_old" /* */, wc.serveRegister)
|
||||||
r.GET(p+"/register" /* */, wc.serveForm(wc.registerForm, false))
|
r.GET(p+"/register" /* */, wc.serveForm(wc.registerForm, false))
|
||||||
r.POST(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.GET(p+"/logout" /* */, wc.serveTemplate("logout", true))
|
||||||
r.POST(p+"/logout" /* */, wc.serveLogout)
|
r.POST(p+"/logout" /* */, wc.serveLogout)
|
||||||
r.GET(p+"/user" /* */, wc.serveTemplate("user_home", true))
|
r.GET(p+"/user" /* */, wc.serveTemplate("user_home", true))
|
||||||
@@ -133,8 +135,18 @@ func (wc *WebController) serveForm(
|
|||||||
|
|
||||||
td.Form.Username = td.Username
|
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
|
// Remove the recaptcha field if captcha is disabled
|
||||||
if wc.captchaSiteKey == "none" {
|
if wc.captchaKey() == "none" {
|
||||||
for i, field := range td.Form.Fields {
|
for i, field := range td.Form.Fields {
|
||||||
if field.Type == forms.FieldTypeCaptcha {
|
if field.Type == forms.FieldTypeCaptcha {
|
||||||
td.Form.Fields = append(
|
td.Form.Fields = append(
|
||||||
|
Reference in New Issue
Block a user