Added toggle for signing up local clients

This commit is contained in:
Donald Zou
2025-12-28 17:02:14 +08:00
parent 0d70d13d0f
commit a3058d2a28
7 changed files with 68 additions and 36 deletions

View File

@@ -54,6 +54,8 @@ def createClientBlueprint(wireguardConfigurations: dict[WireguardConfiguration],
@client.post(f'{prefix}/api/signup')
def ClientAPI_SignUp():
if not dashboardConfig.GetConfig("Clients", "sign_up")[1]:
abort(404)
data = request.get_json()
status, msg = dashboardClients.SignUp(**data)
return ResponseObject(status, msg)
@@ -209,7 +211,10 @@ def createClientBlueprint(wireguardConfigurations: dict[WireguardConfiguration],
@client.get(f'{prefix}/api/serverInformation')
def ClientAPI_ServerInformation():
return ResponseObject(data={
"ServerTimezone": str(get_localzone())
"ServerTimezone": str(get_localzone()),
"SignUp": {
"enable": dashboardConfig.GetConfig("Clients", "sign_up")[1]
}
})
@client.get(f'{prefix}/api/validateAuthentication')

View File

@@ -83,6 +83,7 @@ class DashboardConfig:
},
"Clients": {
"enable": "true",
"sign_up": "true"
},
"WireGuardConfiguration": {
"autostart": "",

View File

@@ -2,7 +2,7 @@
import { ref, reactive } from "vue"
import LocaleText from "@/components/text/localeText.vue";
import OidcSettings from "@/components/clientComponents/clientSettingComponents/oidcSettings.vue";
import { fetchGet } from "@/utilities/fetch.js"
import { fetchGet, fetchPost } from "@/utilities/fetch.js"
const emits = defineEmits(['close'])
import { DashboardConfigurationStore } from "@/stores/DashboardConfigurationStore"
const dashboardConfigurationStore = DashboardConfigurationStore()
@@ -12,12 +12,16 @@ const values = reactive({
})
const toggling = ref(false)
const toggleClientSideApp = async () => {
const updateSettings = async (key: string) => {
toggling.value = true
await fetchGet("/api/clients/toggleStatus", {}, (res) => {
values.enableClients = res.data
await fetchPost("/api/updateDashboardConfigurationItem", {
section: "Clients",
key: key,
value: dashboardConfigurationStore.Configuration.Clients[key]
}, async (res) => {
await dashboardConfigurationStore.getConfiguration()
toggling.value = false
})
toggling.value = false
}
</script>
@@ -37,16 +41,43 @@ const toggleClientSideApp = async () => {
</h6>
<div class="form-check form-switch ms-auto">
<label class="form-check-label" for="oidc_switch">
<LocaleText :t="values.enableClients ? 'Enabled':'Disabled'"></LocaleText>
<LocaleText :t="dashboardConfigurationStore.Configuration.Clients.enable ? 'Enabled':'Disabled'"></LocaleText>
</label>
<input
:disabled="oidcStatusLoading"
v-model="values.enableClients"
@change="toggleClientSideApp()"
:disabled="toggling"
v-model="dashboardConfigurationStore.Configuration.Clients.enable"
@change="updateSettings('enable')"
class="form-check-input" type="checkbox" role="switch" id="oidc_switch">
</div>
</div>
<OidcSettings mode="Client"></OidcSettings>
<hr>
<div>
<div class="d-flex align-items-center">
<h6 class="mb-0">
<LocaleText t="Sign Up as Local Client"></LocaleText>
</h6>
<div class="form-check form-switch ms-auto">
<label class="form-check-label" for="sign_up_switch">
<LocaleText :t="dashboardConfigurationStore.Configuration.Clients.sign_up ? 'Enabled':'Disabled'"></LocaleText>
</label>
<input
:disabled="toggling"
v-model="dashboardConfigurationStore.Configuration.Clients.sign_up"
@change="updateSettings('sign_up')"
class="form-check-input" type="checkbox" role="switch" id="sign_up_switch">
</div>
</div>
<small class="text-muted mb-0">
<LocaleText t="Allow clients to sign up with Email and Password"></LocaleText>
</small>
</div>
<div>
<OidcSettings mode="Client"></OidcSettings>
<small class="text-muted mb-0">
<LocaleText t="Allow clients to access with OpenID"></LocaleText>
</small>
</div>
</div>
</div>
</div>

View File

@@ -1,22 +1,12 @@
<script setup async>
<script setup>
import './assets/main.css'
import NotificationList from "@/components/Notification/notificationList.vue";
import {clientStore} from "@/stores/clientStore.js";
import {axiosGet} from "@/utilities/request.js";
const store = clientStore()
const serverInformation = axiosGet("/api/serverInformation", {})
if (serverInformation){
store.serverInformation = serverInformation;
}
</script>
<template>
<div data-bs-theme="dark" class="text-body bg-body vw-100 vh-100 bg-body">
<div class="d-flex vw-100 p-sm-4 overflow-y-scroll innerContainer d-flex flex-column">
<div class="mx-auto my-sm-auto position-relative"
id="listContainer"
>
<div class="mx-auto my-sm-auto position-relative" id="listContainer">
<Suspense>
<RouterView v-slot="{ Component }">
<Transition name="app" type="transition" mode="out-in">

View File

@@ -96,7 +96,7 @@ if (route.query.Email){
</span>
</button>
</form>
<div>
<div v-if="store.serverInformation.SignUp.enable">
<hr class="my-4">
<div class="d-flex align-items-center">
<span class="text-muted">

View File

@@ -6,43 +6,43 @@ import router from "@/router/router.js";
import {createPinia} from "pinia";
import 'bootstrap/dist/js/bootstrap.bundle.js'
import {axiosPost} from "@/utilities/request.js";
import {axiosGet, axiosPost} from "@/utilities/request.js";
import {clientStore} from "@/stores/clientStore.js";
const params = new URLSearchParams(window.location.search)
const state = params.get('state')
const code = params.get('code')
const initApp = () => {
const initApp = async () => {
const app = createApp(App)
const serverInformation = await axiosGet("/api/serverInformation", {})
app.use(createPinia())
if (serverInformation){
const store = clientStore()
store.serverInformation = serverInformation.data;
}
app.use(router)
app.mount("#app")
}
function removeSearchString() {
let url = new URL(window.location.href);
url.search = ''; // Remove all query parameters
history.replaceState({}, document.title, url.toString());
}
if (state && code){
axiosPost("/api/signin/oidc", {
await axiosPost("/api/signin/oidc", {
provider: state,
code: code,
redirect_uri: window.location.protocol + '//' + window.location.host + window.location.pathname
}).then(data => {
}).then(async (data) => {
let url = new URL(window.location.href);
url.search = '';
history.replaceState({}, document.title, url.toString());
initApp()
await initApp()
if (!data.status){
const store = clientStore()
store.newNotification(data.message, 'danger')
}
})
}else{
initApp()
await initApp()
}

View File

@@ -50,6 +50,11 @@ const router = createRouter({
})
router.beforeEach(async (to, from, next) => {
const store = clientStore()
if (to.path === "/signup" && !store.serverInformation.SignUp.enable){
next('/signin')
store.newNotification("Sign up is disabled. Please contact administrator for more information", "warning")
}
if (to.path === '/signout'){
await axios.get(requestURl('/api/signout')).then(() => {
next('/signin')