diff --git a/src/App.vue b/src/App.vue
index 60a16a3..4e0f5da 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -2,12 +2,13 @@
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/Welcome.vue'
import { store } from './store.js'
-
+import {clearSession} from "./store.js";
/**
* Logout the user.
*/
function logOut() {
- store.loggedIn = false;
+ clearSession();
+ location.href = "/";
}
@@ -22,7 +23,7 @@ function logOut() {
diff --git a/src/components/OAuthCallback.vue b/src/components/OAuthCallback.vue
deleted file mode 100644
index e86c662..0000000
--- a/src/components/OAuthCallback.vue
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
diff --git a/src/router/index.js b/src/router/index.js
index d0da141..2ea8559 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -10,6 +10,7 @@ import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import OAUthError from "../components/OAUthError.vue";
import { objectToQueryString } from "../util/net";
+import {createUser, oauthCallbackHandler} from "../util/oauth";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@@ -44,48 +45,23 @@ router.beforeEach(async (to, from) => {
if (to.path === "/oauth-callback") {
let queryString = objectToQueryString(to.query);
console.info(`Got /oauth-callback with query string '${queryString}`);
- /* Pass the query parameters to the broker to complete login. We will get
- * the session token and user data in return.
- *
- * The URL we post to is broker's base URL and the `openid_connect_path`
- * setting from broker's config.
- */
- const response = await fetch(`${store.baseboxHost}/oauth/complete-login?${queryString}`, {
- method: "POST",
- });
- if (!response.ok) {
- /* redirect to error component */
- console.error("Failed to complete login/get session data: " + response.statusText);
- return {
- name: 'oauth-error',
- query: {
- code: response.status,
- addlInfo: await response.text()
- }
- }
+
+ /* Pass the query string to the handler function */
+ try {
+ await oauthCallbackHandler(queryString);
+ /* Success; redirect to home */
+ } catch (err) {
+ console.error("Failed to finish login: " + err);
}
- /* store session data; this is a JSON object of the following form:
- {
- "token":"47caa9df-ac89-45a8-8b22-9c0925d6aed0",
- "username":"tester",
- "first_name":"Fred",
- "last_name":"Feuerstein",
- "roles":[
- "/user"
- ],
- "claims":{
- "groups":[
- "/user"
- ]
- }
- }
- */
- store.session = await response.json();
- store.userName = store.session.first_name ? store.session.first_name : store.session.username;
+ /* We have to create the logged-in user explicitly; see comment for `createUser()` */
+ try {
+ await createUser();
+ } catch (err) {
+ console.error("Failed to create user: " + err);
+ }
- /* redirect to home */
- return { name: 'home' };
+ return {name: 'home'};
}
});
diff --git a/src/store.js b/src/store.js
index 7eec886..72953c4 100644
--- a/src/store.js
+++ b/src/store.js
@@ -11,11 +11,27 @@ export const store = reactive({
/** Username of the currently logged-in user */
userName: "stranger",
- /** The host that runs basebox and waits for GraphQL requests */
+ /** base URL of basebox broker host */
baseboxHost: "http://127.0.0.1:8080",
/** basebox session data */
- session: null,
+ session: {},
+
+});
+
+/**
+ * Return true if the user is logged in.
+ */
+export function loggedIn() {
+ return store.session && store.session.token;
+}
+
+/**
+ * Clear session data.
+ */
+export function clearSession() {
+ store.session = {};
+}
+
-})
diff --git a/src/util/net.js b/src/util/net.js
index 934a10d..3a004f8 100644
--- a/src/util/net.js
+++ b/src/util/net.js
@@ -5,8 +5,7 @@
* https://basebox.tech
*/
-import {store} from "../store";
-import router from "../router";
+import {clearSession, store} from "../store";
/**
* GqlError - custom error thrown by the gqlQuery function.
@@ -114,7 +113,7 @@ export function gqlQuery(query)
console.info(fetchOpt);
- return fetch(store.getters.gqlUrl, fetchOpt).then(
+ return fetch(`${store.baseboxHost}/graphql`, fetchOpt).then(
/* fetch success */
async response => {
if (response.ok) {
@@ -128,27 +127,25 @@ export function gqlQuery(query)
} else {
/* some errors... */
return new Promise((resolve, reject) => {
- const error = new GqlError(rspJson);
- /* if this is a 401, we redirect to the login page */
- if (error.is401()) {
- router.push({
- name: "Login",
- query: {
- next: router.currentRoute.fullPath,
- }
- });
- }
reject(new GqlError(rspJson));
});
}
} else {
/* low level/network error */
+ /* if this is a 401, we clear the session data */
+ if (response.status === 401) {
+ console.error("Last request failed: unauthorized. Clearing session.");
+ clearSession();
+ return new Promise((resolve, reject) => reject("Unauthorized"));
+ }
+
return new Promise((resolve, reject) => {
reject(new GqlError(response.statusText));
});
}
},
+
/* fetch failure */
reason => {
return new Promise((resolve, reject) => {
diff --git a/src/util/oauth.js b/src/util/oauth.js
index 08d5214..2f31e22 100644
--- a/src/util/oauth.js
+++ b/src/util/oauth.js
@@ -44,23 +44,18 @@ import {gqlQuery} from "./net";
*/
export async function oauthCallbackHandler(queryString) {
- fetch(`${store.baseboxHost}/oauth/complete-login?${queryString}`, {
+ /* Pass query string to the broker to complete the login process. */
+ const response = await fetch(`${store.baseboxHost}/oauth/complete-login?${queryString}`, {
method: "POST",
- }).then(response => {
- if (!response.ok) {
- throw new Error("Failed to get session data: " + response.statusText);
- }
-
- /* Store session data */
- response.json(
- ).then(rspJson => {
- store.session = rspJson;
- store.userName = store.session.first_name ? store.session.first_name : store.session.username;
- });
-
- }).catch(e => {
- throw new Error("Failed to get session data: " + e.toString());
});
+ if (!response.ok) {
+ throw new Error("Failed to get session data: " + response.statusText);
+ }
+
+ /* Store session data */
+ const rspJson = await response.json();
+ store.session = { ...rspJson };
+ store.userName = store.session.first_name ? store.session.first_name : store.session.username;
}
/**
@@ -70,21 +65,17 @@ export async function oauthCallbackHandler(queryString) {
* make sure that out user is known in the app database (basebox broker). After successful
* login, this function must be called to do that.
*
- * @param username unique username of new user
- * @param firstName first name of new user
- * @param lastName last name of new user
- * @returns {Promise}
+ * @throws Error if the user creation failed.
*/
-async function createUser(username, firstName, lastName) {
+export async function createUser() {
- gqlQuery(`query {
+ await gqlQuery(`mutation {
createUser(
- username: "${username}",
- name: "${firstName} ${lastName}"
- )`
- ).catch(err => {
-
- });
-
+ username: "${store.session.username}",
+ name: "${store.session.first_name} ${store.session.last_name}"
+ ) {
+ username
+ }
+ }`);
}
\ No newline at end of file
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 2a0c619..f686087 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -7,6 +7,7 @@