webapp: Removed hardcoded info about views which require authentication

If the return value of a API request equals 401 then the user will be redirected to the login page.
Using this method it's possible to decided within the API if a authentication is needed or not.
This commit is contained in:
Thomas Basler 2022-11-22 20:37:01 +01:00
parent e60619b867
commit a06a8fec3d
15 changed files with 50 additions and 60 deletions

View File

@ -103,20 +103,4 @@ const router = createRouter({
]
});
router.beforeEach((to, from, next) => {
// redirect to login page if not logged in and trying to access a restricted page
const publicPages = ['/', '/login', '/about', '/info/network', '/info/system', '/info/ntp', '/info/mqtt', ];
const authRequired = !publicPages.includes(to.path);
const loggedIn = localStorage.getItem('user');
if (authRequired && !loggedIn) {
return next({
path: '/login',
query: { returnUrl: to.path }
});
}
next();
});
export default router;

View File

@ -1,17 +1,19 @@
import type { Emitter, EventType } from "mitt";
import type { Router } from "vue-router";
export function authHeader(): Headers {
// return authorization header with basic auth credentials
let user = JSON.parse(localStorage.getItem('user') || "");
let user = null;
try {
user = JSON.parse(localStorage.getItem('user') || "");
} catch { }
if (user && user.authdata) {
const headers = new Headers();
headers.append('X-Requested-With', 'XMLHttpRequest');
if (user && user.authdata) {
headers.append('Authorization', 'Basic ' + user.authdata);
headers.append('X-Requested-With', 'XMLHttpRequest')
return new Headers(headers);
} else {
return new Headers();
}
return new Headers(headers);
}
export function logout() {
@ -47,7 +49,7 @@ export function login(username: String, password: String) {
});
}
export function handleResponse(response: Response, emitter: Emitter<Record<EventType, unknown>>) {
export function handleResponse(response: Response, emitter: Emitter<Record<EventType, unknown>>, router: Router) {
return response.text().then(text => {
const data = text && JSON.parse(text);
if (!response.ok) {
@ -55,7 +57,7 @@ export function handleResponse(response: Response, emitter: Emitter<Record<Event
// auto logout if 401 response returned from api
logout();
emitter.emit("logged-out");
location.reload();
router.push({path: "/login", query: { returnUrl: router.currentRoute.value.fullPath }});
}
const error = (data && data.message) || response.statusText;

View File

@ -156,7 +156,7 @@ export default defineComponent({
headers: authHeader(),
body: formData,
})
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(response) => {
this.alertMessage = response.message;

View File

@ -79,7 +79,7 @@ export default defineComponent({
getDtuConfig() {
this.dataLoading = true;
fetch("/api/dtu/config", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(data) => {
this.dtuConfigList = data;
@ -98,7 +98,7 @@ export default defineComponent({
headers: authHeader(),
body: formData,
})
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(response) => {
this.alertMessage = response.message;

View File

@ -463,8 +463,8 @@ export default defineComponent({
isLoggedIn,
getInitialData() {
this.dataLoading = true;
fetch("/api/livedata/status")
.then((response) => response.json())
fetch("/api/livedata/status", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.liveData = data;
this.dataLoading = false;
@ -526,8 +526,8 @@ export default defineComponent({
},
onShowEventlog(serial: number) {
this.eventLogLoading = true;
fetch("/api/eventlog/status?inv=" + serial)
.then((response) => response.json())
fetch("/api/eventlog/status?inv=" + serial, { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.eventLogList = data[serial];
this.eventLogLoading = false;
@ -540,8 +540,8 @@ export default defineComponent({
},
onShowDevInfo(serial: number) {
this.devInfoLoading = true;
fetch("/api/devinfo/status")
.then((response) => response.json())
fetch("/api/devinfo/status", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.devInfoList = data[serial][0];
this.devInfoLoading = false;
@ -559,8 +559,8 @@ export default defineComponent({
this.targetLimitTypeText = "Relative (%)";
this.limitSettingLoading = true;
fetch("/api/limit/status")
.then((response) => response.json())
fetch("/api/limit/status", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.currentLimitList = data[serial];
this.targetLimitList.serial = serial;
@ -583,7 +583,7 @@ export default defineComponent({
headers: authHeader(),
body: formData,
})
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(response) => {
if (response.type == "success") {
@ -614,8 +614,8 @@ export default defineComponent({
onShowPowerSettings(serial: number) {
this.powerSettingLoading = true;
fetch("/api/power/status")
.then((response) => response.json())
fetch("/api/power/status", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.successCommandPower = data[serial].power_set_status;
this.powerSettingSerial = serial;
@ -653,7 +653,7 @@ export default defineComponent({
headers: authHeader(),
body: formData,
})
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(response) => {
if (response.type == "success") {

View File

@ -207,7 +207,7 @@ export default defineComponent({
getInverters() {
this.dataLoading = true;
fetch("/api/inverter/list", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.inverters = data.inverter;
this.dataLoading = false;
@ -222,7 +222,7 @@ export default defineComponent({
headers: authHeader(),
body: formData,
})
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.getInverters();
this.alert = data;

View File

@ -78,7 +78,7 @@ export default defineComponent({
headers: authHeader(),
body: formData,
})
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.alertMessage = data.message;
this.alertType = data.type;

View File

@ -242,7 +242,7 @@ export default defineComponent({
getMqttConfig() {
this.dataLoading = true;
fetch("/api/mqtt/config", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.mqttConfigList = data;
this.dataLoading = false;
@ -259,7 +259,7 @@ export default defineComponent({
headers: authHeader(),
body: formData,
})
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(response) => {
this.alertMessage = response.message;

View File

@ -149,6 +149,7 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { handleResponse, authHeader } from '@/utils/authentication';
import BasePage from '@/components/BasePage.vue';
import type { MqttStatus } from '@/types/MqttStatus';
@ -168,8 +169,8 @@ export default defineComponent({
methods: {
getMqttInfo() {
this.dataLoading = true;
fetch("/api/mqtt/status")
.then((response) => response.json())
fetch("/api/mqtt/status", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.mqttDataList = data;
this.dataLoading = false;

View File

@ -128,7 +128,7 @@ export default defineComponent({
getNetworkConfig() {
this.dataLoading = true;
fetch("/api/network/config", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.networkConfigList = data;
this.dataLoading = false;
@ -145,7 +145,7 @@ export default defineComponent({
headers: authHeader(),
body: formData,
})
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(response) => {
this.alertMessage = response.message;

View File

@ -13,6 +13,7 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { handleResponse, authHeader } from '@/utils/authentication';
import BasePage from '@/components/BasePage.vue';
import WifiStationInfo from "@/components/WifiStationInfo.vue";
import WifiApInfo from "@/components/WifiApInfo.vue";
@ -40,8 +41,8 @@ export default defineComponent({
methods: {
getNetworkInfo() {
this.dataLoading = true;
fetch("/api/network/status")
.then((response) => response.json())
fetch("/api/network/status", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.networkDataList = data;
this.dataLoading = false;

View File

@ -129,7 +129,7 @@ export default defineComponent({
getNtpConfig() {
this.dataLoading = true;
fetch("/api/ntp/config", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(data) => {
this.ntpConfigList = data;
@ -144,7 +144,7 @@ export default defineComponent({
getCurrentTime() {
this.dataLoading = true;
fetch("/api/ntp/time", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(data) => {
this.mcuTime = new Date(
@ -172,7 +172,7 @@ export default defineComponent({
headers: authHeader(),
body: formData,
})
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(response) => {
this.alertMessage = response.message;
@ -195,7 +195,7 @@ export default defineComponent({
headers: authHeader(),
body: formData,
})
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(response) => {
this.alertMessage = response.message;

View File

@ -54,6 +54,7 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { handleResponse, authHeader } from '@/utils/authentication';
import BasePage from '@/components/BasePage.vue';
import type { NtpStatus } from "@/types/NtpStatus";
@ -73,8 +74,8 @@ export default defineComponent({
methods: {
getNtpInfo() {
this.dataLoading = true;
fetch("/api/ntp/status")
.then((response) => response.json())
fetch("/api/ntp/status", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.ntpDataList = data;
this.dataLoading = false;

View File

@ -67,7 +67,7 @@ export default defineComponent({
getPasswordConfig() {
this.dataLoading = true;
fetch("/api/security/password", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(data) => {
this.securityConfigList = data;
@ -94,7 +94,7 @@ export default defineComponent({
headers: authHeader(),
body: formData,
})
.then((response) => handleResponse(response, this.$emitter))
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then(
(response) => {
this.alertMessage = response.message;

View File

@ -13,6 +13,7 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { handleResponse, authHeader } from '@/utils/authentication';
import BasePage from '@/components/BasePage.vue';
import HardwareInfo from "@/components/HardwareInfo.vue";
import FirmwareInfo from "@/components/FirmwareInfo.vue";
@ -40,8 +41,8 @@ export default defineComponent({
methods: {
getSystemInfo() {
this.dataLoading = true;
fetch("/api/system/status")
.then((response) => response.json())
fetch("/api/system/status", { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.systemDataList = data;
this.dataLoading = false;