# Technical documentation — unity-framework

Evidence date: 2026-09-30. Revision: `master` `c72613bec19c4f413bca5d2f4018799b24cc85dc` (2021-02-13, Jaco Brits).

Source: `https://bitbucket.org/overdrive/unity-framework.git`. Identifier values in `src/config.js` and the prefilled login literals in `JWTLoginTab.js` are omitted. The mock JWT secret in `src/@fake-db/db/auth-db.js` is omitted.

## What this repository is

A private npm package `unity-react-app` version `1.0.0` (`package.json`). Create React App (`react-scripts` 3.4.4) on the Fuse React admin template, with AWS Amplify pointed at Cognito, S3, and an API Gateway endpoint named `unity`.

Single branch `master`. 24 commits, all authored by Jaco Brits, 2021-01-08 through 2021-02-13. Remote HEAD is `origin/master`.

`README.md` is the CRA boilerplate (`yarn start`, `yarn test`, `yarn run build`, `yarn run eject`). `LICENSE` is the URL `https://themeforest.net/licenses/terms/regular`. `CREDITS` lists stock avatar, flag, and photo sources.

## Application structure

```text
public/                 CRA index, manifest, Fuse static assets
src/index.js            Amplify.configure, ReactDOM.render, service worker unregister
src/config.js           region, bucket, API host, Cognito ids, MAX_ATTACHMENT_SIZE
src/i18n.js             i18next, lng en
src/app/App.js          Redux, router, Auth, FuseAuthorization, imports @fake-db
src/app/auth/           splash gate, authRoles, login/register/user slices
src/app/services/       jwtService (live), firebaseService and auth0Service (inactive)
src/app/helper/unityRequests.js
src/app/fuse-configs/   routes, navigation, settings, themes, appConfig
src/app/fuse-layouts/   layout1, layout2, layout3
src/app/main/apps/      Fuse demos + users/
src/app/main/login|register|logout|pages|documentation
src/@fuse/              template core (authorization, navigation, utils)
src/@fake-db/           axios-mock-adapter handlers
nav.json                empty file at repo root
```

Path alias: imports such as `app/...`, `@fuse/...`, and `@history` resolve through CRA/jsconfig. `jsconfig.json` sets `baseUrl` to `src`.

There is no `src/app/store/sagas`. Async work is Redux Toolkit `createAsyncThunk` plus Amplify promises.

## Frameworks and languages

| Piece | Evidence |
|---|---|
| Language | JavaScript (no TypeScript app source). `build-docs` script mentions `.ts`/`.tsx` under the Material UI docs folder |
| UI | React 17.0.1, React DOM 17.0.1, Material UI 4.11.1, Fuse components under `src/@fuse` |
| Routing | `react-router` 5.2.0, `react-router-config` 5.1.1, `history` 4.10.1 (`src/@history/@history.js` browser history) |
| State | Redux 4.0.5, `@reduxjs/toolkit` 1.5.0, `react-redux` 7.2.2 |
| HTTP | `axios` 0.21.0 for the mock; `aws-amplify` ^3.3.16 `API` and `Auth` for Unity calls |
| CSS | JSS via Material UI; Tailwind 2.0.1-compat built to `src/styles/tailwind.css` before start and build (`package.json` scripts `tailwind`, `purge-tailwind`) |
| Dates | Moment (`@date-io/moment` in `App.js`) |
| Lint | ESLint 6 with Airbnb, Prettier, React Hooks (`.eslintrc`). `yarn lint` is `eslint` with no path |

`resolutions` pin `react` and `react-dom` to 17.0.1. Both `yarn.lock` and `package-lock.json` are committed. Which lockfile a deploy uses is **Unknown / Requires Confirmation**. `.yarnrc` and `.yarnrc.yml` are present (Yarn PnP-related; `pnpify-sdk` script exists).

## Runtime configuration

`src/config.js` exports:

- `MAX_ATTACHMENT_SIZE`: `5000000` (unused by callers)
- `s3.REGION`: `eu-west-1`
- `s3.BUCKET`: `unity-app-files`
- `apiGateway.REGION`: `eu-west-1`
- `apiGateway.URL`: an execute-api host (value omitted)
- `cognito.REGION`, `USER_POOL_ID`, `APP_CLIENT_ID`, `IDENTITY_POOL_ID` (values omitted)

