From f09969079cf948e0d435d4817d2a7a7f4eb3e4d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Fri, 29 Oct 2021 14:33:31 +0200 Subject: [PATCH] Various changes to support authentication --- client/package-lock.json | 5 +++++ client/package.json | 1 + client/src/components/Snippets/SnippetForm.tsx | 2 +- client/src/containers/Home.tsx | 4 +++- client/src/containers/Profile.tsx | 8 ++++++-- client/src/store/contexts.ts | 3 ++- client/src/store/snippets/index.tsx | 13 +++++++++---- client/src/typescript/interfaces/Context.ts | 1 + client/src/typescript/interfaces/Token.ts | 5 +++++ client/src/typescript/interfaces/index.ts | 1 + client/src/utils/decodeToken.ts | 7 +++++++ 11 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 client/src/typescript/interfaces/Token.ts create mode 100644 client/src/utils/decodeToken.ts diff --git a/client/package-lock.json b/client/package-lock.json index 7e460c6..9fe0848 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9927,6 +9927,11 @@ "object.assign": "^4.1.2" } }, + "jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", diff --git a/client/package.json b/client/package.json index 1bd7a16..617a2cb 100644 --- a/client/package.json +++ b/client/package.json @@ -15,6 +15,7 @@ "clipboard-copy": "^4.0.1", "dayjs": "^1.10.7", "highlight.js": "^11.2.0", + "jwt-decode": "^3.1.2", "node-sass": "^6.0.1", "react": "^17.0.2", "react-dom": "^17.0.2", diff --git a/client/src/components/Snippets/SnippetForm.tsx b/client/src/components/Snippets/SnippetForm.tsx index 718b45c..67adeb6 100644 --- a/client/src/components/Snippets/SnippetForm.tsx +++ b/client/src/components/Snippets/SnippetForm.tsx @@ -35,7 +35,7 @@ export const SnippetForm = (props: Props): JSX.Element => { setFormData({ ...currentSnippet }); } } - }, [currentSnippet]); + }, [currentSnippet, inEdit]); const inputHandler = ( e: ChangeEvent diff --git a/client/src/containers/Home.tsx b/client/src/containers/Home.tsx index 5f772c4..db1dcd1 100644 --- a/client/src/containers/Home.tsx +++ b/client/src/containers/Home.tsx @@ -5,10 +5,12 @@ import { SnippetGrid } from '../components/Snippets/SnippetGrid'; import { SearchBar } from '../components/SearchBar'; export const Home = (): JSX.Element => { - const { snippets, getSnippets, searchResults } = useContext(SnippetsContext); + const { snippets, getSnippets, searchResults, countTags } = + useContext(SnippetsContext); useEffect(() => { getSnippets(); + countTags(); }, []); return ( diff --git a/client/src/containers/Profile.tsx b/client/src/containers/Profile.tsx index 319d9e0..55260dd 100644 --- a/client/src/containers/Profile.tsx +++ b/client/src/containers/Profile.tsx @@ -1,10 +1,11 @@ import { Fragment, useContext } from 'react'; -import { AuthContext } from '../store'; +import { AuthContext, SnippetsContext } from '../store'; import { Button, Card, Layout } from '../components/UI'; import { dateParser } from '../utils'; export const Profile = (): JSX.Element => { const { user, logout } = useContext(AuthContext); + const { clearOnLogout } = useContext(SnippetsContext); return ( @@ -39,7 +40,10 @@ export const Profile = (): JSX.Element => { color='secondary' outline small - handler={logout} + handler={() => { + logout(); + clearOnLogout(); + }} /> diff --git a/client/src/store/contexts.ts b/client/src/store/contexts.ts index 3d1fa2a..6d5cf91 100644 --- a/client/src/store/contexts.ts +++ b/client/src/store/contexts.ts @@ -20,7 +20,8 @@ export const SnippetsContext = createContext({ deleteSnippet: (id: number) => {}, toggleSnippetPin: (id: number) => {}, countTags: () => {}, - searchSnippets: (query: SearchQuery) => {} + searchSnippets: (query: SearchQuery) => {}, + clearOnLogout: () => {} }); export const AuthContext = createContext({ diff --git a/client/src/store/snippets/index.tsx b/client/src/store/snippets/index.tsx index 2afe2da..4318c0d 100644 --- a/client/src/store/snippets/index.tsx +++ b/client/src/store/snippets/index.tsx @@ -40,14 +40,12 @@ export const SnippetsContextProvider = (props: Props): JSX.Element => { await getSnippetByIdAction({ id, setCurrentSnippet }); }; - const setSnippet = async (id: number) => { + const setSnippet = (id: number) => { if (id < 0) { setCurrentSnippet(null); return; } - await getSnippetById(id); - const snippet = snippets.find(s => s.id === id); if (snippet) { @@ -117,6 +115,12 @@ export const SnippetsContextProvider = (props: Props): JSX.Element => { } }; + const clearOnLogout = () => { + setCurrentSnippet(null); + setTagCount([]); + setSnippets([]); + }; + const context: Context = { snippets, searchResults, @@ -130,7 +134,8 @@ export const SnippetsContextProvider = (props: Props): JSX.Element => { deleteSnippet, toggleSnippetPin, countTags, - searchSnippets + searchSnippets, + clearOnLogout }; return ( diff --git a/client/src/typescript/interfaces/Context.ts b/client/src/typescript/interfaces/Context.ts index f278369..94aa308 100644 --- a/client/src/typescript/interfaces/Context.ts +++ b/client/src/typescript/interfaces/Context.ts @@ -14,6 +14,7 @@ export interface SnippetsContext { toggleSnippetPin: (id: number) => void; countTags: () => void; searchSnippets: (query: SearchQuery) => void; + clearOnLogout: () => void; } export interface AuthContext { diff --git a/client/src/typescript/interfaces/Token.ts b/client/src/typescript/interfaces/Token.ts new file mode 100644 index 0000000..ed69cca --- /dev/null +++ b/client/src/typescript/interfaces/Token.ts @@ -0,0 +1,5 @@ +export interface Token { + email: string; + iat: number; + exp: number; +} diff --git a/client/src/typescript/interfaces/index.ts b/client/src/typescript/interfaces/index.ts index e6a6608..2a05812 100644 --- a/client/src/typescript/interfaces/index.ts +++ b/client/src/typescript/interfaces/index.ts @@ -6,3 +6,4 @@ export * from './Context'; export * from './Statistics'; export * from './SearchQuery'; export * from './User'; +export * from './Token'; diff --git a/client/src/utils/decodeToken.ts b/client/src/utils/decodeToken.ts new file mode 100644 index 0000000..e8b1609 --- /dev/null +++ b/client/src/utils/decodeToken.ts @@ -0,0 +1,7 @@ +import jwt_decode from 'jwt-decode'; +import { Token } from '../typescript/interfaces'; + +export const decodeToken = (token: string): Token => { + const decoded: Token = jwt_decode(token); + return decoded; +};