import React from 'react';
import { ErrorDisplay } from '@/components/error';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { IdentityTraits } from '@/components/identity/identity-traits';
import { KratosSchema } from '@/lib/forms/identity-form';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { UAParser } from 'ua-parser-js';
import { RecoveryIdentityAddress, VerifiableIdentityAddress } from '@ory/client';
import { Badge } from '@/components/ui/badge';
import { Check, X } from 'lucide-react';
import { IdentityActions } from '@/components/identity/identity-actions';
import { IdentityCredentials } from '@/components/identity/identity-credentials';
import { checkPermission, requirePermission, requireSession } from '@/lib/action/authentication';
import { permission, relation } from '@/lib/permission';
import { redirect } from 'next/navigation';
import InsufficientPermission from '@/components/insufficient-permission';
import { getIdentity, getIdentitySchema, listIdentitySessions } from '@/lib/action/identity';
interface MergedAddress {
recovery_id?: string;
verifiable_id?: string;
verified?: boolean;
verified_at?: string;
value: string;
via: string;
}
function mergeAddresses(
recovery: RecoveryIdentityAddress[],
verifiable: VerifiableIdentityAddress[],
): MergedAddress[] {
const merged = [...recovery, ...verifiable];
return merged.reduce((acc: MergedAddress[], curr: any) => {
const existingValue =
acc.find(item => item.value && curr.value && item.value === curr.value);
if (!existingValue) {
let newEntry: MergedAddress;
if (curr.status) {
// status property exists only in verifiable addresses
// expecting verifiable address
newEntry = {
verifiable_id: curr.id,
verified: curr.verified,
verified_at: curr.verified_at,
value: curr.value,
via: curr.via,
} as MergedAddress;
} else {
// expecting recovery address
newEntry = {
recovery_id: curr.id,
value: curr.value,
via: curr.via,
} as MergedAddress;
}
acc.push(newEntry);
} else {
const additionalValues = {
recovery_id: existingValue.recovery_id,
verifiable_id: curr.id,
verified: curr.verified,
verified_at: curr.verified_at,
};
Object.assign(existingValue, additionalValues);
}
return acc;
}, []);
}
export default async function UserDetailsPage({ params }: { params: Promise<{ id: string }> }) {
const session = await requireSession();
const identityId = session.identity!.id;
await requirePermission(permission.stack.dashboard, relation.access, identityId);
const pmAccessUser = await checkPermission(permission.user.it, relation.access, identityId);
if (!pmAccessUser) {
return redirect('/user');
}
const pmEditUser = await checkPermission(permission.user.it, relation.edit, identityId);
const pmDeleteUser = await checkPermission(permission.user.it, relation.delete, identityId);
const pmAccessUserTrait = await checkPermission(permission.user.trait, relation.access, identityId);
const pmEditUserTraits = await checkPermission(permission.user.trait, relation.edit, identityId);
const pmAccessUserAddress = await checkPermission(permission.user.address, relation.access, identityId);
const pmAccessUserCredential = await checkPermission(permission.user.credential, relation.access, identityId);
const pmEditUserState = await checkPermission(permission.user.state, relation.edit, identityId);
const pmAccessUserSession = await checkPermission(permission.user.session, relation.access, identityId);
const pmDeleteUserSession = await checkPermission(permission.user.session, relation.delete, identityId);
const pmCreateUserCode = await checkPermission(permission.user.code, relation.create, identityId);
const pmCreateUserLink = await checkPermission(permission.user.link, relation.create, identityId);
const detailIdentityId = (await params).id;
const detailIdentity = pmAccessUser && await getIdentity(detailIdentityId);
if (!detailIdentity) {
return
{addresses[0].value}
{detailIdentity.id}
This user has no active sessions
}