1
0
Fork 0
mirror of https://codeberg.org/MarkusThielker/next-ory.git synced 2025-04-19 09:01:18 +00:00

NORY-59: add authentication and authorisation to user page

This commit is contained in:
Markus Thielker 2025-04-04 19:10:40 +02:00 committed by Markus Thielker
parent 6d277a7d62
commit 0b81a02fba
2 changed files with 67 additions and 19 deletions

View file

@ -33,9 +33,16 @@ interface IdentityDataTableProps {
data: Identity[]; data: Identity[];
page: number; page: number;
query: string; query: string;
permission: {
pmEditUser: boolean;
pmBlockUser: boolean;
pmUnblockUser: boolean;
pmDeleteUser: boolean;
pmDeleteUserSession: boolean;
};
} }
export function IdentityDataTable({ data, page, query }: IdentityDataTableProps) { export function IdentityDataTable({ data, page, query, permission }: IdentityDataTableProps) {
const columns: ColumnDef<Identity>[] = [ const columns: ColumnDef<Identity>[] = [
{ {
@ -137,6 +144,7 @@ export function IdentityDataTable({ data, page, query }: IdentityDataTableProps)
setCurrentIdentity(identity); setCurrentIdentity(identity);
setIdentitySessionVisible(true); setIdentitySessionVisible(true);
}} }}
disabled={!permission.pmDeleteUserSession}
className="flex items-center space-x-2 text-red-500"> className="flex items-center space-x-2 text-red-500">
<UserMinus className="h-4 w-4"/> <UserMinus className="h-4 w-4"/>
<span>Delete sessions</span> <span>Delete sessions</span>
@ -148,6 +156,7 @@ export function IdentityDataTable({ data, page, query }: IdentityDataTableProps)
setCurrentIdentity(identity); setCurrentIdentity(identity);
setBlockIdentityVisible(true); setBlockIdentityVisible(true);
}} }}
disabled={!permission.pmBlockUser}
className="flex items-center space-x-2 text-red-500"> className="flex items-center space-x-2 text-red-500">
<UserX className="h-4 w-4"/> <UserX className="h-4 w-4"/>
<span>Block identity</span> <span>Block identity</span>
@ -160,6 +169,7 @@ export function IdentityDataTable({ data, page, query }: IdentityDataTableProps)
setCurrentIdentity(identity); setCurrentIdentity(identity);
setUnblockIdentityVisible(true); setUnblockIdentityVisible(true);
}} }}
disabled={!permission.pmUnblockUser}
className="flex items-center space-x-2 text-red-500"> className="flex items-center space-x-2 text-red-500">
<UserCheck className="h-4 w-4"/> <UserCheck className="h-4 w-4"/>
<span>Unblock identity</span> <span>Unblock identity</span>
@ -170,6 +180,7 @@ export function IdentityDataTable({ data, page, query }: IdentityDataTableProps)
setCurrentIdentity(identity); setCurrentIdentity(identity);
setDeleteIdentityVisible(true); setDeleteIdentityVisible(true);
}} }}
disabled={!permission.pmDeleteUser}
className="flex items-center space-x-2 text-red-500"> className="flex items-center space-x-2 text-red-500">
<Trash className="h-4 w-4"/> <Trash className="h-4 w-4"/>
<span>Delete identity</span> <span>Delete identity</span>

View file

@ -3,6 +3,8 @@ import { IdentityDataTable } from '@/app/(inside)/user/data-table';
import { SearchInput } from '@/components/search-input'; import { SearchInput } from '@/components/search-input';
import { queryIdentities } from '@/lib/action/identity'; import { queryIdentities } from '@/lib/action/identity';
import { IdentityPagination } from '@/components/pagination'; import { IdentityPagination } from '@/components/pagination';
import { checkPermission, requireRole, requireSession } from '@/lib/action/authentication';
import InsufficientPermission from '@/components/insufficient-permission';
export default async function UserPage( export default async function UserPage(
{ {
@ -12,6 +14,18 @@ export default async function UserPage(
}, },
) { ) {
const session = await requireSession();
const identityId = session.identity!.id;
await requireRole('admin', identityId);
const pmAccessUser = await checkPermission('admin.user', 'access', identityId);
const pmEditUser = await checkPermission('admin.user', 'edit', identityId);
const pmBlockUser = await checkPermission('admin.user', 'block', identityId);
const pmUnblockUser = await checkPermission('admin.user', 'unblock', identityId);
const pmDeleteUser = await checkPermission('admin.user', 'delete', identityId);
const pmDeleteUserSession = await checkPermission('admin.user.session', 'delete', identityId);
const params = await searchParams; const params = await searchParams;
const page = params.page ? Number(params.page) : 1; const page = params.page ? Number(params.page) : 1;
@ -20,7 +34,7 @@ export default async function UserPage(
let pageSize = 50; let pageSize = 50;
let paginationRange = 11; let paginationRange = 11;
const { data, itemCount, pageCount } = await queryIdentities({ page, pageSize, query }); const users = pmAccessUser && await queryIdentities({ page, pageSize, query });
return ( return (
<div className="space-y-4"> <div className="space-y-4">
@ -31,23 +45,46 @@ export default async function UserPage(
</p> </p>
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
{
!pmAccessUser && (
<InsufficientPermission
permission="admin.user"
relation="see"
identityId={identityId}
/>
)
}
{
pmAccessUser && users && (
<>
<SearchInput <SearchInput
value={query} value={query}
pageParamKey="page" pageParamKey="page"
queryParamKey="query" queryParamKey="query"
placeholder="Search for addresses and traits"/> placeholder="Search for addresses and traits"/>
<div> <div>
<p className="text-xs text-neutral-500">{itemCount} item{itemCount && itemCount > 1 ? 's' : ''} found</p> <p className="text-xs text-neutral-500">{users.itemCount} item{users.itemCount && users.itemCount > 1 ? 's' : ''} found</p>
<IdentityDataTable <IdentityDataTable
data={data} data={users.data}
page={page} page={page}
query={query}/> query={query}
permission={{
pmEditUser: pmEditUser,
pmBlockUser: pmBlockUser,
pmUnblockUser: pmUnblockUser,
pmDeleteUser: pmDeleteUser,
pmDeleteUserSession: pmDeleteUserSession,
}}
/>
</div> </div>
<IdentityPagination <IdentityPagination
page={page} page={page}
pageCount={pageCount} pageCount={users.pageCount}
pageParamKey="page" pageParamKey="page"
paginationRange={paginationRange}/> paginationRange={paginationRange}/>
</>
)
}
</div> </div>
</div> </div>
); );