-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TMP: Kratos configured and basic registration and verifications flows…
… are set
- Loading branch information
1 parent
b14c6fd
commit 854b608
Showing
13 changed files
with
334 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// todo remove session id logic since its actually a token and being handled differently | ||
import { redirect } from '@remix-run/node' | ||
import axios from 'axios' | ||
|
||
export async function requireSession(cookieHeader?: string | null) { | ||
console.log('COOKIES: ', cookieHeader) | ||
|
||
try { | ||
const session = await axios.get(`http://kratos:4433/sessions/whoami`, { | ||
headers: { | ||
cookie: cookieHeader | ||
}, | ||
withCredentials: true | ||
}) | ||
|
||
console.log('SESSION DATA: ', session.data) | ||
console.log( | ||
'VERIFIABLE ADDRESSES: ', | ||
session.data.identity.verifiable_addresses | ||
) | ||
|
||
if (session.status !== 200 || !session.data?.active) { | ||
// does active here mean it is a legit logged in session? | ||
// Redirect to auth if there's no valid session | ||
throw redirect('/auth') | ||
} | ||
|
||
return session | ||
} catch { | ||
throw redirect('/auth') | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// This is a dummy page | ||
// TODO: Integrate with Ory Kratos | ||
import { redirect, type LoaderFunctionArgs } from '@remix-run/node' | ||
import { Button } from '../components/ui' | ||
import { useLoaderData } from '@remix-run/react' | ||
|
||
interface FieldAttribute { | ||
name: string | ||
type: string | ||
value?: string | ||
required?: boolean | ||
disabled?: boolean | ||
node_type?: string | ||
autocomplete?: string | ||
} | ||
|
||
interface Field { | ||
type: string | ||
group: string | ||
attributes: FieldAttribute | ||
messages: object[] | ||
meta: object | ||
} | ||
|
||
export const loader = async ({ request }: LoaderFunctionArgs) => { | ||
const url = new URL(request.url) | ||
const flowId = url.searchParams.get('flow') | ||
const cookies = request.headers.get('cookie') | ||
|
||
if (!flowId) { | ||
throw redirect('http://127.0.0.1:4433/self-service/registration/browser') | ||
} else { | ||
const response = await fetch( | ||
`http://kratos:4433/self-service/registration/flows?id=${flowId}`, | ||
{ | ||
headers: { | ||
Cookie: cookies || '' | ||
}, | ||
credentials: 'include' | ||
} | ||
) | ||
|
||
const responseData = await response.json() | ||
const formFields: Field[] = responseData.ui.nodes // returns an array of form fields -> there's also a oauth2_login_challenge here you should investigate | ||
formFields.push({ | ||
type: 'input', | ||
group: 'default', | ||
attributes: { | ||
name: 'method', | ||
type: 'hidden', | ||
disabled: false, | ||
node_type: 'input', | ||
value: 'password', | ||
required: true | ||
}, | ||
messages: [], | ||
meta: {} | ||
}) | ||
return { formFields, flowId } | ||
} | ||
} | ||
|
||
export default function Registration() { | ||
const { formFields } = useLoaderData<typeof loader>() | ||
const { flowId } = useLoaderData<typeof loader>() | ||
const actionUrl = `http://127.0.0.1:4433/self-service/registration?flow=${flowId}` | ||
return ( | ||
<div className='pt-4 flex flex-col'> | ||
<div className='flex flex-col rounded-md bg-offwhite px-6 text-center min-h-[calc(100vh-3rem)]'> | ||
<div className='p-10 space-y-16'> | ||
<h3 className='text-2xl pt-16'>Register for Rafiki Admin</h3> | ||
<div className='space-y-8'> | ||
<form method='post' action={actionUrl}> | ||
<div className='p-4 space-y-3'> | ||
{formFields.map((field, index) => { | ||
const { attributes, type } = field | ||
if (type === 'input' && attributes.type !== 'submit') { | ||
return ( | ||
<input | ||
key={index} | ||
type={attributes.type} | ||
name={attributes.name} | ||
placeholder={attributes.type} | ||
required={attributes.required} | ||
disabled={attributes.disabled} | ||
value={attributes.value} | ||
/> | ||
) | ||
} | ||
return null | ||
})} | ||
<Button type='submit' aria-label='Register' className='ml-2'> | ||
Register | ||
</Button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import { Button } from '../components/ui' | ||
import { useLoaderData, Form } from '@remix-run/react' | ||
import { | ||
redirect, | ||
type LoaderFunctionArgs, | ||
type ActionFunctionArgs | ||
} from '@remix-run/node' | ||
|
||
export const loader = async ({ request }: LoaderFunctionArgs) => { | ||
const url = new URL(request.url) | ||
const flowId = url.searchParams.get('flow') | ||
const cookies = request.headers.get('cookie') | ||
|
||
if (!flowId) { | ||
throw new Error('No verification flow ID found') | ||
} else { | ||
const response = await fetch( | ||
`http://kratos:4433/self-service/verification/flows?id=${flowId}`, | ||
{ | ||
headers: { | ||
Cookie: cookies || '' | ||
}, | ||
credentials: 'include' | ||
} | ||
) | ||
|
||
const flowData = await response.json() | ||
|
||
return { flowData } | ||
} | ||
} | ||
|
||
export default function Verification() { | ||
const { flowData } = useLoaderData<typeof loader>() | ||
const actionUrl = flowData.ui.action | ||
|
||
if (flowData.state === 'passed_challenge') { | ||
return ( | ||
<div className='pt-4 flex flex-col'> | ||
<div className='flex flex-col rounded-md bg-offwhite px-6 text-center min-h-[calc(100vh-3rem)]'> | ||
<div className='p-10 space-y-16'> | ||
<h3 className='text-2xl pt-16'>Success</h3> | ||
<div className='space-y-8'> | ||
{flowData.ui.messages.map((message) => { | ||
return <p key={message.id}>{message.text}</p> | ||
})} | ||
</div> | ||
<div className='space-y-8'> | ||
<Form method='post' action={'/auth/verification'}> | ||
<Button | ||
type='submit' | ||
name='action' | ||
value='login' | ||
aria-label='Login' | ||
className='mr-2' | ||
> | ||
Login | ||
</Button> | ||
</Form> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
) | ||
} else { | ||
return ( | ||
<div className='pt-4 flex flex-col'> | ||
<div className='flex flex-col rounded-md bg-offwhite px-6 text-center min-h-[calc(100vh-3rem)]'> | ||
<div className='p-10 space-y-16'> | ||
<h3 className='text-2xl pt-16'>Verification in progress</h3> | ||
<div className='space-y-8'> | ||
{flowData.ui.messages.map((message) => { | ||
return <p key={message.id}>{message.text}</p> | ||
})} | ||
</div> | ||
<div className='space-y-8'> | ||
<form method={flowData.ui.method} action={actionUrl}> | ||
<div className='p-4 space-y-3'> | ||
{flowData.ui.nodes.map((field, index) => { | ||
const { attributes, type } = field | ||
if (type === 'input' && attributes.type !== 'submit') { | ||
return ( | ||
<input | ||
key={index} | ||
type={attributes.type} | ||
name={attributes.name} | ||
placeholder={attributes.name} | ||
required={attributes.required} | ||
disabled={attributes.disabled} | ||
value={attributes.value} | ||
/> | ||
) | ||
} | ||
return null | ||
})} | ||
<Button type='submit' aria-label='Register' className='ml-2'> | ||
Verify | ||
</Button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
) | ||
} | ||
} | ||
|
||
export async function action({ request }: ActionFunctionArgs) { | ||
const formData = await request.formData() | ||
const action = formData.get('action') | ||
|
||
if (action === 'login') { | ||
return redirect('http://127.0.0.1:4433/self-service/login/browser', { | ||
headers: { | ||
Accept: 'text/html' | ||
} | ||
}) | ||
} | ||
throw new Error('Invalid auth action') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.