Implement register and login using vuetify

This commit is contained in:
Jan Bader 2022-01-24 16:00:01 +00:00
parent d59b9bdbec
commit 3de0447eba
7 changed files with 5841 additions and 43 deletions

View File

@ -98,27 +98,37 @@ func (h *Handler) loginPost(c *gin.Context) {
}) })
} }
func (h *Handler) registerPost(c *gin.Context) { type registerInformation struct {
email, _ := c.GetPostForm("email") Password string `json:"password"`
password, _ := c.GetPostForm("password") Email string `json:"email"`
name, _ := c.GetPostForm("name") Name string `json:"name"`
}
_, err := h.Service.GetUserByUsername(c.Request.Context(), email) func (h *Handler) registerPost(c *gin.Context) {
if err == nil { var register registerInformation
c.AbortWithStatus(http.StatusUnauthorized) c.BindJSON(&register)
if register.Email == "" || register.Password == "" || register.Name == "" {
c.AbortWithError(http.StatusBadRequest, fmt.Errorf("e-mail, password and name are required"))
return return
} }
hash, err := h.CredentialsVerifier.Hash(password) _, err := h.Service.GetUserByUsername(c.Request.Context(), register.Email)
if err == nil {
c.AbortWithError(http.StatusUnauthorized, err)
return
}
hash, err := h.CredentialsVerifier.Hash(register.Password)
if err != nil { if err != nil {
c.AbortWithError(http.StatusUnauthorized, err) c.AbortWithError(http.StatusUnauthorized, err)
return return
} }
createUser := postgres.CreateUserParams{ createUser := postgres.CreateUserParams{
Name: name, Name: register.Name,
Password: hash, Password: hash,
Email: email, Email: register.Email,
} }
_, err = h.Service.CreateUser(c.Request.Context(), createUser) _, err = h.Service.CreateUser(c.Request.Context(), createUser)
if err != nil { if err != nil {

View File

@ -19,13 +19,19 @@ export default {
</script> </script>
<template> <template>
<v-app>
<v-app-bar app>
<ul> <ul>
<li v-if="!loggedIn"><router-link to="/login">Login</router-link></li> <li v-if="!loggedIn"><router-link to="/login">Login</router-link></li>
<li v-if="loggedIn"><a @click="logout">Logout</a></li> <li v-if="loggedIn"><a @click="logout">Logout</a></li>
<li v-if="loggedIn"><router-link to="/">Dashboard</router-link></li> <li v-if="loggedIn"><router-link to="/">Dashboard</router-link></li>
</ul> </ul>
</v-app-bar>
<v-main>
<router-view></router-view> <router-view></router-view>
</v-main>
</v-app>
</template> </template>
<style> <style>

View File

@ -2,8 +2,13 @@ import { createApp } from 'vue/dist/vue.esm-bundler'
import App from './App.vue' import App from './App.vue'
import router from './router/routes.js' import router from './router/routes.js'
import store from './store/index.js' import store from './store/index.js'
import vuetify from './plugins/vuetify'
import { loadFonts } from './plugins/webfontloader'
loadFonts()
const app = createApp(App) const app = createApp(App)
app.use(router) app.use(router)
app.use(store) app.use(store)
app.use(vuetify)
app.mount('#app') app.mount('#app')

View File

@ -7,11 +7,12 @@ export default {
}, },
data() { data() {
return { return {
error: false, error: [],
login: { login: {
user: "", user: "",
password: "" password: ""
} },
showPassword: false
} }
}, },
mounted () { mounted () {
@ -20,14 +21,13 @@ export default {
methods: { methods: {
formSubmit (e) { formSubmit (e) {
e.preventDefault(); e.preventDefault();
console.log("uiae");
fetch("/api/v1/user/login", {method: "POST", body: JSON.stringify(this.$data.login)}) fetch("/api/v1/user/login", {method: "POST", body: JSON.stringify(this.$data.login)})
.then(x => x.json()) .then(x => x.json())
.then(x => { .then(x => {
this.$data.error = "" this.$data.error = ""
this.$store.commit("setToken", x.token); this.$store.commit("setToken", x.token);
}) })
.catch(x => this.$data.error = "Error"); .catch(x => this.$data.error = ["The entered credentials are invalid!"]);
// TODO display invalidCredentials // TODO display invalidCredentials
// TODO redirect to dashboard on success // TODO redirect to dashboard on success
@ -37,24 +37,27 @@ export default {
</script> </script>
<template> <template>
<form id="loginForm" @submit="formSubmit" class="center-block"> <v-container>
<v-row>
<v-col cols="12">
<v-text-field v-model="login.user" type="text" label="Username" />
</v-col>
<v-col cols="12">
<v-text-field v-model="login.password" label="Password"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showPassword ? 'text' : 'password'"
@click:append="showPassword = showPassword"
:error-message="error"
error-count="2"
error />
</v-col>
</v-row>
<div class="form-group"> <div class="form-group">
<label for="username">User</label> {{ error }}
<input type="text" class="form-control" placeholder="User" v-model="login.user" />
</div> </div>
<v-btn type="submit" @click="formSubmit">Login</v-btn>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" placeholder="Password" v-model="login.password" />
<p v-if="error">
The entered credentials are invalid
</p>
</div>
<input type="submit" value="Login" class="btn btn-default" on/>
<p> <p>
New user? <a href="/register">Register</a> instead! New user? <router-link to="/register">Register</router-link> instead!
</p> </p>
</form> </v-container>
</template> </template>

126
web/src/pages/Register.vue Normal file
View File

@ -0,0 +1,126 @@
<!--{{define "title"}}Register{{end}}
{{template "base" .}}
{{define "more-head"}}
<script>
function checkPasswordMatchUi() {
if(checkPasswordMatch())
$("#divCheckPasswordMatch").html("Passwords match.");
else
$("#divCheckPasswordMatch").html("Passwords do not match!");
}
function checkPasswordMatch() {
var password = $("#password").val();
var confirmPassword = $("#password_confirm").val();
return password == confirmPassword;
}
$(document).ready(function () {
$("#password, #password_confirm").keyup(checkPasswordMatchUi);
$('#invalidCredentials').hide();
$('#loginForm').ajaxForm({
beforeSubmit: function(a, b, c) {
var match = checkPasswordMatch();
if(!match){
$("#divCheckPasswordMatch").fadeOut(300).fadeIn(300).fadeOut(300).fadeIn(300);
}
return match;
},
success: function() {
window.location.href = "/dashboard";
},
error: function() {
$('#invalidCredentials').show();
}
});
});
</script>
{{end}}
{{define "main"}}
<form id="loginForm" action="/api/v1/user/register" method="POST" class="center-block">
<div class="form-group">
<label for="password">Password</label>
<input type="password" name="password" id="password" class="form-control" placeholder="Password" />
<input type="password" id="password_confirm" class="form-control" placeholder="Verify password" />
</div>
<div id="divCheckPasswordMatch"></div>
<div id="invalidCredentials">
Username already exists
</div>
<input type="submit" value="Login" class="form-control" />
</form>
{{end}}-->
<script>
export default {
data() {
return {
login: {
email: "",
password: "",
name: ""
}
}
},
methods: {
formSubmit (e) {
e.preventDefault();
fetch("/api/v1/user/register", {method: "POST", body: JSON.stringify(this.$data.login)})
.then(x => x.json())
.then(x => {
this.$data.error = ""
this.$store.commit("setToken", x.token);
})
.catch(x => this.$data.error = ["Something went wrong!"]);
// TODO display invalidCredentials
// TODO redirect to dashboard on success
}
}
}
</script>
<template>
<v-container>
<v-row>
<v-col cols="12">
<v-text-field v-model="login.email" type="text" label="E-Mail" />
</v-col>
<v-col cols="12">
<v-text-field v-model="login.name" type="text" label="Name" />
</v-col>
<v-col cols="6">
<v-text-field v-model="login.password" label="Password"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showPassword ? 'text' : 'password'"
@click:append="showPassword = showPassword"
:error-message="error"
error-count="2"
error />
</v-col>
<v-col cols="6">
<v-text-field v-model="login.password" label="Repeat password"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showPassword ? 'text' : 'password'"
@click:append="showPassword = showPassword"
:error-message="error"
error-count="2"
error />
</v-col>
</v-row>
<div class="form-group">
{{ error }}
</div>
<v-btn type="submit" @click="formSubmit">Register</v-btn>
<p>
Existing user? <router-link to="/login">Login</router-link> instead!
</p>
</v-container>
</template>

View File

@ -2,10 +2,12 @@ import { createRouter, createWebHashHistory } from 'vue-router'
import Budget from '../pages/Budget.vue'; import Budget from '../pages/Budget.vue';
import Dashboard from '../pages/Dashboard.vue'; import Dashboard from '../pages/Dashboard.vue';
import Login from '../pages/Login.vue'; import Login from '../pages/Login.vue';
import Register from '../pages/Register.vue';
const routes = [ const routes = [
{ path: '/', name: 'Index', component: Dashboard }, { path: '/', name: 'Index', component: Dashboard },
{ path: '/login', name: 'Login', component: Login }, { path: '/login', name: 'Login', component: Login },
{ path: '/register', name: 'Register', component: Register },
{ path: '/budget/:budgetid', name: 'Budget', component: Budget }, { path: '/budget/:budgetid', name: 'Budget', component: Budget },
] ]

File diff suppressed because it is too large Load Diff