`src/index.js` maps those into `Amplify.configure`:

- Auth: `mandatorySignIn: true`, user pool, web client id, identity pool
- Storage: bucket `unity-app-files`, same identity pool
- API: one endpoint, `name: "unity"`, the API Gateway URL and region

`.env` contains only `REACT_APP_MAP_KEY=` (empty). No other environment variable is read by `src/config.js`. Cloud targets are compile-time constants, not `.env` entries.

Firebase (`src/app/services/firebaseService/firebaseServiceConfig.js`) and Auth0 (`auth0ServiceConfig.js`) configs are commented placeholders.

## Authentication

Startup (`src/app/auth/Auth.js`): only `jwtCheck()` runs. Firebase and Auth0 checks are commented out.

`JwtService` (`src/app/services/jwtService/jwtService.js`):

1. Axios response interceptor: status 401 with `err.config` and no `__isRetryRequest` emits `onAutoLogout` and clears the session. The interceptor assumes `err.response` exists; a network error without `response` throws when reading `.status`.
2. `handleAuthentication` reads `localStorage.jwt_access_token`.
3. Missing token → `onNoAccessToken`.
4. Unexpired token (`jwt-decode` `exp`) → `onAutoLogin` → `signInWithToken` → axios GET `/api/auth/access-token` → mock verifier in `auth-db.js`.
5. Expired token → clear storage, message `access_token expired`.

Sign-in (`signInWithEmailAndPassword`):

1. `Auth.signIn(email, password)`.
2. Store `accessToken.jwtToken` (Cognito access token, not the id token) in `localStorage` and on axios.
3. `API.get("unity", "/unity/uuid/" + username)`.
4. `buildUser` assigns `role: "superuser"`.

`signInWithToken` does not call Amplify. Logout (`setSession(null)`) deletes the localStorage key and the axios header. No `Auth.signOut()`.

The id token is used only inside `unityRequests` and the unused `postData` function, and `unityRequests` does not pass the header object to `API.post`.

## API calls this client makes

| Method | Path | Caller | Transport |
|---|---|---|---|
| GET | `/unity/uuid/{cognitoUsername}` | `jwtService.signInWithEmailAndPassword`, `users` `getUserData` | Amplify `API.get` |
| GET | `/unity/getuser/{userId}` | `getUserById` | Amplify `API.get` |
| POST | `/unity/getusers/1` | `getUsers` via `unityRequests` | Amplify `API.post` without the built `myInit` |
| POST | `/unity/getusers` | `jwtService.postData` | Amplify `API.post` with id-token header; function is uncalled |
| GET | `/api/auth/access-token` | `signInWithToken` | axios → mock |
| POST | `/api/auth/register` | `createUser` | axios → mock |
| POST | `/api/auth/user/update` | `updateUserData` | axios → mock |
| POST | `/api/users-app/add-user` and `update-user`, `remove-user`, `remove-users`, star toggles, `update-security`, `getUserById` | `usersSlice` thunks | axios → mock `users-db.js` |

`getUserById` on the mock (`users-db.js`) is not the function the profile uses. The profile uses Amplify. The mock handler remains for the old axios thunk, which is commented out inside `userSlice.js`.

`src/@fake-db/mock.js` plus `index.js`: `mock.onAny().passThrough()` so unknown axios URLs leave the browser.

## User-management module

Reducer mount: `withReducer('usersApp', reducer)` in `UsersApp.js`. Combined state: `usersApp.users` (entity adapter) and `usersApp.user` (single object).

Entity adapter `setAll` expects each row to have an `id`. The table's profile link uses `UserID`. Both can be true only if the payload contains both fields. The payload sample is not in the repo. **Unknown / Requires Confirmation**.

Routes (`UsersAppConfig.js`), in order:

1. `/apps/users/profile/:id` → `UserProfilePage` (lazy)
2. `/apps/users/:id` → `UsersApp` (lazy)
3. `/apps/users` → redirect to `/apps/users/all`

Profile is registered first so `profile` is not captured as `:id`.

`SecurityDialog.js` has `import { updateSecurity, getState } from './store/usersSlice'`. `usersSlice.js` does not export `getState`. `getState` is not called in the dialog body. Whether the bundler fails the users chunk on that import was not executed. **Unknown** at runtime; the import is **Implemented**.

Two `SecurityListItem` components:

