1
0
Fork 0
mirror of https://codeberg.org/MarkusThielker/next-ory.git synced 2025-07-02 12:59:20 +00:00

NORY-1: add user session management

This commit is contained in:
Markus Thielker 2024-11-24 00:06:00 +01:00
parent a74e7f3ebd
commit e2a8f1d2a4
No known key found for this signature in database
9 changed files with 934 additions and 143 deletions

View file

@ -1,18 +1,21 @@
'use client';
import React, { useCallback, useEffect, useState } from 'react';
import { SettingsFlow, UpdateSettingsFlowBody } from '@ory/client';
import { kratos } from '@/ory/sdk/kratos';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import AccountSettings from '@/components/accountSettings';
import { HandleError, kratos, LogoutLink } from '@/ory';
import { useRouter, useSearchParams } from 'next/navigation';
import { toast } from 'sonner';
import { AxiosError } from 'axios';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Flow, HandleError, LogoutLink } from '@/ory';
import { ThemeToggle } from '@/components/themeToggle';
import { Button } from '@/components/ui/button';
import { LogOut } from 'lucide-react';
import AccountSessions from '@/components/accountSessions';
import { AxiosError } from 'axios';
import { SettingsFlow, UpdateSettingsFlowBody } from '@ory/client';
import { toast } from 'sonner';
export default function Home() {
export default function Page() {
const onLogout = LogoutLink();
const [flow, setFlow] = useState<SettingsFlow>();
@ -22,8 +25,6 @@ export default function Home() {
const returnTo = params.get('return_to') ?? undefined;
const flowId = params.get('flow') ?? undefined;
const onLogout = LogoutLink();
const getFlow = useCallback((flowId: string) => {
return kratos
.getSettingsFlow({ id: String(flowId) })
@ -41,7 +42,7 @@ export default function Home() {
.createBrowserSettingsFlow({ returnTo })
.then(({ data }) => {
setFlow(data);
router.push(`?flow=${data.id}`);
addQueryParam('flow', data.id);
})
.catch(handleError);
}, [handleError]);
@ -98,6 +99,14 @@ export default function Home() {
}, [flowId, router, returnTo, createFlow, getFlow]);
const addQueryParam = useCallback((name: string, value: string) => {
const newParams = new URLSearchParams(params.toString());
newParams.set(name, value);
router.push('?' + newParams.toString());
},
[params],
);
return (
<div className="flex flex-col min-h-screen items-center text-3xl relative space-y-4">
<div className="absolute flex flex-row w-fit items-center space-x-4 top-4 right-4">
@ -106,135 +115,23 @@ export default function Home() {
<LogOut className="h-[1.2rem] w-[1.2rem]"/>
</Button>
</div>
<div className="flex flex-col items-center space-y-4 w-full max-w-md">
<p className="mt-4 py-4 text-4xl">Settings</p>
{
flow?.ui.nodes.some(({ group }) => group === 'profile') && (
<Card className="w-full max-w-md animate-fadeIn">
<CardHeader>
<CardTitle>
Password
</CardTitle>
</CardHeader>
<CardContent>
<Flow
onSubmit={updateFlow}
flow={flow}
only="profile"
hideGlobalMessages/>
</CardContent>
</Card>
)
}
{
flow?.ui.nodes.some(({ group }) => group === 'password') && (
<Card className="w-full max-w-md animate-fadeIn">
<CardHeader>
<CardTitle>
Password
</CardTitle>
</CardHeader>
<CardContent>
<Flow
onSubmit={updateFlow}
flow={flow}
only="password"
hideGlobalMessages/>
</CardContent>
</Card>
)
}
{
flow?.ui.nodes.some(({ group }) => group === 'totp') && (
<Card className="w-full max-w-md animate-fadeIn">
<CardHeader>
<CardTitle>
MFA
</CardTitle>
</CardHeader>
<CardContent>
<Flow
onSubmit={updateFlow}
flow={flow}
only="totp"
hideGlobalMessages/>
</CardContent>
</Card>
)
}
{
flow?.ui.nodes.some(({ group }) => group === 'oidc') && (
<Card className="w-full max-w-md animate-fadeIn">
<CardHeader>
<CardTitle>
Connect Socials
</CardTitle>
</CardHeader>
<CardContent>
<Flow
onSubmit={updateFlow}
flow={flow}
only="oidc"
hideGlobalMessages/>
</CardContent>
</Card>
)
}
{
flow?.ui.nodes.some(({ group }) => group === 'link') && (
<Card className="w-full max-w-md animate-fadeIn">
<CardHeader>
<CardTitle>
Connect Socials
</CardTitle>
</CardHeader>
<CardContent>
<Flow
onSubmit={updateFlow}
flow={flow}
only="link"
hideGlobalMessages/>
</CardContent>
</Card>
)
}
{
flow?.ui.nodes.some(({ group }) => group === 'webauthn') && (
<Card className="w-full max-w-md animate-fadeIn">
<CardHeader>
<CardTitle>
Connect Socials
</CardTitle>
</CardHeader>
<CardContent>
<Flow
onSubmit={updateFlow}
flow={flow}
only="webauthn"
hideGlobalMessages/>
</CardContent>
</Card>
)
}
{
flow?.ui.nodes.some(({ group }) => group === 'lookup_secret') && (
<Card className="w-full max-w-md animate-fadeIn">
<CardHeader>
<CardTitle>
Recovery Codes
</CardTitle>
</CardHeader>
<CardContent>
<Flow
onSubmit={updateFlow}
flow={flow}
only="lookup_secret"
hideGlobalMessages/>
</CardContent>
</Card>
)
}
</div>
<Tabs
defaultValue="account"
value={params.get('tab') ?? undefined}
className="w-full max-w-md"
onValueChange={(value) => addQueryParam('tab', value)}>
<TabsList className="grid w-full grid-cols-2 mt-16">
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="sessions">Sessions</TabsTrigger>
</TabsList>
<TabsContent value="account" className="mb-16">
<AccountSettings flow={flow} updateFlow={updateFlow}/>
</TabsContent>
<TabsContent value="sessions" className="mb-16">
<AccountSessions/>
</TabsContent>
</Tabs>
</div>
);
}