feat: login_challenge and scope storing, mock api
This commit is contained in:
@ -1,28 +1,63 @@
|
||||
"use client";
|
||||
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { useSelector } from "react-redux";
|
||||
import { Button, Text } from "@mantine/core";
|
||||
import SERVICES from "@/constants/services";
|
||||
import { ServiceCode } from "@/enums/ServiceCode";
|
||||
import SCOPES from "@/constants/scopes";
|
||||
import { Scopes } from "@/enums/Scopes";
|
||||
import { notifications } from "@/lib/notifications";
|
||||
import { RootState } from "@/lib/store";
|
||||
import ServiceData from "@/types/ServiceData";
|
||||
import { AuthService } from "@/mocks/authService";
|
||||
|
||||
const ConsentButton: FC = () => {
|
||||
const serviceCode = useSelector(
|
||||
(state: RootState) => state.targetService.serviceCode
|
||||
);
|
||||
const [serviceData, setServiceData] = useState<ServiceData>();
|
||||
const auth = useSelector((state: RootState) => state.auth);
|
||||
const [clientName, setClientName] = useState<string>(Scopes.UNDEFINED);
|
||||
const [serviceRequiredAccess, setServiceRequiredAccess] =
|
||||
useState<string>("");
|
||||
|
||||
const setAccessesForScope = () => {
|
||||
const accesses: string[] = [];
|
||||
(auth.scope ?? []).forEach((scopeItem: Scopes) => {
|
||||
const access = SCOPES[scopeItem];
|
||||
if (access) accesses.push(access);
|
||||
});
|
||||
setServiceRequiredAccess(accesses.join("\n"));
|
||||
};
|
||||
|
||||
const requestConsent = () => {
|
||||
if (!auth.loginChallenge || auth.scope.length === 0) return;
|
||||
|
||||
new AuthService()
|
||||
.requestConsent(auth.loginChallenge)
|
||||
.then(response => response.data)
|
||||
.then(({ clientName }) => {
|
||||
setClientName(clientName);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
notifications.error({ message: error.toString() });
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (serviceCode === ServiceCode.UNDEFINED) {
|
||||
redirect("services");
|
||||
}
|
||||
setServiceData(SERVICES[serviceCode]);
|
||||
}, [serviceCode]);
|
||||
setAccessesForScope();
|
||||
requestConsent();
|
||||
}, []);
|
||||
|
||||
const confirmAccess = () => {};
|
||||
const confirmAccess = () => {
|
||||
if (!auth.loginChallenge) return;
|
||||
|
||||
new AuthService()
|
||||
.approveConsent(auth.loginChallenge)
|
||||
.then(response => response.data)
|
||||
.then(({ redirectUrl }) => {
|
||||
window.location.href = redirectUrl;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
notifications.error({ message: error.toString() });
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -34,8 +69,7 @@ const ConsentButton: FC = () => {
|
||||
<Text
|
||||
fz={"h4"}
|
||||
ta="center">
|
||||
Сервис {serviceData?.name} получит{" "}
|
||||
{serviceData?.requiredAccesses}
|
||||
Сервис {clientName} получит {serviceRequiredAccess}
|
||||
</Text>
|
||||
</>
|
||||
);
|
||||
|
||||
19
src/app/login/page.tsx
Normal file
19
src/app/login/page.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import LoginForm from "@/components/LoginForm/LoginForm";
|
||||
import Logo from "@/components/Logo/Logo";
|
||||
import PageItem from "@/components/PageBlock/PageItem";
|
||||
import PageContainer from "@/components/PageContainer/PageContainer";
|
||||
|
||||
interface LoginPageProps {
|
||||
searchParams: { login_challenge?: string };
|
||||
}
|
||||
|
||||
export default function LoginPage({ searchParams }: LoginPageProps) {
|
||||
return (
|
||||
<PageContainer center>
|
||||
<PageItem fullScreenMobile>
|
||||
<Logo title={"Вход"} />
|
||||
<LoginForm loginChallenge={searchParams.login_challenge} />
|
||||
</PageItem>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@ -1,15 +1,5 @@
|
||||
import LoginForm from "@/components/LoginForm/LoginForm";
|
||||
import Logo from "@/components/Logo/Logo";
|
||||
import PageItem from "@/components/PageBlock/PageItem";
|
||||
import PageContainer from "@/components/PageContainer/PageContainer";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
export default function MainPage() {
|
||||
return (
|
||||
<PageContainer center>
|
||||
<PageItem fullScreenMobile>
|
||||
<Logo title={"Вход"} />
|
||||
<LoginForm />
|
||||
</PageItem>
|
||||
</PageContainer>
|
||||
);
|
||||
redirect("/login");
|
||||
}
|
||||
|
||||
@ -5,8 +5,8 @@ import { redirect } from "next/navigation";
|
||||
import { Button, Stack, Title } from "@mantine/core";
|
||||
import styles from "@/app/services/components/ServicesList/ServicesList.module.css";
|
||||
import TitleWithLines from "@/components/TitleWithLines/TitleWithLines";
|
||||
import SERVICES from "@/constants/services";
|
||||
import { ServiceCode } from "@/enums/ServiceCode";
|
||||
import SCOPES from "@/constants/scopes";
|
||||
import { Scopes } from "@/enums/Scopes";
|
||||
import { setTargetService } from "@/lib/features/targetService/targetServiceSlice";
|
||||
import { useAppDispatch } from "@/lib/store";
|
||||
import ServiceData from "@/types/ServiceData";
|
||||
@ -15,10 +15,10 @@ const ServicesList = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const services = useMemo(
|
||||
() =>
|
||||
Object.entries(SERVICES)
|
||||
.filter(([key]) => key !== ServiceCode.UNDEFINED)
|
||||
Object.entries(SCOPES)
|
||||
.filter(([key]) => key !== Scopes.UNDEFINED)
|
||||
.map(([, value]) => value),
|
||||
[SERVICES]
|
||||
[SCOPES]
|
||||
);
|
||||
|
||||
const onServiceClick = (service: ServiceData) => {
|
||||
|
||||
@ -2,10 +2,15 @@
|
||||
|
||||
import { FC } from "react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { useSelector } from "react-redux";
|
||||
import { Button, PinInput, Stack } from "@mantine/core";
|
||||
import { useForm } from "@mantine/form";
|
||||
import ResendVerificationCode from "@/app/verify-phone/components/ResendVerificationCode/ResendVerificationCode";
|
||||
import style from "@/app/verify-phone/components/VerifyPhoneForm/VerifyPhone.module.css";
|
||||
import { setScope } from "@/lib/features/auth/authSlice";
|
||||
import { notifications } from "@/lib/notifications";
|
||||
import { RootState, useAppDispatch } from "@/lib/store";
|
||||
import { AuthService } from "@/mocks/authService";
|
||||
|
||||
type VerifyNumberForm = {
|
||||
code: string;
|
||||
@ -20,11 +25,27 @@ const VerifyPhoneForm: FC = () => {
|
||||
code: code => code.length !== 6 && "Введите весь код",
|
||||
},
|
||||
});
|
||||
const authState = useSelector((state: RootState) => state.auth);
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const handleSubmit = (values: VerifyNumberForm) => {
|
||||
console.log(values);
|
||||
if (!authState.phoneNumber || !authState.loginChallenge) return;
|
||||
|
||||
redirect("/services");
|
||||
new AuthService()
|
||||
.approveLogin(
|
||||
authState.phoneNumber,
|
||||
values.code,
|
||||
authState.loginChallenge
|
||||
)
|
||||
.then(response => response.data)
|
||||
.then(({ redirectUrl, scope }) => {
|
||||
dispatch(setScope(scope));
|
||||
window.location.href = redirectUrl;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
notifications.error({ message: error.toString() });
|
||||
});
|
||||
};
|
||||
|
||||
const navigateToLogin = () => redirect("/");
|
||||
|
||||
Reference in New Issue
Block a user