Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d21046d
Upgrade to React 19 (#1)
floomm Aug 11, 2025
972208e
Migrate to Vite + TypeScript and clean up project
floomm Aug 12, 2025
13004a4
Generate GraphQL schema
floomm Aug 12, 2025
3fcbd7c
Use generated GraphQL types
floomm Aug 13, 2025
941ec73
Redesign GUI with Shadcn
floomm Aug 21, 2025
37529da
Fix overflow due to sidebar
floomm Aug 21, 2025
993e0d3
Create and use data table wrappers
floomm Aug 21, 2025
bb4e472
Renamings for consistency
floomm Aug 21, 2025
2147fcd
Fix checkbox CSS issue in data table
floomm Aug 21, 2025
34512fb
Small design changes on scanner page
floomm Aug 22, 2025
d29afeb
Finally fix CSS checkbox issue in data tables
floomm Aug 22, 2025
a9270ed
Add firmware action columns
floomm Aug 23, 2025
1873067
Generate updated GraphQL schema
floomm Sep 2, 2025
10e098b
Rename EnvConfig.ts to EnvConfig.js
floomm Sep 10, 2025
e76265c
Implement Importer Page
floomm Sep 20, 2025
14d1dc5
Add basic firmware page
floomm Sep 20, 2025
d838c3e
Add loading animation when deleting a firmware
floomm Sep 25, 2025
3060597
Cleanup GraphQL queries
floomm Sep 26, 2025
70f7847
Add App Page
floomm Sep 30, 2025
aafe3b7
Implement new scanner page
floomm Oct 3, 2025
9de7154
Add firmware reference button to app page
floomm Oct 3, 2025
858bed2
Add file page
floomm Oct 8, 2025
c4d74c6
Create action-buttons.tsx
floomm Oct 8, 2025
16fba6e
Add scan app action buttons to app and firmware pages
floomm Oct 8, 2025
36a44eb
Add some reports & reactivate emulator page
floomm Oct 16, 2025
bb8c04b
Set verbatimModuleSyntax to false
floomm Oct 16, 2025
37afa31
Merge branch 'main' of https://github.com/floomm/FMD-WebClient
floomm Oct 16, 2025
57a0cb5
Add how to contribute
floomm Oct 17, 2025
8e55c70
Update README.md
floomm Oct 17, 2025
3e068de
Replace EnvConfig.js with envconfig.ts
floomm Oct 17, 2025
6f2de82
Clean up file structure
floomm Oct 17, 2025
7b41183
Add cursor pagination to firmware tables
floomm Oct 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:experimental
FROM node:20.7-slim AS firmwaredroid-frontend
FROM node:22-slim AS firmwaredroid-frontend

# Build frontend
RUN mkdir -p /usr/src/app/build
Expand Down
43 changes: 40 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,59 @@
# FirmwareDroid Client

FirmwareDroid is an analysis tool for Android firmware. This repository contains the FirmwareDroid frontend implementation
with React.

FirmwareDroid is an analysis tool for Android firmware. This repository contains the FirmwareDroid frontend implementation with React.

# Contribution

Feel free to contribute and open pull requests.

As a first step, follow the [Getting Started guide](https://firmwaredroid.github.io/posts/getting-started/) to install FirmwareDroid.

If you have successfully set up FirmwareDroid, please stop and remove its containers.

```shell
docker compose down
```

Next, please open directory `/FirmwareDroid` and uncomment the following line in file `docker-compose.yml`.

```shell
cd FirmwareDroid
```

```dockerfile
- ./firmware-droid-client/build:/usr/share/nginx/html # Dev-Route
```

Optionally, fork repository <https://github.com/FirmwareDroid/FMD-WebClient>, delete directory `/firmware-droid-client` and clone your forked repository. Note that the web frontend directory needs to be called `firmware-droid-client`.

```shell
rm -rf firmware-droid-client

git clone https://github.com/<username-with-fork>/FMD-WebClient firmware-droid-client
```

Then, open directory `/firmware-droid-client` and install the web frontend's dependencies and build it.

```shell
cd firmware-droid-client

yarn install && yarn build
```

And then switch back to directory `/FirmwareDroid` and create and start the containers again.

```shell
cd ..

docker compose up
```

At this point, verify that the web frontend is running at <https://fmd.localhost>.

If it is running, you are set to make changes to the frontend's source code in `/firmware-droid-client`. To apply your changes build the project again.

```shell
yarn build
```

Finally, if you refresh the page you should see your changes.
19 changes: 19 additions & 0 deletions codegen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type {CodegenConfig} from '@graphql-codegen/cli';

const config: CodegenConfig = {
schema: './schema/schema.graphql',
// All GraphQL queries/mutations/subscriptions must be in src/graphql/ and end with .graphql.ts(x)
documents: ['src/components/**/*.graphql.{ts,tsx}'],
generates: {
'./src/__generated__/': {
preset: 'client',
plugins: [],
presetConfig: {
gqlTagName: 'gql',
}
}
},
ignoreNoDocuments: true,
};

export default config;
21 changes: 21 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/global.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
33 changes: 33 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import {globalIgnores} from 'eslint/config'
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'

export default tseslint.config([
globalIgnores(['dist', 'build']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
...tseslint.configs.strictTypeChecked,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
21 changes: 21 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<link rel="icon" href="/favicon.ico"/>
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link href="./src/global.css" rel="stylesheet">
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json"/>
<title>FirmwareDroid</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="./src/main.tsx"></script>
</body>
</html>
8 changes: 0 additions & 8 deletions jsconfig.json

This file was deleted.

137 changes: 70 additions & 67 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,75 +1,78 @@
{
"name": "firmwaredroid-client",
"version": "0.1.0",
"name": "firmware-droid-client",
"private": true,
"dependencies": {
"@apollo/client": "^3.8.4",
"@babel/plugin-syntax-jsx": "^7.22.5",
"@reduxjs/toolkit": "^1.9.6",
"android-emulator-webrtc": "^1.0.18",
"bootstrap": "^5.3.2",
"bootstrap-icons": "^1.11.1",
"graphql": "^16.8.1",
"list": "^2.0.19",
"node-sass": "^9.0.0",
"react": "^18.2.0",
"react-bootstrap": "^2.9.0",
"react-bootstrap-table-next": "^4.0.3",
"react-bootstrap-table2-paginator": "^2.1.2",
"react-cookie": "^6.1.1",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-icons": "^4.11.0",
"react-lazylog": "^4.5.3",
"react-redux": "^8.1.3",
"react-router-dom": "^6.16.0",
"react-scripts": "^5.0.1",
"react-terminal": "^1.3.1",
"redux": "^4.2.1",
"styled-components": "^6.0.8",
"yarn": "^1.22.19"
},
"version": "0.2.0",
"type": "module",
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"build_docker_image": "docker build ./ -f ./Dockerfile -t firmwaredroid-frontend --platform=\"linux/amd64\"",
"dev_deploy": "react-scripts build && rm -R -f ../FirmwareDroid/firmware-droid-client/build/ && cp -v -r ./build ../FirmwareDroid/firmware-droid-client/build/",
"test": "react-scripts test",
"eject": "react-scripts eject",
"serve": "serve -s build"
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint firmware-droid-client",
"preview": "vite preview",
"build_docker_image": "docker ../build ./ -f ./Dockerfile -t firmwaredroid-frontend --platform=\"linux/amd64\"",
"dev_deploy": "vite build && rm -R -f ../FirmwareDroid/firmware-droid-client/build/ && cp -v -r ./dist ../FirmwareDroid/firmware-droid-client/build/",
"schema:export": "docker compose exec -T web sh -lc 'cd /var/www/source && python manage.py graphql_schema --schema api.v2.schema.FirmwareDroidRootSchema.schema --out /var/www/firmware-droid-client/schema/schema.graphql --indent 2'",
"codegen": "graphql-codegen",
"codegen:all": "yarn schema:export && yarn codegen"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"proxy": [
"https://fmd.localhost"
]
"dependencies": {
"@apollo/client": "^3.13.9",
"@hookform/resolvers": "^5.2.1",
"@popperjs/core": "^2.11.8",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-navigation-menu": "^1.2.14",
"@radix-ui/react-progress": "^1.1.7",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tooltip": "^1.2.8",
"@tailwindcss/vite": "^4.1.12",
"@tanstack/react-table": "^8.21.3",
"android-emulator-webrtc": "^1.0.18",
"bootstrap": "^5.3.8",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"events": "^3.3.0",
"graphql": "^16.11.0",
"jwt-decode": "^4.0.0",
"lucide-react": "^0.540.0",
"next-themes": "^0.4.6",
"react": "^19.1.1",
"react-bootstrap": "^2.10.10",
"react-dom": "^19.1.1",
"react-dropzone": "^14.3.8",
"react-hook-form": "^7.62.0",
"react-resizable-panels": "^3.0.4",
"react-router": "^7.8.0",
"sass": "^1.90.0",
"shadcn": "^2.10.0",
"styled-components": "^6.1.19",
"tailwind-merge": "^3.3.1",
"tailwindcss": "^4.1.12",
"zod": "^4.0.17"
},
"devDependencies": {
"@babel/cli": "^7.23.0",
"@babel/core": "^7.23.0",
"@babel/node": "^7.22.19",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/plugin-proposal-unicode-property-regex": "^7.18.6",
"@babel/preset-env": "^7.22.20",
"@babel/preset-react": "^7.22.15",
"@babel/runtime": "^7.23.1",
"@testing-library/jest-dom": "^6.1.3",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.5.1"
"@eslint/js": "^9.33.0",
"@graphql-codegen/cli": "^5.0.7",
"@graphql-codegen/client-preset": "^4.8.3",
"@types/node": "^24.2.1",
"@types/react": "^19.1.10",
"@types/react-dom": "^19.1.7",
"@vitejs/plugin-react": "^5.0.0",
"eslint": "^9.33.0",
"eslint-plugin-react-dom": "^1.52.4",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"eslint-plugin-react-x": "^1.52.4",
"globals": "^16.3.0",
"tw-animate-css": "^1.3.6",
"typescript": "~5.8.3",
"typescript-eslint": "^8.39.1",
"vite": "7.1.5"
}
}
43 changes: 0 additions & 43 deletions public/index.html

This file was deleted.

Binary file removed public/logo192.png
Binary file not shown.
Binary file removed public/logo512.png
Binary file not shown.
Loading