|
|
@ -2,24 +2,18 @@ |
|
|
<main> |
|
|
<main> |
|
|
<div v-cloak class="container mx-auto max-w-3xl px-5 md:px-0"> |
|
|
<div v-cloak class="container mx-auto max-w-3xl px-5 md:px-0"> |
|
|
<div v-if="authenticated === true"> |
|
|
<div v-if="authenticated === true"> |
|
|
<span |
|
|
<Header /> |
|
|
v-if="requiresPassword" |
|
|
|
|
|
class="text-sm text-gray-400 dark:text-neutral-400 mb-10 mr-2 mt-3 cursor-pointer hover:underline float-right" |
|
|
|
|
|
@click="logout" |
|
|
|
|
|
> |
|
|
|
|
|
Logout |
|
|
|
|
|
<IconLogout /> |
|
|
|
|
|
</span> |
|
|
|
|
|
<h1 class="text-4xl dark:text-neutral-200 font-medium mt-2 mb-2"> |
|
|
|
|
|
<img src="./assets/img/logo.png" width="32" class="inline align-middle dark:bg" /> |
|
|
|
|
|
<span class="align-middle">WireGuard</span> |
|
|
|
|
|
</h1> |
|
|
|
|
|
<h2 class="text-sm text-gray-400 dark:text-neutral-400 mb-10"></h2> |
|
|
|
|
|
|
|
|
|
|
|
<UpdateNotification :latest-release="latestRelease" :current-release="currentRelease" /> |
|
|
<UpdateNotification :latest-release="latestRelease" :current-release="currentRelease" /> |
|
|
|
|
|
|
|
|
<div class="shadow-md rounded-lg bg-white dark:bg-neutral-700 overflow-hidden"> |
|
|
<div class="shadow-md rounded-lg bg-white dark:bg-neutral-700 overflow-hidden"> |
|
|
<ClientNewButton @create-new-client="handleNewClient" /> |
|
|
<div class="flex flex-row flex-auto items-center p-3 px-5 border-b-2 border-gray-100 dark:border-neutral-600"> |
|
|
|
|
|
<div class="flex-grow"> |
|
|
|
|
|
<p class="text-2xl font-medium dark:text-neutral-200">Clients</p> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="flex-shrink-0"> |
|
|
|
|
|
<ClientNewButton /> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
<div v-if="clients && clients.length > 0"> |
|
|
<div v-if="clients && clients.length > 0"> |
|
|
<!-- Client --> |
|
|
<!-- Client --> |
|
|
@ -30,13 +24,7 @@ |
|
|
<div v-if="clients && clients.length === 0"> |
|
|
<div v-if="clients && clients.length === 0"> |
|
|
<p class="text-center m-10 text-gray-400 dark:text-neutral-400 text-sm"> |
|
|
<p class="text-center m-10 text-gray-400 dark:text-neutral-400 text-sm"> |
|
|
There are no clients yet.<br /><br /> |
|
|
There are no clients yet.<br /><br /> |
|
|
<button |
|
|
<ClientNewButton /> |
|
|
class="bg-red-800 hover:bg-red-700 text-white border-2 border-none py-2 px-4 rounded inline-flex items-center transition" |
|
|
|
|
|
@click="handleNewClient()" |
|
|
|
|
|
> |
|
|
|
|
|
<IconNew class="w-4 mr-2" /> |
|
|
|
|
|
<span class="text-sm">New Client</span> |
|
|
|
|
|
</button> |
|
|
|
|
|
</p> |
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
<div v-if="clients === null" class="text-gray-200 dark:text-red-300 p-5"> |
|
|
<div v-if="clients === null" class="text-gray-200 dark:text-red-300 p-5"> |
|
|
@ -64,7 +52,7 @@ |
|
|
<Auth /> |
|
|
<Auth /> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div v-if="authenticated === null" class="text-gray-300 dark:text-red-300 pt-24 pb-12"> |
|
|
<div v-if="authenticated === null"> |
|
|
<LoadingSpinner /> |
|
|
<LoadingSpinner /> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
@ -74,19 +62,17 @@ |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
<script setup> |
|
|
<script setup> |
|
|
import { ref, onMounted, onBeforeUnmount } from 'vue'; |
|
|
import { ref, onBeforeUnmount, onBeforeMount } from 'vue'; |
|
|
import sha256 from 'crypto-js/sha256'; |
|
|
|
|
|
|
|
|
|
|
|
import Auth from '@/components/Auth.vue'; |
|
|
import Auth from '@/components/Auth.vue'; |
|
|
import UpdateNotification from '@/components/UpdateNotification.vue'; |
|
|
import UpdateNotification from '@/components/UpdateNotification.vue'; |
|
|
import ClientNewButton from '@/components/ClientNewButton.vue'; |
|
|
import ClientNewButton from '@/components/ClientNewButton.vue'; |
|
|
import IconLogout from '@/components/icons/IconLogout.vue'; |
|
|
|
|
|
import IconNew from '@/components/icons/IconNew.vue'; |
|
|
|
|
|
import LoadingSpinner from '@/components/LoadingSpinner.vue'; |
|
|
import LoadingSpinner from '@/components/LoadingSpinner.vue'; |
|
|
import Footer from '@/components/Footer.vue'; |
|
|
import Footer from '@/components/Footer.vue'; |
|
|
import ModalQRCode from '@/components/ModalQRCode.vue'; |
|
|
import ModalQRCode from '@/components/ModalQRCode.vue'; |
|
|
import ModalCreateClient from '@/components/ModalCreateClient.vue'; |
|
|
import ModalCreateClient from '@/components/ModalCreateClient.vue'; |
|
|
import ModalDeleteClient from '@/components/ModalDeleteClient.vue'; |
|
|
import ModalDeleteClient from '@/components/ModalDeleteClient.vue'; |
|
|
|
|
|
import Header from '@/components/Header.vue'; |
|
|
|
|
|
|
|
|
import API from '@/services/api'; |
|
|
import API from '@/services/api'; |
|
|
import Client from '@/components/Client.vue'; |
|
|
import Client from '@/components/Client.vue'; |
|
|
@ -97,9 +83,7 @@ import { storeToRefs } from 'pinia'; |
|
|
const store = useStore(); |
|
|
const store = useStore(); |
|
|
const { authenticated, requiresPassword } = storeToRefs(store); |
|
|
const { authenticated, requiresPassword } = storeToRefs(store); |
|
|
|
|
|
|
|
|
const { clients, clientsPersist, clientCreateShowModal, clientToDelete, clientCreateName, qrcode } = storeToRefs(store); |
|
|
const { clients, clientCreateShowModal, clientToDelete, clientCreateName, qrcode } = storeToRefs(store); |
|
|
|
|
|
|
|
|
const logout = store.logout; |
|
|
|
|
|
|
|
|
|
|
|
const currentRelease = ref(null); |
|
|
const currentRelease = ref(null); |
|
|
const latestRelease = ref(null); |
|
|
const latestRelease = ref(null); |
|
|
@ -108,32 +92,28 @@ const refreshInterval = ref(null); |
|
|
|
|
|
|
|
|
const api = new API(); |
|
|
const api = new API(); |
|
|
|
|
|
|
|
|
onMounted(() => { |
|
|
const refresh = store.refresh; |
|
|
|
|
|
|
|
|
|
|
|
onBeforeMount(() => { |
|
|
api |
|
|
api |
|
|
.getSession() |
|
|
.getSession() |
|
|
.then((session) => { |
|
|
.then((session) => { |
|
|
authenticated.value = session.authenticated; |
|
|
authenticated.value = session.authenticated; |
|
|
// authenticated.value = false; //debug |
|
|
// authenticated.value = false; //debug |
|
|
requiresPassword.value = session.requiresPassword; |
|
|
requiresPassword.value = session.requiresPassword; |
|
|
|
|
|
refresh(); |
|
|
refreshInterval.value = setInterval(refresh, 1000); |
|
|
refreshInterval.value = setInterval(refresh, 1000); |
|
|
}) |
|
|
}) |
|
|
.catch((err) => { |
|
|
.catch((err) => { |
|
|
console.log(err.message || err.toString()); |
|
|
console.log(err.message || err.toString()); |
|
|
}); |
|
|
}); |
|
|
|
|
|
getRelease(); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
onBeforeUnmount(() => { |
|
|
onBeforeUnmount(() => { |
|
|
clearInterval(refreshInterval.value); |
|
|
clearInterval(refreshInterval.value); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
getRelease(); |
|
|
|
|
|
|
|
|
|
|
|
function handleNewClient() { |
|
|
|
|
|
clientCreateShowModal.value = true; |
|
|
|
|
|
clientCreateName.value = ''; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function getRelease() { |
|
|
async function getRelease() { |
|
|
try { |
|
|
try { |
|
|
const currentReleaseData = await api.getRelease(); |
|
|
const currentReleaseData = await api.getRelease(); |
|
|
@ -162,58 +142,4 @@ async function getRelease() { |
|
|
console.log('Something went wrong', error); |
|
|
console.log('Something went wrong', error); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
async function refresh({ updateCharts = false } = {}) { |
|
|
|
|
|
if (!authenticated.value) return; |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
const clientsData = await api.getClients(); |
|
|
|
|
|
clients.value = clientsData.map((client) => { |
|
|
|
|
|
if (client.name.includes('@') && client.name.includes('.')) { |
|
|
|
|
|
client.avatar = `https://www.gravatar.com/avatar/${sha256(client.name)}?d=blank`; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!clientsPersist[client.id]) { |
|
|
|
|
|
clientsPersist[client.id] = {}; |
|
|
|
|
|
clientsPersist[client.id].transferRxHistory = Array(50).fill(0); |
|
|
|
|
|
clientsPersist[client.id].transferRxPrevious = client.transferRx; |
|
|
|
|
|
clientsPersist[client.id].transferTxHistory = Array(50).fill(0); |
|
|
|
|
|
clientsPersist[client.id].transferTxPrevious = client.transferTx; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Debug |
|
|
|
|
|
client.transferRx = clientsPersist[client.id].transferRxPrevious + Math.random() * 1000; |
|
|
|
|
|
client.transferTx = clientsPersist[client.id].transferTxPrevious + Math.random() * 1000; |
|
|
|
|
|
client.latestHandshakeAt = new Date('2024-03-20'); |
|
|
|
|
|
updateCharts = true; // DEV TODO: Update. Get from settings |
|
|
|
|
|
|
|
|
|
|
|
if (updateCharts) { |
|
|
|
|
|
clientsPersist[client.id].transferRxCurrent = client.transferRx - clientsPersist[client.id].transferRxPrevious; |
|
|
|
|
|
clientsPersist[client.id].transferRxPrevious = client.transferRx; |
|
|
|
|
|
clientsPersist[client.id].transferTxCurrent = client.transferTx - clientsPersist[client.id].transferTxPrevious; |
|
|
|
|
|
clientsPersist[client.id].transferTxPrevious = client.transferTx; |
|
|
|
|
|
|
|
|
|
|
|
clientsPersist[client.id].transferRxHistory.push(clientsPersist[client.id].transferRxCurrent); |
|
|
|
|
|
clientsPersist[client.id].transferRxHistory.shift(); |
|
|
|
|
|
|
|
|
|
|
|
clientsPersist[client.id].transferTxHistory.push(clientsPersist[client.id].transferTxCurrent); |
|
|
|
|
|
clientsPersist[client.id].transferTxHistory.shift(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
client.transferTxCurrent = clientsPersist[client.id].transferTxCurrent; |
|
|
|
|
|
client.transferRxCurrent = clientsPersist[client.id].transferRxCurrent; |
|
|
|
|
|
|
|
|
|
|
|
client.transferTxHistory = clientsPersist[client.id].transferTxHistory; |
|
|
|
|
|
client.transferRxHistory = clientsPersist[client.id].transferRxHistory; |
|
|
|
|
|
client.transferMax = Math.max(...client.transferTxHistory, ...client.transferRxHistory); |
|
|
|
|
|
|
|
|
|
|
|
client.hoverTx = clientsPersist[client.id].hoverTx; |
|
|
|
|
|
client.hoverRx = clientsPersist[client.id].hoverRx; |
|
|
|
|
|
|
|
|
|
|
|
return client; |
|
|
|
|
|
}); |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.log('Something went wrong', error); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
</script> |
|
|
</script> |
|
|
|