Signup page: check for username uniqueness
This commit is contained in:
parent
be0d401de8
commit
4d1a057a73
57
pkg/controller/api/username_check.go
Normal file
57
pkg/controller/api/username_check.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"code.nonshy.com/nonshy/website/pkg/models"
|
||||
)
|
||||
|
||||
// UsernameCheck API.
|
||||
func UsernameCheck() http.HandlerFunc {
|
||||
// Request JSON schema.
|
||||
type Request struct {
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
// Response JSON schema.
|
||||
type Response struct {
|
||||
OK bool `json:"OK"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
SendJSON(w, http.StatusNotAcceptable, Response{
|
||||
Error: "POST method only",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Parse request payload.
|
||||
var req Request
|
||||
if err := ParseJSON(r, &req); err != nil {
|
||||
SendJSON(w, http.StatusBadRequest, Response{
|
||||
Error: fmt.Sprintf("Error with request payload: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Username to test.
|
||||
var username = strings.TrimSpace(strings.ToLower(req.Username))
|
||||
|
||||
// Does it exist?
|
||||
if _, err := models.FindUser(username); err == nil {
|
||||
SendJSON(w, http.StatusOK, Response{
|
||||
Error: "That username is already taken, please try another one.",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Send success response.
|
||||
SendJSON(w, http.StatusOK, Response{
|
||||
OK: true,
|
||||
})
|
||||
})
|
||||
}
|
|
@ -93,6 +93,7 @@ func New() http.Handler {
|
|||
// JSON API endpoints.
|
||||
mux.HandleFunc("/v1/version", api.Version())
|
||||
mux.HandleFunc("/v1/users/me", api.LoginOK())
|
||||
mux.HandleFunc("/v1/users/check-username", api.UsernameCheck())
|
||||
mux.Handle("/v1/likes", middleware.LoginRequired(api.Likes()))
|
||||
mux.Handle("/v1/notifications/read", middleware.LoginRequired(api.ReadNotification()))
|
||||
mux.Handle("/v1/notifications/delete", middleware.LoginRequired(api.ClearNotification()))
|
||||
|
|
|
@ -108,6 +108,20 @@
|
|||
value="{{.Username}}"
|
||||
required>
|
||||
<small class="has-text-grey">Usernames are 3 to 32 characters a-z 0-9 . -</small>
|
||||
|
||||
<!-- Username checking -->
|
||||
<div class="notification is-info is-light py-2 px-4 mt-1"
|
||||
id="username-checking" style="display: none">
|
||||
<i class="fa fa-spinner fa-spin mr-1"></i> Checking username...
|
||||
</div>
|
||||
<div class="notification is-success is-light py-2 px-4 mt-1"
|
||||
id="username-ok" style="display: none">
|
||||
<i class="fa fa-check mr-1"></i> Looks good!
|
||||
</div>
|
||||
<div class="notification is-danger is-light py-2 px-4 mt-1"
|
||||
id="username-error" style="display: none">
|
||||
<i class="fa fa-xmark mr-1"></i> That username is already taken!
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="password">Enter a passphrase:</label>
|
||||
|
@ -153,3 +167,61 @@
|
|||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{define "scripts"}}
|
||||
<script>
|
||||
window.addEventListener("DOMContentLoaded", (event) => {
|
||||
// Set up username checking script.
|
||||
const $username = document.querySelector("#username"),
|
||||
$unCheck = document.querySelector("#username-checking"),
|
||||
$unOK = document.querySelector("#username-ok"),
|
||||
$unError = document.querySelector("#username-error");
|
||||
|
||||
let onChange = (e) => {
|
||||
$unCheck.style.display = "block";
|
||||
$unOK.style.display = "none";
|
||||
$unError.style.display = "none";
|
||||
|
||||
if ($username.value.length < 3) {
|
||||
$unCheck.style.display = "none";
|
||||
return;
|
||||
};
|
||||
|
||||
return fetch("/v1/users/check-username", {
|
||||
method: "POST",
|
||||
mode: "same-origin",
|
||||
cache: "no-cache",
|
||||
credentials: "same-origin",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"username": $username.value,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.StatusCode !== 200) {
|
||||
window.alert(data.data.error);
|
||||
return;
|
||||
}
|
||||
|
||||
let result = data.data;
|
||||
if (result.OK) {
|
||||
$unOK.style.display = "block";
|
||||
$unError.style.display = "none";
|
||||
} else {
|
||||
$unOK.style.display = "none";
|
||||
$unError.style.display = "block";
|
||||
}
|
||||
}).catch(resp => {
|
||||
window.alert(resp);
|
||||
}).finally(() => {
|
||||
$unCheck.style.display = "none";
|
||||
})
|
||||
};
|
||||
|
||||
$username.addEventListener("change", onChange);
|
||||
$username.addEventListener("blur", onChange);
|
||||
});
|
||||
</script>
|
||||
{{end}}
|
||||
|
|
Loading…
Reference in New Issue
Block a user