mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
feat: Enable two-factor authentication on login page
This commit is contained in:
@@ -79,20 +79,29 @@ const LoginPage: () => JSX.Element = () => {
|
||||
src={OneUptimeLogo}
|
||||
alt="OneUptime"
|
||||
/>
|
||||
{!showTwoFactorAuth && <><h2 className="mt-6 text-center text-2xl tracking-tight text-gray-900">
|
||||
Sign in to your account
|
||||
</h2>
|
||||
<p className="mt-2 text-center text-sm text-gray-600">
|
||||
Join thousands of business that use OneUptime to help them stay online
|
||||
all the time.
|
||||
</p></>}
|
||||
{!showTwoFactorAuth && (
|
||||
<>
|
||||
<h2 className="mt-6 text-center text-2xl tracking-tight text-gray-900">
|
||||
Sign in to your account
|
||||
</h2>
|
||||
<p className="mt-2 text-center text-sm text-gray-600">
|
||||
Join thousands of business that use OneUptime to help them stay
|
||||
online all the time.
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
|
||||
{showTwoFactorAuth && <><h2 className="mt-6 text-center text-2xl tracking-tight text-gray-900">
|
||||
Two Factor Authentication
|
||||
</h2>
|
||||
<p className="mt-2 text-center text-sm text-gray-600">
|
||||
Select two factor authentication method. You will be asked to enter a code from the selected method.
|
||||
</p></>}
|
||||
{showTwoFactorAuth && (
|
||||
<>
|
||||
<h2 className="mt-6 text-center text-2xl tracking-tight text-gray-900">
|
||||
Two Factor Authentication
|
||||
</h2>
|
||||
<p className="mt-2 text-center text-sm text-gray-600">
|
||||
Select two factor authentication method. You will be asked to
|
||||
enter a code from the selected method.
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
|
||||
@@ -143,10 +152,15 @@ const LoginPage: () => JSX.Element = () => {
|
||||
value: User | JSONObject,
|
||||
miscData: JSONObject | undefined,
|
||||
) => {
|
||||
if ((miscData as JSONObject)["twoFactorAuth"] === true) {
|
||||
if (
|
||||
miscData &&
|
||||
(miscData as JSONObject)["twoFactorAuth"] === true
|
||||
) {
|
||||
const twoFactorAuthList: Array<UserTwoFactorAuth> =
|
||||
UserTwoFactorAuth.fromJSONArray(
|
||||
(miscData as JSONObject)["twoFactorAuthList"] as JSONArray,
|
||||
(miscData as JSONObject)[
|
||||
"twoFactorAuthList"
|
||||
] as JSONArray,
|
||||
UserTwoFactorAuth,
|
||||
);
|
||||
setTwoFactorAuthList(twoFactorAuthList);
|
||||
@@ -196,7 +210,7 @@ const LoginPage: () => JSX.Element = () => {
|
||||
description: "Enter the code from your authenticator app",
|
||||
required: true,
|
||||
dataTestId: "code",
|
||||
fieldType: FormFieldSchemaType.Text
|
||||
fieldType: FormFieldSchemaType.Text,
|
||||
},
|
||||
]}
|
||||
submitButtonText={"Login"}
|
||||
@@ -208,7 +222,8 @@ const LoginPage: () => JSX.Element = () => {
|
||||
|
||||
try {
|
||||
const code: string = data["code"] as string;
|
||||
const twoFactorAuthId: string = selectedTwoFactorAuth.id?.toString() as string;
|
||||
const twoFactorAuthId: string =
|
||||
selectedTwoFactorAuth.id?.toString() as string;
|
||||
|
||||
const result: HTTPErrorResponse | HTTPResponse<JSONObject> =
|
||||
await API.post(VERIFY_TWO_FACTOR_AUTH_API_URL, {
|
||||
@@ -242,24 +257,31 @@ const LoginPage: () => JSX.Element = () => {
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-10 text-center">
|
||||
{!selectedTwoFactorAuth && <div className="text-muted mb-0 text-gray-500">
|
||||
Don't have an account?{" "}
|
||||
<Link
|
||||
to={new Route("/accounts/register")}
|
||||
className="text-indigo-500 hover:text-indigo-900 cursor-pointer"
|
||||
>
|
||||
Register.
|
||||
</Link>
|
||||
</div>}
|
||||
{selectedTwoFactorAuth ? <div className="text-muted mb-0 text-gray-500">
|
||||
<Link
|
||||
onClick={() => {
|
||||
setSelectedTwoFactorAuth(undefined);
|
||||
}}
|
||||
className="text-indigo-500 hover:text-indigo-900 cursor-pointer"
|
||||
>
|
||||
Select a different two factor authentication method
|
||||
</Link></div> : <></>}
|
||||
{!selectedTwoFactorAuth && (
|
||||
<div className="text-muted mb-0 text-gray-500">
|
||||
Don't have an account?{" "}
|
||||
<Link
|
||||
to={new Route("/accounts/register")}
|
||||
className="text-indigo-500 hover:text-indigo-900 cursor-pointer"
|
||||
>
|
||||
Register.
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
{selectedTwoFactorAuth ? (
|
||||
<div className="text-muted mb-0 text-gray-500">
|
||||
<Link
|
||||
onClick={() => {
|
||||
setSelectedTwoFactorAuth(undefined);
|
||||
}}
|
||||
className="text-indigo-500 hover:text-indigo-900 cursor-pointer"
|
||||
>
|
||||
Select a different two factor authentication method
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -632,7 +632,9 @@ const login: LoginFunction = async (options: {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadDataException("Invalid login: Email or password does not match."),
|
||||
new BadDataException(
|
||||
"Invalid login: Email or password does not match.",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -654,14 +656,16 @@ const login: LoginFunction = async (options: {
|
||||
);
|
||||
}
|
||||
|
||||
return Response.sendEntityResponse(
|
||||
req, res, user, User, {
|
||||
miscData: {
|
||||
twoFactorAuthList: UserTwoFactorAuth.toJSONArray(twoFactorAuthList, UserTwoFactorAuth),
|
||||
twoFactorAuth: true
|
||||
},
|
||||
});
|
||||
}
|
||||
return Response.sendEntityResponse(req, res, user, User, {
|
||||
miscData: {
|
||||
twoFactorAuthList: UserTwoFactorAuth.toJSONArray(
|
||||
twoFactorAuthList,
|
||||
UserTwoFactorAuth,
|
||||
),
|
||||
twoFactorAuth: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (verifyTwoFactorAuth) {
|
||||
// code from req
|
||||
|
||||
@@ -58,7 +58,6 @@ export class Service extends DatabaseService<Model> {
|
||||
protected override async onBeforeDelete(
|
||||
deleteBy: DeleteBy<Model>,
|
||||
): Promise<OnDelete<Model>> {
|
||||
|
||||
const itemsToBeDeleted: Array<Model> = await this.findBy({
|
||||
query: deleteBy.query,
|
||||
select: {
|
||||
|
||||
Reference in New Issue
Block a user