diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index c1d2fe3..c1d4158 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -13,7 +13,7 @@ "identifier": "http:default", "allow": [ { - "url": "http://192.168.1.147:*" + "url": "http://127.0.0.1:*" }, { "url": "https://alatreon.org/chatapp/*" @@ -25,7 +25,7 @@ "identifier": "websocket:default", "allow": [ { - "url": "ws://192.168.1.147:*" + "url": "ws://127.0.0.1:*" }, { "url": "wss://alatreon.org/chatapp/*" diff --git a/src/api/client.ts b/src/api/client.ts index bbd4f33..7dc70a2 100644 --- a/src/api/client.ts +++ b/src/api/client.ts @@ -1,5 +1,5 @@ import { fetch } from '@tauri-apps/plugin-http'; -import { initAuth, logout } from '../store.ts' +import { getAuthData, clearAuthData } from '../authStore' import { API } from '../main.ts' import router from '../router' @@ -7,12 +7,11 @@ export async function apiFetch( path: string, options: RequestInit = {} ): Promise { - const auth = await initAuth() + const auth = await getAuthData() const res = await fetch(`${API}${path}`, { - method: options.method || 'GET', - body: options.body, ...options, + method: options.method || 'GET', headers: { 'Content-Type': 'application/json', ...(auth.token ? { Authorization: `Bearer ${auth.token}` } : {}), @@ -21,7 +20,7 @@ export async function apiFetch( }) if (res.status === 401) { - await logout() + await clearAuthData() router.push('/login') throw new Error("Session expired") } diff --git a/src/api/rooms.ts b/src/api/rooms.ts index 2f653b8..29c8ac4 100644 --- a/src/api/rooms.ts +++ b/src/api/rooms.ts @@ -1,8 +1,8 @@ import { apiFetch } from './client' -import type { Room } from '../types' +import type { Room, RoomInvite } from '../types' -export function fetchRooms(userUuid: string) { - return apiFetch(`/rooms/${userUuid}`) +export function fetchRooms() { + return apiFetch(`/rooms`) } export function createRoom(name: string, global: boolean) { @@ -12,3 +12,20 @@ export function createRoom(name: string, global: boolean) { }) } +export function fetchRoomInvites() { + return apiFetch('/rooms/invites') +} + +export function sendRoomInvite(receiverUsername: string, roomUuid: string) { + return apiFetch('/rooms/invite', { + method: 'POST', + body: JSON.stringify({ receiver_username: receiverUsername, room_uuid: roomUuid }), + }); +} + +export function acceptRoomInvite(senderUuid: string, roomUuid: string) { + return apiFetch('/rooms/join', { + method: 'POST', + body: JSON.stringify({ sender_uuid: senderUuid, room_uuid: roomUuid }), + }) +} diff --git a/src/authStore.ts b/src/authStore.ts new file mode 100644 index 0000000..bbc7f96 --- /dev/null +++ b/src/authStore.ts @@ -0,0 +1,41 @@ +import { load, Store } from '@tauri-apps/plugin-store' + +let store: Store | null = null + +async function getStore() { + if (!store) store = await load('store.json') + return store +} + +export async function getAuthData() { + const s = await getStore() + const token = await s.get('token') + const uuid = await s.get('uuid') + return { token: token || null, uuid: uuid || null, isAuthenticated: !!token } +} + +export async function saveAuthData(token: string, uuid: string) { + const s = await getStore() + await s.set('token', token) + await s.set('uuid', uuid) + await s.save() +} + +export async function clearAuthData() { + const s = await getStore() + await s.delete('token') + await s.delete('uuid') + await s.save() +} + +export async function setLastRoom(uuid: string) { + if (!uuid || uuid === 'none') return + const s = await getStore() + await s.set('last_room_uuid', uuid) + await s.save() +} + +export async function getLastRoom(): Promise { + const s = await getStore() + return (await s.get('last_room_uuid')) ?? null +} diff --git a/src/components/MessageInput.vue b/src/components/MessageInput.vue index f6631a6..d8b3eb2 100644 --- a/src/components/MessageInput.vue +++ b/src/components/MessageInput.vue @@ -1,5 +1,5 @@ + + diff --git a/src/router.ts b/src/router.ts index e2659be..b531476 100644 --- a/src/router.ts +++ b/src/router.ts @@ -4,6 +4,7 @@ import { initAuth, getLastRoom, setLastRoom } from './store' import LoginPage from './pages/LoginPage.vue' import ChatPage from './pages/ChatPage.vue' import FriendListPage from './pages/FriendListPage.vue' +import NofificationsPage from './pages/NotificationsPage.vue' const router = createRouter({ history: createWebHistory(), @@ -21,7 +22,8 @@ const router = createRouter({ component: ChatPage, props: true }, - { path: '/friendlist', component: FriendListPage } + { path: '/friendlist', component: FriendListPage }, + { path: '/notifications', component: NofificationsPage } ], }) diff --git a/src/store.ts b/src/store.ts index 71488e9..18e0b9a 100644 --- a/src/store.ts +++ b/src/store.ts @@ -1,36 +1,10 @@ -import { load, Store } from '@tauri-apps/plugin-store' -import type { LoginResponse } from './types' import { apiFetch } from './api/client' +import type { LoginResponse } from './types' +import * as authStore from './authStore' -let store: Store | null = null - -async function getStore() { - if (!store) { - store = await load('store.json') - } - return store -} - -export async function setLastRoom(uuid: string) { - if (!uuid || uuid === 'none') return - - const s = await getStore() - await s.set('last_room_uuid', uuid) - await s.save() -} - -export async function getLastRoom(): Promise { - const s = await getStore() - const lastRoom = await s.get('last_room_uuid') - return lastRoom ?? null -} - -export async function initAuth() { - const s = await getStore() - const token = await s.get('token') - const uuid = await s.get('uuid') - return { token: token || null, uuid: uuid || null, isAuthenticated: !!token } -} +export const initAuth = authStore.getAuthData +export const getLastRoom = authStore.getLastRoom +export const setLastRoom = authStore.setLastRoom export async function login(email: string, username: string, password: string) { const res: LoginResponse = await apiFetch('/login', { @@ -38,35 +12,23 @@ export async function login(email: string, username: string, password: string) { body: JSON.stringify({ email, username, password }), }) - const s = await getStore() - await s.set('token', res.token) - await s.set('uuid', res.uuid) - await s.save() - + await authStore.saveAuthData(res.token, res.uuid) return { token: res.token, uuid: res.uuid, isAuthenticated: true } } export async function logout() { - const s = await getStore() - await s.delete('token') - await s.delete('uuid') - await s.save() + await authStore.clearAuthData() return { token: null, uuid: null, isAuthenticated: false } } export async function validateToken(): Promise { - const auth = await initAuth() + const auth = await authStore.getAuthData() if (!auth.token) return false try { await apiFetch('/validate-token') return true - } catch (e: any) { - // Only logout if token is bad - if (e.message.includes('401')) { - await logout() - return false - } - return true + } catch (e) { + return false } } diff --git a/src/types.ts b/src/types.ts index 9436461..6aab130 100644 --- a/src/types.ts +++ b/src/types.ts @@ -27,3 +27,10 @@ export interface FriendRequest { sender_uuid: string sender_username: string } + +export interface RoomInvite { + room_uuid: string + room_name: string + sender_uuid: string + sender_username: string +}