diff --git a/dashboard/public/js/index.js b/dashboard/public/js/index.js
index 3642525dd..cce21f916 100644
--- a/dashboard/public/js/index.js
+++ b/dashboard/public/js/index.js
@@ -74,8 +74,8 @@ app.config(['$routeProvider', function ($routeProvider) {
controller: 'BrandingController',
templateUrl: 'views/branding.html?' + window.VITE_CACHE_ID
}).when('/network', {
- controller: 'NetworkController',
- templateUrl: 'views/network.html?' + window.VITE_CACHE_ID
+ // controller: 'NetworkController',
+ // templateUrl: 'views/network.html?' + window.VITE_CACHE_ID
}).when('/domains', {
controller: 'DomainsController',
templateUrl: 'views/domains.html?' + window.VITE_CACHE_ID
diff --git a/dashboard/src/Index.vue b/dashboard/src/Index.vue
index a8c0e1891..6e8fd9368 100644
--- a/dashboard/src/Index.vue
+++ b/dashboard/src/Index.vue
@@ -4,6 +4,7 @@ import { Notification } from 'pankow';
import AppsView from './views/AppsView.vue';
import AppstoreView from './views/AppstoreView.vue';
+import NetworkView from './views/NetworkView.vue';
import ProfileView from './views/ProfileView.vue';
import ServicesView from './views/ServicesView.vue';
import SupportView from './views/SupportView.vue';
@@ -17,6 +18,7 @@ const API_ORIGIN = import.meta.env.VITE_API_ORIGIN ? import.meta.env.VITE_API_OR
const VIEWS = {
APPS: 'apps',
APPSTORE: 'appstore',
+ NETWORK: 'network',
PROFILE: 'profile',
SUPPORT: 'support',
SERVICES: 'services',
@@ -29,6 +31,7 @@ export default {
components: {
AppsView,
AppstoreView,
+ NetworkView,
Notification,
ProfileView,
SupportView,
@@ -63,6 +66,8 @@ export default {
that.view = VIEWS.APPS;
} else if (view.indexOf(VIEWS.APPSTORE) === 0) {
that.view = VIEWS.APPSTORE;
+ } else if (view === VIEWS.NETWORK) {
+ that.view = VIEWS.NETWORK;
} else if (view === VIEWS.PROFILE) {
that.view = VIEWS.PROFILE;
} else if (view === VIEWS.SERVICES) {
@@ -92,14 +97,13 @@ export default {
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/dashboard/src/models/NetworkModel.js b/dashboard/src/models/NetworkModel.js
new file mode 100644
index 000000000..be29aa4d6
--- /dev/null
+++ b/dashboard/src/models/NetworkModel.js
@@ -0,0 +1,121 @@
+
+import { fetcher } from 'pankow';
+
+function create(origin, accessToken) {
+ return {
+ async getIpv4Config() {
+ let error, result;
+ try {
+ result = await fetcher.get(`${origin}/api/v1/network/ipv4_config`, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null, result.body];
+ },
+ async getIpv4() {
+ let error, result;
+ try {
+ result = await fetcher.get(`${origin}/api/v1/network/ipv4`, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null, result.body.ip];
+ },
+ async getIpv6Config() {
+ let error, result;
+ try {
+ result = await fetcher.get(`${origin}/api/v1/network/ipv6_config`, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null, result.body];
+ },
+ async getIpv6() {
+ let error, result;
+ try {
+ result = await fetcher.get(`${origin}/api/v1/network/ipv6`, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null, result.body.ip];
+ },
+ async getDynDnsConfig() {
+ let error, result;
+ try {
+ result = await fetcher.get(`${origin}/api/v1/network/dynamic_dns`, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null, result.body];
+ },
+ async setDynDnsConfig(enabled) {
+ let error, result;
+ try {
+ result = await fetcher.post(`${origin}/api/v1/network/dynamic_dns`, { enabled }, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null];
+ },
+ async getBlocklist() {
+ let error, result;
+ try {
+ result = await fetcher.get(`${origin}/api/v1/network/blocklist`, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null, result.body.blocklist];
+ },
+ async setBlocklist(blocklist) {
+ let error, result;
+ try {
+ result = await fetcher.post(`${origin}/api/v1/network/blocklist`, { blocklist }, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null];
+ },
+ async getTrustedIps() {
+ let error, result;
+ try {
+ result = await fetcher.get(`${origin}/api/v1/reverseproxy/trusted_ips`, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null, result.body.trustedIps];
+ },
+ async setTrustedIps(trustedIps) {
+ let error, result;
+ try {
+ result = await fetcher.post(`${origin}/api/v1/reverseproxy/trusted_ips`, { trustedIps }, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null];
+ },
+ };
+}
+
+export default {
+ create,
+};
diff --git a/dashboard/src/views/NetworkView.vue b/dashboard/src/views/NetworkView.vue
new file mode 100644
index 000000000..c38e56d9e
--- /dev/null
+++ b/dashboard/src/views/NetworkView.vue
@@ -0,0 +1,213 @@
+
+
+
+
+
{{ $t('network.title') }}
+
+
+ {{ $t('network.ip.description') }}
+
+
+
{{ $t('network.ip.provider') }}
+
{{ prettyIpProviderName(ipv4Provider) }}
+
+
+
{{ $t('network.ip.address') }}
+
{{ ipv4Address || `${ipv4DetectedAddress} (${$t('network.ip.detected')})` }}
+
+
+
{{ $t('network.ip.interface') }}
+
{{ ipv4InterfaceName }}
+
+
+
+
+
+
+ {{ $t('network.ipv6.description') }}
+
+
+
{{ $t('network.ip.provider') }}
+
{{ prettyIpProviderName(ipv6Provider) }}
+
+
+
{{ $t('network.ip.address') }}
+
{{ ipv6Address || `${ipv6DetectedAddress} (${$t('network.ip.detected')})` }}
+
+
+
+
{{ $t('network.ip.interface') }}
+
{{ ipv6InterfaceName }}
+
+
+
+
+
+
+
+
{{ $t('network.firewall.blockedIpRanges') }}
+
{{ $t('network.firewall.blocklist', { blockCount: blocklistLength }) }}
+
+
+
{{ $t('network.trustedIpRanges') }}
+
{{ $t('network.trustedIps.summary', { trustCount: trustedIpsLength }) }}
+
+
+
+
+ {{ $t('network.dyndns.description') }}
+
+
+
+ {{ $t(dynDnsIsEnabled ? 'main.statusEnabled' : 'main.statusDisabled') }}
+
+
+
+
+
+
+