1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
// 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 <https://www.gnu.org/licenses/>.
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<PermissionRequest[]>([])
const activeRequests = computed(() => filter(all.value, r => r.status == PrStatus.Pending))
const windowPending = shallowRef<PermissionRequest | undefined>()
const rules = shallowRef<AutoAllowRule[]>([])
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,
}
}
}
|