Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 38 additions & 6 deletions webapp_frontend/src/background/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,39 @@ import {hostname, userPath} from "./api";

import {AddUser, UserState} from "../redux/actions/userTypes";
import store from "../redux/store";
import {addAccessToken, addRefreshToken} from "../redux/actions/tokens";
import {addAccessToken, addRefreshToken, checkedCookies, removeTokens} from "../redux/actions/tokens";
import {addUser} from "../redux/actions/user";
import {AccessToken, AddAccessToken, AddRefreshToken, TokensState} from "../redux/actions/tokenTypes";
import {AccessToken, AddAccessToken, AddRefreshToken, CheckedCookies, RemoveTokens, TokensState} from "../redux/actions/tokenTypes";
import {deleteCookie, getCookie, setCookie} from "../methods/cookies";


// reference: https://daveceddia.com/access-redux-store-outside-react/


const cookieName:string='refreshToken';

export interface BackendLoginData {
refreshToken: string,
user: UserState

}

export const loginWithUsernameAndPassword = (userName: string, password: string): Promise<BackendLoginData> => {

export const checkForCookie=()=>{
let refreshTokenCookieValue=getCookie(cookieName)
if (refreshTokenCookieValue){
store.dispatch(addRefreshToken(refreshTokenCookieValue) as AddRefreshToken)
getAccessTokenWithRefreshToken();
}
store.dispatch(checkedCookies(true) as CheckedCookies)


}



export const loginWithUsernameAndPassword = (userName: string, password: string,stayLoggedIn:boolean): Promise<BackendLoginData> => {
console.log("[Auth] loginWithUsernameAndPassword")
return new Promise<BackendLoginData>((resolve, reject) => {
let config = {
headers: {
Expand All @@ -29,9 +47,15 @@ export const loginWithUsernameAndPassword = (userName: string, password: string)

return Axios.get(hostname + userPath + '/login', config)
.then((data) => {
store.dispatch(addRefreshToken(data.data.refreshToken) as AddRefreshToken)
console.log(data.data)
store.dispatch(addRefreshToken(data.data.tokenValue) as AddRefreshToken)
store.dispatch(addUser(data.data.user as UserState) as AddUser)

if (stayLoggedIn){
setCookie(cookieName,data.data.tokenValue,60)
}


getAccessTokenWithRefreshToken()
})
.catch(((error) => {
Expand All @@ -57,17 +81,25 @@ export const getAccessTokenWithRefreshToken = () => {

Axios.get(hostname + userPath + '/auth', config)
.then((data) => {
setAuthHeaderToAxios(data.data.token)
setAuthHeaderToAxios(data.data.tokenValue)

store.dispatch(addAccessToken({token: data.data.token, timestamp: data.data.validUntil}as AccessToken) as AddAccessToken);
store.dispatch(addAccessToken({token: data.data.tokenValue, timestamp: data.data.validUntil}as AccessToken) as AddAccessToken);

})
.catch(((error) => {
store.dispatch(removeTokens()as RemoveTokens);

console.log(error)
//you probably want to notify the user, maybe with a toast or similar
}));

}

export const logout=()=>{
store.dispatch(removeTokens()as RemoveTokens);
deleteCookie(cookieName);
}

function setAuthHeaderToAxios(accessToken: string) {
Axios.defaults.headers.common['Authorization'] =
`Bearer ${accessToken}`;
Expand Down
3 changes: 2 additions & 1 deletion webapp_frontend/src/background/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ const prod: constants = {

const dev: constants = {
url: {
API_URL: 'https://cors-anywhere.herokuapp.com/http://filefighter.ddns.net:3001',
API_URL: 'https://cors-anywhere.herokuapp.com/http://filefighter.ddns.net:3001',
// API_URL: 'http://localhost:8080',
}
};
export const constants = process.env.NODE_ENV === 'development' ? dev : prod;
28 changes: 28 additions & 0 deletions webapp_frontend/src/background/methods/cookies.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export function getCookie(cname:string) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for(let i = 0; i <ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
return "";
}


export function setCookie(cname:string, cvalue:string, exdays:number) {
let d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
let expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}


export function deleteCookie(cname:string){
document.cookie = cname+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
}
9 changes: 7 additions & 2 deletions webapp_frontend/src/background/redux/actions/tokenTypes.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const ADD_REFRESH_TOKEN = "ADD_REFRESH_TOKEN";
export const ADD_ACCESS_TOKEN = "ADD_ACCESS_TOKEN";
export const CHECKED_COOKIES = "CHECKED_COOKIES";
export const REMOVE_TOKENS = "REMOVE_TOKENS";


export interface AccessToken {
Expand All @@ -26,10 +27,14 @@ export interface AddAccessToken {
payload: AccessToken
}

export interface CheckedCookies{
export interface RemoveTokens {
type: typeof REMOVE_TOKENS
}

export interface CheckedCookies {
type: typeof CHECKED_COOKIES,
payload: boolean
}

export type TokenActionsTypes = AddRefreshToken | AddAccessToken|CheckedCookies;
export type TokenActionsTypes = AddRefreshToken | AddAccessToken | RemoveTokens | CheckedCookies;

5 changes: 4 additions & 1 deletion webapp_frontend/src/background/redux/actions/tokens.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {ADD_REFRESH_TOKEN, ADD_ACCESS_TOKEN, AccessToken, CHECKED_COOKIES} from "./tokenTypes";
import {ADD_REFRESH_TOKEN, ADD_ACCESS_TOKEN, AccessToken, CHECKED_COOKIES, REMOVE_TOKENS} from "./tokenTypes";


export const addRefreshToken = (content: string) => ({
Expand All @@ -11,6 +11,9 @@ export const addAccessToken = (content: AccessToken) => ({
payload: content
});

export const removeTokens = ()=>({
type: REMOVE_TOKENS
})

export const checkedCookies = (content: boolean) => ({
type: CHECKED_COOKIES,
Expand Down
9 changes: 8 additions & 1 deletion webapp_frontend/src/background/redux/reducers/tokens.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {ADD_REFRESH_TOKEN, ADD_ACCESS_TOKEN, TokenActionsTypes, TokensState, AccessToken, CHECKED_COOKIES} from "../actions/tokenTypes";
import {ADD_REFRESH_TOKEN, ADD_ACCESS_TOKEN, TokenActionsTypes, TokensState, AccessToken, CHECKED_COOKIES, REMOVE_TOKENS} from "../actions/tokenTypes";

const initialState: TokensState = {
refreshToken: null,
Expand Down Expand Up @@ -26,6 +26,13 @@ export default function (state = initialState, action: TokenActionsTypes) {
checkedCookies: state.checkedCookies
};
}
case REMOVE_TOKENS:{
return {
refreshToken: null,
accessToken: null,
checkedCookies: true
}
}
case CHECKED_COOKIES: {
return {
refreshToken: state.refreshToken,
Expand Down
5 changes: 3 additions & 2 deletions webapp_frontend/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {addAccessToken, addRefreshToken, checkedCookies} from "../background/red
import {SystemState} from "../background/redux/actions/sytemState";

import Login from "./basicElements/Login";
import {checkForCookie} from "../background/api/auth";



Expand Down Expand Up @@ -44,7 +45,7 @@ function App(props: Props): ReactElement {

if (props.tokens.checkedCookies) {

if (props.tokens.refreshToken) {
if (props.tokens.refreshToken && props.tokens.accessToken) {

return (
<div className="App">
Expand All @@ -63,7 +64,7 @@ function App(props: Props): ReactElement {
return (<Login/>)
}
} else {
props.checkedCookies(true)
checkForCookie();

return (<div>Loading</div>)
}
Expand Down
25 changes: 18 additions & 7 deletions webapp_frontend/src/components/basicElements/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import React, {FormEvent, ReactElement, useState} from 'react';
import {Button, Form, Container, Row,Col} from "react-bootstrap";
import {Button, Form, Container, Row,Col,Spinner} from "react-bootstrap";
import {loginWithUsernameAndPassword} from "../../background/api/auth";


function Login(): ReactElement {
const [userName, setUsername] = useState<string>("");
const [password, setPassword] = useState<string>("");
const [stayLoggedIn, setStayLoggedIn] = useState<boolean>(false);
const [errorMessage, setErrorMessage] = useState<string>("");
const [loading,setLoading]=useState<boolean>(false);


const handleSubmit = (event: FormEvent) => {
event.preventDefault();
loginWithUsernameAndPassword(userName, password)
setLoading(true)
loginWithUsernameAndPassword(userName, password,stayLoggedIn)
.then(() => {
//nothing to do here :)
setErrorMessage("");
setLoading(false);
})
.catch(((error) => {
console.log(error);
setErrorMessage(error.response.data.message);
setLoading(false)
setErrorMessage(error.response?.data.message);
}))


Expand All @@ -44,11 +47,19 @@ function Login(): ReactElement {
</Form.Text>
</Form.Group>
<Form.Group controlId="formBasicCheckbox">
<Form.Check type="checkbox" label="Check me out" onChange={() => setStayLoggedIn(!stayLoggedIn)}/>
<Form.Check type="checkbox" label="Stay logged in. (By clicking this you accept the usage of cookies.)" onChange={() => setStayLoggedIn(!stayLoggedIn)}/>
</Form.Group>
<Button variant="primary" type="submit">
Submit
<Button variant="primary" type="submit" >
<Spinner
as="span"
animation="grow"
size="sm"
role="status"
aria-hidden="true"
className={loading? "" :"d-none"}
/> <span className={loading? "sr-only" :"d-none"}>Loading...</span>Submit
</Button>

<p className="text-danger">{errorMessage}</p>
</Form>
</Col>
Expand Down
6 changes: 4 additions & 2 deletions webapp_frontend/src/components/pages/Health.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import logo from "../../assets/images/logos/logo.png";
import {Button, Table} from "react-bootstrap";
import {callBackendHealth} from "../../background/api/api";
import {audioOnOff, setAudioVolumeByID} from "../../background/methods/sound"
import {logout} from "../../background/api/auth";

export default function Health() {

Expand All @@ -11,7 +12,7 @@ export default function Health() {

useEffect(() => {
updateVariables()
},[]);
}, []);

function updateVariables(): void {
Promise.all([callBackendHealth()])
Expand Down Expand Up @@ -58,6 +59,7 @@ export default function Health() {
</tbody>
</Table>
</div>
<Button onClick={() => logout()}>Logout</Button>
</>
)
}
}
1 change: 1 addition & 0 deletions webapp_frontend/src/style/custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ $blue: #1a4965;
@import "~bootstrap/scss/tables";
@import "~bootstrap/scss/utilities";
@import "~bootstrap/scss/forms";
@import "~bootstrap/scss/spinners";