- `tabs/SecurityListItem.js` — used by Access Control. Checkboxes default to `true`. Permission lookup is commented out.
- `SecurityListItem.js` (module root) — used by `SecurityDialog`. Reads `user.permissions[item.id + action]` during `useState` init, which throws if `permissions` is missing.

`uuid` package is imported in `AccessControlTab.js` and `SecurityDialog.js` (`uuid.v4()`). `uuid` is not listed in `package.json` dependencies. Whether it resolves transitively was not installed in this investigation. **Unknown / Requires Confirmation**.

## Navigation and layouts

- Live menu: `src/app/fuse-configs/navigationConfig.js`, loaded by `src/app/store/fuse/navigationSlice.js`.
- Access-control tree: `src/app/fuse-configs/appConfig.js`. It duplicates the Applications and Pages groups and stops before the documentation / role-example sections that `navigationConfig.js` continues with. User Management is in both.
- Default layout style `layout1` (`settingsConfig.js`). Layouts 2 and 3 exist under `src/app/fuse-layouts` and are selectable through Fuse settings.
- i18n navigation bundles: `navigation-i18n/en.js`, `tr.js`, `ar.js`. App copy in `src/i18n.js` is English only.

## Demo data and template surface

`App.js` imports `@fake-db`, which loads handlers for academy, analytics, auth, calendar, chat, contacts, users, e-commerce, faq, file manager, icons, invoices, knowledge base, mail, notes, profile, project dashboard, quick panel, scrumboard, search, and todo.

Those screens are part of the shipped bundle. They are not backed by the `unity` API.

## Build, development, and test

| Script | What it does |
|---|---|
| `yarn start` | `tailwind` then `react-scripts start` (README: http://localhost:3000) |
| `yarn build` | tailwind, `purge-tailwindcss.js`, `cross-env GENERATE_SOURCEMAP=false react-scripts build` |
| `yarn test` | `react-scripts test --env=node` |
| `yarn lint` | `eslint` |
| `analyze` | production build plus `source-map-explorer` |
| `build-docs` | regenerates Material UI documentation examples |
| `eject` | CRA eject |

No test files (`*.test.js`, `*.spec.js`) are in the tree. No CI file, Dockerfile, or hosting manifest is in the tree.

Tailwind source is `src/styles/tailwind-config.css` with `tailwind.config.js` at the repo root. Purge step is `purge-tailwindcss.js`.

Browserslist: production `>0.2%, not dead, not op_mini all`; development last 1 version of Chrome, Firefox, and Safari.

## Deployment and infrastructure

Not described in the repository. `Amplify.configure` runs in the browser; there is no `amplify/` backend folder, no CloudFormation, and no pipeline.

Inferred from the client config only: the browser is expected to reach Cognito, an API Gateway stage whose URL contains `/prod`, and S3 bucket `unity-app-files`, all in `eu-west-1`. Whether those resources still exist, and which account owns them, is **Unknown / Requires Confirmation**.

The 2026-09-28 onboarding snapshot listed `sonar-project.properties` and `sonarqube_scan.bat` at the repo root. They are not in commit `c72613b`.

## Security notes (evidence, not a pentest)

- Cloud identifiers and a login username/password literal are committed. Values are omitted from Silicon Ark on purpose. Human review should decide on rotation. Files: `src/config.js`, `src/app/main/login/tabs/JWTLoginTab.js`.
- Cognito access token is stored in `localStorage`.
- `unityRequests` logs `Auth.currentSession()` promise to the console (`console.log(user)`).
- Route guard does not require a session except where a config sets `auth`.
- Mock auth stores passwords on the in-memory user objects (`auth-db.js`) and will echo them only inside that process. The mock is bundled into the client because `App.js` imports `@fake-db`.
- Axios interceptor logs the user out on HTTP 401. Amplify errors do not go through that interceptor.

## Monitoring, jobs, queues, databases

None in this repository. No worker, cron, queue client, or database driver. Sonar configuration is not in the committed tree (see above).

## Related Silicon Ark projects

`unity-skeleton` documents a different Fuse/Amplify client (sales and ticketing, last commit 2020-10-29) that also names an API `unity` and the bucket `unity-app-files`. `unity-frontend`, `unityFrontend`, `unity-lambda-api`, and `unity-lite` are separate directories. Shared-backend questions are **Unknown / Requires Confirmation**. Do not merge their requirements into this tree.
