feat: init auth across the app

This commit is contained in:
swve 2022-09-24 13:15:40 +02:00
parent 9479a4b127
commit 3b85a73ec1
12 changed files with 204 additions and 29 deletions

View file

@ -1,12 +1,15 @@
import React from "react";
import styled from "styled-components";
import Link from "next/link";
import { AuthContext } from "../security/AuthProvider";
export const HeaderProfileBox = () => {
const auth: any = React.useContext(AuthContext);
return (
<ProfileArea>
{" "}
<span>HeaderProfileBox</span>{" "}
<span>HeaderProfileBox {String(auth.isAuthenticated)}</span>{" "}
<UnidentifiedArea>
<ul>
<li>

View file

@ -0,0 +1,47 @@
import React, { useEffect } from "react";
import { getRefreshToken, getUserInfo } from "../../services/auth/auth";
export const AuthContext: any = React.createContext({});
export interface Auth {
access_token: string;
isAuthenticated: boolean;
userInfo: {};
isLoading: boolean;
}
const AuthProvider = (props: any) => {
const [auth, setAuth] = React.useState<Auth>({ access_token: "", isAuthenticated: false, userInfo: {}, isLoading: true });
async function checkRefreshToken() {
let data = await getRefreshToken();
return data.access_token;
}
async function checkAuth() {
let access_token = await checkRefreshToken();
let isAuthenticated = false;
let userInfo = {};
let isLoading = false;
if (access_token) {
userInfo = await getUserInfo(access_token);
isAuthenticated = true;
setAuth({ access_token, isAuthenticated, userInfo, isLoading });
} else if (!access_token) {
isAuthenticated = false;
setAuth({ access_token, isAuthenticated, userInfo, isLoading });
}
}
// TODO(mvp) : fix performance issues > no need to check auth on every render
useEffect(() => {
if (!auth.isAuthenticated) {
checkAuth();
}
}, []);
return <AuthContext.Provider value={auth}>{props.children}</AuthContext.Provider>;
};
export default AuthProvider;

View file

@ -6,8 +6,10 @@ import Link from "next/link";
export const Menu = () => {
return (
<GlobalHeader>
<LogoArea>
<Logo>
<img style={{ width: "30px", opacity: "0.9", margin: "10px", paddingRight: "4px" }} src="./learnhouse_icon.png" alt="" />
<Link href={"/"}>
<a>
<img src="./learnhouse_logo.png" alt="" />
@ -50,7 +52,9 @@ const Logo = styled.div`
display: flex;
place-items: center;
padding-left: 20px;
a{
margin: 0;
}
img {
width: 100px;
}

View file

@ -2,23 +2,26 @@ import React from "react";
import Head from "next/head";
import { Header } from "./header";
import styled from "styled-components";
import AuthProvider from "../security/AuthProvider";
const Layout = (props: any) => {
return (
<div>
<Head>
<title>{props.title}</title>
<meta name="description" content={props.description} />
<link rel="icon" href="/favicon.ico" />
</Head>
<Header></Header>
<Main className="min-h-screen">{props.children}</Main>
<AuthProvider>
<Head>
<title>{props.title}</title>
<meta name="description" content={props.description} />
<link rel="icon" href="/favicon.ico" />
</Head>
<Header></Header>
<Main className="min-h-screen">{props.children}</Main>
<Footer>
<a href="" target="_blank" rel="noopener noreferrer">
<img src="/learnhouse_icon.png" alt="Learnhouse Logo" />
</a>
</Footer>
<Footer>
<a href="" target="_blank" rel="noopener noreferrer">
<img src="/learnhouse_icon.png" alt="Learnhouse Logo" />
</a>
</Footer>
</AuthProvider>
</div>
);
};
@ -33,9 +36,9 @@ const Footer = styled.footer`
margin: 20px;
font-size: 16px;
img{
width: 40px;
opacity: 0.40;
img {
width: 20px;
opacity: 0.4;
display: inline;
}
`;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Before After
Before After

View file

@ -5,7 +5,8 @@ interface LoginAndGetTokenResponse {
token_type: "string";
}
// TODO : everything in this file need to be refactored / mvp phase
// ⚠️ mvp phase code
// TODO : everything in this file need to be refactored including security issues fix
export async function loginAndGetToken(username: string, password: string): Promise<LoginAndGetTokenResponse> {
// Request Config
@ -21,21 +22,34 @@ export async function loginAndGetToken(username: string, password: string): Prom
};
// fetch using await and async
const response = await fetch(`${getAPIUrl()}auth/token`, requestOptions);
const response = await fetch(`${getAPIUrl()}auth/login`, requestOptions);
const data = await response.json();
return data;
}
export async function getUserInfo(token: string): Promise<any> {
const HeadersConfig = new Headers({ Authorization: `Bearer ${token}`, Origin: "http://localhost:3000" });
const requestOptions: any = {
method: "GET",
headers: HeadersConfig,
redirect: "follow",
credentials: "include"
credentials: "include",
};
return fetch(`${getAPIUrl()}auth/users/me`, requestOptions)
return fetch(`${getAPIUrl()}users/profile`, requestOptions)
.then((result) => result.json())
.catch((error) => console.log("error", error));
}
export async function getRefreshToken(): Promise<any> {
const requestOptions: any = {
method: "POST",
redirect: "follow",
credentials: "include",
};
return fetch(`${getAPIUrl()}auth/refresh`, requestOptions)
.then((result) => result.json())
.catch((error) => console.log("error", error));
}

View file

@ -1,10 +1,11 @@
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,500;0,700;1,400;1,500&display=swap');
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family: 'DM Sans' , -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
a {