diff --git a/app.vue b/app.vue index 643fc86..47873f0 100644 --- a/app.vue +++ b/app.vue @@ -1,7 +1,13 @@ + + \ No newline at end of file diff --git a/components/Message.vue b/components/Message.vue index 78f2889..70115c5 100644 --- a/components/Message.vue +++ b/components/Message.vue @@ -1,7 +1,7 @@ @@ -108,27 +98,38 @@ onMounted(async () => { \ No newline at end of file diff --git a/composables/auth.ts b/composables/auth.ts index ccb45ca..19ac694 100644 --- a/composables/auth.ts +++ b/composables/auth.ts @@ -30,11 +30,11 @@ export const useAuth = () => { { username, password: hashedPass, device_name: "Linux Laptop" } - }) as { access_token: string, refresh_token: string }; fetch + }) as { access_token: string, refresh_token: string }; console.log("hi"); accessToken.value = res.access_token; console.log("access token:", accessToken.value); - await fetchUser(); + //await fetchUser(); } async function logout(password: string) { @@ -60,19 +60,21 @@ export const useAuth = () => { async function refresh() { console.log("refreshing"); - try { - const res = await fetchWithApi("/auth/refresh", { - method: "POST" - }) as { access_token: string }; + const res = await fetchWithApi("/auth/refresh", { + method: "POST" + }) as any; + console.log("finished refreshing:", res); + if (res && res.access_token) { accessToken.value = res.access_token; console.log("set new access token"); - } catch (error) { - console.error("refresh error:", error); + } else { + console.log("refresh didn't return access token"); } } async function fetchUser() { if (!accessToken.value) return; + console.log("fetchuser access token:", accessToken.value); const res = await fetchWithApi("/users/me") as UserResponse; user.value = res; return user.value; diff --git a/error.vue b/error.vue new file mode 100644 index 0000000..dff8c5f --- /dev/null +++ b/error.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/layouts/auth.vue b/layouts/auth.vue index f90dc84..356dcd5 100644 --- a/layouts/auth.vue +++ b/layouts/auth.vue @@ -1,7 +1,6 @@ @@ -74,7 +74,9 @@ const errorMessages = reactive({ //const authStore = useAuthStore(); const auth = useAuth(); -const redirectTo = useRoute().query.redirect_to; +const query = useRoute().query as Record; +const searchParams = new URLSearchParams(query); +const loginUrl = `/login?${searchParams}` onMounted(() => { if (auth.accessToken.value) { @@ -120,7 +122,12 @@ const apiVersion = useRuntimeConfig().public.apiVersion; async function register(e: Event) { e.preventDefault(); console.log("Sending registration data"); - await auth.register(form.username, form.email, form.password); + try { + await auth.register(form.username, form.email, form.password); + return await navigateTo(query.redirect_to); + } catch (error) { + console.error("Error registering:", error); + } //return navigateTo(redirectTo ? redirectTo as string : useAppConfig().baseURL as string); } diff --git a/pages/servers/[serverId]/channels/[channelId].vue b/pages/servers/[serverId]/channels/[channelId].vue index efa2858..eb6ba46 100644 --- a/pages/servers/[serverId]/channels/[channelId].vue +++ b/pages/servers/[serverId]/channels/[channelId].vue @@ -39,25 +39,20 @@ const route = useRoute(); -const server: GuildResponse | undefined = await fetchWithApi(`servers/${route.params.serverId}`); - -const channels: ChannelResponse[] | undefined = await fetchWithApi( - `servers/${route.params.serverId}/channels` -); -const channel: ChannelResponse | undefined = await fetchWithApi( - route.path -); +const loading = useState("loading"); const channelUrlPath = `servers/${route.params.serverId}/channels/${route.params.channelId}`; -console.log("channel:", channel); +const server = ref(); +const channels = ref(); +const channel = ref(); const showInvitePopup = ref(false); import type { ChannelResponse, GuildResponse, MessageResponse } from "~/types/interfaces"; //const servers = await fetchWithApi("/servers") as { uuid: string, name: string, description: string }[]; -//console.log("servers:", servers); +//console.log("channelid: servers:", servers); const members = [ { id: "3287484395", @@ -106,6 +101,23 @@ const members = [ } ]; +onMounted(async () => { + loading.value = true; + console.log("channelid: set loading to true"); + server.value = await fetchWithApi(`servers/${route.params.serverId}`); + + channels.value = await fetchWithApi( + `servers/${route.params.serverId}/channels` + ); + channel.value = await fetchWithApi( + route.path + ); + + console.log("channelid: channel:", channel); + loading.value = false; + console.log("channelid: set loading to false"); +}); + function showServerSettings() { } function toggleInvitePopup(e: Event) { diff --git a/pages/verify-email.vue b/pages/verify-email.vue new file mode 100644 index 0000000..cae02ea --- /dev/null +++ b/pages/verify-email.vue @@ -0,0 +1,32 @@ + + + + + \ No newline at end of file diff --git a/types/interfaces.ts b/types/interfaces.ts index 05830d2..c0c87a9 100644 --- a/types/interfaces.ts +++ b/types/interfaces.ts @@ -32,10 +32,11 @@ export interface ChannelResponse { } export interface MessageResponse { - uuid: string - channel_uuid: string - user_uuid: string - message: string + uuid: string, + channel_uuid: string, + user_uuid: string, + message: string, + user: UserResponse } export interface InviteResponse { @@ -49,6 +50,6 @@ export interface UserResponse { username: string, display_name: string | null, avatar: string | null, - email: string, - email_verified: boolean + email?: string, + email_verified?: boolean } diff --git a/utils/fetchWithApi.ts b/utils/fetchWithApi.ts index c0ebf2e..79fdae8 100644 --- a/utils/fetchWithApi.ts +++ b/utils/fetchWithApi.ts @@ -9,63 +9,74 @@ export default async (path: string, options: NitroFetchOptions = {}) path = path.slice(0, path.lastIndexOf("/")); } console.log("formatted path:", path); - try { - const accessToken = useCookie("access_token"); - console.log("access token:", accessToken.value); - const apiBase = useCookie("api_base").value; - const apiVersion = useRuntimeConfig().public.apiVersion; - console.log("heyoooo") - console.log("apiBase:", apiBase); - if (!apiBase) { - console.log("no api base"); - return; - } - console.log("path:", path) - const { revoke, refresh } = useAuth(); - console.log("access token 2:", accessToken.value); - - let headers: HeadersInit = {}; - - if (accessToken.value) { - headers = { - ...options.headers, - "Authorization": `Bearer ${accessToken.value}` - }; - } else { - headers = { - ...options.headers - }; - } - - let reauthFailed = false; - while (!reauthFailed) { - try { - console.log("fetching:", URL.parse(apiBase + path)); - const res = await $fetch(URL.parse(apiBase + path)!.href, { - ...options, - headers, - credentials: "include" - }); - - return res; - } catch (error: any) { - if (error?.response?.status === 401) { - if (!path.startsWith("/auth/refresh")) { - try { - await refresh(); - } catch (error: any) { - if (error?.response?.status === 401) { - reauthFailed = true; - await revoke(); - return; - } + const accessToken = useCookie("access_token"); + console.log("access token:", accessToken.value); + const apiBase = useCookie("api_base").value; + const apiVersion = useRuntimeConfig().public.apiVersion; + console.log("heyoooo") + console.log("apiBase:", apiBase); + if (!apiBase) { + console.log("no api base"); + return; + } + console.log("path:", path) + const { revoke, refresh } = useAuth(); + console.log("access token 2:", accessToken.value); + + let headers: HeadersInit = {}; + + if (accessToken.value) { + headers = { + ...options.headers, + "Authorization": `Bearer ${accessToken.value}` + }; + } else { + headers = { + ...options.headers + }; + } + + let reauthFailed = false; + while (!reauthFailed) { + try { + console.log("fetching:", URL.parse(apiBase + path)); + const res = await $fetch(URL.parse(apiBase + path)!.href, { + ...options, + headers, + credentials: "include" + }); + + return res; + } catch (error: any) { + console.error("Error fetching resource"); + if (error?.response?.status === 401) { + console.log("Error status is 401"); + if (!path.startsWith("/auth/refresh")) { + console.log("Path is not refresh endpoint"); + try { + console.log("Trying to refresh"); + await refresh(); + console.log("Successfully refreshed token"); + } catch (error: any) { + console.log("Failed to refresh token"); + if (error?.response?.status === 401) { + console.log("Refresh returned 401"); + reauthFailed = true; + console.log("Revoking"); + await revoke(); + console.log("Redirecting to login"); + await navigateTo("/login"); + console.log("redirected"); + return; } } + } else { + console.log("Path is refresh endpoint, throwing error"); + throw error; } - throw error; } + console.log("throwing error"); + throw error; } - } catch (error) { - console.error("error:", error); } } diff --git a/utils/scrollToBottom.ts b/utils/scrollToBottom.ts new file mode 100644 index 0000000..aca99b4 --- /dev/null +++ b/utils/scrollToBottom.ts @@ -0,0 +1,6 @@ +export default (element: Ref) => { + if (element.value) { + element.value.scrollTo({ top: element.value.scrollHeight }); + return; + } +}