2022-02-22 08:18:07 +00:00
|
|
|
import Head from 'next/head';
|
|
|
|
|
import { useRouter } from 'next/router';
|
2022-03-02 21:02:13 +00:00
|
|
|
import type { FormEvent } from 'react';
|
|
|
|
|
import { useEffect, useRef, useState } from 'react';
|
2022-02-18 18:12:45 +00:00
|
|
|
|
|
|
|
|
export default function Login() {
|
2022-02-22 08:18:07 +00:00
|
|
|
const router = useRouter();
|
|
|
|
|
const { id, audience, acsUrl, providerName, relayState } = router.query;
|
2022-03-02 21:02:13 +00:00
|
|
|
|
|
|
|
|
const [state, setState] = useState({
|
|
|
|
|
username: 'jackson',
|
|
|
|
|
domain: 'example.com',
|
2023-10-20 22:59:23 +00:00
|
|
|
acsUrl: 'https://sso.eu.boxyhq.com/api/oauth/saml',
|
2022-03-03 18:40:32 +00:00
|
|
|
audience: 'https://saml.boxyhq.com',
|
2022-03-02 21:02:13 +00:00
|
|
|
});
|
2022-02-24 06:20:00 +00:00
|
|
|
|
2022-03-03 18:40:32 +00:00
|
|
|
const acsUrlInp = useRef<HTMLInputElement>(null);
|
2022-02-24 06:20:00 +00:00
|
|
|
const emailInp = useRef<HTMLInputElement>(null);
|
2022-07-26 21:28:46 +00:00
|
|
|
|
2022-02-24 06:20:00 +00:00
|
|
|
useEffect(() => {
|
2022-03-03 18:40:32 +00:00
|
|
|
if (acsUrl && emailInp.current) {
|
2022-02-24 06:20:00 +00:00
|
|
|
emailInp.current.focus();
|
|
|
|
|
emailInp.current.select();
|
2022-03-03 18:40:32 +00:00
|
|
|
} else if (acsUrlInp.current) {
|
|
|
|
|
acsUrlInp.current.focus();
|
|
|
|
|
acsUrlInp.current.select();
|
2022-02-24 06:20:00 +00:00
|
|
|
}
|
2022-03-04 11:51:24 +00:00
|
|
|
}, [acsUrl]);
|
2022-02-22 08:18:07 +00:00
|
|
|
|
2022-03-02 21:02:13 +00:00
|
|
|
const handleChange = (e: FormEvent<HTMLInputElement | HTMLSelectElement>): void => {
|
|
|
|
|
const { name, value } = e.currentTarget;
|
|
|
|
|
|
|
|
|
|
setState({
|
|
|
|
|
...state,
|
|
|
|
|
[name]: value,
|
|
|
|
|
});
|
2022-02-22 08:18:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
|
|
|
|
e.preventDefault();
|
2022-03-02 21:02:13 +00:00
|
|
|
|
|
|
|
|
const { username, domain } = state;
|
|
|
|
|
|
2022-02-22 08:18:07 +00:00
|
|
|
const response = await fetch(`/api/saml/auth`, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
2022-03-02 21:02:13 +00:00
|
|
|
body: JSON.stringify({
|
|
|
|
|
email: `${username}@${domain}`,
|
|
|
|
|
id,
|
2022-03-03 18:40:32 +00:00
|
|
|
audience: audience || state.audience,
|
|
|
|
|
acsUrl: acsUrl || state.acsUrl,
|
2022-03-02 21:02:13 +00:00
|
|
|
providerName,
|
|
|
|
|
relayState,
|
|
|
|
|
}),
|
2022-02-22 08:18:07 +00:00
|
|
|
});
|
2022-03-02 21:02:13 +00:00
|
|
|
|
2022-02-22 08:18:07 +00:00
|
|
|
if (response.ok) {
|
2022-02-22 08:33:22 +00:00
|
|
|
const newDoc = document.open('text/html', 'replace');
|
2022-03-02 21:02:13 +00:00
|
|
|
|
2022-07-26 21:28:46 +00:00
|
|
|
newDoc.write(await response.text());
|
2022-02-22 08:33:22 +00:00
|
|
|
newDoc.close();
|
2022-02-22 08:18:07 +00:00
|
|
|
} else {
|
|
|
|
|
document.write('Error in getting SAML response');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-18 18:12:45 +00:00
|
|
|
return (
|
2022-07-26 21:28:46 +00:00
|
|
|
<>
|
2022-02-18 18:12:45 +00:00
|
|
|
<Head>
|
2022-03-02 21:16:28 +00:00
|
|
|
<title>Mock SAML Identity Provider - Login</title>
|
2022-02-18 18:12:45 +00:00
|
|
|
</Head>
|
2022-07-26 21:28:46 +00:00
|
|
|
<div className='flex min-h-full items-center justify-center'>
|
|
|
|
|
<div className='flex w-full max-w-xl flex-col px-3'>
|
|
|
|
|
<div className='space-y-2'>
|
2022-07-27 07:52:38 +00:00
|
|
|
<div className='border-2 p-4'>
|
2022-07-26 21:28:46 +00:00
|
|
|
<h2 className='mb-5 text-center text-2xl font-bold text-gray-900'>SAML SSO Login</h2>
|
|
|
|
|
<form onSubmit={handleSubmit}>
|
|
|
|
|
<div className='grid grid-cols-2 gap-y-1 gap-x-5'>
|
|
|
|
|
{!acsUrl ? (
|
|
|
|
|
<div className='col-span-2'>
|
|
|
|
|
<div className='form-control'>
|
|
|
|
|
<label className='label'>
|
|
|
|
|
<span className='label-text font-bold'>ACS URL</span>
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
type='text'
|
|
|
|
|
className='input input-bordered'
|
|
|
|
|
name='acsUrl'
|
|
|
|
|
id='acsUrl'
|
|
|
|
|
ref={acsUrlInp}
|
|
|
|
|
autoComplete='off'
|
2023-10-20 22:59:23 +00:00
|
|
|
placeholder='https://sso.eu.boxyhq.com/api/oauth/saml'
|
2022-07-26 21:28:46 +00:00
|
|
|
value={state.acsUrl}
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
/>
|
|
|
|
|
<label className='label'>
|
|
|
|
|
<span className='label-text-alt'>This is where we will post the SAML Response</span>
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='form-control col-span-2'>
|
|
|
|
|
<label className='label'>
|
|
|
|
|
<span className='label-text font-bold'>Audience</span>
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
type='text'
|
|
|
|
|
className='input input-bordered'
|
|
|
|
|
name='audience'
|
|
|
|
|
id='audience'
|
|
|
|
|
autoComplete='off'
|
|
|
|
|
placeholder='https://saml.boxyhq.com'
|
|
|
|
|
value={state.audience}
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
) : null}
|
|
|
|
|
<div className='form-control'>
|
|
|
|
|
<label className='label'>
|
|
|
|
|
<span className='label-text font-bold'>Email</span>
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
name='username'
|
|
|
|
|
id='username'
|
|
|
|
|
ref={emailInp}
|
|
|
|
|
autoComplete='off'
|
|
|
|
|
type='text'
|
|
|
|
|
placeholder='jackson'
|
|
|
|
|
value={state.username}
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
className='input input-bordered'
|
|
|
|
|
title='Please provide a mock email address'
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='form-control'>
|
|
|
|
|
<label className='label'>
|
|
|
|
|
<span className='label-text font-bold'>Domain</span>
|
|
|
|
|
</label>
|
|
|
|
|
<select
|
|
|
|
|
name='domain'
|
|
|
|
|
id='domain'
|
|
|
|
|
className='select select-bordered'
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
value={state.domain}>
|
|
|
|
|
<option value='example.com'>@example.com</option>
|
|
|
|
|
<option value='example.org'>@example.org</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='form-control col-span-2'>
|
|
|
|
|
<label className='label'>
|
|
|
|
|
<span className='label-text font-bold'>Password</span>
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
id='password'
|
|
|
|
|
autoComplete='off'
|
|
|
|
|
type='password'
|
|
|
|
|
defaultValue='samlstrongpassword'
|
|
|
|
|
className='input input-bordered'
|
|
|
|
|
/>
|
|
|
|
|
<label className='label'>
|
|
|
|
|
<span className='label-text-alt'>Any password works</span>
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
<button className='btn btn-primary col-span-2 block'>Sign In</button>
|
2022-03-04 11:51:24 +00:00
|
|
|
</div>
|
2022-07-26 21:28:46 +00:00
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='alert alert-info'>
|
|
|
|
|
<div>
|
|
|
|
|
<span className='text-sm text-white'>
|
|
|
|
|
This is a simulated login screen, feel free to pick any username but you are restricted to
|
|
|
|
|
two domains example.com and example.org. But this should allow you to test all combinations
|
|
|
|
|
of your authentication and user modelling.
|
|
|
|
|
</span>
|
2022-03-03 18:40:32 +00:00
|
|
|
</div>
|
2022-03-02 21:02:13 +00:00
|
|
|
</div>
|
2022-02-18 18:12:45 +00:00
|
|
|
</div>
|
2022-07-26 21:28:46 +00:00
|
|
|
</div>
|
2022-03-02 21:16:28 +00:00
|
|
|
</div>
|
2022-07-26 21:28:46 +00:00
|
|
|
</>
|
2022-02-18 18:12:45 +00:00
|
|
|
);
|
|
|
|
|
}
|