Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement React GUI #69

Draft
wants to merge 89 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
fb3e0c8
Added empty react project.
inbarbarkai Apr 21, 2022
c57693e
Implemented the login flow.
inbarbarkai Apr 22, 2022
0176777
Automatically routing the user to index.
inbarbarkai Apr 22, 2022
64b4b3a
Creating custom image of keycloak.
inbarbarkai Apr 27, 2022
88121f2
Added app container.
inbarbarkai Apr 27, 2022
718ae95
Needs the correct permissions (chmod +x)
May 2, 2022
e38f85f
added invitaions ui
KamiTzayig May 13, 2022
10d5636
Some docker fixes and improvements
May 14, 2022
171ea36
Removed unused interface.
inbarbarkai May 15, 2022
fbf1dca
Added user model.
inbarbarkai May 15, 2022
d455065
Implemented a helper class to convert snake case to camel case.
inbarbarkai May 15, 2022
c75ca0d
Converted user dictionary to an object.
inbarbarkai May 19, 2022
a625037
Fixed authentication configuration.
inbarbarkai May 19, 2022
573f43a
Added options to get the server base URL.
inbarbarkai May 19, 2022
f5a227c
Implemented service to get invitations.
inbarbarkai May 19, 2022
591ea0a
Getting invitations.
inbarbarkai May 19, 2022
d8b5447
Using context to get the necessery services.
inbarbarkai May 19, 2022
1330515
Fixed useEffect dependency argument.
inbarbarkai May 19, 2022
f265a7c
Implified root path.
inbarbarkai May 19, 2022
c6ca792
Converting json before casting.
inbarbarkai May 19, 2022
18cb663
Fully implemented the inviter proxy class.
inbarbarkai May 20, 2022
b559d1d
Fixed rename.
inbarbarkai May 20, 2022
81ca1c2
Converted models to interfaces.
inbarbarkai May 20, 2022
e75322e
Implemented helper method to convert an object to snake case.
inbarbarkai May 20, 2022
81635d6
Using current user for creating an invitation.
inbarbarkai May 20, 2022
fc7288e
Fixed compile warnings.
inbarbarkai May 20, 2022
25e3db5
Converting to snake_case before sending to server.
inbarbarkai May 20, 2022
b55566e
Renamed user to inviter.
inbarbarkai May 20, 2022
ffd5de8
Fixed casing.
inbarbarkai May 20, 2022
15bb631
Updated packages.
inbarbarkai May 20, 2022
75ec673
Implemented a view for creating a new invitation.
inbarbarkai May 20, 2022
e4de228
Converted to a form.
inbarbarkai May 20, 2022
b29b70a
Separated logic from view.
inbarbarkai May 20, 2022
af51f82
Fixed infinite loop.
inbarbarkai May 20, 2022
2daa831
Fixed component name.
inbarbarkai May 20, 2022
4b41445
Fixed update and create invitation requests.
inbarbarkai May 20, 2022
fec5e93
Implemented feature for updating an invitation.
inbarbarkai May 20, 2022
d267ea0
Implemented handling of unauthorized response.
inbarbarkai May 20, 2022
9190dcc
Allowing to pass a return url via the session state.
inbarbarkai May 20, 2022
db69e30
Implemented placeholders for admin and guard functionality.
inbarbarkai May 20, 2022
c1ef7a0
fix: web/Dockerfile to reduce vulnerabilities (#76)
snyk-bot May 26, 2022
43a7532
fixed some lint issues
KamiTzayig Jun 3, 2022
4f71b1c
working on a solution for create invitation error
KamiTzayig Jun 4, 2022
f924299
fixed useApplicationContext error
KamiTzayig Jun 4, 2022
6746c45
improved invitation screen ui
KamiTzayig Jun 4, 2022
f661a0d
improving ui, and adding "my invitations"
KamiTzayig Jun 7, 2022
d237027
improvment of invitaion form ui
KamiTzayig Jun 15, 2022
a229478
Simplified invitations form implementation.
inbarbarkai Jun 15, 2022
69b76ea
Fixed form implementation.
inbarbarkai Jun 15, 2022
edb5f1a
Formatted the code.
inbarbarkai Jun 15, 2022
7c02fda
Fixed conversion method.
inbarbarkai Jun 16, 2022
7b500a2
Converting object to string.
inbarbarkai Jun 16, 2022
c62e516
Using generic get method.
inbarbarkai Jun 16, 2022
8ee0108
Fixed authentication handling.
inbarbarkai Jun 16, 2022
93fde23
Getting the proxy before calling useEffect.
inbarbarkai Jun 16, 2022
8521c5d
Fixed fetch method.
inbarbarkai Jun 16, 2022
1b42c35
Moved rendering of a row to a separate method.
inbarbarkai Jun 16, 2022
358a5ef
Removed unnecessery alert.
inbarbarkai Jun 16, 2022
1341692
Removed mock data.
inbarbarkai Jun 16, 2022
99e3717
Added invite route
inbarbarkai Jun 16, 2022
79b5aa5
Removed unnecessery script argument.
inbarbarkai Jun 16, 2022
ad34981
Restored original configuration.
inbarbarkai Jun 16, 2022
e045e08
Fixed linter errors.
inbarbarkai Jun 16, 2022
d67b1e4
starting to work on guard screen
KamiTzayig Jun 16, 2022
675133f
added base table for guard screen
KamiTzayig Jun 26, 2022
71b8a96
guard proxy
KamiTzayig Jun 27, 2022
abc4dfc
Added guard proxy to context.
inbarbarkai Jul 9, 2022
8492d33
Implemented call to backend when changing admittance.
inbarbarkai Jul 9, 2022
2eae348
Fixed getting the pending invitations.
inbarbarkai Jul 15, 2022
5228244
Fixed getting users from keycloak.
inbarbarkai Jul 15, 2022
60fff08
Filling the name of the user while displaying the invitation.
inbarbarkai Jul 15, 2022
f31e2d3
Moved logic to a store.
inbarbarkai Jul 15, 2022
91ebd0c
Updated react packages.
inbarbarkai Jul 15, 2022
1c11df9
Fixed linter errors.
inbarbarkai Jul 15, 2022
47dbada
Removed unused imports.
inbarbarkai Jul 15, 2022
7524a2b
Extracted logo to an external component.
inbarbarkai Jul 15, 2022
48a1a88
Implemented links to invitations.
inbarbarkai Jul 15, 2022
b0f884b
Added routing for guard.
inbarbarkai Jul 15, 2022
04dbf1e
Implemented method to parse a JWT token.
inbarbarkai Aug 24, 2022
ce871f0
Implemented method to get the user roles.
inbarbarkai Aug 24, 2022
ebfbd31
Implemented a unified navigation bar.
inbarbarkai Aug 24, 2022
a4181bd
using the new navigation bar.
inbarbarkai Aug 24, 2022
e8aad4c
Removed the individual navigation bars.
inbarbarkai Aug 24, 2022
363f2c5
Updated keycloak seed
inbarbarkai Aug 24, 2022
81ea683
Updated packages
inbarbarkai Aug 24, 2022
c1e6d00
fix: web/Dockerfile to reduce vulnerabilities (#90)
snyk-bot Jan 25, 2023
968df40
Update Dockerfile
yarons Jun 15, 2023
e1e3791
fix: web/Dockerfile to reduce vulnerabilities (#91)
yarons Oct 4, 2023
3d7ef07
fix: web/Dockerfile to reduce vulnerabilities (#92)
yarons Oct 26, 2023
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: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,5 @@ dmypy.json

# Pyre type checker
.pyre/
node_modules/
package-lock.json
40 changes: 31 additions & 9 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3.9"
services:
app:
hostname: app
api:
hostname: api
build: .
restart: unless-stopped
volumes:
Expand All @@ -14,13 +14,32 @@ services:
environment:
IVT_OPENID_DISCOVERY_URL: 'http://keycloak:8080/auth/realms/master/.well-known/openid-configuration'
IVT_OPENID_DISCOVERY_EXTERNAL_URL: 'http://keycloak.localhost/auth/realms/master/.well-known/openid-configuration'
# IVT_ENABLE_AUTH: 'true'
IVT_ENABLE_AUTH: 'true'
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.localhost`)"
- "traefik.http.routers.api.entrypoints=web"
- "traefik.docker.network=web"
- "traefik.http.services.api.loadbalancer.server.port=8090"
ports:
- "8090:8090"

app:
hostname: app
build:
dockerfile: Dockerfile
context: web
restart: unless-stopped
networks:
- web
depends_on:
- "api"
labels:
- "traefik.enable=true"
- "traefik.http.routers.invitease.rule=Host(`invitease.localhost`)"
- "traefik.http.routers.invitease.entrypoints=web"
- "traefik.http.routers.app.rule=Host(`app.localhost`)"
- "traefik.http.routers.app.entrypoints=web"
- "traefik.docker.network=web"
- "traefik.http.services.invitease.loadbalancer.server.port=8090"
- "traefik.http.services.app.loadbalancer.server.port=80"

dbmanager:
image: dpage/pgadmin4
Expand Down Expand Up @@ -60,15 +79,17 @@ services:
- pg_data:/var/lib/postgresql/data

keycloak:
image: jboss/keycloak:latest
hostname: keycloak
restart: unless-stopped
networks:
- web
depends_on:
- db
volumes:
- ./init/keycloak:/opt/jboss/startup-scripts
build:
dockerfile: Dockerfile
yarons marked this conversation as resolved.
Show resolved Hide resolved
context: keycloak
ports:
- "8081:8080"
environment:
- DB_VENDOR=POSTGRES
- DB_ADDR=db
Expand Down Expand Up @@ -97,6 +118,7 @@ services:
- "--entrypoints.web.address=:80"
depends_on:
- "app"
- "dbmanager"
restart: unless-stopped
labels:
- "traefik.enable=true"
Expand Down
4 changes: 4 additions & 0 deletions keycloak/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM jboss/keycloak:latest

ADD kc-seed.sh /opt/jboss/startup-scripts/kc-seed.sh
ADD standalone.xml /opt/jboss/keycloak/standalone/configuration/standalone.xml
File renamed without changes.
593 changes: 593 additions & 0 deletions keycloak/standalone.xml

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions web/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM node:18-bullseye-slim as builder

RUN mkdir /source

WORKDIR /source

ADD src/ /source/src
ADD public/ /source/public
ADD package.json tsconfig.json /source/

RUN npm install \
&& npm run build

FROM nginx:1.21.6-alpine

ADD nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /source/build /var/www/
19 changes: 19 additions & 0 deletions web/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
worker_processes 5; ## Default: 1

events {
worker_connections 4096; ## Default: 1024
}

http {
server {
listen 80;
listen [::]:80;

root /var/www/;
index index.html index.htm;

location / {
try_files $uri $uri/ /index.html;
}
}
}
37 changes: 37 additions & 0 deletions web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "invitease",
"version": "0.1.0",
"private": true,
"dependencies": {
"oidc-client-ts": "^2.0.3",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-router-dom": "^6.3.0",
"react-scripts": "^5.0.0"
},
"scripts": {
"start": "react-scripts --max_old_space_size=8128 start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/react": "^18.0.6",
"@types/react-dom": "^18.0.2"
}
}
9 changes: 9 additions & 0 deletions web/public/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
config = {
'serverUrl': 'http://invitease.localhost/',
'applicationRoot':'http://localhost:3000/',
'authentication': {
'clientId': 'invitease',
'serviceUrl': 'http://keycloak.localhost/auth/realms/master/',
'scope': 'openid profile email phone'
}
}
13 changes: 13 additions & 0 deletions web/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">

<head>
<script src="./config.js"></script>
</head>

<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>

</html>
19 changes: 19 additions & 0 deletions web/src/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from 'react';
import { Routes, Route, Navigate } from "react-router-dom";
import Example from './components/example';
import SecureRoute from './components/secureRoute';
import { SigninCallback } from "./components/signinCallback";

function App() {

return (
<Routes>
<Route path='/' element={<Navigate to='index' />}>
</Route>
<Route path="signin-callback" element={<SigninCallback />} />
<Route path='index' element={<SecureRoute><Example /></SecureRoute>} />
</Routes>
);
}

export default App;
20 changes: 20 additions & 0 deletions web/src/components/example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from 'react';
import { useState } from 'react';
import { User } from 'oidc-client-ts';
import { AuthenticationService } from '../services/authenticationService';
import { SettingsService } from '../services/settingsService';

export default function Example() {
let authSettings = new SettingsService().getAuthenticationSettings();
let authService = new AuthenticationService(authSettings);
const [user, setUser] = useState<User | undefined>();
React.useEffect(() => {
if (!user) {
authService.getUser()
.then(user => setUser(user));
}
}, [user]);
return (<pre>
{JSON.stringify(user, null, 2)}
</pre>);
}
17 changes: 17 additions & 0 deletions web/src/components/secureRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as React from 'react';
import { useEffect } from 'react';
import { AuthenticationService } from '../services/authenticationService';
import { SettingsService } from '../services/settingsService';

export default function SecureRoute(props: any) {
let authSettings = new SettingsService().getAuthenticationSettings();
let authService = new AuthenticationService(authSettings);
useEffect(() => {
authService.getUser().then(user => {
if (!user) {
authService.login();
}
});
});
return (<>{props.children}</>);
}
13 changes: 13 additions & 0 deletions web/src/components/signinCallback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as React from 'react';
import { AuthenticationService } from '../services/authenticationService';
import { SettingsService } from '../services/settingsService';

export function SigninCallback() {
let authSettings = new SettingsService().getAuthenticationSettings();
let authService = new AuthenticationService(authSettings);
React.useEffect(() => {
authService.handleSignin()
.then(user => (window as any).location.href = authSettings.applicationRoot + "index");
});
return (<></>);
}
13 changes: 13 additions & 0 deletions web/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import App from './app';
import { BrowserRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
40 changes: 40 additions & 0 deletions web/src/services/authenticationService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Log, User, UserManager } from 'oidc-client-ts';
import { AuthenticationSettings } from '../settings/AuthenticationSettings';

export class AuthenticationService {
public userManager: UserManager;

constructor(settings: AuthenticationSettings) {
const oidcSettings = {
authority: settings.serviceUrl,
client_id: settings.clientId,
redirect_uri: settings.applicationRoot + `signin-callback`,
yarons marked this conversation as resolved.
Show resolved Hide resolved
response_type: 'code',
scope: settings.scope
};
this.userManager = new UserManager(oidcSettings);

Log.setLogger(console);
Log.setLevel(Log.INFO);
}

public getUser(): Promise<User | null> {
return this.userManager.getUser();
}

public login(): Promise<void> {
return this.userManager.signinRedirect();
}

public renewToken(): Promise<User> {
return this.userManager.signinSilent();
}

public logout(): Promise<void> {
return this.userManager.signoutRedirect();
}

public async handleSignin(): Promise<void> {
await this.userManager.signinRedirectCallback();
}
}
14 changes: 14 additions & 0 deletions web/src/services/settingsService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { AuthenticationSettings } from '../settings/AuthenticationSettings';

export class SettingsService {
public getAuthenticationSettings(): AuthenticationSettings {
let settings = new AuthenticationSettings();

settings.clientId = (window as any).config.authentication.clientId;
settings.serviceUrl = (window as any).config.authentication.serviceUrl;
settings.scope = (window as any).config.authentication.clientScope;
settings.applicationRoot = (window as any).config.applicationRoot;

return settings;
}
}
6 changes: 6 additions & 0 deletions web/src/settings/AuthenticationSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class AuthenticationSettings {
clientId: string
serviceUrl: string
scope: string
applicationRoot: string
}
16 changes: 16 additions & 0 deletions web/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"noImplicitAny": true,
"removeComments": true,
"declaration": true,
"sourceMap": true,
"jsx": "react"
},
"include": [
"./src/**/*.tsx",
"./src/**/*.ts"
],
"exclude": [
"node_modules"
]
}