1
0
Fork 0
mirror of https://codeberg.org/MarkusThielker/next-ory.git synced 2025-04-16 13:49:28 +00:00

NORY-59: move stack status requests to protected server actions

This commit is contained in:
Markus Thielker 2025-04-04 16:22:38 +02:00
parent 48c14c08a2
commit cbc6b05173
3 changed files with 135 additions and 51 deletions

View file

@ -1,40 +1,20 @@
import { getHydraMetadataApi, getKetoMetadataApi, getKratosMetadataApi } from '@/ory/sdk/server'; import { StatusCard } from '@/components/status-card';
import { MetadataApiReady, StatusCard } from '@/components/status-card'; import { hydraMetadata, ketoMetadata, kratosMetadata } from '@/lib/action/metadata';
import { checkPermission, requireRole, requireSession } from '@/lib/action/authentication';
import InsufficientPermission from '@/components/insufficient-permission';
export default async function RootPage() { export default async function RootPage() {
const kratosMetadataApi = await getKratosMetadataApi(); const session = await requireSession();
const kratosVersion = await kratosMetadataApi.getVersion() const identityId = session.identity!.id;
.then(res => res.data.version)
.catch(() => undefined);
const kratosStatus = await fetch(process.env.ORY_KRATOS_ADMIN_URL + '/health/ready')
.then((response) => response.json() as MetadataApiReady)
.catch(() => {
return { errors: ['No instance running'] } as MetadataApiReady;
});
await requireRole('admin', identityId);
const hydraMetadataApi = await getHydraMetadataApi(); const pmAccessStackStatus = await checkPermission('admin.stack.status', 'access', identityId);
const hydraVersion = await hydraMetadataApi.getVersion()
.then(res => res.data.version)
.catch(() => undefined);
const hydraStatus = await fetch(process.env.ORY_HYDRA_ADMIN_URL + '/health/ready')
.then((response) => response.json() as MetadataApiReady)
.catch(() => {
return { errors: ['No instance running'] } as MetadataApiReady;
});
const ketoMetadataApi = await getKetoMetadataApi();
const ketoVersion = await ketoMetadataApi.getVersion()
.then(res => res.data.version)
.catch(() => undefined);
const ketoStatus = await fetch(process.env.ORY_KETO_ADMIN_URL + '/health/ready')
.then((response) => response.json() as MetadataApiReady)
.catch(() => {
return { errors: ['No instance running'] } as MetadataApiReady;
});
const kratos = pmAccessStackStatus && await kratosMetadata();
const hydra = pmAccessStackStatus && await hydraMetadata();
const keto = pmAccessStackStatus && await ketoMetadata();
return ( return (
<div className="flex flex-col space-y-4"> <div className="flex flex-col space-y-4">
@ -43,25 +23,46 @@ export default async function RootPage() {
<p className="text-lg font-light">See the list of all applications in your stack</p> <p className="text-lg font-light">See the list of all applications in your stack</p>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-4 gap-4"> <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<StatusCard {
title="Ory Kratos" !pmAccessStackStatus && (
version={kratosVersion} <InsufficientPermission
name="Kratos" permission="admin.stack.status"
status={kratosStatus} relation="access"
className="flex-1"/> identityId={identityId}
<StatusCard classNames="col-span-1 md:col-span-4"
title="Ory Hydra" />
version={hydraVersion} )
name="Hydra" }
status={hydraStatus} {
className="flex-1"/> kratos && (
<StatusCard <StatusCard
title="Ory Keto" title="Ory Kratos"
version={ketoVersion} version={kratos.version}
name="Keto" name="Kratos"
status={ketoStatus} status={kratos.status}
className="flex-1"/> className="flex-1"/>
<div className="flex-1"/> )
}
{
hydra && (
<StatusCard
title="Ory Hydra"
version={hydra.version}
name="Hydra"
status={hydra.status}
className="flex-1"/>
)
}
{
keto && (
<StatusCard
title="Ory Keto"
version={keto.version}
name="Keto"
status={keto.status}
className="flex-1"/>
)
}
</div> </div>
</div> </div>
); );

View file

@ -50,7 +50,7 @@ export function StatusCard({ title, version, name, status, className }: StatusCa
</TooltipTrigger> </TooltipTrigger>
<TooltipContent> <TooltipContent>
{ {
status.errors.map((error) => <span>{error}</span>) status.errors.map((error) => <span key={error}>{error}</span>)
} }
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>

View file

@ -0,0 +1,83 @@
'use server';
import { getHydraMetadataApi, getKetoMetadataApi, getKratosMetadataApi } from '@/ory/sdk/server';
import { MetadataApiReady } from '@/components/status-card';
import { checkPermission, requireSession } from '@/lib/action/authentication';
export async function kratosMetadata() {
const session = await requireSession();
const allowed = await checkPermission('admin.stack.status', 'access', session.identity!.id);
if (!allowed) {
return;
}
const api = await getKratosMetadataApi();
const version = await api.getVersion()
.then(res => res.data.version)
.catch(() => undefined);
const status = await fetch(process.env.ORY_KRATOS_ADMIN_URL + '/health/ready')
.then((response) => response.json() as MetadataApiReady)
.catch(() => {
return { errors: ['No instance running'] } as MetadataApiReady;
});
return {
version,
status,
};
}
export async function hydraMetadata() {
const session = await requireSession();
const allowed = await checkPermission('admin.stack.status', 'access', session.identity!.id);
if (!allowed) {
return;
}
const api = await getHydraMetadataApi();
const version = await api.getVersion()
.then(res => res.data.version)
.catch(() => undefined);
const status = await fetch(process.env.ORY_HYDRA_ADMIN_URL + '/health/ready')
.then((response) => response.json() as MetadataApiReady)
.catch(() => {
return { errors: ['No instance running'] } as MetadataApiReady;
});
return {
version,
status,
};
}
export async function ketoMetadata() {
const session = await requireSession();
const allowed = await checkPermission('admin.stack.status', 'access', session.identity!.id);
if (!allowed) {
return;
}
const api = await getKetoMetadataApi();
const version = await api.getVersion()
.then(res => res.data.version)
.catch(() => undefined);
const status = await fetch(process.env.ORY_KETO_ADMIN_URL + '/health/ready')
.then((response) => response.json() as MetadataApiReady)
.catch(() => {
return { errors: ['No instance running'] } as MetadataApiReady;
});
return {
version,
status,
};
}