// Copyright (C) 2024 Vaughn Nugent // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . import 'pinia' import { filter, find } from 'lodash' import { PiniaPluginContext, storeToRefs } from 'pinia' import { computed, shallowRef } from 'vue' import { PrStatus, onWatchableChange, PermissionRequest } from "../../features" import { get } from '@vueuse/core' import { AutoAllowRule } from '../../features/permissions' export interface PermissionApi { readonly pending: PermissionRequest[] readonly all: PermissionRequest[] readonly windowPending: PermissionRequest | undefined readonly isPopup: boolean readonly rules: AutoAllowRule[], readonly rulesForCurrentOrigin: AutoAllowRule[] } declare module 'pinia' { export interface PiniaCustomProperties { permissions: PermissionApi } } export const permissionsPlugin = ({ store }: PiniaPluginContext) => { const { permission } = store.plugins const { currentOrigin } = storeToRefs(store) const all = shallowRef([]) const activeRequests = computed(() => filter(all.value, r => r.status == PrStatus.Pending)) const windowPending = shallowRef() const rules = shallowRef([]) const rulesForCurrentOrigin = computed(() => filter(rules.value, r => r.origin == get(currentOrigin))) const closeIfPopup = () => { const windowQueryArgs = new URLSearchParams(window.location.search) if (windowQueryArgs.has("closeable")) { window.close() } } const getPendingWindowRequest = () => { const uuid = getWindowUuid() const req = get(activeRequests) return find(req, r => r.uuid == uuid) } const getWindowUuid = () => { const queryArgs = new URLSearchParams(window.location.search) return queryArgs.get("uuid") } //watch for status changes onWatchableChange(permission, async () => { //get latest requests and current ruleset all.value = await permission.getRequests() rules.value = await permission.getRules() //update window pending request windowPending.value = getPendingWindowRequest() //if there are no more pending requests, close the popup if (activeRequests.value.length == 0) { closeIfPopup() } //If the window's request is no longer pending, close the popup if (getWindowUuid() && !get(windowPending)){ closeIfPopup() } }, { immediate: true }) return { permissions:{ all, rules, rulesForCurrentOrigin, pending: activeRequests, isPopup: getWindowUuid() !== null, } } }