add vuex store and federation layer for api calls

This commit is contained in:
j3d1 2024-04-08 20:57:04 +02:00
parent 0fd49bc023
commit 8d64a3c528
4 changed files with 506 additions and 1 deletions

132
frontend/src/store.js Normal file
View file

@ -0,0 +1,132 @@
import {createStore} from 'vuex';
import router from '@/router';
import FallBackResolver from "@/dns";
import NeighborsCache from "@/neigbors";
import {createNullAuth, createSignAuth, createTokenAuth, ServerSet, ServerSetUnion} from "@/federation";
export default createStore({
state: {
local_loaded: false,
last_load: {},
user: null,
token: null,
keypair: null,
remember: false,
home_servers: null,
resolver: new FallBackResolver(),
unreachable_neighbors: new NeighborsCache(),
},
mutations: {
setUser(state, user) {
state.user = user;
if (state.remember)
localStorage.setItem('user', user);
},
setToken(state, token) {
state.token = token;
if (state.remember)
localStorage.setItem('token', token);
},
setKey(state, keypair) {
state.keypair = nacl.crypto_sign_keypair_from_seed(nacl.from_hex(keypair))
if (state.remember)
localStorage.setItem('keypair', nacl.to_hex(state.keypair.signSk).slice(0, 64))
},
setRemember(state, remember) {
state.remember = remember;
if (!remember) {
localStorage.removeItem('user');
localStorage.removeItem('token');
localStorage.removeItem('keypair');
}
localStorage.setItem('remember', remember);
},
setHomeServers(state, home_servers) {
state.home_servers = home_servers;
},
logout(state) {
state.user = null;
state.token = null;
state.keypair = null;
localStorage.removeItem('user');
localStorage.removeItem('token');
localStorage.removeItem('keypair');
router.push('/login');
},
load_local(state) {
if (state.local_loaded)
return;
const remember = localStorage.getItem('remember');
const user = localStorage.getItem('user');
const token = localStorage.getItem('token');
const keypair = localStorage.getItem('keypair');
if (user && token) {
this.commit('setUser', user);
this.commit('setToken', token);
if (keypair) {
this.commit('setKey', keypair)
}
}
state.cache_loaded = true;
}
},
actions: {
async login({commit, dispatch, state, getters}, {username, password, remember}) {
commit('setRemember', remember);
const data = await dispatch('lookupServer', {username}).then(servers => new ServerSet(servers, state.unreachable_neighbors))
.then(set => set.post(getters.nullAuth, '/auth/token/', {username, password}))
if (data.token && data.key) {
commit('setToken', data.token);
commit('setUser', username);
commit('setKey', data.key);
const s = await dispatch('lookupServer', {username}).then(servers => new ServerSet(servers, state.unreachable_neighbors))
commit('setHomeServers', s)
return true;
} else {
return false;
}
},
async lookupServer({state}, {username}) {
const domain = username.split('@')[1]
const request = '_toolshed-server._tcp.' + domain + '.'
return await state.resolver.query(request, 'SRV').then(
(result) => result.map(
(answer) => answer.target + ':' + answer.port))
},
async getHomeServers({state, dispatch, commit}) {
if (state.home_servers)
return state.home_servers
const promise = dispatch('lookupServer', {username: state.user}).then(servers => new ServerSet(servers, state.unreachable_neighbors))
commit('setHomeServers', promise)
return promise
},
async getFriendServers({state, dispatch, commit}, {username}) {
return dispatch('lookupServer', {username}).then(servers => new ServerSet(servers, state.unreachable_neighbors))
},
},
getters: {
isLoggedIn(state) {
if (!state.local_loaded) {
state.remember = localStorage.getItem('remember') === 'true'
state.user = localStorage.getItem('user')
state.token = localStorage.getItem('token')
const keypair = localStorage.getItem('keypair')
if (keypair)
state.keypair = nacl.crypto_sign_keypair_from_seed(nacl.from_hex(keypair))
state.local_loaded = true
}
return state.user !== null && state.token !== null;
},
signAuth(state) {
return createSignAuth(state.user, state.keypair.signSk)
},
tokenAuth(state) {
return createTokenAuth(state.token)
},
nullAuth(state) {
return createNullAuth({})
},
}
})