Add example.org to the domain list so that users can test multiple domains (#12)
* Add the email domain dropdown * Fix #5 Co-authored-by: Deepak Prabhakara <deepak@boxyhq.com>
This commit is contained in:
parent
e413c794f0
commit
eb0a0fe518
@ -1,6 +1,6 @@
|
|||||||
import { createHash } from 'crypto';
|
import { createHash } from 'crypto';
|
||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
||||||
import config from 'lib/env';
|
import config from 'lib/env';
|
||||||
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import type { User } from 'types';
|
import type { User } from 'types';
|
||||||
import {
|
import {
|
||||||
createResponseForm,
|
createResponseForm,
|
||||||
@ -14,9 +14,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
if (req.method === 'POST') {
|
if (req.method === 'POST') {
|
||||||
const email = req.body.email;
|
const email = req.body.email;
|
||||||
|
|
||||||
if (!email.endsWith('@example.com')) {
|
if (!email.endsWith('@example.com') && !email.endsWith('@example.org')) {
|
||||||
res.status(403).send(`${email} denied access`);
|
res.status(403).send(`${email} denied access`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = createHash('sha256').update(email).digest('hex');
|
const id = createHash('sha256').update(email).digest('hex');
|
||||||
|
|
||||||
const user: User = {
|
const user: User = {
|
||||||
|
|||||||
@ -1,12 +1,16 @@
|
|||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
|
||||||
import type { FormEvent } from 'react';
|
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
import type { FormEvent } from 'react';
|
||||||
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { id, audience, acsUrl, providerName, relayState } = router.query;
|
const { id, audience, acsUrl, providerName, relayState } = router.query;
|
||||||
const [email, setEmail] = useState('jackson');
|
|
||||||
|
const [state, setState] = useState({
|
||||||
|
username: 'jackson',
|
||||||
|
domain: 'example.com',
|
||||||
|
});
|
||||||
|
|
||||||
// Set focus to email input on load
|
// Set focus to email input on load
|
||||||
const emailInp = useRef<HTMLInputElement>(null);
|
const emailInp = useRef<HTMLInputElement>(null);
|
||||||
@ -17,22 +21,39 @@ export default function Login() {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleChange = (e: FormEvent<HTMLInputElement>): void => {
|
const handleChange = (e: FormEvent<HTMLInputElement | HTMLSelectElement>): void => {
|
||||||
setEmail(e.currentTarget.value);
|
const { name, value } = e.currentTarget;
|
||||||
|
|
||||||
|
setState({
|
||||||
|
...state,
|
||||||
|
[name]: value,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
const { username, domain } = state;
|
||||||
|
|
||||||
const response = await fetch(`/api/saml/auth`, {
|
const response = await fetch(`/api/saml/auth`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ email: `${email}@example.com`, id, audience, acsUrl, providerName, relayState }),
|
body: JSON.stringify({
|
||||||
|
email: `${username}@${domain}`,
|
||||||
|
id,
|
||||||
|
audience,
|
||||||
|
acsUrl,
|
||||||
|
providerName,
|
||||||
|
relayState,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const newHtml = await response.text();
|
const newHtml = await response.text();
|
||||||
const newDoc = document.open('text/html', 'replace');
|
const newDoc = document.open('text/html', 'replace');
|
||||||
|
|
||||||
newDoc.write(newHtml);
|
newDoc.write(newHtml);
|
||||||
newDoc.close();
|
newDoc.close();
|
||||||
} else {
|
} else {
|
||||||
@ -45,25 +66,36 @@ export default function Login() {
|
|||||||
<Head>
|
<Head>
|
||||||
<title>Mock SAML IdP - Login</title>
|
<title>Mock SAML IdP - Login</title>
|
||||||
</Head>
|
</Head>
|
||||||
<div className='relative top-20 mx-auto w-[465px] max-w-[90%] rounded-xl p-10 text-[#145698] shadow-lg shadow-indigo-200'>
|
<div className='relative top-20 mx-auto w-[465px] max-w-[90%] rounded-md border p-10 text-[#145698]'>
|
||||||
<h2 className='mb-3 text-center text-3xl font-bold'>Login</h2>
|
<h2 className='mb-3 text-center text-3xl font-bold'>Login</h2>
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<div>
|
<div className='flex items-end gap-x-1'>
|
||||||
<label htmlFor='email' className='mb-2 block'>
|
<div>
|
||||||
Email
|
<label htmlFor='username' className='mb-2 block'>
|
||||||
</label>
|
Email
|
||||||
<input
|
</label>
|
||||||
id='email'
|
<input
|
||||||
ref={emailInp}
|
name='username'
|
||||||
autoComplete='off'
|
id='username'
|
||||||
type='text'
|
ref={emailInp}
|
||||||
placeholder='jackson'
|
autoComplete='off'
|
||||||
value={email}
|
type='text'
|
||||||
|
placeholder='jackson'
|
||||||
|
value={state.username}
|
||||||
|
onChange={handleChange}
|
||||||
|
className='input'
|
||||||
|
title='please provide a mock example.com email address'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<select
|
||||||
|
name='domain'
|
||||||
|
id='domain'
|
||||||
|
className='select w-full'
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className='input w-[65%]'
|
value={state.domain}>
|
||||||
title='please provide a mock example.com email address'
|
<option value='example.com'>@example.com</option>
|
||||||
/>
|
<option value='example.org'>@example.org</option>
|
||||||
<span className='ml-2 w-1/4'>@example.com</span>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className='mt-5'>
|
<div className='mt-5'>
|
||||||
<label htmlFor='password' className='mb-2 block'>
|
<label htmlFor='password' className='mb-2 block'>
|
||||||
|
|||||||
@ -26,10 +26,14 @@ a {
|
|||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
.button {
|
.button {
|
||||||
@apply block px-4 py-2 leading-8 text-white bg-indigo-500 rounded-md shadow-md hover:bg-indigo-600 focus:outline-none focus:ring-4 focus:ring-indigo-300 focus:ring-opacity-100;
|
@apply block rounded-md bg-indigo-500 px-4 py-2 leading-8 text-white shadow-md hover:bg-indigo-600 focus:outline-none focus:ring-4 focus:ring-indigo-300 focus:ring-opacity-100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
@apply px-3 py-1 text-base leading-8 text-gray-700 transition-colors duration-200 ease-in-out bg-gray-100 bg-opacity-50 border border-gray-300 rounded-md outline-none focus:border-indigo-500 focus:bg-transparent focus:ring-2 focus:ring-indigo-300;
|
@apply rounded-md border border-gray-300 bg-gray-100 bg-opacity-50 px-3 py-1 text-base leading-8 text-gray-700 outline-none transition-colors duration-200 ease-in-out focus:border-indigo-500 focus:bg-transparent focus:ring-2 focus:ring-indigo-300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select {
|
||||||
|
@apply rounded-md border border-gray-300 bg-gray-100 bg-opacity-50 px-3 py-2.5 text-base leading-8 text-gray-700 outline-none transition-colors duration-200 ease-in-out focus:border-indigo-500 focus:bg-transparent focus:ring-2 focus:ring-indigo-300;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user