Skip to content

Commit

Permalink
use typescript for form.html in separate file, allow customization of
Browse files Browse the repository at this point in the history
requirement strings

Password requirement text is now loaded by the typescript, and can be
customized by changing the validationStrings variable. See wiki for more
info.
  • Loading branch information
hrfee committed Oct 20, 2020
1 parent 2f9965b commit 9abb177
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 131 deletions.
127 changes: 25 additions & 102 deletions data/templates/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ <h1>
<div class="card-body">
<ul class="list-group">
{{ range $key, $value := .requirements }}
<li id="{{ $key }}" class="list-group-item list-group-item-danger">
<div> {{ $value }}</div>
<li id="{{ $key }}" min="{{ $value }}" class="list-group-item list-group-item-danger">
<div></div>
</li>
{{ end }}
</ul>
Expand All @@ -116,107 +116,30 @@ <h1>
</div>
<script src="serialize.js"></script>
<script>
{{ if .bs5 }}
var bsVersion = 5;
{{ else }}
var bsVersion = 4;
{{ end }}
if (bsVersion == 5) {
var successBox = new bootstrap.Modal(document.getElementById('successBox'));
} else if (bsVersion == 4) {
var successBox = {
show : function() {
return $('#successBox').modal('show');
},
hide : function() {
return $('#successBox').modal('hide');
}
};
};
var code = window.location.href.split('/').pop();
function toggleSpinner () {
var submitButton = document.getElementById('submitButton');
var oldSpan = document.getElementById('createAccount');
var newSpan = document.createElement('span');
newSpan.id = 'createAccount';
if (document.getElementById('createAccountSpinner')) {
newSpan.appendChild(document.createTextNode('Create Account'));
submitButton.disabled = false;
} else {
var spinner = document.createElement('span');
spinner.id = 'createAccountSpinner';
spinner.classList.add('spinner-border', 'spinner-border-sm');
spinner.setAttribute('role', 'status');
spinner.setAttribute('aria-hidden', 'true');
var text = document.createTextNode(' Creating...');
newSpan.appendChild(spinner);
newSpan.appendChild(text);
submitButton.disabled = true;
var usernameEnabled = {{ .username }}
var validationStrings = {
"length": {
"singular": "Must have at least {n} character",
"plural": "Must have a least {n} characters"
},
"uppercase": {
"singular": "Must have at least {n} uppercase character",
"plural": "Must have at least {n} uppercase characters"
},
"lowercase": {
"singular": "Must have at least {n} lowercase character",
"plural": "Must have at least {n} lowercase characters"
},
"number": {
"singular": "Must have at least {n} number",
"plural": "Must have at least {n} numbers"
},
"special": {
"singular": "Must have at least {n} special character",
"plural": "Must have at least {n} special characters"
}
submitButton.replaceChild(newSpan, oldSpan);
};
document.getElementById('accountForm').onsubmit = function() {
if (document.getElementById('errorMessage')) {
document.getElementById('errorMessage').remove();
}
toggleSpinner();
var send = serializeForm('accountForm');
send['code'] = code;
{{ if not .username }}
send['email'] = send['username'];
{{ end }}
send = JSON.stringify(send);
var req = new XMLHttpRequest();
req.open("POST", "/newUser", true);
req.responseType = 'json';
req.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
req.onreadystatechange = function() {
if (this.readyState == 4) {
toggleSpinner();
var data = this.response;
if ('error' in data || data['success'] == false) {
if (typeof(data['error']) != 'undefined') {
var errorMessage = data['error'];
} else {
var errorMessage = 'Unknown Error';
}
var text = document.createTextNode(errorMessage);
var error = document.createElement('button');
error.classList.add('btn', 'btn-outline-danger');
error.setAttribute('disabled', '');
error.appendChild(text);
error.id = 'errorMessage';
document.getElementById('errorBox').appendChild(error);
} else {
var valid = true
for (var key in data) {
if (data.hasOwnProperty(key)) {
var criterion = document.getElementById(key);
if (criterion) {
if (data[key] == false) {
valid = false;
if (criterion.classList.contains('list-group-item-success')) {
criterion.classList.remove('list-group-item-success');
criterion.classList.add('list-group-item-danger');
};
} else {
if (criterion.classList.contains('list-group-item-danger')) {
criterion.classList.remove('list-group-item-danger');
criterion.classList.add('list-group-item-success');
};
};
};
};
};
if (valid == true) {
successBox.show();
};
};
};
};
req.send(send);
return false;
};
}
</script>
<script src="form.js"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14
github.com/swaggo/gin-swagger v1.2.0
github.com/swaggo/swag v1.6.8 // indirect
github.com/swaggo/swag v1.6.9 // indirect
github.com/ugorji/go v1.1.9 // indirect
github.com/urfave/cli/v2 v2.2.0 // indirect
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ github.com/swaggo/swag v1.6.7 h1:e8GC2xDllJZr3omJkm9YfmK0Y56+rMO3cg0JBKNz09s=
github.com/swaggo/swag v1.6.7/go.mod h1:xDhTyuFIujYiN3DKWC/H/83xcfHp+UE/IzWWampG7Zc=
github.com/swaggo/swag v1.6.8 h1:z3ZNcpJs/NLMpZcKqXUsBELmmY2Ocy09JXKx5gu3L4M=
github.com/swaggo/swag v1.6.8/go.mod h1:a0IpNeMfGidNOcm2TsqODUh9JHdHu3kxDA0UlGbBKjI=
github.com/swaggo/swag v1.6.9 h1:BukKRwZjnEcUxQt7Xgfrt9fpav0hiWw9YimdNO9wssw=
github.com/swaggo/swag v1.6.9/go.mod h1:a0IpNeMfGidNOcm2TsqODUh9JHdHu3kxDA0UlGbBKjI=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
Expand Down
10 changes: 5 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,11 +447,11 @@ func start(asDaemon, firstCall bool) {
app.loadStrftime()

validatorConf := ValidatorConf{
"characters": app.config.Section("password_validation").Key("min_length").MustInt(0),
"uppercase characters": app.config.Section("password_validation").Key("upper").MustInt(0),
"lowercase characters": app.config.Section("password_validation").Key("lower").MustInt(0),
"numbers": app.config.Section("password_validation").Key("number").MustInt(0),
"special characters": app.config.Section("password_validation").Key("special").MustInt(0),
"length": app.config.Section("password_validation").Key("min_length").MustInt(0),
"uppercase": app.config.Section("password_validation").Key("upper").MustInt(0),
"lowercase": app.config.Section("password_validation").Key("lower").MustInt(0),
"number": app.config.Section("password_validation").Key("number").MustInt(0),
"special": app.config.Section("password_validation").Key("special").MustInt(0),
}
if !app.config.Section("password_validation").Key("enabled").MustBool(false) {
for key := range validatorConf {
Expand Down
38 changes: 15 additions & 23 deletions pwval.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package main

import (
"fmt"
"strings"
"unicode"
)

Expand All @@ -21,11 +19,11 @@ func (vd *Validator) init(criteria ValidatorConf) {

// This isn't used, its for swagger
type PasswordValidation struct {
Characters bool `json:"characters,omitempty"` // Number of characters
Lowercase bool `json:"lowercase characters,omitempty"` // Number of lowercase characters
Uppercase bool `json:"uppercase characters,omitempty"` // Number of uppercase characters
Numbers bool `json:"numbers,omitempty"` // Number of numbers
Specials bool `json:"special characters,omitempty"` // Number of special characters
Characters bool `json:"length,omitempty"` // Number of characters
Lowercase bool `json:"lowercase,omitempty"` // Number of lowercase characters
Uppercase bool `json:"uppercase,omitempty"` // Number of uppercase characters
Numbers bool `json:"number,omitempty"` // Number of numbers
Specials bool `json:"special,omitempty"` // Number of special characters
}

func (vd *Validator) validate(password string) map[string]bool {
Expand All @@ -34,17 +32,17 @@ func (vd *Validator) validate(password string) map[string]bool {
count[key] = 0
}
for _, c := range password {
count["characters"] += 1
count["length"] += 1
if unicode.IsUpper(c) {
count["uppercase characters"] += 1
count["uppercase"] += 1
} else if unicode.IsLower(c) {
count["lowercase characters"] += 1
count["lowercase"] += 1
} else if unicode.IsNumber(c) {
count["numbers"] += 1
} else {
for _, s := range vd.specialChars {
if c == s {
count["special characters"] += 1
count["special"] += 1
}
}
}
Expand All @@ -60,18 +58,12 @@ func (vd *Validator) validate(password string) map[string]bool {
return results
}

func (vd *Validator) getCriteria() map[string]string {
lines := map[string]string{}
for criterion, min := range vd.criteria {
if min > 0 {
text := fmt.Sprintf("Must have at least %d ", min)
if min == 1 {
text += strings.TrimSuffix(criterion, "s")
} else {
text += criterion
}
lines[criterion] = text
func (vd *Validator) getCriteria() ValidatorConf {
criteria := ValidatorConf{}
for key, num := range vd.criteria {
if num != 0 {
criteria[key] = num
}
}
return lines
return criteria
}

0 comments on commit 9abb177

Please sign in to comment.