Add user registration

This commit is contained in:
Simone Gotti 2019-03-29 18:08:54 +01:00
parent fcb3ea9b54
commit ef5a9c4994
10 changed files with 213 additions and 45 deletions

View File

@ -36,6 +36,7 @@
</div> </div>
</div> </div>
<div v-else class="navbar-item"> <div v-else class="navbar-item">
<router-link class="button" to="/register">Sign up</router-link>
<router-link class="button" to="/login">Login</router-link> <router-link class="button" to="/login">Login</router-link>
</div> </div>
</div> </div>

View File

@ -1,4 +1,3 @@
<template> <template>
<div> <div>
<div class="field"> <div class="field">
@ -25,7 +24,7 @@
<button <button
@click="$emit('login', { username, password })" @click="$emit('login', { username, password })"
class="button is-info is-fullwidth" class="button is-info is-fullwidth"
>Login with {{name}}</button> >{{action}} with {{name}}</button>
</p> </p>
</div> </div>
</div> </div>
@ -36,8 +35,9 @@
import { apiurl, loginurl, fetch } from "@/util/auth"; import { apiurl, loginurl, fetch } from "@/util/auth";
export default { export default {
name: "Loginform", name: "LoginForm",
props: { props: {
action: String,
name: String name: String
}, },
data: function() { data: function() {

View File

@ -0,0 +1,35 @@
<template>
<div>
<div class="field">
<p class="control has-icons-left has-icons-right">
<input v-model="username" class="input" type="email" placeholder="Email">
<span class="icon is-small is-left">
<i class="fas fa-envelope"></i>
</span>
<span class="icon is-small is-right">
<i class="fas fa-check"></i>
</span>
</p>
</div>
<div class="field">
<p class="control">
<button @click="$emit('login', { username })" class="button is-info is-fullwidth">Register</button>
</p>
</div>
</div>
</template>
<script>
import { apiurl, loginurl, fetch } from "@/util/auth";
export default {
name: "RegisterForm",
props: {
username: String
}
};
</script>

View File

@ -21,6 +21,7 @@ new Vue({
if (user) { if (user) {
store.dispatch('setUser', user) store.dispatch('setUser', user)
} }
store.dispatch("setRegisterUser", null)
}, },
render: h => h(App) render: h => h(App)
}).$mount("#app"); }).$mount("#app");

View File

