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">
<SearchInput {
value={query} !pmAccessUser && (
pageParamKey="page" <InsufficientPermission
queryParamKey="query" permission="admin.user"
placeholder="Search for addresses and traits"/> relation="see"
<div> identityId={identityId}
<p className="text-xs text-neutral-500">{itemCount} item{itemCount && itemCount > 1 ? 's' : ''} found</p> />
<IdentityDataTable )
data={data} }
page={page} {
query={query}/> pmAccessUser && users && (
</div> <>
<IdentityPagination <SearchInput
page={page} value={query}
pageCount={pageCount} pageParamKey="page"
pageParamKey="page" queryParamKey="query"
paginationRange={paginationRange}/> placeholder="Search for addresses and traits"/>
<div>
<p className="text-xs text-neutral-500">{users.itemCount} item{users.itemCount && users.itemCount > 1 ? 's' : ''} found</p>
<IdentityDataTable
data={users.data}
page={page}
query={query}
permission={{
pmEditUser: pmEditUser,
pmBlockUser: pmBlockUser,
pmUnblockUser: pmUnblockUser,
pmDeleteUser: pmDeleteUser,
pmDeleteUserSession: pmDeleteUserSession,
}}
/>
</div>
<IdentityPagination
page={page}
pageCount={users.pageCount}
pageParamKey="page"
paginationRange={paginationRange}/>
</>
)
}
</div> </div>
</div> </div>
); );