diff --git a/general/components/Header/AuthLoginModal.vue b/general/components/Header/AuthLoginModal.vue
index 0fb89758..ba50869c 100644
--- a/general/components/Header/AuthLoginModal.vue
+++ b/general/components/Header/AuthLoginModal.vue
@@ -64,6 +64,21 @@
Create an account
+
@@ -80,6 +95,8 @@ const toastStore = useToastStore();
const authStore = useAuthStore();
const authModalStore = useAuthModalStore();
+const route = useRoute();
+
const identifier = ref('');
const password = ref('');
const error = ref(null);
@@ -117,8 +134,7 @@ const handleSubmit = async () => {
});
if (response.jwt && response.user) {
- authStore.setJwt(response.jwt);
- authStore.setUserData(response.user);
+ await authStore.loginAndFetchProfile(response.jwt, response.user);
toastStore.addToast('You are logged in.');
hideModal();
} else {
@@ -142,5 +158,29 @@ const handleSubmit = async () => {
}
};
+const connectGithub = () => {
+ const githubConnectUrl = `${baseURL()}/api/connect/github`;
+
+ authStore.setRedirectLink(route.fullPath);
+
+ window.location.href = githubConnectUrl;
+};
+
const modalOpen = computed(() => authModalStore.authModal === 'login');
+
+
diff --git a/general/pages/connect/github.vue b/general/pages/connect/github.vue
new file mode 100644
index 00000000..69f9a366
--- /dev/null
+++ b/general/pages/connect/github.vue
@@ -0,0 +1,135 @@
+
+
+
+
+
+ Connecting
+ {{ statusMessage }}
+
+
+
+
+
+
+
+
diff --git a/general/stores/auth.ts b/general/stores/auth.ts
index 97660a97..51daaf52 100644
--- a/general/stores/auth.ts
+++ b/general/stores/auth.ts
@@ -1,4 +1,5 @@
import { defineStore } from 'pinia';
+import { useRuntimeConfig } from '#app';
export interface UserData {
id: number;
@@ -22,6 +23,7 @@ export interface UserData {
interface AuthState {
jwt: string | null;
user: UserData | null;
+ redirectLink: string | null;
}
export const useAuthStore = defineStore({
@@ -29,7 +31,8 @@ export const useAuthStore = defineStore({
state: (): AuthState => {
return {
jwt: null,
- user: null
+ user: null,
+ redirectLink: null
};
},
actions: {
@@ -39,9 +42,56 @@ export const useAuthStore = defineStore({
setUserData(user: UserData) {
this.user = user;
},
+ setRedirectLink(link: string) {
+ this.redirectLink = link;
+ },
+ clearRedirectLink() {
+ this.redirectLink = null;
+ },
+ async fetchFullProfile() {
+ if (!this.jwt) {
+ throw new Error('No JWT token available');
+ }
+
+ const runtimeConfig = useRuntimeConfig();
+ const baseURL =
+ typeof window !== 'undefined'
+ ? window.location.origin + `${runtimeConfig.public.strapiBasePath}`
+ : `${runtimeConfig.public.strapiBaseUrl}`;
+
+ try {
+ const response = await $fetch(
+ `${baseURL}/api/users/me?populate=role`,
+ {
+ method: 'GET',
+ headers: {
+ Authorization: `Bearer ${this.jwt}`
+ }
+ }
+ );
+
+ if (response) {
+ this.setUserData(response);
+ } else {
+ throw new Error('Invalid response from server');
+ }
+ } catch (error) {
+ console.error('Error fetching full profile:', error);
+ throw error;
+ }
+ },
+ async loginAndFetchProfile(
+ jwt: string,
+ initialUserData: Partial
+ ) {
+ this.setJwt(jwt);
+ this.setUserData({ ...initialUserData } as UserData);
+ await this.fetchFullProfile();
+ },
clear() {
this.jwt = null;
this.user = null;
+ this.redirectLink = null;
}
},
persist: {
@@ -49,7 +99,7 @@ export const useAuthStore = defineStore({
const runtimeConfig = useRuntimeConfig();
return `ontoviewer-auth-${runtimeConfig.public.ontologyName}`;
},
- storage: process.client ? localStorage : undefined,
- paths: ['jwt', 'user']
+ storage: import.meta.client ? localStorage : undefined,
+ paths: ['jwt', 'user', 'redirectLink']
}
});