diff --git a/src/dashboard.py b/src/dashboard.py index 0f3d47d..8ecff42 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -1096,6 +1096,7 @@ class DashboardConfig: self.SetConfig(section, key, value, True) self.__createAPIKeyTable() self.DashboardAPIKeys = self.__getAPIKeys() + self.APIAccessed = False def __createAPIKeyTable(self): existingTable = sqldb.cursor().execute("SELECT name FROM sqlite_master WHERE type='table' AND name = 'DashboardAPIKeys'").fetchall() @@ -1343,6 +1344,7 @@ def _getWireguardConfigurationAvailableIP(configName: str) -> tuple[bool, list[s return False, None + ''' API Routes ''' @@ -1351,7 +1353,8 @@ API Routes def auth_req(): if request.method.lower() == 'options': return ResponseObject(True) - + + DashboardConfig.APIAccessed = False if "api" in request.path: if str(request.method) == "GET": DashboardLogger.log(str(request.url), str(request.remote_addr), Message=str(request.args)) @@ -1368,6 +1371,7 @@ def auth_req(): apiKeyExist = len(list(filter(lambda x : x.Key == apiKey, DashboardConfig.DashboardAPIKeys))) == 1 DashboardLogger.log(str(request.url), str(request.remote_addr), Message=f"API Key Access: {('true' if apiKeyExist else 'false')} - Key: {apiKey}") if not apiKeyExist: + DashboardConfig.APIAccessed = False response = Flask.make_response(app, { "status": False, "message": "API Key does not exist", @@ -1376,7 +1380,9 @@ def auth_req(): response.content_type = "application/json" response.status_code = 401 return response + DashboardConfig.APIAccessed = True else: + DashboardConfig.APIAccessed = False if ('/static/' not in request.path and "username" not in session and "/" != request.path and "validateAuthentication" not in request.path and "authenticate" not in request.path and "getDashboardConfiguration" not in request.path and "getDashboardTheme" not in request.path @@ -1408,6 +1414,17 @@ def API_ValidateAuthentication(): @app.route('/api/authenticate', methods=['POST']) def API_AuthenticateLogin(): data = request.get_json() + if DashboardConfig.APIAccessed: + + authToken = hashlib.sha256(f"{request.headers.get('wg-dashboard-apikey')}{datetime.now()}".encode()).hexdigest() + session['username'] = authToken + resp = ResponseObject(True, DashboardConfig.GetConfig("Other", "welcome_session")[1]) + print(data['host']) + resp.set_cookie("authToken", authToken, domain=data['host']) + session.permanent = True + return resp + + valid = bcrypt.checkpw(data['password'].encode("utf-8"), DashboardConfig.GetConfig("Account", "password")[1].encode("utf-8")) totpEnabled = DashboardConfig.GetConfig("Account", "enable_totp")[1] diff --git a/src/static/app/src/App.vue b/src/static/app/src/App.vue index bc12a67..a311bd7 100644 --- a/src/static/app/src/App.vue +++ b/src/static/app/src/App.vue @@ -16,8 +16,11 @@ watch(store.CrossServerConfiguration, () => { diff --git a/src/static/app/src/components/signInComponents/RemoteServerList.vue b/src/static/app/src/components/signInComponents/RemoteServerList.vue index a52dcd1..8c8a266 100644 --- a/src/static/app/src/components/signInComponents/RemoteServerList.vue +++ b/src/static/app/src/components/signInComponents/RemoteServerList.vue @@ -14,7 +14,7 @@ export default { diff --git a/src/static/app/src/router/index.js b/src/static/app/src/router/index.js index 1072cb0..b31b5c1 100644 --- a/src/static/app/src/router/index.js +++ b/src/static/app/src/router/index.js @@ -138,19 +138,28 @@ router.beforeEach(async (to, from, next) => { } if (to.meta.requiresAuth){ - if (cookie.getCookie("authToken") && await checkAuth()){ + if (!dashboardConfigurationStore.getActiveCrossServer()){ + if (cookie.getCookie("authToken") && await checkAuth()){ + await dashboardConfigurationStore.getConfiguration() + if (!wireguardConfigurationsStore.Configurations && to.name !== "Configuration List"){ + await wireguardConfigurationsStore.getConfigurations(); + } + dashboardConfigurationStore.Redirect = undefined; + next() + }else{ + dashboardConfigurationStore.Redirect = to; + next("/signin") + dashboardConfigurationStore.newMessage("WGDashboard", "Session Ended", "warning") + } + }else{ await dashboardConfigurationStore.getConfiguration() if (!wireguardConfigurationsStore.Configurations && to.name !== "Configuration List"){ await wireguardConfigurationsStore.getConfigurations(); } - dashboardConfigurationStore.Redirect = undefined; next() - }else{ - dashboardConfigurationStore.Redirect = to; - next("/signin") - dashboardConfigurationStore.newMessage("WGDashboard", "Session Ended", "warning") } }else { + next(); } }); diff --git a/src/static/app/src/stores/DashboardConfigurationStore.js b/src/static/app/src/stores/DashboardConfigurationStore.js index ab62507..effe5a5 100644 --- a/src/static/app/src/stores/DashboardConfigurationStore.js +++ b/src/static/app/src/stores/DashboardConfigurationStore.js @@ -13,13 +13,12 @@ export const DashboardConfigurationStore = defineStore('DashboardConfigurationSt }, CrossServerConfiguration:{ Enable: false, - ServerList: [] + ServerList: {} } }), actions: { initCrossServerConfiguration(){ const currentConfiguration = localStorage.getItem('CrossServerConfiguration'); - if (currentConfiguration === null){ localStorage.setItem('CrossServerConfiguration', JSON.stringify(this.CrossServerConfiguration)) }else{ @@ -30,9 +29,23 @@ export const DashboardConfigurationStore = defineStore('DashboardConfigurationSt localStorage.setItem('CrossServerConfiguration', JSON.stringify(this.CrossServerConfiguration)) }, addCrossServerConfiguration(){ - this.CrossServerConfiguration.ServerList.push( - {host: "", apiKey: ""} - ) + this.CrossServerConfiguration.ServerList[v4().toString()] = {host: "", apiKey: "", active: false} + }, + deleteCrossServerConfiguration(key){ + delete this.CrossServerConfiguration.ServerList[key]; + }, + getActiveCrossServer(){ + const key = localStorage.getItem('ActiveCrossServerConfiguration'); + if (key !== null){ + return this.CrossServerConfiguration.ServerList[key] + } + return undefined + }, + setActiveCrossServer(key){ + localStorage.setItem('ActiveCrossServerConfiguration', key) + }, + removeActiveCrossServer(){ + localStorage.removeItem('ActiveCrossServerConfiguration') }, async getConfiguration(){ @@ -49,6 +62,7 @@ export const DashboardConfigurationStore = defineStore('DashboardConfigurationSt }, async signOut(){ await fetchGet("/api/signout", {}, (res) => { + this.removeActiveCrossServer(); this.$router.go('/signin') }); }, diff --git a/src/static/app/src/utilities/fetch.js b/src/static/app/src/utilities/fetch.js index c7cd2dc..b8b5bd8 100644 --- a/src/static/app/src/utilities/fetch.js +++ b/src/static/app/src/utilities/fetch.js @@ -1,11 +1,31 @@ import router from "@/router/index.js"; import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js"; + +const getHeaders = () => { + let headers = { + "content-type": "application/json" + } + const store = DashboardConfigurationStore(); + const apiKey = store.getActiveCrossServer(); + if (apiKey){ + headers['wg-dashboard-apikey'] = apiKey.apiKey + } + return headers +} + +const getUrl = (url) => { + const store = DashboardConfigurationStore(); + const apiKey = store.getActiveCrossServer(); + if (apiKey){ + return `${apiKey.host}${url}` + } + return url +} + export const fetchGet = async (url, params=undefined, callback=undefined) => { const urlSearchParams = new URLSearchParams(params); - await fetch(`${url}?${urlSearchParams.toString()}`, { - headers: { - "content-type": "application/json" - } + await fetch(`${getUrl(url)}?${urlSearchParams.toString()}`, { + headers: getHeaders() }) .then((x) => { const store = DashboardConfigurationStore(); @@ -26,10 +46,8 @@ export const fetchGet = async (url, params=undefined, callback=undefined) => { } export const fetchPost = async (url, body, callback) => { - await fetch(`${url}`, { - headers: { - "content-type": "application/json" - }, + await fetch(`${getUrl(url)}`, { + headers: getHeaders(), method: "POST", body: JSON.stringify(body) }).then((x) => {