Skip to content

Commit d7ac8dc

Browse files
authored
Merge pull request #9 from vitruv-tools/develop
Develop
2 parents f0fe363 + 38e2edd commit d7ac8dc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+7878
-268
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
name: Frontend CI
22

33
on:
4-
# Run on push and PRs to main
4+
# Run on push and PRs to main and develop
55
push:
6-
branches: [main]
6+
branches:
7+
- main
8+
- develop
79
pull_request:
8-
branches: [main]
10+
branches:
11+
- main
12+
- develop
913
workflow_dispatch:
1014

1115
jobs:

AUTHENTICATION.md

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
# Authentication System Documentation
2+
3+
This document describes the authentication system implemented in the Vitruv UI Methodologist application.
4+
5+
## Overview
6+
7+
The authentication system provides:
8+
- User sign-up and sign-in functionality
9+
- Automatic token refresh
10+
- Secure API requests with authentication
11+
- Token management and storage
12+
13+
## API Endpoints
14+
15+
### Sign Up
16+
- **URL**: `POST http://localhost:9811/api/v1/users/sign-up`
17+
- **Request Body**:
18+
```json
19+
{
20+
"email": "string",
21+
"roleType": "user",
22+
"username": "string",
23+
"firstName": "string",
24+
"lastName": "string",
25+
"password": "string"
26+
}
27+
```
28+
- **Response**:
29+
```json
30+
{
31+
"data": {},
32+
"message": "string"
33+
}
34+
```
35+
36+
### Sign In
37+
- **URL**: `POST http://localhost:9811/api/v1/users/login`
38+
- **Request Body**:
39+
```json
40+
{
41+
"username": "string",
42+
"password": "string"
43+
}
44+
```
45+
- **Response**:
46+
```json
47+
{
48+
"access_token": "string",
49+
"refresh_token": "string",
50+
"expires_in": 0,
51+
"refresh_expires_in": 0,
52+
"token_type": "string",
53+
"session_state": "string",
54+
"scope": "string",
55+
"not-before-policy": 0
56+
}
57+
```
58+
59+
### Token Refresh
60+
- **URL**: `POST http://localhost:9811/api/v1/users/access-token/by-refresh-token`
61+
- **Request Body**:
62+
```json
63+
{
64+
"refreshToken": "string"
65+
}
66+
```
67+
- **Response**: Same as sign-in response
68+
69+
## Usage
70+
71+
### Basic Authentication
72+
73+
```typescript
74+
import { useAuth } from '../contexts/AuthContext';
75+
76+
function MyComponent() {
77+
const { signIn, signUp, signOut, user, isAuthenticated } = useAuth();
78+
79+
const handleSignIn = async () => {
80+
try {
81+
await signIn('username', 'password');
82+
console.log('Signed in successfully');
83+
} catch (error) {
84+
console.error('Sign in failed:', error);
85+
}
86+
};
87+
88+
const handleSignUp = async () => {
89+
try {
90+
await signUp({
91+
username: 'newuser',
92+
email: 'user@example.com',
93+
password: 'password123',
94+
firstName: 'John',
95+
lastName: 'Doe',
96+
roleType: 'user'
97+
});
98+
console.log('Signed up successfully');
99+
} catch (error) {
100+
console.error('Sign up failed:', error);
101+
}
102+
};
103+
104+
return (
105+
<div>
106+
{isAuthenticated ? (
107+
<div>
108+
<p>Welcome, {user?.username}!</p>
109+
<button onClick={signOut}>Sign Out</button>
110+
</div>
111+
) : (
112+
<div>
113+
<button onClick={handleSignIn}>Sign In</button>
114+
<button onClick={handleSignUp}>Sign Up</button>
115+
</div>
116+
)}
117+
</div>
118+
);
119+
}
120+
```
121+
122+
### Making Authenticated API Requests
123+
124+
```typescript
125+
import { apiService, userApi, projectApi } from '../services/api';
126+
127+
// Using the authenticated service directly
128+
const getData = async () => {
129+
try {
130+
const response = await apiService.authenticatedRequest('/api/v1/some-endpoint');
131+
console.log(response);
132+
} catch (error) {
133+
console.error('API request failed:', error);
134+
}
135+
};
136+
137+
// Using predefined API methods
138+
const getUserProfile = async () => {
139+
try {
140+
const profile = await userApi.getProfile();
141+
console.log(profile);
142+
} catch (error) {
143+
console.error('Failed to get profile:', error);
144+
}
145+
};
146+
147+
const createNewProject = async () => {
148+
try {
149+
const project = await projectApi.createProject({
150+
name: 'My Project',
151+
description: 'A new project'
152+
});
153+
console.log('Project created:', project);
154+
} catch (error) {
155+
console.error('Failed to create project:', error);
156+
}
157+
};
158+
```
159+
160+
### Token Refresh
161+
162+
The system automatically handles token refresh, but you can also manually refresh tokens:
163+
164+
```typescript
165+
import { useAuth } from '../contexts/AuthContext';
166+
167+
function TokenRefreshExample() {
168+
const { refreshToken } = useAuth();
169+
170+
const handleManualRefresh = async () => {
171+
try {
172+
const result = await refreshToken();
173+
console.log('Token refreshed:', result);
174+
} catch (error) {
175+
console.error('Token refresh failed:', error);
176+
}
177+
};
178+
179+
return (
180+
<button onClick={handleManualRefresh}>
181+
Refresh Token
182+
</button>
183+
);
184+
}
185+
```
186+
187+
### Using the Token Refresh Hook
188+
189+
```typescript
190+
import { useTokenRefresh } from '../hooks/useTokenRefresh';
191+
192+
function TokenManagement() {
193+
const { refreshToken, getValidToken } = useTokenRefresh();
194+
195+
const handleGetValidToken = async () => {
196+
try {
197+
const token = await getValidToken();
198+
if (token) {
199+
console.log('Valid token:', token);
200+
} else {
201+
console.log('No valid token available');
202+
}
203+
} catch (error) {
204+
console.error('Failed to get valid token:', error);
205+
}
206+
};
207+
208+
return (
209+
<div>
210+
<button onClick={handleGetValidToken}>Get Valid Token</button>
211+
</div>
212+
);
213+
}
214+
```
215+
216+
## Automatic Features
217+
218+
### Token Expiration Handling
219+
- The system automatically detects when access tokens expire
220+
- Automatically attempts to refresh tokens before they expire
221+
- If refresh fails, the user is automatically signed out
222+
223+
### Automatic Token Refresh
224+
- Tokens are checked every minute
225+
- Refresh is attempted 5 minutes before expiration
226+
- Failed refreshes trigger automatic sign-out
227+
228+
### Secure API Requests
229+
- All authenticated requests automatically include the current token
230+
- Failed requests due to invalid tokens automatically retry after refresh
231+
- Seamless token refresh without user intervention
232+
233+
## Configuration
234+
235+
### Backend URL
236+
The backend URL is configured in `src/services/auth.ts`:
237+
```typescript
238+
private static readonly LOCAL_API_BASE_URL = 'http://localhost:9811';
239+
```
240+
241+
### Token Storage
242+
Tokens are stored in localStorage with the following keys:
243+
- `auth.access_token` - Current access token
244+
- `auth.refresh_token` - Current refresh token
245+
- `auth.expires_in` - Access token expiration time
246+
- `auth.refresh_expires_in` - Refresh token expiration time
247+
- `auth.token_type` - Token type (usually "Bearer")
248+
- `auth.session_state` - Session state
249+
- `auth.scope` - Token scope
250+
- `auth.not_before_policy` - Not before policy timestamp
251+
252+
## Error Handling
253+
254+
The system provides comprehensive error handling:
255+
- Network errors are caught and displayed to users
256+
- Authentication failures trigger appropriate error messages
257+
- Token refresh failures result in automatic sign-out
258+
- API errors include detailed error messages from the backend
259+
260+
## Security Features
261+
262+
- Tokens are automatically refreshed before expiration
263+
- Failed authentication attempts are handled gracefully
264+
- Secure token storage in localStorage
265+
- Automatic cleanup of expired tokens
266+
- Protection against token reuse attacks
267+
268+
## Testing
269+
270+
To test the authentication system:
271+
272+
1. Ensure your backend server is running on `localhost:9811`
273+
2. Use the sign-up form to create a new account
274+
3. Use the sign-in form to authenticate
275+
4. Check the browser's developer tools to see stored tokens
276+
5. Test API calls that require authentication
277+
6. Wait for token expiration to test automatic refresh
278+
279+
## Troubleshooting
280+
281+
### Common Issues
282+
283+
1. **Backend Connection Failed**
284+
- Ensure your backend server is running on port 9811
285+
- Check that the API endpoints are accessible
286+
287+
2. **Token Refresh Fails**
288+
- Check that refresh tokens are valid
289+
- Verify the refresh endpoint is working
290+
- Check browser console for detailed error messages
291+
292+
3. **Authentication State Lost**
293+
- Check localStorage for stored tokens
294+
- Verify token expiration times
295+
- Check for JavaScript errors in the console
296+
297+
### Debug Mode
298+
299+
Enable debug logging by checking the browser console. The system logs:
300+
- Authentication attempts
301+
- Token refresh operations
302+
- API request details
303+
- Error information
304+
305+
## Migration from Legacy System
306+
307+
If you're migrating from the old authentication system:
308+
309+
1. Update your components to use the new `useAuth` hook
310+
2. Replace direct API calls with the new `apiService`
311+
3. Update any hardcoded authentication logic
312+
4. Test the new token refresh functionality
313+
314+
The legacy authentication methods are still available in `AuthService.signInLegacy()` for backward compatibility.

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ A React-based flow modeling application for creating and managing Vitruvius diag
77
- **Drag & Drop Interface**: Create flow diagrams by dragging nodes from the sidebar
88
- **Editable Nodes**: Double-click nodes to edit their labels
99
- **Flow Connections**: Connect nodes to create relationships
10+
- **Undo/Redo Functionality**: Use Ctrl+Z to undo and Ctrl+Y to redo changes
11+
- **Node Deletion**: Delete nodes by selecting them and clicking the delete button
1012
- **Deploy Functionality**: Deploy your models to the Vitruvius backend
1113
- **Modern UI**: Clean and intuitive user interface
1214

@@ -65,10 +67,12 @@ For detailed architecture documentation, see [ARCHITECTURE.md](./ARCHITECTURE.md
6567

6668
## Usage
6769

68-
1. **Creating Nodes**: Drag "Sequence Table" or "Object Table" from the sidebar onto the canvas
70+
1. **Creating Nodes**: Drag UML elements from the sidebar onto the canvas
6971
2. **Editing Nodes**: Double-click any node to edit its label
7072
3. **Connecting Nodes**: Click and drag from one node's handle to another to create connections
71-
4. **Deploying**: Click the "Deploy" button to send your model to the backend
73+
4. **Deleting Nodes**: Select a node and click the red delete button (×) that appears
74+
5. **Undo/Redo**: Use Ctrl+Z to undo changes or Ctrl+Y to redo them
75+
6. **Deploying**: Click the "Deploy" button to send your model to the backend
7276

7377
## Technology Stack
7478

0 commit comments

Comments
 (0)