generated from Arquisoft/wiq_0
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #93 from Arquisoft/develop
v0.2.0
- Loading branch information
Showing
11 changed files
with
239 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ | |
|
||
# misc | ||
.DS_Store | ||
.env | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import axios, { HttpStatusCode } from "axios"; | ||
|
||
export function isUserLogged() { | ||
return getLoginData().jwtToken !== null; | ||
} | ||
|
||
export function saveToken(requestAnswer) { | ||
axios.defaults.headers.common["Authorization"] = "Bearer " + requestAnswer.data.token; | ||
sessionStorage.setItem("jwtToken", requestAnswer.data.token); | ||
sessionStorage.setItem("jwtRefreshToken", requestAnswer.data.refresh_Token); | ||
sessionStorage.setItem("jwtReceptionMillis", Date.now().toString()); | ||
} | ||
|
||
export function getLoginData() { | ||
return { | ||
"jwtToken": sessionStorage.getItem("jwtToken"), | ||
"jwtRefreshToken": sessionStorage.getItem("jwtRefreshToken"), | ||
"jwtReceptionDate": new Date(sessionStorage.getItem("jwtReceptionMillis")) | ||
}; | ||
} | ||
|
||
export async function login(loginData, onSuccess, onError) { | ||
try { | ||
let requestAnswer = await axios.post(process.env.REACT_APP_API_ENDPOINT | ||
+ process.env.REACT_APP_LOGIN_ENDPOINT, loginData); | ||
if (HttpStatusCode.Ok === requestAnswer.status) { | ||
saveToken(requestAnswer); | ||
onSuccess(); | ||
} else { | ||
onError(); | ||
} | ||
} catch { | ||
onError(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,5 +9,5 @@ export default i18n.use(Backend) | |
.use(initReactI18next) | ||
.init({ | ||
fallbackLng: "en", | ||
debug: true | ||
debug: false | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,77 @@ | ||
import { Center } from "@chakra-ui/layout"; | ||
import { Heading, Input, InputGroup, Stack, InputLeftElement, chakra, Box, Avatar, FormControl, InputRightElement, Text, IconButton } from "@chakra-ui/react"; | ||
import { ViewIcon, ViewOffIcon } from '@chakra-ui/icons' | ||
import axios, { HttpStatusCode } from "axios"; | ||
import React, { useState } from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
import { useNavigate } from "react-router-dom"; | ||
import { FaLock, FaAddressCard } from "react-icons/fa"; | ||
import ButtonEf from '../components/ButtonEf'; | ||
import '../styles/AppView.css'; | ||
|
||
export default function Login() { | ||
|
||
const [hasError, setHasError] = useState(false); | ||
const navigate = useNavigate(); | ||
const { t } = useTranslation(); | ||
|
||
const [showPassword, setShowPassword] = useState(false); | ||
const changeShowP = () => setShowPassword(!showPassword); | ||
|
||
const ChakraFaCardAlt = chakra(FaAddressCard); | ||
const ChakraFaLock = chakra(FaLock); | ||
|
||
const sendLogin = async () => { | ||
let data = {}; | ||
let response = await axios.post(process.env.API_URL, data); | ||
if (response.status === HttpStatusCode.Accepted) { | ||
navigate("/home"); | ||
} else { | ||
setHasError(true); | ||
} | ||
} | ||
|
||
return ( | ||
<Center display={"flex"} flexDirection={"column"} w={"100wh"} h={"100vh"} | ||
bg={"blue.50"} justifyContent={"center"} alignItems={"center"}> | ||
<Stack flexDir={"column"} mb="2" justifyContent="center" alignItems={"center"}> | ||
<Avatar bg="blue.500" /> | ||
<Heading as="h2" color="blue.400">{ t("common.login")}</Heading> | ||
{ | ||
!hasError ? | ||
<></> : | ||
<Center bgColor={"#FFA98A"} margin={"1vh 0vw"} padding={"1vh 0vw"} | ||
color={"#FF0500"} border={"0.1875em solid #FF0500"} | ||
borderRadius={"0.75em"} maxW={"100%"} minW={"30%"}> | ||
<Text>{t("error.login")}</Text> | ||
</Center> | ||
} | ||
<Box minW={{md: "400px"}}> | ||
<Stack spacing={4} p="1rem" backgroundColor="whiteAlpha.900" boxShadow="md"> | ||
<FormControl> | ||
<InputGroup> | ||
<InputLeftElement children={<ChakraFaCardAlt color="gray.300" />}/> | ||
<Input type="text" placeholder={t("session.email")} /> | ||
</InputGroup> | ||
</FormControl> | ||
<FormControl> | ||
<InputGroup> | ||
<InputLeftElement children={<ChakraFaLock color="gray.300" />}/> | ||
<Input type={showPassword ? "text" : "password"} placeholder={t("session.password")}/> | ||
<InputRightElement> | ||
<IconButton h="1.75rem" size="sm" onClick={changeShowP} aria-label='Shows or hides the password' icon={showPassword ? <ViewOffIcon/> : <ViewIcon/>} data-testid="togglePasswordButton"/> | ||
</InputRightElement> | ||
</InputGroup> | ||
</FormControl> | ||
<ButtonEf dataTestId={"Login"} variant={"solid"} colorScheme={"blue"} text={t("common.login")} onClick={sendLogin}/> | ||
</Stack> | ||
</Box> | ||
</Stack> | ||
</Center> | ||
); | ||
import { Center } from "@chakra-ui/layout"; | ||
import { Heading, Input, InputGroup, Stack, InputLeftElement, chakra, Box, Avatar, FormControl, InputRightElement, Text, IconButton } from "@chakra-ui/react"; | ||
import { ViewIcon, ViewOffIcon } from '@chakra-ui/icons' | ||
import React, {useEffect, useState} from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
import { useNavigate } from "react-router-dom"; | ||
import { FaLock, FaAddressCard } from "react-icons/fa"; | ||
import ButtonEf from '../components/ButtonEf'; | ||
import '../styles/AppView.css'; | ||
import {isUserLogged, login} from "../components/auth/AuthUtils"; | ||
|
||
export default function Login() { | ||
|
||
const navigate = useNavigate(); | ||
const navigateToDashboard = () => { | ||
if (isUserLogged()) { | ||
navigate("/dashboard"); | ||
} | ||
} | ||
|
||
useEffect(navigateToDashboard); | ||
const [hasError, setHasError] = useState(false); | ||
const { t } = useTranslation(); | ||
|
||
const [showPassword, setShowPassword] = useState(false); | ||
const changeShowP = () => setShowPassword(!showPassword); | ||
|
||
const ChakraFaCardAlt = chakra(FaAddressCard); | ||
const ChakraFaLock = chakra(FaLock); | ||
|
||
const sendLogin = async () => { | ||
const loginData = { | ||
"email": document.getElementById("user").value, | ||
"password": document.getElementById("password").value | ||
}; | ||
await login(loginData, navigateToDashboard, () => setHasError(true)); | ||
} | ||
|
||
return ( | ||
<Center display={"flex"} flexDirection={"column"} w={"100wh"} h={"100vh"} | ||
bg={"blue.50"} justifyContent={"center"} alignItems={"center"}> | ||
<Stack flexDir={"column"} mb="2" justifyContent="center" alignItems={"center"}> | ||
<Avatar bg="blue.500" /> | ||
<Heading as="h2" color="blue.400">{ t("common.login")}</Heading> | ||
{ | ||
!hasError ? | ||
<></> : | ||
<Center bgColor={"#FFA98A"} margin={"1vh 0vw"} padding={"1vh 0vw"} | ||
color={"#FF0500"} border={"0.1875em solid #FF0500"} | ||
borderRadius={"0.75em"} maxW={"100%"} minW={"30%"}> | ||
<Text>{t("error.login")}</Text> | ||
</Center> | ||
} | ||
<Box minW={{md: "400px"}}> | ||
<Stack spacing={4} p="1rem" backgroundColor="whiteAlpha.900" boxShadow="md"> | ||
<FormControl> | ||
<InputGroup> | ||
<InputLeftElement children={<ChakraFaCardAlt color="gray.300" />}/> | ||
<Input type="text" id={"user"} placeholder={t("session.email")} /> | ||
</InputGroup> | ||
</FormControl> | ||
<FormControl> | ||
<InputGroup> | ||
<InputLeftElement children={<ChakraFaLock color="gray.300" />}/> | ||
<Input type={showPassword ? "text" : "password"} id={"password"} placeholder={t("session.password")}/> | ||
<InputRightElement> | ||
<IconButton h="1.75rem" size="sm" onClick={changeShowP} aria-label='Shows or hides the password' icon={showPassword ? <ViewOffIcon/> : <ViewIcon/>} data-testid="togglePasswordButton"/> | ||
</InputRightElement> | ||
</InputGroup> | ||
</FormControl> | ||
<ButtonEf dataTestId={"Login"} variant={"solid"} colorScheme={"blue"} text={t("common.login")} onClick={sendLogin}/> | ||
</Stack> | ||
</Box> | ||
</Stack> | ||
</Center> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import MockAdapter from "axios-mock-adapter"; | ||
import axios, { HttpStatusCode } from "axios"; | ||
import {isUserLogged, login, saveToken} from "components/auth/AuthUtils"; | ||
|
||
const mockAxios = new MockAdapter(axios); | ||
|
||
describe("Auth Utils tests", () => { | ||
describe("when the user is not authenticated", () => { | ||
|
||
beforeEach(() => { | ||
sessionStorage.clear(); | ||
mockAxios.reset(); | ||
}); | ||
|
||
it("does not have a stored token", () => { | ||
expect(isUserLogged()).not.toBe(true); | ||
}); | ||
|
||
it("can log in", async () => { | ||
|
||
// Mock axios and the onSuccess and onError functions | ||
mockAxios.onPost().replyOnce(HttpStatusCode.Ok, { | ||
"token": "token", | ||
"refresh_Token": "refreshToken" | ||
}); | ||
const mockOnSucess = jest.fn(); | ||
const mockOnError = jest.fn(); | ||
|
||
// Test | ||
const loginData = { | ||
"email": "[email protected]", | ||
"password": "test" | ||
}; | ||
|
||
await login(loginData, mockOnSucess, mockOnError); | ||
|
||
//Check the user is now logged in | ||
expect(isUserLogged()).toBe(true); | ||
}); | ||
}); | ||
|
||
describe("when the user is authenticated", () => { | ||
|
||
beforeAll(() => { | ||
sessionStorage.setItem("jwtToken", "token"); | ||
}) | ||
|
||
afterEach(() => { | ||
sessionStorage.clear(); | ||
}) | ||
|
||
it("has a stored token", () => { | ||
expect(isUserLogged()).toBe(true); | ||
}); | ||
}); | ||
|
||
describe("saving the token", () => { | ||
beforeEach(() => { | ||
sessionStorage.clear(); | ||
}); | ||
|
||
it ("is saved", () => { | ||
let mockResponse = { | ||
"data": { | ||
"token": "token", | ||
"refresh_Token": "refreshToken" | ||
} | ||
}; | ||
saveToken(mockResponse); | ||
expect(sessionStorage.getItem("jwtToken")).toBe(mockResponse.data.token); | ||
expect(sessionStorage.getItem("jwtRefreshToken")).toBe(mockResponse.data.refresh_Token); | ||
}); | ||
}); | ||
}); | ||
|
||
|
Oops, something went wrong.