diff --git a/client/src/components/Apps/Apps.tsx b/client/src/components/Apps/Apps.tsx
index 8d3a5df..2d2d588 100644
--- a/client/src/components/Apps/Apps.tsx
+++ b/client/src/components/Apps/Apps.tsx
@@ -29,7 +29,10 @@ interface Props {
}
export const Apps = (props: Props): JSX.Element => {
- const { apps, loading } = useSelector((state: State) => state.apps);
+ const {
+ apps: { apps, loading },
+ auth: { isAuthenticated },
+ } = useSelector((state: State) => state);
const dispatch = useDispatch();
const { getApps } = bindActionCreators(actionCreators, dispatch);
@@ -76,10 +79,12 @@ export const Apps = (props: Props): JSX.Element => {
subtitle={Go back}
/>
-
+ {isAuthenticated && (
+
+ )}
{loading ? (
diff --git a/client/src/components/Bookmarks/Bookmarks.tsx b/client/src/components/Bookmarks/Bookmarks.tsx
index db6ec02..cee07fe 100644
--- a/client/src/components/Bookmarks/Bookmarks.tsx
+++ b/client/src/components/Bookmarks/Bookmarks.tsx
@@ -34,9 +34,10 @@ export enum ContentType {
}
export const Bookmarks = (props: Props): JSX.Element => {
- const { loading, categories } = useSelector(
- (state: State) => state.bookmarks
- );
+ const {
+ bookmarks: { loading, categories },
+ auth: { isAuthenticated },
+ } = useSelector((state: State) => state);
const dispatch = useDispatch();
const { getCategories } = bindActionCreators(actionCreators, dispatch);
@@ -109,28 +110,30 @@ export const Bookmarks = (props: Props): JSX.Element => {
Go back} />
-
-
addActionHandler(ContentType.category)}
- />
- addActionHandler(ContentType.bookmark)}
- />
- editActionHandler(ContentType.category)}
- />
- editActionHandler(ContentType.bookmark)}
- />
-
+ {isAuthenticated && (
+
+
addActionHandler(ContentType.category)}
+ />
+ addActionHandler(ContentType.bookmark)}
+ />
+ editActionHandler(ContentType.category)}
+ />
+ editActionHandler(ContentType.bookmark)}
+ />
+
+ )}
{loading ? (
diff --git a/client/src/components/Home/Home.tsx b/client/src/components/Home/Home.tsx
index f8652cb..1b96b66 100644
--- a/client/src/components/Home/Home.tsx
+++ b/client/src/components/Home/Home.tsx
@@ -124,7 +124,9 @@ export const Home = (): JSX.Element => {
isPinned)
+ ? categories.filter(
+ ({ isPinned, bookmarks }) => isPinned && bookmarks.length
+ )
: bookmarkSearchResult
}
totalCategories={categories.length}
diff --git a/client/src/components/Settings/AppDetails/AuthForm/AuthForm.tsx b/client/src/components/Settings/AppDetails/AuthForm/AuthForm.tsx
index 3b54575..4c56838 100644
--- a/client/src/components/Settings/AppDetails/AuthForm/AuthForm.tsx
+++ b/client/src/components/Settings/AppDetails/AuthForm/AuthForm.tsx
@@ -51,6 +51,7 @@ export const AuthForm = (): JSX.Element => {
id="password"
name="password"
placeholder="••••••"
+ autoComplete="current-password"
value={formData.password}
onChange={(e) =>
setFormData({ ...formData, password: e.target.value })
diff --git a/client/src/components/Settings/StyleSettings/StyleSettings.tsx b/client/src/components/Settings/StyleSettings/StyleSettings.tsx
index b2d7c8e..23d9ff3 100644
--- a/client/src/components/Settings/StyleSettings/StyleSettings.tsx
+++ b/client/src/components/Settings/StyleSettings/StyleSettings.tsx
@@ -9,8 +9,9 @@ import { actionCreators } from '../../../store';
// Typescript
import { ApiResponse } from '../../../interfaces';
-// UI
+// Other
import { InputGroup, Button } from '../../UI';
+import { applyAuth } from '../../../utility';
export const StyleSettings = (): JSX.Element => {
const dispatch = useDispatch();
@@ -34,7 +35,11 @@ export const StyleSettings = (): JSX.Element => {
e.preventDefault();
axios
- .put>('/api/config/0/css', { styles: customStyles })
+ .put>(
+ '/api/config/0/css',
+ { styles: customStyles },
+ { headers: applyAuth() }
+ )
.then(() => {
createNotification({
title: 'Success',
diff --git a/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx b/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx
index 96edf97..7b84da8 100644
--- a/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx
+++ b/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx
@@ -5,7 +5,7 @@ import axios from 'axios';
import { useSelector } from 'react-redux';
// Typescript
-import { Weather, ApiResponse, Config } from '../../../interfaces';
+import { Weather, ApiResponse } from '../../../interfaces';
// CSS
import classes from './WeatherWidget.module.css';
diff --git a/client/src/store/action-creators/app.ts b/client/src/store/action-creators/app.ts
index f84bfbd..ddd88fa 100644
--- a/client/src/store/action-creators/app.ts
+++ b/client/src/store/action-creators/app.ts
@@ -11,6 +11,7 @@ import {
UpdateAppAction,
} from '../actions/app';
import axios from 'axios';
+import { applyAuth } from '../../utility';
export const getApps =
() => async (dispatch: Dispatch>) => {
@@ -20,7 +21,9 @@ export const getApps =
});
try {
- const res = await axios.get>('/api/apps');
+ const res = await axios.get>('/api/apps', {
+ headers: applyAuth(),
+ });
dispatch({
type: ActionType.getAppsSuccess,
@@ -35,9 +38,15 @@ export const pinApp =
(app: App) => async (dispatch: Dispatch) => {
try {
const { id, isPinned, name } = app;
- const res = await axios.put>(`/api/apps/${id}`, {
- isPinned: !isPinned,
- });
+ const res = await axios.put>(
+ `/api/apps/${id}`,
+ {
+ isPinned: !isPinned,
+ },
+ {
+ headers: applyAuth(),
+ }
+ );
const status = isPinned
? 'unpinned from Homescreen'
@@ -63,7 +72,9 @@ export const pinApp =
export const addApp =
(formData: NewApp | FormData) => async (dispatch: Dispatch) => {
try {
- const res = await axios.post>('/api/apps', formData);
+ const res = await axios.post>('/api/apps', formData, {
+ headers: applyAuth(),
+ });
dispatch({
type: ActionType.createNotification,
@@ -88,7 +99,9 @@ export const addApp =
export const deleteApp =
(id: number) => async (dispatch: Dispatch) => {
try {
- await axios.delete>(`/api/apps/${id}`);
+ await axios.delete>(`/api/apps/${id}`, {
+ headers: applyAuth(),
+ });
dispatch({
type: ActionType.createNotification,
@@ -113,7 +126,10 @@ export const updateApp =
try {
const res = await axios.put>(
`/api/apps/${id}`,
- formData
+ formData,
+ {
+ headers: applyAuth(),
+ }
);
dispatch({
@@ -155,7 +171,9 @@ export const reorderApps =
})
);
- await axios.put>('/api/apps/0/reorder', updateQuery);
+ await axios.put>('/api/apps/0/reorder', updateQuery, {
+ headers: applyAuth(),
+ });
dispatch({
type: ActionType.reorderApps,
diff --git a/client/src/store/action-creators/auth.ts b/client/src/store/action-creators/auth.ts
index f27c447..038eebb 100644
--- a/client/src/store/action-creators/auth.ts
+++ b/client/src/store/action-creators/auth.ts
@@ -8,6 +8,7 @@ import {
LogoutAction,
} from '../actions/auth';
import axios, { AxiosError } from 'axios';
+import { getApps, getCategories } from '.';
export const login =
(formData: { password: string; duration: string }) =>
@@ -24,6 +25,9 @@ export const login =
type: ActionType.login,
payload: res.data.data.token,
});
+
+ dispatch(getApps());
+ dispatch(getCategories());
} catch (err) {
dispatch(authError(err, true));
}
@@ -35,6 +39,9 @@ export const logout = () => (dispatch: Dispatch) => {
dispatch({
type: ActionType.logout,
});
+
+ dispatch(getApps());
+ dispatch(getCategories());
};
export const autoLogin = () => async (dispatch: Dispatch) => {
@@ -50,6 +57,9 @@ export const autoLogin = () => async (dispatch: Dispatch) => {
type: ActionType.autoLogin,
payload: token,
});
+
+ dispatch(getApps());
+ dispatch(getCategories());
} catch (err) {
dispatch(authError(err, false));
}
@@ -69,4 +79,7 @@ export const authError =
},
});
}
+
+ dispatch(getApps());
+ dispatch(getCategories());
};
diff --git a/client/src/store/action-creators/bookmark.ts b/client/src/store/action-creators/bookmark.ts
index c299ec6..5010bd3 100644
--- a/client/src/store/action-creators/bookmark.ts
+++ b/client/src/store/action-creators/bookmark.ts
@@ -8,6 +8,7 @@ import {
NewBookmark,
NewCategory,
} from '../../interfaces';
+import { applyAuth } from '../../utility';
import { ActionType } from '../action-types';
import {
AddBookmarkAction,
@@ -31,7 +32,9 @@ export const getCategories =
});
try {
- const res = await axios.get>('/api/categories');
+ const res = await axios.get>('/api/categories', {
+ headers: applyAuth(),
+ });
dispatch({
type: ActionType.getCategoriesSuccess,
@@ -47,7 +50,8 @@ export const addCategory =
try {
const res = await axios.post>(
'/api/categories',
- formData
+ formData,
+ { headers: applyAuth() }
);
dispatch({
@@ -75,7 +79,8 @@ export const addBookmark =
try {
const res = await axios.post>(
'/api/bookmarks',
- formData
+ formData,
+ { headers: applyAuth() }
);
dispatch({
@@ -101,7 +106,8 @@ export const pinCategory =
const { id, isPinned, name } = category;
const res = await axios.put>(
`/api/categories/${id}`,
- { isPinned: !isPinned }
+ { isPinned: !isPinned },
+ { headers: applyAuth() }
);
const status = isPinned
@@ -128,7 +134,9 @@ export const pinCategory =
export const deleteCategory =
(id: number) => async (dispatch: Dispatch) => {
try {
- await axios.delete>(`/api/categories/${id}`);
+ await axios.delete>(`/api/categories/${id}`, {
+ headers: applyAuth(),
+ });
dispatch({
type: ActionType.createNotification,
@@ -153,7 +161,8 @@ export const updateCategory =
try {
const res = await axios.put>(
`/api/categories/${id}`,
- formData
+ formData,
+ { headers: applyAuth() }
);
dispatch({
@@ -179,7 +188,9 @@ export const deleteBookmark =
(bookmarkId: number, categoryId: number) =>
async (dispatch: Dispatch) => {
try {
- await axios.delete>(`/api/bookmarks/${bookmarkId}`);
+ await axios.delete>(`/api/bookmarks/${bookmarkId}`, {
+ headers: applyAuth(),
+ });
dispatch({
type: ActionType.createNotification,
@@ -218,7 +229,8 @@ export const updateBookmark =
try {
const res = await axios.put>(
`/api/bookmarks/${bookmarkId}`,
- formData
+ formData,
+ { headers: applyAuth() }
);
dispatch({
@@ -295,7 +307,8 @@ export const reorderCategories =
await axios.put>(
'/api/categories/0/reorder',
- updateQuery
+ updateQuery,
+ { headers: applyAuth() }
);
dispatch({
diff --git a/client/src/store/action-creators/config.ts b/client/src/store/action-creators/config.ts
index d81a2a2..bcc41e4 100644
--- a/client/src/store/action-creators/config.ts
+++ b/client/src/store/action-creators/config.ts
@@ -18,7 +18,7 @@ import {
WeatherForm,
} from '../../interfaces';
import { ActionType } from '../action-types';
-import { storeUIConfig } from '../../utility';
+import { storeUIConfig, applyAuth } from '../../utility';
const keys: (keyof Config)[] = [
'useAmericanDate',
@@ -55,7 +55,13 @@ export const updateConfig =
) =>
async (dispatch: Dispatch) => {
try {
- const res = await axios.put>('/api/config', formData);
+ const res = await axios.put>(
+ '/api/config',
+ formData,
+ {
+ headers: applyAuth(),
+ }
+ );
dispatch({
type: ActionType.createNotification,
@@ -96,7 +102,9 @@ export const fetchQueries =
export const addQuery =
(query: Query) => async (dispatch: Dispatch) => {
try {
- const res = await axios.post>('/api/queries', query);
+ const res = await axios.post>('/api/queries', query, {
+ headers: applyAuth(),
+ });
dispatch({
type: ActionType.addQuery,
@@ -111,7 +119,10 @@ export const deleteQuery =
(prefix: string) => async (dispatch: Dispatch) => {
try {
const res = await axios.delete>(
- `/api/queries/${prefix}`
+ `/api/queries/${prefix}`,
+ {
+ headers: applyAuth(),
+ }
);
dispatch({
@@ -129,7 +140,10 @@ export const updateQuery =
try {
const res = await axios.put>(
`/api/queries/${oldPrefix}`,
- query
+ query,
+ {
+ headers: applyAuth(),
+ }
);
dispatch({
diff --git a/client/src/utility/applyAuth.ts b/client/src/utility/applyAuth.ts
new file mode 100644
index 0000000..95dcfb2
--- /dev/null
+++ b/client/src/utility/applyAuth.ts
@@ -0,0 +1,4 @@
+export const applyAuth = () => {
+ const token = localStorage.getItem('token') || '';
+ return { Authorization: `Bearer ${token}` };
+};
diff --git a/client/src/utility/index.ts b/client/src/utility/index.ts
index 0210d08..9ca9bba 100644
--- a/client/src/utility/index.ts
+++ b/client/src/utility/index.ts
@@ -10,3 +10,4 @@ export * from './storeUIConfig';
export * from './validators';
export * from './parseTime';
export * from './decodeToken';
+export * from './applyAuth';