Implement register and login using vuetify
This commit is contained in:
parent
d59b9bdbec
commit
3de0447eba
@ -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(®ister)
|
||||||
|
|
||||||
|
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 {
|
||||||
|
@ -19,13 +19,19 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ul>
|
<v-app>
|
||||||
<li v-if="!loggedIn"><router-link to="/login">Login</router-link></li>
|
<v-app-bar app>
|
||||||
<li v-if="loggedIn"><a @click="logout">Logout</a></li>
|
<ul>
|
||||||
<li v-if="loggedIn"><router-link to="/">Dashboard</router-link></li>
|
<li v-if="!loggedIn"><router-link to="/login">Login</router-link></li>
|
||||||
</ul>
|
<li v-if="loggedIn"><a @click="logout">Logout</a></li>
|
||||||
|
<li v-if="loggedIn"><router-link to="/">Dashboard</router-link></li>
|
||||||
|
</ul>
|
||||||
|
</v-app-bar>
|
||||||
|
|
||||||
<router-view></router-view>
|
<v-main>
|
||||||
|
<router-view></router-view>
|
||||||
|
</v-main>
|
||||||
|
</v-app>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -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')
|
||||||
|
@ -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>
|
||||||
<div class="form-group">
|
<v-row>
|
||||||
<label for="username">User</label>
|
<v-col cols="12">
|
||||||
<input type="text" class="form-control" placeholder="User" v-model="login.user" />
|
<v-text-field v-model="login.user" type="text" label="Username" />
|
||||||
</div>
|
</v-col>
|
||||||
|
<v-col cols="12">
|
||||||
<div class="form-group">
|
<v-text-field v-model="login.password" label="Password"
|
||||||
<label for="password">Password</label>
|
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
|
||||||
<input type="password" class="form-control" placeholder="Password" v-model="login.password" />
|
:type="showPassword ? 'text' : 'password'"
|
||||||
<p v-if="error">
|
@click:append="showPassword = showPassword"
|
||||||
The entered credentials are invalid
|
:error-message="error"
|
||||||
</p>
|
error-count="2"
|
||||||
</div>
|
error />
|
||||||
|
</v-col>
|
||||||
<input type="submit" value="Login" class="btn btn-default" on/>
|
</v-row>
|
||||||
|
<div class="form-group">
|
||||||
<p>
|
{{ error }}
|
||||||
New user? <a href="/register">Register</a> instead!
|
</div>
|
||||||
</p>
|
<v-btn type="submit" @click="formSubmit">Login</v-btn>
|
||||||
</form>
|
<p>
|
||||||
|
New user? <router-link to="/register">Register</router-link> instead!
|
||||||
|
</p>
|
||||||
|
</v-container>
|
||||||
</template>
|
</template>
|
126
web/src/pages/Register.vue
Normal file
126
web/src/pages/Register.vue
Normal 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>
|
@ -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 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
5652
web/yarn.lock
5652
web/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user