Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Commit

Permalink
Merge branch 'main' of https://github.com/ethyca/fidesops into braze-svg
Browse files Browse the repository at this point in the history
  • Loading branch information
sadaqatullah committed Oct 3, 2022
2 parents 9dc4d7f + b966074 commit b1e2d3c
Show file tree
Hide file tree
Showing 27 changed files with 951 additions and 174 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ The types of changes are:
* `Security` in case of vulnerabilities.

## [Unreleased](https://github.com/ethyca/fidesops/compare/1.7.2...main)

### Changed

* Refactor privacy center to be more modular [#1363](https://github.com/ethyca/fidesops/pull/1363)

### Docs
* Update docs footer links [#1406](https://github.com/ethyca/fidesops/pull/1406)
### Fixed

* Distinguish whether webhook has been visited and no fields were found, versus never visited [#1339](https://github.com/ethyca/fidesops/pull/1339)
Expand All @@ -40,6 +41,8 @@ The types of changes are:
* Add consent request api [#1387](https://github.com/ethyca/fidesops/pull/1387)
* Add authenticated route to get consent preferences [#1402](https://github.com/ethyca/fidesops/pull/1402)
* Access and erasure support for Braze [#1248](https://github.com/ethyca/fidesops/pull/1248)
* Admin UI: Persist Redux store to localStorage [#1401](https://github.com/ethyca/fidesops/pull/1409)
* Adds SaaS Connector Registry for Braze Connector [1418](https://github.com/ethyca/fidesops/pull/1418/files)

### Removed

Expand Down
27 changes: 21 additions & 6 deletions clients/ops/admin-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions clients/ops/admin-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"react-dom": "^17.0.2",
"react-feature-flags": "^1.0.0",
"react-redux": "^7.2.6",
"redux-persist": "^6.0.0",
"whatwg-fetch": "^3.6.2",
"yup": "^0.32.11"
},
Expand Down
109 changes: 89 additions & 20 deletions clients/ops/admin-ui/src/app/store.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import { configureStore, StateFromReducersMapObject } from "@reduxjs/toolkit";
import {
AnyAction,
combineReducers,
configureStore,
StateFromReducersMapObject,
} from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/query/react";

import { STORED_CREDENTIALS_KEY } from "../constants";
import {
authApi,
AuthState,
credentialStorage,
reducer as authReducer,
} from "../features/auth";
FLUSH,
PAUSE,
PERSIST,
persistReducer,
persistStore,
PURGE,
REGISTER,
REHYDRATE,
} from "redux-persist";
import createWebStorage from "redux-persist/lib/storage/createWebStorage";

import { STORAGE_ROOT_KEY } from "../constants";
import { authApi, AuthState, reducer as authReducer } from "../features/auth";
import {
connectionTypeApi,
reducer as connectionTypeReducer,
Expand All @@ -25,27 +36,83 @@ import {
userApi,
} from "../features/user-management";

const reducer = {
[privacyRequestApi.reducerPath]: privacyRequestApi.reducer,
subjectRequests: privacyRequestsReducer,
[userApi.reducerPath]: userApi.reducer,
/**
* To prevent the "redux-perist failed to create sync storage. falling back to noop storage"
* console message within Next.js, the following snippet is required.
* {@https://mightycoders.xyz/redux-persist-failed-to-create-sync-storage-falling-back-to-noop-storage}
*/
const createNoopStorage = () => ({
getItem() {
return Promise.resolve(null);
},
setItem(_key: any, value: any) {
return Promise.resolve(value);
},
removeItem() {
return Promise.resolve();
},
});

const storage =
typeof window !== "undefined"
? createWebStorage("local")
: createNoopStorage();

const reducerMap = {
[authApi.reducerPath]: authApi.reducer,
userManagement: userManagementReducer,
[datastoreConnectionApi.reducerPath]: datastoreConnectionApi.reducer,
datastoreConnections: datastoreConnectionReducer,
auth: authReducer,
[connectionTypeApi.reducerPath]: connectionTypeApi.reducer,
connectionType: connectionTypeReducer,
[datastoreConnectionApi.reducerPath]: datastoreConnectionApi.reducer,
datastoreConnections: datastoreConnectionReducer,
[privacyRequestApi.reducerPath]: privacyRequestApi.reducer,
subjectRequests: privacyRequestsReducer,
[userApi.reducerPath]: userApi.reducer,
userManagement: userManagementReducer,
};

export type RootState = StateFromReducersMapObject<typeof reducer>;
const allReducers = combineReducers(reducerMap);

const rootReducer = (state: any, action: AnyAction) => {
let newState = { ...state };
if (action.type === "auth/logout") {
storage.removeItem(STORAGE_ROOT_KEY);
newState = undefined;
}
return allReducers(newState, action);
};

const persistConfig = {
key: "root",
storage,
/*
NOTE: It is also strongly recommended to blacklist any api(s) that you have configured with RTK Query.
If the api slice reducer is not blacklisted, the api cache will be automatically persisted
and restored which could leave you with phantom subscriptions from components that do not exist any more.
(https://redux-toolkit.js.org/usage/usage-guide#use-with-redux-persist)
*/
blacklist: [
authApi.reducerPath,
connectionTypeApi.reducerPath,
datastoreConnectionApi.reducerPath,
privacyRequestApi.reducerPath,
userApi.reducerPath,
],
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

export type RootState = StateFromReducersMapObject<typeof reducerMap>;

export const makeStore = (preloadedState?: Partial<RootState>) =>
configureStore({
reducer,
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(
credentialStorage.middleware,
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}).concat(
privacyRequestApi.middleware,
userApi.middleware,
authApi.middleware,
Expand All @@ -58,7 +125,7 @@ export const makeStore = (preloadedState?: Partial<RootState>) =>

let storedAuthState: AuthState | undefined;
if (typeof window !== "undefined" && "localStorage" in window) {
const storedAuthStateString = localStorage.getItem(STORED_CREDENTIALS_KEY);
const storedAuthStateString = localStorage.getItem(STORAGE_ROOT_KEY);
if (storedAuthStateString) {
try {
storedAuthState = JSON.parse(storedAuthStateString);
Expand All @@ -74,6 +141,8 @@ const store = makeStore({
auth: storedAuthState,
});

export const persistor = persistStore(store);

setupListeners(store.dispatch);

export default store;
5 changes: 4 additions & 1 deletion clients/ops/admin-ui/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ const API_URL = process.env.NEXT_PUBLIC_FIDESOPS_API
: "";
export const BASE_URL = API_URL + BASE_API_URN;

export const STORED_CREDENTIALS_KEY = "auth.fidesops-admin-ui";
/**
* Redux-persist storage root key
*/
export const STORAGE_ROOT_KEY = "persist:root";

export const USER_PRIVILEGES: UserPrivileges[] = [
{
Expand Down

This file was deleted.

29 changes: 2 additions & 27 deletions clients/ops/admin-ui/src/features/auth/auth.slice.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import {
createListenerMiddleware,
createSlice,
PayloadAction,
} from "@reduxjs/toolkit";
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

import type { RootState } from "../../app/store";
import { BASE_URL, STORED_CREDENTIALS_KEY } from "../../constants";
import { BASE_URL } from "../../constants";
import { addCommonHeaders } from "../common/CommonHeaders";
import { utf8ToB64 } from "../common/utils";
import { User } from "../user-management/types";
Expand Down Expand Up @@ -56,27 +52,6 @@ export const selectToken = (state: RootState) => selectAuth(state).token;

export const { login, logout } = authSlice.actions;

export const credentialStorage = createListenerMiddleware();
credentialStorage.startListening({
actionCreator: login,
effect: (action, { getState }) => {
if (window && window.localStorage) {
localStorage.setItem(
STORED_CREDENTIALS_KEY,
JSON.stringify(selectAuth(getState() as RootState))
);
}
},
});
credentialStorage.startListening({
actionCreator: logout,
effect: () => {
if (window && window.localStorage) {
localStorage.removeItem(STORED_CREDENTIALS_KEY);
}
},
});

// Auth API
export const authApi = createApi({
reducerPath: "authApi",
Expand Down
Loading

0 comments on commit b1e2d3c

Please sign in to comment.