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