diff --git a/src/dashboard.py b/src/dashboard.py index e535e7c..b0a250f 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -509,6 +509,7 @@ class WireguardConfiguration: self.createDatabase() with open(self.configPath, "w+") as configFile: self.__parser.write(configFile) + print(f"[WGDashboard] Configuration file {self.configPath} created") self.__initPeersList() print(f"[WGDashboard] Initialized Configuration: {name}") @@ -2086,11 +2087,14 @@ def API_getWireguardConfigurations(): def API_addWireguardConfiguration(): data = request.get_json() requiredKeys = [ - "ConfigurationName", "Address", "ListenPort", "PrivateKey" + "ConfigurationName", "Address", "ListenPort", "PrivateKey", "Protocol" ] for i in requiredKeys: if i not in data.keys(): return ResponseObject(False, "Please provide all required parameters.") + + if data.get("Protocol") not in ProtocolsEnabled(): + return ResponseObject(False, "Please provide a valid protocol: wg / awg.") # Check duplicate names, ports, address for i in WireguardConfigurations.values(): @@ -2110,22 +2114,27 @@ def API_addWireguardConfiguration(): "Address") if "Backup" in data.keys(): - if not os.path.exists(os.path.join( - DashboardConfig.GetConfig("Server", "wg_conf_path")[1], - 'WGDashboard_Backup', - data["Backup"])) or not os.path.exists(os.path.join( - DashboardConfig.GetConfig("Server", "wg_conf_path")[1], - 'WGDashboard_Backup', - data["Backup"].replace('.conf', '.sql'))): - return ResponseObject(False, "Backup file does not exist") + path = { + "wg": DashboardConfig.GetConfig("Server", "wg_conf_path")[1], + "awg": DashboardConfig.GetConfig("Server", "awg_conf_path")[1] + } + + if (os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"])) and + os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): + protocol = "wg" + elif (os.path.exists(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"])) and + os.path.exists(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): + protocol = "awg" + else: + return ResponseObject(False, "Backup does not exist") shutil.copy( - os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], 'WGDashboard_Backup', data["Backup"]), - os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], f'{data["ConfigurationName"]}.conf') + os.path.join(path[protocol], 'WGDashboard_Backup', data["Backup"]), + os.path.join(path[protocol], f'{data["ConfigurationName"]}.conf') ) - WireguardConfigurations[data['ConfigurationName']] = WireguardConfiguration(data=data, name=data['ConfigurationName']) + WireguardConfigurations[data['ConfigurationName']] = WireguardConfiguration(data=data, name=data['ConfigurationName']) if protocol == 'wg' else AmneziaWireguardConfiguration(data=data, name=data['ConfigurationName']) else: - WireguardConfigurations[data['ConfigurationName']] = WireguardConfiguration(data=data) + WireguardConfigurations[data['ConfigurationName']] = WireguardConfiguration(data=data) if data.get('Protocol') == 'wg' else AmneziaWireguardConfiguration(data=data) return ResponseObject() @app.get(f'{APP_PREFIX}/api/toggleWireguardConfiguration/') @@ -2197,30 +2206,32 @@ def API_getAllWireguardConfigurationBackup(): b = WireguardConfigurations[i].getBackups(True) if len(b) > 0: data['ExistingConfigurations'][i] = WireguardConfigurations[i].getBackups(True) - - directory = os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], 'WGDashboard_Backup') - files = [(file, os.path.getctime(os.path.join(directory, file))) - for file in os.listdir(directory) if os.path.isfile(os.path.join(directory, file))] - files.sort(key=lambda x: x[1], reverse=True) - - for f, ct in files: - if RegexMatch(r"^(.*)_(.*)\.(conf)$", f): - s = re.search(r"^(.*)_(.*)\.(conf)$", f) - name = s.group(1) - if name not in existingConfiguration: - if name not in data['NonExistingConfigurations'].keys(): - data['NonExistingConfigurations'][name] = [] - - date = s.group(2) - d = { - "filename": f, - "backupDate": date, - "content": open(os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], 'WGDashboard_Backup', f), 'r').read() - } - if f.replace(".conf", ".sql") in list(os.listdir(directory)): - d['database'] = True - d['databaseContent'] = open(os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], 'WGDashboard_Backup', f.replace(".conf", ".sql")), 'r').read() - data['NonExistingConfigurations'][name].append(d) + + for protocol in ProtocolsEnabled(): + directory = os.path.join(DashboardConfig.GetConfig("Server", f"{protocol}_conf_path")[1], 'WGDashboard_Backup') + files = [(file, os.path.getctime(os.path.join(directory, file))) + for file in os.listdir(directory) if os.path.isfile(os.path.join(directory, file))] + files.sort(key=lambda x: x[1], reverse=True) + + for f, ct in files: + if RegexMatch(r"^(.*)_(.*)\.(conf)$", f): + s = re.search(r"^(.*)_(.*)\.(conf)$", f) + name = s.group(1) + if name not in existingConfiguration: + if name not in data['NonExistingConfigurations'].keys(): + data['NonExistingConfigurations'][name] = [] + + date = s.group(2) + d = { + "protocol": protocol, + "filename": f, + "backupDate": date, + "content": open(os.path.join(DashboardConfig.GetConfig("Server", f"{protocol}_conf_path")[1], 'WGDashboard_Backup', f), 'r').read() + } + if f.replace(".conf", ".sql") in list(os.listdir(directory)): + d['database'] = True + d['databaseContent'] = open(os.path.join(DashboardConfig.GetConfig("Server", f"{protocol}_conf_path")[1], 'WGDashboard_Backup', f.replace(".conf", ".sql")), 'r').read() + data['NonExistingConfigurations'][name].append(d) return ResponseObject(data=data) @app.get(f'{APP_PREFIX}/api/createWireguardConfigurationBackup') @@ -2944,6 +2955,9 @@ def API_SystemStatus(): # pass return ResponseObject(data=status) +@app.get(f'{APP_PREFIX}/api/protocolsEnabled') +def API_ProtocolsEnabled(): + return ResponseObject(data=ProtocolsEnabled()) @app.get(f'{APP_PREFIX}/') def index(): @@ -2980,10 +2994,15 @@ def gunicornConfig(): _, app_port = DashboardConfig.GetConfig("Server", "app_port") return app_ip, app_port -def AmneziaWGEnabled(): +def ProtocolsEnabled() -> list[str]: from shutil import which + protocols = [] + if which('awg') is not None and which('awg-quick') is not None: + protocols.append("awg") + if which('wg') is not None and which('wg-quick') is not None: + protocols.append("wg") + return protocols - return which('awg') is not None and which('awg-quick') is not None def InitWireguardConfigurationsList(startup: bool = False): confs = os.listdir(DashboardConfig.GetConfig("Server", "wg_conf_path")[1]) @@ -3000,7 +3019,7 @@ def InitWireguardConfigurationsList(startup: bool = False): except WireguardConfiguration.InvalidConfigurationFileException as e: print(f"{i} have an invalid configuration file.") - if AmneziaWGEnabled(): + if "awg" in ProtocolsEnabled(): confs = os.listdir(DashboardConfig.GetConfig("Server", "awg_conf_path")[1]) confs.sort() for i in confs: diff --git a/src/static/app/src/components/protocolBadge.vue b/src/static/app/src/components/protocolBadge.vue new file mode 100644 index 0000000..53b2c5d --- /dev/null +++ b/src/static/app/src/components/protocolBadge.vue @@ -0,0 +1,21 @@ + + + + + WireGuard + + + AmneziaWG + + + + \ No newline at end of file diff --git a/src/static/app/src/components/restoreConfigurationComponents/backupGroup.vue b/src/static/app/src/components/restoreConfigurationComponents/backupGroup.vue index 69e84a1..ec64b5b 100644 --- a/src/static/app/src/components/restoreConfigurationComponents/backupGroup.vue +++ b/src/static/app/src/components/restoreConfigurationComponents/backupGroup.vue @@ -2,12 +2,14 @@ import {onMounted, ref} from "vue"; import dayjs from "dayjs"; import LocaleText from "@/components/text/localeText.vue"; +import ProtocolBadge from "@/components/protocolBadge.vue"; const props = defineProps({ configurationName: String, backups: Array, open: false, - selectedConfigurationBackup: Object + selectedConfigurationBackup: Object, + protocol: Array }) const emit = defineEmits(["select"]) @@ -28,18 +30,20 @@ onMounted(() => { - - - - - {{configurationName}} - - - - - - - + + + + {{configurationName}} + + + + + + + + diff --git a/src/static/app/src/components/restoreConfigurationComponents/confirmBackup.vue b/src/static/app/src/components/restoreConfigurationComponents/confirmBackup.vue index 82f6749..44fb38f 100644 --- a/src/static/app/src/components/restoreConfigurationComponents/confirmBackup.vue +++ b/src/static/app/src/components/restoreConfigurationComponents/confirmBackup.vue @@ -6,6 +6,7 @@ import {parse} from "cidr-tools"; import {fetchPost} from "@/utilities/fetch.js"; import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js"; import {useRouter} from "vue-router"; +import ProtocolBadge from "@/components/protocolBadge.vue"; const props = defineProps({ @@ -14,7 +15,8 @@ const props = defineProps({ const newConfiguration = reactive({ ConfigurationName: props.selectedConfigurationBackup.filename.split("_")[0], - Backup: props.selectedConfigurationBackup.filename + Backup: props.selectedConfigurationBackup.filename, + Protocol: props.selectedConfigurationBackup.protocol }) const lineSplit = props.selectedConfigurationBackup.content.split("\n"); @@ -136,6 +138,16 @@ const submitRestore = async () => { + + + + + + + + + + diff --git a/src/static/app/src/router/router.js b/src/static/app/src/router/router.js index e0b89b1..80eb95d 100644 --- a/src/static/app/src/router/router.js +++ b/src/static/app/src/router/router.js @@ -180,11 +180,7 @@ router.beforeEach(async (to, from, next) => { next() } }else { - if (to.path === "/signin" && await checkAuth()){ - next("/") - }else{ - next() - } + next() } }); diff --git a/src/static/app/src/views/newConfiguration.vue b/src/static/app/src/views/newConfiguration.vue index 20bbb2f..f6f1f4c 100644 --- a/src/static/app/src/views/newConfiguration.vue +++ b/src/static/app/src/views/newConfiguration.vue @@ -2,15 +2,22 @@ import {parse} from "cidr-tools"; import '@/utilities/wireguard.js' import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js"; -import {fetchPost} from "@/utilities/fetch.js"; +import {fetchGet, fetchPost} from "@/utilities/fetch.js"; import LocaleText from "@/components/text/localeText.vue"; +import {ref} from "vue"; export default { name: "newConfiguration", components: {LocaleText}, - setup(){ + async setup(){ const store = WireguardConfigurationsStore() - return {store} + const protocols = ref([]) + await fetchGet("/api/protocolsEnabled", {}, (res) => { + protocols.value = res.data + }) + + + return {store, protocols} }, data(){ return { @@ -279,30 +286,31 @@ export default { - - PreUp + + {{ key }} - - - - - PreDown - - - - - - PostUp - - - - - - PostDown - - + + + + + + + + + + + + + + + + + + + diff --git a/src/static/app/src/views/restoreConfiguration.vue b/src/static/app/src/views/restoreConfiguration.vue index ecd6ade..3a482c6 100644 --- a/src/static/app/src/views/restoreConfiguration.vue +++ b/src/static/app/src/views/restoreConfiguration.vue @@ -67,6 +67,7 @@ const selectedConfiguration = ref("") @select="(b) => {selectedConfigurationBackup = b; selectedConfiguration = c; confirm = true}" :selectedConfigurationBackup="selectedConfigurationBackup" :open="selectedConfiguration === c" + :protocol="[...new Set(backups.NonExistingConfigurations[c].map(x => x.protocol))]" v-for="c in Object.keys(backups.NonExistingConfigurations)" :configuration-name="c" :backups="backups.NonExistingConfigurations[c]">