@ -11,6 +11,7 @@ import runs from "./components/runs.vue";
import run from "./components/run.vue"; import run from "./components/run.vue";
import task from "./components/task.vue"; import task from "./components/task.vue";
import Oauth2 from "./views/Oauth2.vue"; import Oauth2 from "./views/Oauth2.vue";
import Register from "./views/Register.vue";
import Login from "./views/Login.vue"; import Login from "./views/Login.vue";
import Logout from "./views/Logout.vue"; import Logout from "./views/Logout.vue";
@ -19,6 +20,11 @@ Vue.use(VueRouter);
export default new VueRouter({ export default new VueRouter({
mode: "history", mode: "history",
routes: [ routes: [
{
path: "/register",
name: "register",
component: Register,
},
{ {
path: "/login", path: "/login",
name: "login", name: "login",

View File

@ -5,23 +5,33 @@ Vue.use(Vuex)
const state = { const state = {
user: null, user: null,
registeruser: null
} }
const getters = { const getters = {
user: state => { user: state => {
return state.user return state.user
},
registeruser: state => {
return state.registeruser
} }
} }
const mutations = { const mutations = {
setUser(state, user) { setUser(state, user) {
state.user = user state.user = user
},
setRegisterUser(state, user) {
state.registeruser = user
} }
} }
const actions = { const actions = {
setUser({ commit }, user) { setUser({ commit }, user) {
commit('setUser', user) commit('setUser', user)
},
setRegisterUser({ commit }, user) {
commit('setRegisterUser', user)
} }
} }

View File

@ -36,11 +36,19 @@ export function loginurl() {
return new URL(API_URL + "/login"); return new URL(API_URL + "/login");
} }
export function authorizeurl() {
return new URL(API_URL + "/authorize");
}
export function registerurl() {
return new URL(API_URL + "/register");
}
export function oauth2callbackurl() { export function oauth2callbackurl() {
return new URL(API_URL + "/oauth2/callback"); return new URL(API_URL + "/oauth2/callback");
} }
export function fetch(url, init) { export async function fetch(url, init) {
if (init === undefined) { if (init === undefined) {
init = {} init = {}
} }
@ -52,11 +60,10 @@ export function fetch(url, init) {
init.headers["Authorization"] = "bearer " + idToken init.headers["Authorization"] = "bearer " + idToken
} }
return window.fetch(url, init).then(res => { let res = await window.fetch(url, init)
if (res.status === 401) { if (res.status === 401) {
router.push({ name: "login" }) router.push({ name: "login" })
} else { return res } } else { return res }
})
} }
export function setIdToken(idToken) { export function setIdToken(idToken) {

View File

@ -2,7 +2,8 @@
<div> <div>
<div class="column is-4 is-offset-4"> <div class="column is-4 is-offset-4">
<div class="box" v-for="rs in remotesources" v-bind:key="rs.id"> <div class="box" v-for="rs in remotesources" v-bind:key="rs.id">
<Loginform <LoginForm
action="Login"
:name="rs.name" :name="rs.name"
v-if="rs.auth_type == 'password'" v-if="rs.auth_type == 'password'"
v-on:login="doLogin(rs.name, $event.username, $event.password)" v-on:login="doLogin(rs.name, $event.username, $event.password)"
@ -18,13 +19,13 @@
</template> </template>
<script> <script>
import Loginform from "@/components/loginform"; import LoginForm from "@/components/loginform";
import { apiurl, loginurl, fetch, login, logout } from "@/util/auth"; import { apiurl, loginurl, fetch, login, logout } from "@/util/auth";
export default { export default {
name: "Login", name: "Login",
components: { components: {
Loginform LoginForm
}, },
data: function() { data: function() {
return { return {
@ -32,27 +33,21 @@ export default {
}; };
}, },
methods: { methods: {
getRemoteSources() { async getRemoteSources() {
fetch(apiurl("/remotesources")) let res = await (await fetch(apiurl("/remotesources"))).json();
.then(res => res.json())
.then(res => {
console.log("remote sources result", res); console.log("remote sources result", res);
this.remotesources = res; this.remotesources = res;
});
}, },
doLogin(rsName, username, password) { async doLogin(rsName, username, password) {
let u = loginurl(); let u = loginurl();
console.log("u:", u); let res = await (await fetch(u, {
fetch(u, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
remote_source_name: rsName, remote_source_name: rsName,
login_name: username, login_name: username,
password: password password: password
}) })
}) })).json();
.then(res => res.json())
.then(res => {
console.log("login result", res); console.log("login result", res);
if (res.oauth2_redirect) { if (res.oauth2_redirect) {
window.location = res.oauth2_redirect; window.location = res.oauth2_redirect;
@ -60,7 +55,6 @@ export default {
} }
login(res.token, res.user); login(res.token, res.user);
this.$router.push({ name: "home" }); this.$router.push({ name: "home" });
});
} }
}, },
created: function() { created: function() {

View File

@ -1,11 +1,12 @@
<template> <template>
<div> <div>
<div>{{code}}</div> <div>{{code}}</div>
<div>{{username}}</div>
</div> </div>
</template> </template>
<script> <script>
import { apiurl, oauth2callbackurl, fetch, setUser } from "@/util/auth"; import { apiurl, oauth2callbackurl, login, fetch } from "@/util/auth";
export default { export default {
components: {}, components: {},
@ -15,23 +16,24 @@ export default {
return { return {
run: null, run: null,
code: this.$route.query.code, code: this.$route.query.code,
polling: null polling: null,
username: null
}; };
}, },
methods: { methods: {
doOauth2() { async doOauth2() {
let u = oauth2callbackurl(); let u = oauth2callbackurl();
u.searchParams.append("code", this.$route.query.code); u.searchParams.append("code", this.$route.query.code);
u.searchParams.append("state", this.$route.query.state); u.searchParams.append("state", this.$route.query.state);
fetch(u) let res = await (await fetch(u)).json();
.then(res => res.json())
.then(res => {
console.log("oauth2 result", res); console.log("oauth2 result", res);
if (res.request_type === "loginuser") { if (res.request_type === "loginuser") {
this.$root.login(res.response.token, res.response.user); login(res.response.token, res.response.user);
this.$router.push("/"); this.$router.push("/");
} else if (res.request_type === "authorize") {
this.$store.dispatch("setRegisterUser", res.response);
this.$router.push("/register");
} }
});
} }
}, },
created: function() { created: function() {

112
src/views/Register.vue Normal file
View File

@ -0,0 +1,112 @@
<template>
<div>
<div v-if="registeruser" class="column is-4 is-offset-4">
<div>{{registeruser.remote_user_info.LoginName}}</div>
<RegisterForm
:username="registeruser.remote_user_info.LoginName"
v-on:login="doRegister(registeruser.remote_source_name, $event.username, registeruser.remote_source_login_name, registeruser.remote_source_login_password)"
/>
</div>
<div v-else class="column is-4 is-offset-4">
<div class="box" v-for="rs in remotesources" v-bind:key="rs.id">
<LoginForm
action="Register"
:name="rs.name"
v-if="rs.auth_type == 'password'"
v-on:login="doAuthorize(rs.name, $event.username, $event.password)"
/>
<button
v-else
class="button is-info is-fullwidth"
@click="doAuthorize(rs.name)"
>Register with {{rs.name}}</button>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from "vuex";
import LoginForm from "@/components/loginform";
import RegisterForm from "@/components/registerform";
import { apiurl, authorizeurl, registerurl, fetch, logout } from "@/util/auth";
export default {
name: "Register",
components: {
LoginForm,
RegisterForm
},
data: function() {
return {
remotesources: null
};
},
computed: {
...mapGetters(["registeruser"])
},
methods: {
async getRemoteSources() {
let res = await (await fetch(apiurl("/remotesources"))).json();
console.log("remote sources result", res);
this.remotesources = res;
},
async doAuthorize(rsName, username, password) {
let u = authorizeurl();
let res = await (await fetch(u, {
method: "POST",
body: JSON.stringify({
remote_source_name: rsName,
login_name: username,
password: password
})
})).json();
console.log("login result", res);
if (res.oauth2_redirect) {
window.location = res.oauth2_redirect;
return;
}
this.$store.dispatch("setRegisterUser", {
remote_user_info: res.remote_user_info,
remote_source_name: res.remote_source_name,
remote_source_login_name: username,
remote_source_login_password: password
});
},
async doRegister(
rsName,
username,
remote_login_name,
remote_login_password
) {
let u = registerurl();
let res = await (await fetch(u, {
method: "POST",
body: JSON.stringify({
username: username,
remote_source_name: rsName,
remote_source_login_name: remote_login_name,
remote_source_login_password: remote_login_password
})
})).json();
console.log("register result", res);
if (res.oauth2_redirect) {
window.location = res.oauth2_redirect;
return;
}
this.$router.push({ name: "home" });
}
},
created: function() {
logout();
this.getRemoteSources();
}
};
</script>