mirror of
https://github.com/openziti/zrok.git
synced 2025-06-24 19:51:32 +02:00
the registration process is a bit of an embedded 'micro app' (#841)
This commit is contained in:
parent
c5381b5ae3
commit
f3adf0cae9
@ -1,12 +1,19 @@
|
|||||||
import {Box, Button, Checkbox, Container, FormControlLabel, TextField, Typography} from "@mui/material";
|
import {Box, Button, Checkbox, Container, FormControlLabel, Grid2, TextField, Typography} from "@mui/material";
|
||||||
import zroket from "./assets/zrok-1.0.0-rocket-purple.svg";
|
import zroket from "./assets/zrok-1.0.0-rocket-purple.svg";
|
||||||
import {useParams} from "react-router";
|
import {useParams} from "react-router";
|
||||||
import {useFormik} from "formik";
|
import {useFormik} from "formik";
|
||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
import {useRef, useState} from "react";
|
import {useEffect, useRef, useState} from "react";
|
||||||
|
import {AccountApi, MetadataApi} from "./api";
|
||||||
|
import ClipboardText from "./ClipboardText.tsx";
|
||||||
|
|
||||||
const Register = () => {
|
interface SetPasswordFormProps {
|
||||||
const { regToken } = useParams();
|
email: string;
|
||||||
|
touLink: string;
|
||||||
|
register: (v) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SetPasswordForm = ({ email, touLink, register }: SetPasswordFormProps) => {
|
||||||
const [checked, setChecked] = useState<boolean>(false);
|
const [checked, setChecked] = useState<boolean>(false);
|
||||||
const checkedRef = useRef<boolean>();
|
const checkedRef = useRef<boolean>();
|
||||||
checkedRef.current = checked;
|
checkedRef.current = checked;
|
||||||
@ -19,6 +26,7 @@ const Register = () => {
|
|||||||
},
|
},
|
||||||
onSubmit: v => {
|
onSubmit: v => {
|
||||||
console.log(v);
|
console.log(v);
|
||||||
|
register(v);
|
||||||
},
|
},
|
||||||
validationSchema: Yup.object({
|
validationSchema: Yup.object({
|
||||||
password: Yup.string()
|
password: Yup.string()
|
||||||
@ -43,45 +51,193 @@ const Register = () => {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box component="form" onSubmit={form.handleSubmit}>
|
||||||
|
<Typography component="div" align="center"><h2>Welcome to zrok!</h2></Typography>
|
||||||
|
<Typography component="p" align="center" sx={{ mb: 2 }}><code>{email}</code></Typography>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
type="password"
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
label="Create a Password"
|
||||||
|
value={form.values.password}
|
||||||
|
onChange={form.handleChange}
|
||||||
|
onBlur={form.handleBlur}
|
||||||
|
error={form.errors.password !== undefined}
|
||||||
|
helperText={form.errors.password}
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
type="password"
|
||||||
|
id="confirm"
|
||||||
|
name="confirm"
|
||||||
|
label="Confirm Your Password"
|
||||||
|
value={form.values.confirm}
|
||||||
|
onChange={form.handleChange}
|
||||||
|
onBlur={form.handleBlur}
|
||||||
|
error={form.errors.confirm !== undefined}
|
||||||
|
helperText={form.errors.confirm}
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
/>
|
||||||
|
<FormControlLabel control={<Checkbox checked={checked} onChange={toggleChecked} />} label={<p>I accept the <span dangerouslySetInnerHTML={{__html: touLink as string}}></span></p>} sx={{ mt: 2 }} />
|
||||||
|
<Button type="submit" fullWidth variant="contained" sx={{ mt: 3, mb: 2 }} style={{ color: "#9bf316" }} disabled={!checked}>
|
||||||
|
Register Account
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RegistrationCompleteProps {
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RegistrationComplete = ({ token }: RegistrationCompleteProps) => {
|
||||||
|
return (
|
||||||
|
<Box component="div">
|
||||||
|
<Container>
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
|
<Typography component="div">
|
||||||
|
<h2>Registration completed!</h2>
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
<Container>
|
||||||
|
<Box>
|
||||||
|
<Typography component="p">
|
||||||
|
Your account was created successfully!
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ mt: 3 }}>
|
||||||
|
<Typography component="p">
|
||||||
|
Your new account token is: <code>{token}</code> <ClipboardText text={token} />
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ mt: 3 }}>
|
||||||
|
<Typography component="p">
|
||||||
|
You can create an environment using your account token, like this:
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ mt: 3 }}>
|
||||||
|
<Typography component="p">
|
||||||
|
<code>$ zrok enable {token}</code> <ClipboardText text={"zrok enable " + token} />
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ mt: 3 }}>
|
||||||
|
<Typography component="p">
|
||||||
|
<strong>Your account token is a secret (like a password).
|
||||||
|
Please do not share it with anyone!</strong>
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ mt: 3 }}>
|
||||||
|
<Typography component="p">
|
||||||
|
You can use your new password to log into the console here:
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ mt: 3 }}>
|
||||||
|
<Typography component="p">
|
||||||
|
<a href={window.location.origin}>{window.location.origin}</a>
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ mt: 3 }}>
|
||||||
|
<Typography component="p">
|
||||||
|
<h3>Enjoy zrok!</h3>
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const InvalidToken = () => {
|
||||||
|
return (
|
||||||
|
<Box component="div">
|
||||||
|
<Container>
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
|
<Typography component="div"><h2 style={{ color: "red" }} align="center">Invalid registration token?!</h2></Typography>
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
<Container>
|
||||||
|
<Box>
|
||||||
|
<Typography component="p">
|
||||||
|
Your registration token may have expired!
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ mt: 3 }}>
|
||||||
|
<Typography component="p">
|
||||||
|
Please use the <code>zrok invite</code> command to
|
||||||
|
generate a new registration request and try again.
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Register = () => {
|
||||||
|
const { regToken } = useParams();
|
||||||
|
const [component, setComponent] = useState<React.JSX.Element>(null);
|
||||||
|
const [error, setError] = useState<boolean>(false);
|
||||||
|
const [email, setEmail] = useState<string>();
|
||||||
|
const [touLink, setTouLink] = useState<string>();
|
||||||
|
|
||||||
|
const doRegistration = (v) => {
|
||||||
|
new AccountApi().register({body: {token: regToken, password: v.password}})
|
||||||
|
.then(d => {
|
||||||
|
console.log(d);
|
||||||
|
setComponent(<RegistrationComplete token={d.token!} />);
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
console.log("doRegistration", e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(regToken) {
|
||||||
|
new AccountApi().verify({body: {token: regToken}})
|
||||||
|
.then((d) => {
|
||||||
|
console.log(d);
|
||||||
|
setEmail(d.email);
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
setError(true);
|
||||||
|
console.log("error", e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [regToken]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(email) {
|
||||||
|
new MetadataApi()._configuration()
|
||||||
|
.then(d => {
|
||||||
|
setTouLink(d.touLink);
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
e.response.json().then(ex => {
|
||||||
|
console.log("register", ex.message);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [email]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(!error && email && touLink) {
|
||||||
|
setComponent(<SetPasswordForm email={email!} touLink={touLink!} register={doRegistration} />);
|
||||||
|
} else {
|
||||||
|
if(error) {
|
||||||
|
setComponent(<InvalidToken />);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [touLink, error]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Typography component="div">
|
<Typography component="div">
|
||||||
<Container maxWidth="xs">
|
<Container maxWidth="sm">
|
||||||
<Box sx={{marginTop: 8, display: "flex", flexDirection: "column", alignItems: "center"}}>
|
<Box sx={{marginTop: 8, display: "flex", flexDirection: "column", alignItems: "center"}}>
|
||||||
<img src={zroket} height="300"/>
|
<img src={zroket} height="300"/>
|
||||||
<h1 style={{ color: "#241775" }}>z r o k</h1>
|
<h1 style={{ color: "#241775" }}>z r o k</h1>
|
||||||
<Box component="form" onSubmit={form.handleSubmit}>
|
{component}
|
||||||
<Typography component="div" align="center"><h2>Welcome to zrok!</h2></Typography>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
type="password"
|
|
||||||
id="password"
|
|
||||||
name="password"
|
|
||||||
label="Create a Password"
|
|
||||||
value={form.values.password}
|
|
||||||
onChange={form.handleChange}
|
|
||||||
onBlur={form.handleBlur}
|
|
||||||
error={form.errors.password !== undefined}
|
|
||||||
helperText={form.errors.password}
|
|
||||||
sx={{ mt: 2 }}
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
type="password"
|
|
||||||
id="confirm"
|
|
||||||
name="confirm"
|
|
||||||
label="Confirm Your Password"
|
|
||||||
value={form.values.confirm}
|
|
||||||
onChange={form.handleChange}
|
|
||||||
onBlur={form.handleBlur}
|
|
||||||
error={form.errors.confirm !== undefined}
|
|
||||||
helperText={form.errors.confirm}
|
|
||||||
sx={{ mt: 2 }}
|
|
||||||
/>
|
|
||||||
<FormControlLabel control={<Checkbox checked={checked} onChange={toggleChecked} />} label="I accept the Terms of Service" sx={{ mt: 2 }} />
|
|
||||||
<Button type="submit" fullWidth variant="contained" sx={{ mt: 3, mb: 2 }} style={{ color: "#9bf316" }} disabled={!checked}>
|
|
||||||
Register Account
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Container>
|
</Container>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user