Jelajahi Sumber

refactor: On permissions update ensure user is still authorized to view route

Owen Diffey 2 tahun lalu
induk
melakukan
0cfa98fef1

+ 17 - 3
frontend/src/main.ts

@@ -281,13 +281,17 @@ router.beforeEach((to, from, next) => {
 			else next();
 		};
 
-		if (userAuthStore.gotData) gotData();
+		if (userAuthStore.gotData && userAuthStore.gotPermissions) gotData();
 		else {
 			const unsubscribe = userAuthStore.$onAction(
 				({ name, after, onError }) => {
-					if (name === "authData") {
+					if (name === "authData" || name === "updatePermissions") {
 						after(() => {
-							gotData();
+							if (
+								userAuthStore.gotData &&
+								userAuthStore.gotPermissions
+							)
+								gotData();
 							unsubscribe();
 						});
 
@@ -376,6 +380,16 @@ lofig.folder = defaultConfigURL;
 
 	ws.socket.on("keep.event:user.role.updated", res => {
 		userAuthStore.updateRole(res.data.role);
+		userAuthStore.updatePermissions().then(() => {
+			const { meta } = router.currentRoute.value;
+			if (
+				meta &&
+				meta.permissionRequired &&
+				!userAuthStore.hasPermission(meta.permissionRequired)
+			)
+				window.location.href =
+					"/?msg=You no longer have access to the page you were viewing.";
+		});
 	});
 
 	app.mount("#root");

+ 19 - 12
frontend/src/pages/Station/Sidebar/Users.vue

@@ -125,7 +125,8 @@ const searchForUser = page => {
 watch(
 	() => hasPermission("stations.update"),
 	value => {
-		if (!value && tab.value === "djs") showTab("active");
+		if (!value && (tab.value === "djs" || tab.value === "add-dj"))
+			showTab("active");
 	}
 );
 
@@ -326,7 +327,7 @@ onMounted(async () => {
 			</div>
 			<div
 				v-if="hasPermission('stations.update')"
-				class="tab"
+				class="tab add-dj-tab"
 				v-show="tab === 'add-dj'"
 			>
 				<h5 class="has-text-centered">Add Station DJ</h5>
@@ -489,7 +490,7 @@ onMounted(async () => {
 		.tab-selection {
 			display: flex;
 			overflow-x: auto;
-			margin-bottom: 20px;
+			margin-bottom: 10px;
 			.button {
 				border-radius: 0;
 				border: 0;
@@ -518,7 +519,7 @@ onMounted(async () => {
 			overflow-y: auto;
 
 			.menu {
-				margin-top: 10px;
+				margin-top: 20px;
 				width: 100%;
 
 				.menu-list {
@@ -578,16 +579,22 @@ onMounted(async () => {
 				font-size: 20px;
 			}
 
-			.control.is-grouped.input-with-button {
-				margin: 10px 0 0 0 !important;
-				& > .control {
-					margin-bottom: 0 !important;
+			&.add-dj-tab {
+				.control.is-grouped.input-with-button {
+					margin: 20px 0 0 0 !important;
+					& > .control {
+						margin-bottom: 0 !important;
+					}
 				}
-			}
 
-			.load-more-button {
-				width: 100%;
-				margin-top: 10px;
+				.menu {
+					margin-top: 10px;
+				}
+
+				.load-more-button {
+					width: 100%;
+					margin-top: 10px;
+				}
 			}
 		}
 	}

+ 26 - 3
frontend/src/pages/Station/index.vue

@@ -1344,17 +1344,40 @@ onMounted(async () => {
 	});
 
 	socket.on("event:station.djs.added", res => {
-		if (res.data.user._id === userId.value) updatePermissions();
+		if (res.data.user._id === userId.value)
+			updatePermissions().then(() => {
+				if (
+					!hasPermission("stations.view") &&
+					station.value.privacy === "private"
+				)
+					window.location.href =
+						"/?msg=You no longer have access to the station you were in.";
+			});
 		addDj(res.data.user);
 	});
 
 	socket.on("event:station.djs.removed", res => {
-		if (res.data.user._id === userId.value) updatePermissions();
+		if (res.data.user._id === userId.value)
+			updatePermissions().then(() => {
+				if (
+					!hasPermission("stations.view") &&
+					station.value.privacy === "private"
+				)
+					window.location.href =
+						"/?msg=You no longer have access to the station you were in.";
+			});
 		removeDj(res.data.user);
 	});
 
 	socket.on("keep.event:user.role.updated", () => {
-		updatePermissions();
+		updatePermissions().then(() => {
+			if (
+				!hasPermission("stations.view") &&
+				station.value.privacy === "private"
+			)
+				window.location.href =
+					"/?msg=You no longer have access to the station you were in.";
+		});
 	});
 
 	if (JSON.parse(localStorage.getItem("muted"))) {

+ 2 - 1
frontend/src/stores/userAuth.ts

@@ -19,6 +19,7 @@ export const useUserAuthStore = defineStore("userAuth", {
 			expiresAt: null
 		},
 		gotData: false,
+		gotPermissions: false,
 		permissions: {}
 	}),
 	actions: {
@@ -243,7 +244,6 @@ export const useUserAuthStore = defineStore("userAuth", {
 		},
 		updateRole(role) {
 			this.role = role;
-			this.updatePermissions();
 		},
 		hasPermission(permission) {
 			return !!(this.permissions && this.permissions[permission]);
@@ -252,6 +252,7 @@ export const useUserAuthStore = defineStore("userAuth", {
 			return new Promise(resolve => {
 				ws.socket.dispatch("utils.getPermissions", res => {
 					this.permissions = res.data.permissions;
+					this.gotPermissions = true;
 					resolve(this.permissions);
 				});
 			});