mirror of
https://github.com/fankes/beszel.git
synced 2025-10-19 01:39:34 +08:00
updates to user roles
This commit is contained in:
2
main.go
2
main.go
@@ -153,7 +153,7 @@ func main() {
|
||||
deleteServerConnection(newRecord)
|
||||
}
|
||||
|
||||
// if server is set to pending, try to connect
|
||||
// if server is set to pending (unpause), try to connect
|
||||
if newStatus == "pending" {
|
||||
go updateServer(newRecord)
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ func init() {
|
||||
{
|
||||
"id": "2hz5ncl8tizk5nx",
|
||||
"created": "2024-07-07 16:08:20.979Z",
|
||||
"updated": "2024-07-14 19:51:52.377Z",
|
||||
"updated": "2024-07-17 15:27:00.429Z",
|
||||
"name": "systems",
|
||||
"type": "base",
|
||||
"system": false,
|
||||
@@ -91,20 +91,36 @@ func init() {
|
||||
"options": {
|
||||
"maxSize": 2000000
|
||||
}
|
||||
},
|
||||
{
|
||||
"system": false,
|
||||
"id": "jcarjnjj",
|
||||
"name": "users",
|
||||
"type": "relation",
|
||||
"required": true,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"cascadeDelete": false,
|
||||
"minSelect": null,
|
||||
"maxSelect": null,
|
||||
"displayFields": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"indexes": [],
|
||||
"listRule": "",
|
||||
"viewRule": "@request.auth.id != \"\"",
|
||||
"createRule": "@request.auth.id != \"\" && @request.auth.admin = true",
|
||||
"updateRule": "",
|
||||
"deleteRule": "@request.auth.id != \"\" && @request.auth.admin = true",
|
||||
"listRule": "@request.auth.id != \"\" && users.id ?= @request.auth.id",
|
||||
"viewRule": "@request.auth.id != \"\" && users.id ?= @request.auth.id",
|
||||
"createRule": "@request.auth.id != \"\" && users.id ?= @request.auth.id && @request.auth.role != \"readonly\"",
|
||||
"updateRule": "@request.auth.id != \"\" && users.id ?= @request.auth.id && @request.auth.role != \"readonly\"",
|
||||
"deleteRule": "@request.auth.id != \"\" && users.id ?= @request.auth.id && @request.auth.role != \"readonly\"",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"id": "ej9oowivz8b2mht",
|
||||
"created": "2024-07-07 16:09:09.179Z",
|
||||
"updated": "2024-07-14 03:36:23.089Z",
|
||||
"updated": "2024-07-15 22:44:12.297Z",
|
||||
"name": "system_stats",
|
||||
"type": "base",
|
||||
"system": false,
|
||||
@@ -151,7 +167,7 @@ func init() {
|
||||
{
|
||||
"id": "juohu4jipgc13v7",
|
||||
"created": "2024-07-07 16:09:57.976Z",
|
||||
"updated": "2024-07-14 03:36:23.090Z",
|
||||
"updated": "2024-07-15 22:44:12.297Z",
|
||||
"name": "container_stats",
|
||||
"type": "base",
|
||||
"system": false,
|
||||
@@ -196,11 +212,28 @@ func init() {
|
||||
{
|
||||
"id": "_pb_users_auth_",
|
||||
"created": "2024-07-14 16:25:18.226Z",
|
||||
"updated": "2024-07-14 16:25:18.235Z",
|
||||
"updated": "2024-07-17 15:18:01.385Z",
|
||||
"name": "users",
|
||||
"type": "auth",
|
||||
"system": false,
|
||||
"schema": [
|
||||
{
|
||||
"system": false,
|
||||
"id": "qkbp58ae",
|
||||
"name": "role",
|
||||
"type": "select",
|
||||
"required": true,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"maxSelect": 1,
|
||||
"values": [
|
||||
"user",
|
||||
"admin",
|
||||
"readonly"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"system": false,
|
||||
"id": "users_avatar",
|
||||
@@ -222,16 +255,6 @@ func init() {
|
||||
"maxSize": 5242880,
|
||||
"protected": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"system": false,
|
||||
"id": "ebyl7gfs",
|
||||
"name": "admin",
|
||||
"type": "bool",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"indexes": [],
|
||||
@@ -255,7 +278,7 @@ func init() {
|
||||
{
|
||||
"id": "elngm8x1l60zi2v",
|
||||
"created": "2024-07-15 01:16:04.044Z",
|
||||
"updated": "2024-07-15 18:48:55.881Z",
|
||||
"updated": "2024-07-15 22:44:12.297Z",
|
||||
"name": "alerts",
|
||||
"type": "base",
|
||||
"system": false,
|
||||
|
@@ -53,6 +53,7 @@ export function AddServerButton() {
|
||||
const formData = new FormData(e.target as HTMLFormElement)
|
||||
const data = Object.fromEntries(formData) as Record<string, any>
|
||||
data.status = 'pending'
|
||||
data.users = pb.authStore.model!.id
|
||||
data.info = {
|
||||
cpu: 0,
|
||||
m: 0,
|
||||
|
@@ -55,6 +55,7 @@ export default function DiskChart({
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<YAxis
|
||||
className="tracking-tighter"
|
||||
width={75}
|
||||
domain={[0, diskSize]}
|
||||
// ticks={ticks}
|
||||
|
@@ -45,7 +45,8 @@ export default function DiskIoChart({
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<YAxis
|
||||
width={75}
|
||||
className="tracking-tighter"
|
||||
width={80}
|
||||
domain={[0, 'auto']}
|
||||
// ticks={ticks}
|
||||
tickCount={9}
|
||||
|
@@ -60,7 +60,7 @@ import { useMemo, useState } from 'react'
|
||||
import { $systems, pb, navigate } from '@/lib/stores'
|
||||
import { useStore } from '@nanostores/react'
|
||||
import { AddServerButton } from '../add-server'
|
||||
import { cn, copyToClipboard, isAdmin } from '@/lib/utils'
|
||||
import { cn, copyToClipboard, isReadOnlyUser } from '@/lib/utils'
|
||||
import AlertsButton from '../table-alerts'
|
||||
|
||||
function CellFormatter(info: CellContext<SystemRecord, unknown>) {
|
||||
@@ -167,15 +167,8 @@ export default function SystemsTable() {
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{/* <DropdownMenuLabel>Actions</DropdownMenuLabel> */}
|
||||
{/* <DropdownMenuItem
|
||||
onSelect={() => {
|
||||
navigate(`/server/${name}`)
|
||||
}}
|
||||
>
|
||||
View details
|
||||
</DropdownMenuItem> */}
|
||||
<DropdownMenuItem
|
||||
className={cn(isReadOnlyUser() && 'hidden')}
|
||||
onClick={() => {
|
||||
pb.collection('systems').update(id, {
|
||||
status: status === 'paused' ? 'pending' : 'paused',
|
||||
@@ -198,9 +191,9 @@ export default function SystemsTable() {
|
||||
<CopyIcon className="mr-2.5 h-4 w-4" />
|
||||
Copy host
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuSeparator className={cn(isReadOnlyUser() && 'hidden')} />
|
||||
<AlertDialogTrigger asChild>
|
||||
<DropdownMenuItem>
|
||||
<DropdownMenuItem className={cn(isReadOnlyUser() && 'hidden')}>
|
||||
<Trash2Icon className="mr-2.5 h-4 w-4" />
|
||||
Delete
|
||||
</DropdownMenuItem>
|
||||
@@ -264,11 +257,9 @@ export default function SystemsTable() {
|
||||
onChange={(event) => table.getColumn('name')?.setFilterValue(event.target.value)}
|
||||
className="max-w-sm"
|
||||
/>
|
||||
{isAdmin() && (
|
||||
<div className="ml-auto flex gap-2">
|
||||
<AddServerButton />
|
||||
</div>
|
||||
)}
|
||||
<div className={cn('ml-auto flex gap-2', isReadOnlyUser() && 'hidden')}>
|
||||
<AddServerButton />
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-md border overflow-hidden">
|
||||
<Table>
|
||||
|
@@ -95,7 +95,7 @@ export function UserAuthForm({
|
||||
email,
|
||||
password,
|
||||
passwordConfirm: password,
|
||||
admin: true,
|
||||
role: 'admin',
|
||||
verified: true,
|
||||
})
|
||||
await pb.collection('users').authWithPassword(email, password)
|
||||
|
@@ -75,7 +75,9 @@ export const formatDay = (timestamp: string) => {
|
||||
export const updateFavicon = (newIconUrl: string) =>
|
||||
((document.querySelector("link[rel='icon']") as HTMLLinkElement).href = newIconUrl)
|
||||
|
||||
export const isAdmin = () => pb.authStore.model?.admin
|
||||
export const isAdmin = () => pb.authStore.model?.role === 'admin'
|
||||
export const isReadOnlyUser = () => pb.authStore.model?.role === 'readonly'
|
||||
// export const isDefaultUser = () => pb.authStore.model?.role === 'user'
|
||||
|
||||
/** Update systems / alerts list when records change */
|
||||
export function updateRecordList<T extends RecordModel>(
|
||||
|
Reference in New Issue
Block a user