233 lines
No EOL
9.6 KiB
JavaScript
233 lines
No EOL
9.6 KiB
JavaScript
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,
|
|
friends: [],
|
|
item_map: {},
|
|
home_servers: null,
|
|
all_friends_servers: null,
|
|
resolver: new FallBackResolver(),
|
|
unreachable_neighbors: new NeighborsCache(),
|
|
availability_policies: [],
|
|
},
|
|
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);
|
|
},
|
|
setInventoryItems(state, {url, items}) {
|
|
state.item_map[url] = items;
|
|
},
|
|
setFriends(state, friends) {
|
|
state.friends = friends;
|
|
},
|
|
setHomeServers(state, home_servers) {
|
|
state.home_servers = home_servers;
|
|
},
|
|
setAllFriendsServers(state, servers) {
|
|
state.all_friends_servers = servers;
|
|
},
|
|
setAvailabilityPolicies(state, availability_policies) {
|
|
state.availability_policies = availability_policies;
|
|
},
|
|
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 getAllKnownServers({state, dispatch, commit}) {
|
|
const friends = await dispatch('fetchFriends')
|
|
if (state.all_friends_servers)
|
|
return state.all_friends_servers
|
|
const promise = (async () => {
|
|
const servers = new ServerSetUnion([])
|
|
const home = await dispatch('getHomeServers')
|
|
servers.add(home)
|
|
for (const friend of friends) {
|
|
const s = await dispatch('lookupServer', {username: friend.username})
|
|
servers.add(new ServerSet(s, state.unreachable_neighbors))
|
|
}
|
|
return servers
|
|
})()
|
|
commit('setAllFriendsServers', promise)
|
|
return promise
|
|
},
|
|
async getFriendServers({state, dispatch, commit}, {username}) {
|
|
return dispatch('lookupServer', {username}).then(servers => new ServerSet(servers, state.unreachable_neighbors))
|
|
},
|
|
async fetchInventoryItems({commit, dispatch, getters}) {
|
|
const servers = await dispatch('getHomeServers')
|
|
const items = await servers.get(getters.signAuth, '/api/inventory_items/')
|
|
items.map(item => item.files.map(file => file.owner = item.owner))
|
|
commit('setInventoryItems', {url: '/', items})
|
|
return items
|
|
},
|
|
async fetchFriends({commit, dispatch, getters, state}) {
|
|
const servers = await dispatch('getHomeServers')
|
|
const data = await servers.get(getters.signAuth, '/api/friends/')
|
|
commit('setFriends', data)
|
|
return data
|
|
},
|
|
async fetchFriendRequests({state, dispatch, getters}) {
|
|
const servers = await dispatch('getHomeServers')
|
|
return await servers.get(getters.signAuth, '/api/friendrequests/')
|
|
},
|
|
async requestFriend({state, dispatch, getters}, {username}) {
|
|
if (username in state.friends) {
|
|
return true;
|
|
}
|
|
const home_servers = await dispatch('getHomeServers')
|
|
const home_reply = await home_servers.post(getters.signAuth, '/api/friendrequests/', {
|
|
befriender: state.user,
|
|
befriendee: username
|
|
})
|
|
if (home_reply.status !== 'pending' || !home_reply.secret)
|
|
return false;
|
|
|
|
const befriendee_servers = await dispatch('getFriendServers', {username})
|
|
const ext_reply = await befriendee_servers.post(getters.signAuth, '/api/friendrequests/', {
|
|
befriender: state.user,
|
|
befriendee: username,
|
|
befriender_key: nacl.to_hex(state.keypair.signPk),
|
|
secret: home_reply.secret
|
|
})
|
|
return true;
|
|
},
|
|
async acceptFriend({state, dispatch, getters}, {id, secret, befriender}) {
|
|
const home_servers = await dispatch('getHomeServers')
|
|
const home_reply = await home_servers.post(getters.signAuth, '/api/friends/', {
|
|
friend_request_id: id, secret: secret
|
|
})
|
|
const ext_servers = await dispatch('getFriendServers', {username: befriender})
|
|
const ext_reply = await ext_servers.post(getters.signAuth, '/api/friendrequests/', {
|
|
befriender: state.user,
|
|
befriendee: befriender,
|
|
befriender_key: nacl.to_hex(state.keypair.signPk),
|
|
secret: secret
|
|
})
|
|
return true
|
|
},
|
|
async declineFriend({state, dispatch, getters}, {id}) {
|
|
const servers = await dispatch('getHomeServers')
|
|
return await servers.delete(getters.signAuth, '/api/friendrequests/' + id + '/')
|
|
},
|
|
async dropFriend({state, dispatch, getters}, {id}) {
|
|
const servers = await dispatch('getHomeServers')
|
|
return await servers.delete(getters.signAuth, '/api/friends/' + id + '/')
|
|
},
|
|
},
|
|
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({})
|
|
},
|
|
inventory_items(state) {
|
|
return state.item_map['/'] || []
|
|
},
|
|
loaded_items(state) {
|
|
return Object.entries(state.item_map).reduce((acc, [url, items]) => {
|
|
return acc.concat(items)
|
|
}, [])
|
|
},
|
|
}
|
|
}) |