stash
This commit is contained in:
parent
297ad7bd99
commit
905452cdf3
6 changed files with 109 additions and 43 deletions
|
@ -32,8 +32,8 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
console.log(this.$route)
|
//console.log(this.$route)
|
||||||
console.log(this.$route.params.query)
|
//console.log(this.$route.params.query)
|
||||||
this.query = decodeURIComponent(this.$route.params.query || encodeURIComponent(""));
|
this.query = decodeURIComponent(this.$route.params.query || encodeURIComponent(""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ class FallBackResolver {
|
||||||
endpoints: this._servers,
|
endpoints: this._servers,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
if(result.answers.length === 0) throw new Error('No answer');
|
||||||
const first = result.answers[0];
|
const first = result.answers[0];
|
||||||
this._cache[key] = {time: Date.now(), ...first}; // TODO hadle multiple answers
|
this._cache[key] = {time: Date.now(), ...first}; // TODO hadle multiple answers
|
||||||
localStorage.setItem('dns-cache', JSON.stringify(this._cache));
|
localStorage.setItem('dns-cache', JSON.stringify(this._cache));
|
||||||
|
|
|
@ -67,6 +67,11 @@ export default createStore({
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
router.push('/');
|
router.push('/');
|
||||||
|
/*if (this.$route.query.redirect) {
|
||||||
|
router.push({path: this.$route.query.redirect});
|
||||||
|
} else {
|
||||||
|
router.push({path: '/'});
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -109,10 +114,10 @@ export default createStore({
|
||||||
if (state.unreachable_neighbors.queryUnreachable(host)) {
|
if (state.unreachable_neighbors.queryUnreachable(host)) {
|
||||||
throw new Error('unreachable neighbor')
|
throw new Error('unreachable neighbor')
|
||||||
}
|
}
|
||||||
if(!state.user || !state.keypair) {
|
if (!state.user || !state.keypair) {
|
||||||
throw new Error('no user or keypair')
|
throw new Error('no user or keypair')
|
||||||
}
|
}
|
||||||
const url = host + target
|
const url = "http://" + host + target // TODO https
|
||||||
const signature = nacl.crypto_sign_detached(nacl.encode_utf8(url), state.keypair.signSk)
|
const signature = nacl.crypto_sign_detached(nacl.encode_utf8(url), state.keypair.signSk)
|
||||||
const auth = 'Signature ' + state.user + ':' + nacl.to_hex(signature)
|
const auth = 'Signature ' + state.user + ':' + nacl.to_hex(signature)
|
||||||
return await fetch(url, {
|
return await fetch(url, {
|
||||||
|
@ -124,13 +129,14 @@ export default createStore({
|
||||||
).then(response => response.json())
|
).then(response => response.json())
|
||||||
},
|
},
|
||||||
async apiFederatedPost({state}, {host, target, data}) {
|
async apiFederatedPost({state}, {host, target, data}) {
|
||||||
|
console.log('apiFederatedPost', host, target, data)
|
||||||
if (state.unreachable_neighbors.queryUnreachable(host)) {
|
if (state.unreachable_neighbors.queryUnreachable(host)) {
|
||||||
throw new Error('unreachable neighbor')
|
throw new Error('unreachable neighbor')
|
||||||
}
|
}
|
||||||
if(!state.user || !state.keypair) {
|
if (!state.user || !state.keypair) {
|
||||||
throw new Error('no user or keypair')
|
throw new Error('no user or keypair')
|
||||||
}
|
}
|
||||||
const url = host + target
|
const url = "http://" + host + target // TODO https
|
||||||
const json = JSON.stringify(data)
|
const json = JSON.stringify(data)
|
||||||
const signature = nacl.crypto_sign_detached(nacl.encode_utf8(url + json), state.keypair.signSk)
|
const signature = nacl.crypto_sign_detached(nacl.encode_utf8(url + json), state.keypair.signSk)
|
||||||
const auth = 'Signature ' + state.user + ':' + nacl.to_hex(signature)
|
const auth = 'Signature ' + state.user + ':' + nacl.to_hex(signature)
|
||||||
|
@ -163,6 +169,20 @@ export default createStore({
|
||||||
credentials: 'omit',
|
credentials: 'omit',
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
}).then(response => response.json())
|
}).then(response => response.json())
|
||||||
|
},
|
||||||
|
async requestFriend({state, dispatch}, {username}) {
|
||||||
|
console.log('requesting friend ' + username)
|
||||||
|
if(username in state.friends) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const server = await dispatch('getFriendServer', {username})
|
||||||
|
const data = await dispatch('apiFederatedPost', {
|
||||||
|
host: server[0],
|
||||||
|
target: '/api/friendrequests/',
|
||||||
|
data: {befriender: state.user, befriendee: username, befriender_key: nacl.to_hex(state.keypair.signPk)}
|
||||||
|
})
|
||||||
|
console.log(data)
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
|
|
|
@ -15,29 +15,45 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width:40%;">Name</th>
|
<th style="width:40%;">Name</th>
|
||||||
<th class="d-none d-md-table-cell" style="width:25%">Server</th>
|
<th class="d-none d-md-table-cell" style="width:25%">Server</th>
|
||||||
<th>Actions</th>
|
<th>
|
||||||
|
<a @click="fetchFriends" class="align-middle">
|
||||||
|
<b-icon-arrow-clockwise></b-icon-arrow-clockwise>
|
||||||
|
Refresh
|
||||||
|
</a>
|
||||||
|
<a @click="showNewFriend" class="align-middle">
|
||||||
|
<b-icon-plus></b-icon-plus>
|
||||||
|
Add Friend
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
<tr v-if="show_newfriend">
|
||||||
|
<td colspan="2">
|
||||||
|
<input type="text" class="form-control" placeholder="user@domain"
|
||||||
|
v-model="newfriend">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-primary" @click="tryRequestFriend">Send Request</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr v-for="friend in friendslist" :key="friend.name">
|
<tr v-for="friend in friendslist" :key="friend.name">
|
||||||
<td>{{ friend.name }}</td>
|
<td>{{ friend.name }}</td>
|
||||||
<td class="d-none d-md-table-cell">{{ friend.server.join(', ') }}</td>
|
<td class="d-none d-md-table-cell">{{ friend.server.join(', ') }}</td>
|
||||||
<td class="table-action">
|
<td class="table-action">
|
||||||
<a href="#">
|
<a href="#" class="align-middle">
|
||||||
<b-icon-pencil-square></b-icon-pencil-square>
|
<b-icon-pencil-square></b-icon-pencil-square>
|
||||||
|
Edit
|
||||||
</a>
|
</a>
|
||||||
<a href="#">
|
<a href="#" class="align-middle">
|
||||||
<b-icon-trash></b-icon-trash>
|
<b-icon-trash></b-icon-trash>
|
||||||
|
Delete
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
|
||||||
<button class="btn" @click="fetchFriends">Refresh</button>
|
|
||||||
<router-link to="/inventory/new" class="btn btn-primary">Add</router-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,6 +75,8 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
friends: {},
|
friends: {},
|
||||||
|
show_newfriend: false,
|
||||||
|
newfriend: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -75,7 +93,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['getFriends', "getFriendServer"]),
|
...mapActions(['getFriends', "getFriendServer", "requestFriend"]),
|
||||||
fetchFriends() {
|
fetchFriends() {
|
||||||
this.getFriends().then((friends) => {
|
this.getFriends().then((friends) => {
|
||||||
friends.map((friend) => {
|
friends.map((friend) => {
|
||||||
|
@ -84,6 +102,18 @@ export default {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
showNewFriend() {
|
||||||
|
this.show_newfriend = true
|
||||||
|
},
|
||||||
|
tryRequestFriend() {
|
||||||
|
this.requestFriend({username: this.newfriend}).then((ok) => {
|
||||||
|
if (ok) {
|
||||||
|
this.show_newfriend = false
|
||||||
|
this.newfriend = ""
|
||||||
|
this.fetchFriends()
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -73,7 +73,7 @@ export default {
|
||||||
try {
|
try {
|
||||||
const servers = await this.getFriends().then(friends => friends.map(friend => this.getFriendServer({username: friend})))
|
const servers = await this.getFriends().then(friends => friends.map(friend => this.getFriendServer({username: friend})))
|
||||||
const urls = servers.map(server => server.then(s => {
|
const urls = servers.map(server => server.then(s => {
|
||||||
return {host: `http://${s}`, target: "/api/inventory_items/"}
|
return {host: s, target: "/api/inventory_items/"}
|
||||||
}))
|
}))
|
||||||
urls.map(url => url.then(u => this.apiFederatedGet(u).then(items => {
|
urls.map(url => url.then(u => this.apiFederatedGet(u).then(items => {
|
||||||
this.setInventoryItems({url: u.domain, items})
|
this.setInventoryItems({url: u.domain, items})
|
||||||
|
|
|
@ -4,37 +4,36 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">Inventory</div>
|
<div class="card-header">Create New Item</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<table class="table table-striped">
|
<div class="mb-3">
|
||||||
<thead>
|
<label for="name" class="form-label">Name</label>
|
||||||
<tr>
|
<input type="text" class="form-control" id="name" name="name"
|
||||||
<th>Item</th>
|
placeholder="Enter item name" v-model="item.name">
|
||||||
<th>Quantity</th>
|
</div>
|
||||||
<th>Owner</th>
|
<div class="mb-3">
|
||||||
<th>Actions</th>
|
<label for="description" class="form-label">Description</label>
|
||||||
</tr>
|
<textarea class="form-control" id="description" name="description"
|
||||||
</thead>
|
placeholder="Enter description" v-model="item.description"></textarea>
|
||||||
<tbody>
|
</div>
|
||||||
<tr v-for="item in inventory_items" :key="item.id">
|
<div class="mb-3">
|
||||||
<td>{{ item.name }}</td>
|
<label for="quantity" class="form-label">Quantity</label>
|
||||||
<td>{{ item.quantity }}</td>
|
<input type="number" class="form-control" id="quantity" name="quantity"
|
||||||
<td>{{ item.owner }}</td>
|
placeholder="Enter quantity" v-model="item.quantity">
|
||||||
<td>
|
</div>
|
||||||
<a href="#">
|
<div class="mb-3">
|
||||||
<b-icon-pencil-square></b-icon-pencil-square>
|
<label for="price" class="form-label">Price</label>
|
||||||
</a>
|
<input type="number" class="form-control" id="price" name="price"
|
||||||
<a href="#">
|
placeholder="Enter price" v-model="item.price">
|
||||||
<b-icon-trash></b-icon-trash>
|
</div>
|
||||||
</a>
|
<div class="mb-3">
|
||||||
</td>
|
<label for="image" class="form-label">Image</label>
|
||||||
</tr>
|
<input type="text" class="form-control" id="image" name="image"
|
||||||
</tbody>
|
placeholder="Enter image" v-model="item.image">
|
||||||
</table>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<button class="btn" @click="getInventoryItems">Refresh</button>
|
<button type="submit" class="btn btn-primary" @click="createInventoryItem(item)">Add</button>
|
||||||
<router-link to="/inventory/new" class="btn btn-primary">Add</router-link>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -46,13 +45,29 @@
|
||||||
<script>
|
<script>
|
||||||
import * as BIcons from "bootstrap-icons-vue";
|
import * as BIcons from "bootstrap-icons-vue";
|
||||||
import BaseLayout from "@/components/BaseLayout.vue";
|
import BaseLayout from "@/components/BaseLayout.vue";
|
||||||
|
import {createApp} from "vue";
|
||||||
|
import {mapActions} from "vuex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "InventoryNew",
|
name: "InventoryNew",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
item: {
|
||||||
|
name: "",
|
||||||
|
description: "",
|
||||||
|
quantity: 0,
|
||||||
|
price: 0,
|
||||||
|
image: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
BaseLayout,
|
BaseLayout,
|
||||||
...BIcons
|
...BIcons
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(['createInventoryItem']),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue