Privileged header items

This commit is contained in:
Jorge Vargas 2025-02-11 00:13:15 -06:00
parent 1631ce7bf6
commit 181cc33dd1
7 changed files with 88 additions and 27 deletions

View file

@ -21,11 +21,11 @@
"studios": "Studios", "studios": "Studios",
"requests": "Requests", "requests": "Requests",
"submitalbum": "Submit Album", "submitalbum": "Submit Album",
"admingrounds": "Admin Grounds", "adminGrounds": "Admin Grounds",
"managealbums": "Manage Albums", "manageAlbums": "Manage Albums",
"manageusers": "Manage Users", "manageUsers": "Manage Users",
"managerequests": "Manage Requests", "manageRequests": "Manage Requests",
"managesubmissions": "Manage Submissions", "manageSubmissions": "Manage Submissions",
"profilePic": "Profile picture", "profilePic": "Profile picture",
"emailSuccess": "An email with further instructions has been sent to the address linked to the account. Check your spam folder.", "emailSuccess": "An email with further instructions has been sent to the address linked to the account. Check your spam folder.",
"close": "Close", "close": "Close",

View file

@ -520,7 +520,7 @@ model users {
updatedAt DateTime @db.DateTime(0) updatedAt DateTime @db.DateTime(0)
image String? @db.VarChar(255) image String? @db.VarChar(255)
roles User_Role[] roleList User_Role[]
albumHistories albumHistories[] albumHistories albumHistories[]
comments comments[] comments comments[]
favorites favorites[] favorites favorites[]

View file

@ -14,6 +14,7 @@ import prismaClient from 'utils/prisma-client.js'
const { value: bannerId } = (await prismaClient.config.findUnique({ where: { name: 'banner' } })) ?? {} const { value: bannerId } = (await prismaClient.config.findUnique({ where: { name: 'banner' } })) ?? {}
const { value: bannerPosition } = (await prismaClient.config.findUnique({ where: { name: 'banner-position' } })) ?? {} const { value: bannerPosition } = (await prismaClient.config.findUnique({ where: { name: 'banner-position' } })) ?? {}
const { session } = Astro.locals
--- ---
<header class='relative'> <header class='relative'>
@ -67,20 +68,33 @@ const { value: bannerPosition } = (await prismaClient.config.findUnique({ where:
</Fragment> </Fragment>
</Dropdown> </Dropdown>
<!-- <a href='/requests'><NavButton>{m.requests()}</NavButton></a> {
<a href='#'><NavButton>{m.submitalbum()}</NavButton></a> --> session ? (
<>
<!-- <Dropdown> <a href='/requests'>
{m.admingrounds()} <NavButton>{m.requests()}</NavButton>
<Fragment slot='items'> </a>
<DropdownItem href='/admin'>{m.managealbums()}</DropdownItem> <NavButton>{m.submitalbum()}</NavButton>
<DropdownItem href='/admin/user'>{m.manageusers()}</DropdownItem> <Dropdown>
<DropdownItem href='/admin/request'>{m.managerequests()}</DropdownItem> {m.adminGrounds()}
<DropdownItem href='/admin/submission' <Fragment slot='items'>
>{m.managesubmissions()}</DropdownItem <DropdownItem href='/admin' perms>
> {m.manageAlbums()}
</Fragment> </DropdownItem>
</Dropdown> --> <DropdownItem href='/admin/user' perms>
{m.manageUsers()}
</DropdownItem>
<DropdownItem href='/admin/request' perms>
{m.manageRequests()}
</DropdownItem>
<DropdownItem href='/admin/submission' perms>
{m.manageSubmissions()}
</DropdownItem>
</Fragment>
</Dropdown>
</>
) : null
}
</Toggler> </Toggler>
</nav> </nav>
</header> </header>

View file

@ -1,10 +1,14 @@
--- ---
const { class: className, href } = Astro.props const { class: className, href, perms = false } = Astro.props
const { pages } = Astro.locals
const show = !perms || pages.includes(href)
--- ---
<a {
href={href} show ? (
class:list={['hover:bg-gray-hover py-1 text-left ps-4', className]} <a href={href} class:list={['hover:bg-gray-hover py-1 text-left ps-4', className]}>
> <slot />
<slot /> </a>
</a> ) : null
}

2
src/env.d.ts vendored
View file

@ -4,5 +4,7 @@ declare namespace App {
interface Locals { interface Locals {
user: import('better-auth').User | null user: import('better-auth').User | null
session: import('better-auth').Session | null session: import('better-auth').Session | null
permissions: string[]
pages: string[]
} }
} }

View file

@ -1,6 +1,9 @@
import { auth } from 'auth' import { auth } from 'auth'
import { defineMiddleware } from 'astro:middleware' import { defineMiddleware } from 'astro:middleware'
import PAGES from 'utils/pages.json'
import prismaClient from 'utils/prisma-client'
export const onRequest = defineMiddleware(async (context, next) => { export const onRequest = defineMiddleware(async (context, next) => {
const isAuthed = await auth.api.getSession({ const isAuthed = await auth.api.getSession({
headers: context.request.headers headers: context.request.headers
@ -9,9 +12,21 @@ export const onRequest = defineMiddleware(async (context, next) => {
if (isAuthed) { if (isAuthed) {
context.locals.user = isAuthed.user context.locals.user = isAuthed.user
context.locals.session = isAuthed.session context.locals.session = isAuthed.session
const user = await prismaClient.users.findUnique({
select: { roleList: { select: { roles: { select: { permissions: true } } } } },
where: { id: isAuthed.user.id }
})
const permissions = (user?.roleList.map((r) => r.roles.permissions).flat() as string[]) ?? []
const pages = PAGES.filter((p) => p.perms.some((r) => permissions.includes(r))).map((p) => p.url)
context.locals.permissions = permissions
context.locals.pages = pages
} else { } else {
context.locals.user = null context.locals.user = null
context.locals.session = null context.locals.session = null
context.locals.permissions = []
context.locals.pages = []
} }
return next() return next()

26
src/utils/pages.json Normal file
View file

@ -0,0 +1,26 @@
[
{
"url": "/admin/1",
"perms": ["UPDATE"]
},
{
"url": "/admin/user",
"perms": ["MANAGE_USER"]
},
{
"url": "/admin/album/add",
"perms": ["CREATE", "UPDATE"]
},
{
"url": "/admin/album/:id",
"perms": ["UPDATE"]
},
{
"url": "/admin/request",
"perms": ["REQUESTS"]
},
{
"url": "/admin/submission",
"perms": ["REQUESTS"]
}
]