mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-11-06 16:00:28 +01:00
Ohhhhh kay testing CORS :)
This commit is contained in:
parent
55e0d2695d
commit
54142b73fb
@ -47,7 +47,11 @@ UPDATE = None
|
||||
app = Flask("WGDashboard")
|
||||
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 5206928
|
||||
app.secret_key = secrets.token_urlsafe(32)
|
||||
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
|
||||
cors = CORS(app, resources={r"/api/*": {
|
||||
"origins": "*",
|
||||
"methods": "DELETE, POST, GET, OPTIONS",
|
||||
"allow_headers": ["Content-Type", "wg-dashboard-apikey"]
|
||||
}})
|
||||
|
||||
class ModelEncoder(JSONEncoder):
|
||||
def default(self, o: Any) -> Any:
|
||||
@ -1345,6 +1349,9 @@ API Routes
|
||||
|
||||
@app.before_request
|
||||
def auth_req():
|
||||
if request.method.lower() == 'options':
|
||||
return ResponseObject(True)
|
||||
|
||||
if "api" in request.path:
|
||||
if str(request.method) == "GET":
|
||||
DashboardLogger.log(str(request.url), str(request.remote_addr), Message=str(request.args))
|
||||
@ -1385,6 +1392,10 @@ def auth_req():
|
||||
response.status_code = 401
|
||||
return response
|
||||
|
||||
@app.route('/api/handshake', methods=["GET", "OPTIONS"])
|
||||
def API_ValidateAPIKey():
|
||||
return ResponseObject(True)
|
||||
|
||||
|
||||
@app.route('/api/validateAuthentication', methods=["GET"])
|
||||
def API_ValidateAuthentication():
|
||||
|
4
src/static/app/dist/assets/index.css
vendored
4
src/static/app/dist/assets/index.css
vendored
File diff suppressed because one or more lines are too long
54
src/static/app/dist/assets/index.js
vendored
54
src/static/app/dist/assets/index.js
vendored
File diff suppressed because one or more lines are too long
@ -1,7 +1,17 @@
|
||||
<script setup>
|
||||
import { RouterView } from 'vue-router'
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import {watch} from "vue";
|
||||
const store = DashboardConfigurationStore();
|
||||
store.initCrossServerConfiguration();
|
||||
|
||||
watch(store.CrossServerConfiguration, () => {
|
||||
store.syncCrossServerConfiguration()
|
||||
}, {
|
||||
deep: true
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -0,0 +1,93 @@
|
||||
<script>
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export default {
|
||||
name: "RemoteServer",
|
||||
props: {
|
||||
server: Object
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
active: false,
|
||||
startTime: undefined,
|
||||
endTime: undefined
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handshake(){
|
||||
this.startTime = undefined;
|
||||
this.endTime = undefined;
|
||||
|
||||
this.startTime = dayjs()
|
||||
fetch(`//${this.server.host}/api/handshake`, {
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
"wg-dashboard-apikey": this.server.apiKey
|
||||
},
|
||||
method: "GET",
|
||||
signal: AbortSignal.timeout(5000)
|
||||
}).then(res => res.json()).then(res => {
|
||||
this.active = true;
|
||||
this.endTime = dayjs()
|
||||
}).catch((res) => {
|
||||
console.log(res)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.handshake()
|
||||
},
|
||||
computed: {
|
||||
getHandshakeTime(){
|
||||
if (this.startTime && this.endTime){
|
||||
return dayjs().subtract(this.startTime).millisecond()
|
||||
}else{
|
||||
return "N/A"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="card rounded-3">
|
||||
<div class="card-body">
|
||||
<div class="d-flex gap-3 w-100">
|
||||
<div class="d-flex gap-3 align-items-center flex-grow-1">
|
||||
<i class="bi bi-server"></i>
|
||||
<input class="form-control form-control-sm"
|
||||
v-model="this.server.host"
|
||||
type="url">
|
||||
</div>
|
||||
<div class="d-flex gap-3 align-items-center flex-grow-1">
|
||||
<i class="bi bi-key-fill"></i>
|
||||
<input class="form-control form-control-sm"
|
||||
v-model="this.server.apiKey"
|
||||
type="text">
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button
|
||||
@click="this.$emit('delete')"
|
||||
class="ms-auto btn btn-sm bg-danger-subtle text-danger-emphasis border-1 border-danger-subtle">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
<button class="ms-auto btn btn-sm bg-success-subtle text-success-emphasis border-1 border-success-subtle">
|
||||
<i class="bi bi-arrow-right-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer gap-2 d-flex align-items-center">
|
||||
<span class="dot ms-0 me-2" :class="[this.active ? 'active':'inactive']"></span>
|
||||
{{this.getHandshakeTime}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.dot.inactive{
|
||||
background-color: #dc3545;
|
||||
box-shadow: 0 0 0 0.2rem #dc354545;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,35 @@
|
||||
<script>
|
||||
import RemoteServer from "@/components/signInComponents/RemoteServer.vue";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
|
||||
export default {
|
||||
name: "RemoteServerList",
|
||||
setup(){
|
||||
const store = DashboardConfigurationStore();
|
||||
return {store}
|
||||
},
|
||||
components: {RemoteServer}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-100 mt-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<h5 class="mb-0">Server List</h5>
|
||||
<button
|
||||
@click="this.store.addCrossServerConfiguration()"
|
||||
class="btn bg-primary-subtle text-primary-emphasis border-1 border-primary-subtle shadow-sm ms-auto">
|
||||
<i class="bi bi-plus-circle-fill me-2"></i>Server
|
||||
</button>
|
||||
</div>
|
||||
<div class="w-100 py-3 d-flex gap-3 flex-column" style="height: 400px">
|
||||
<RemoteServer v-for="(server, index) in this.store.CrossServerConfiguration.ServerList"
|
||||
@delete="this.store.CrossServerConfiguration.ServerList.splice(index, 1)"
|
||||
:server="server"></RemoteServer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -10,9 +10,31 @@ export const DashboardConfigurationStore = defineStore('DashboardConfigurationSt
|
||||
Peers: {
|
||||
Selecting: false,
|
||||
RefreshInterval: undefined
|
||||
},
|
||||
CrossServerConfiguration:{
|
||||
Enable: false,
|
||||
ServerList: []
|
||||
}
|
||||
}),
|
||||
actions: {
|
||||
initCrossServerConfiguration(){
|
||||
const currentConfiguration = localStorage.getItem('CrossServerConfiguration');
|
||||
|
||||
if (currentConfiguration === null){
|
||||
localStorage.setItem('CrossServerConfiguration', JSON.stringify(this.CrossServerConfiguration))
|
||||
}else{
|
||||
this.CrossServerConfiguration = JSON.parse(currentConfiguration)
|
||||
}
|
||||
},
|
||||
syncCrossServerConfiguration(){
|
||||
localStorage.setItem('CrossServerConfiguration', JSON.stringify(this.CrossServerConfiguration))
|
||||
},
|
||||
addCrossServerConfiguration(){
|
||||
this.CrossServerConfiguration.ServerList.push(
|
||||
{host: "", apiKey: ""}
|
||||
)
|
||||
},
|
||||
|
||||
async getConfiguration(){
|
||||
await fetchGet("/api/getDashboardConfiguration", {}, (res) => {
|
||||
if (res.status) this.Configuration = res.data
|
||||
|
@ -2,10 +2,11 @@
|
||||
import {fetchGet, fetchPost} from "../utilities/fetch.js";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import Message from "@/components/messageCentreComponent/message.vue";
|
||||
import RemoteServerList from "@/components/signInComponents/RemoteServerList.vue";
|
||||
|
||||
export default {
|
||||
name: "signin",
|
||||
components: {Message},
|
||||
components: {RemoteServerList, Message},
|
||||
async setup(){
|
||||
const store = DashboardConfigurationStore()
|
||||
let theme = ""
|
||||
@ -83,7 +84,7 @@ export default {
|
||||
|
||||
<template>
|
||||
<div class="container-fluid login-container-fluid d-flex main flex-column" :data-bs-theme="this.theme">
|
||||
<div class="login-box m-auto" style="width: 600px;">
|
||||
<div class="login-box m-auto" style="width: 700px;">
|
||||
<div class="m-auto">
|
||||
<div class="card px-4 py-5 rounded-4 shadow-lg">
|
||||
<div class="card-body">
|
||||
@ -92,7 +93,8 @@ export default {
|
||||
<div class="alert alert-danger mt-2 mb-0" role="alert" v-if="loginError">
|
||||
{{this.loginErrorMessage}}
|
||||
</div>
|
||||
<form @submit="(e) => {e.preventDefault(); this.auth();}">
|
||||
<form @submit="(e) => {e.preventDefault(); this.auth();}"
|
||||
v-if="!this.store.CrossServerConfiguration.Enable">
|
||||
<div class="form-group text-body">
|
||||
<label for="username" class="text-left" style="font-size: 1rem">
|
||||
<i class="bi bi-person-circle"></i></label>
|
||||
@ -128,6 +130,16 @@ export default {
|
||||
</span>
|
||||
</button>
|
||||
</form>
|
||||
<RemoteServerList v-else></RemoteServerList>
|
||||
|
||||
<div class="d-flex mt-3">
|
||||
<div class="form-check form-switch ms-auto">
|
||||
<input
|
||||
v-model="this.store.CrossServerConfiguration.Enable"
|
||||
class="form-check-input" type="checkbox" role="switch" id="flexSwitchCheckChecked">
|
||||
<label class="form-check-label" for="flexSwitchCheckChecked">Access Remote Server</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,34 +6,7 @@ import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({mode}) => {
|
||||
if (mode === 'production'){
|
||||
return {
|
||||
base: "/static/app/dist",
|
||||
plugins: [
|
||||
vue(),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
}
|
||||
},
|
||||
server:{
|
||||
proxy: {
|
||||
'/api': proxy
|
||||
}
|
||||
},
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
rollupOptions: {
|
||||
output: {
|
||||
entryFileNames: `assets/[name].js`,
|
||||
chunkFileNames: `assets/[name].js`,
|
||||
assetFileNames: `assets/[name].[ext]`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mode === 'electron'){
|
||||
return {
|
||||
@ -64,4 +37,32 @@ export default defineConfig(({mode}) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
base: "/static/app/dist",
|
||||
plugins: [
|
||||
vue(),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
}
|
||||
},
|
||||
server:{
|
||||
proxy: {
|
||||
'/api': proxy
|
||||
},
|
||||
host: '0.0.0.0'
|
||||
},
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
rollupOptions: {
|
||||
output: {
|
||||
entryFileNames: `assets/[name].js`,
|
||||
chunkFileNames: `assets/[name].js`,
|
||||
assetFileNames: `assets/[name].[ext]`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user