Создание шифрованного API

This commit is contained in:
2024-06-25 13:11:51 +07:00
parent 4345ddc645
commit 26d973a1a7
14 changed files with 776 additions and 66 deletions
+193
View File
@@ -0,0 +1,193 @@
<script setup>
import {Icon} from "@iconify/vue";
import {onBeforeMount, ref} from "vue";
import {appWindow} from "@tauri-apps/api/window";
import {useDark, useToggle} from "@vueuse/core";
import {invoke} from "@tauri-apps/api";
import ConfirmModal from "./api_components/ConfirmModal.vue";
import {listen} from "@tauri-apps/api/event";
import SettingsModal from "./api_components/SettingsModal.vue";
const isDark = useDark();
const toggleDark = useToggle(isDark);
let pending = ref(true);
let api_status = ref(false);
let confirm_modal = ref(false);
let settings_modal = ref(false);
let settings_port = ref(0);
let settings_autostart = ref(true);
let input_val = ref((() => {
let string = "";
for(let i = 0; i < 5; i++) string += (Math.random() + 1).toString(36).substring(2);
return string;
})())
async function get_status() {
pending.value = true;
await invoke('get_status')
.then((res) => {
api_status.value = res;
});
}
onBeforeMount(async () => {
await invoke('check_or_create_config_file')
.then(async () => {
await get_status();
pending.value = false;
});
await listen('update_api', async () => {
await get_status();
pending.value = false;
})
});
async function run_api() {
await invoke('start_tcp_server');
}
async function stop_api() {
await invoke('send_command_to_server', {
command: "stop"
});
}
async function open_settings() {
await invoke('get_port')
.then(async (res) => {
settings_port.value = res;
await invoke('get_autostart')
.then((res) => {
settings_autostart.value = res;
settings_modal.value = true;
})
})
}
async function regen_token(){
confirm_modal.value = false;
await invoke('reset_token')
.then((res) => {
let input = document.getElementById('token_con');
let timer = document.getElementById('timer');
input.type = "text";
input_val.value = res;
let i = 15;
timer.textContent = i.toString() + "s";
let timerI = setInterval(() => {
i--;
if(i===0){
input_val.value = (() => {
let string = "";
for(let i = 0; i < 5; i++) string += (Math.random() + 1).toString(36).substring(2);
return string;
})();
input.type = "password";
timer.textContent = "";
clearInterval(timerI);
} else{
timer.textContent = i.toString() + "s";
}
}, 1000);
});
}
function select_input(event){
event.target.select();
}
</script>
<template>
<div data-tauri-drag-region class="z-50 opacity-50 titlebar h-[30px] select-none fixed flex justify-end top-0 right-0 left-0 bg-gray-100 dark:bg-zinc-800">
<div @click="appWindow.minimize()" class="titlebar-button hover:bg-gray-200 dark:hover:bg-gray-700 justify-center inline-flex w-[30px] h-[30px] items-center dark:text-white" id="titlebar-minimize">
<Icon class="" icon="mdi:window-minimize" width="20" height="20"/>
</div>
<div @click="appWindow.toggleMaximize()" class="titlebar-button hover:bg-gray-200 dark:hover:bg-gray-700 justify-center inline-flex w-[30px] h-[30px] items-center dark:text-white" id="titlebar-maximize">
<Icon class="" icon="mdi:window-maximize" width="20" height="20"/>
</div>
<div @click="appWindow.close()" class="titlebar-button hover:bg-gray-200 dark:hover:bg-gray-700 justify-center inline-flex w-[30px] h-[30px] items-center dark:text-white" id="titlebar-close">
<Icon class="" icon="mdi:close" width="26" height="26"/>
</div>
</div>
<div v-if="pending">
<Icon icon="line-md:loading-twotone-loop" width="96" height="96" class="text-green-500 absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]"/>
</div>
<div v-else>
<button class="absolute top-10 left-2" @click="open_settings">
<Icon icon="material-symbols:settings-outline" width="38" height="38" class="text-zinc-600 dark:text-zinc-200"/>
</button>
<button class="absolute top-10 right-2" @click="toggleDark()">
<Icon v-if="!isDark" class="group-hover:invert text-yellow-400" icon="flowbite:sun-solid" width="38" height="38"/>
<Icon v-else class="group-hover:invert text-blue-400" icon="ri:moon-fill" width="38" height="38"/>
</button>
<div class="mt-8">
<p class="text-center dark:text-white">API</p>
<div class="grid grid-cols-1 grid-rows-1 sm:grid-cols-2 sm:grid-rows-2 mt-8 sm:mt-2 gap-2.5 dark:text-white md:mt-4 md:mx-16 lg:mt-8 lg:mx-24">
<div class="text-center shadow dark:shadow-white mx-4 sm:mx-0 sm:ml-4 rounded-lg p-1">
<p class="mb-4">Статус</p>
<div v-if="!api_status" class="flex text-center align-middle items-center">
<Icon class="text-red-500" icon="oui:dot" width="36" height="36"/>
<span>Не подключено</span>
<button @click="run_api" class="bg-green-500 text-white rounded-lg py-1 px-2 ml-2 hover:bg-green-600 transition-colors">Запустить</button>
</div>
<div v-else class="flex text-center align-middle items-center">
<Icon class="text-green-500" icon="oui:dot" width="36" height="36"/>
<span>Работает</span>
<button @click="stop_api" class="bg-green-500 text-white rounded-lg py-1 px-2 ml-2 hover:bg-green-600 transition-colors">Остановить</button>
</div>
</div>
<div class="grid text-center shadow dark:shadow-white mx-4 sm:mx-0 sm:mr-4 rounded-lg p-1 justify-center items-center">
<div v-if="api_status">
<p class="mb-2">Токен подключения</p>
<div>
<input @click="select_input" size="30" id="token_con" readonly type="password" class="rounded-lg my-0.5 px-2 dark:bg-zinc-700"
:value="input_val">
</div>
<div class="flex justify-center items-center">
<button class="text-[15px] m-1 rounded-lg bg-red-500 text-white py-1 px-2" @click="confirm_modal = true">Сгенерировать новый</button>
<p id="timer" class="text-xl ml-2"></p>
</div>
</div>
<p v-else class="underline decoration-red-500 decoration-2 underline-offset-2">Нет подключения</p>
</div>
</div>
</div>
<div v-if="confirm_modal || settings_modal" class="bg-black w-[100vw] h-full fixed top-0 opacity-70 z-40"/>
<ConfirmModal v-if="confirm_modal" @close="confirm_modal = false" @yes="regen_token"/>
<SettingsModal v-if="settings_modal" @close="settings_modal = false" :autostart="settings_autostart" :port="settings_port"/>
</div>
</template>
<style>
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
overflow-x: hidden;
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
background-color: rgb(246 247 248);
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
:root.dark {
background-color: rgb(30, 30, 30);
}
</style>