Skip to content

Commit ceb17ee

Browse files
committed
fix autherization error for morph management
1 parent 57e40bf commit ceb17ee

2 files changed

Lines changed: 25 additions & 15 deletions

File tree

nodebook-base/frontend/src/NodeCard.tsx

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Subgraph } from './Subgraph';
66
import { NLPParsingModal } from './NLPParsingModal';
77
import type { Node, Edge, AttributeType, Morph } from './types';
88
import { API_BASE_URL } from './api-config';
9+
import { keycloakAuth } from './services/keycloakAuth';
910
import './NodeCard.css';
1011

1112
interface NodeCardProps {
@@ -34,23 +35,29 @@ export function NodeCard({ node, allNodes, allRelations, attributes, isActive, o
3435
// Morph change state
3536
const [isChangingMorph, setIsChangingMorph] = useState(false);
3637

37-
// Helper function for authenticated API calls
38-
const authenticatedFetch = (url: string, options: RequestInit = {}) => {
39-
const token = localStorage.getItem('token');
38+
// Helper function for authenticated API calls with token refresh
39+
const authenticatedFetch = async (url: string, options: RequestInit = {}) => {
40+
// Ensure access token is valid (refresh if near expiry)
41+
await keycloakAuth.ensureValidToken();
42+
let token = localStorage.getItem('token');
4043
const headers: Record<string, string> = {
41-
...options.headers,
42-
'Authorization': `Bearer ${token}`,
44+
...options.headers as Record<string, string>,
4345
};
44-
45-
// Only set Content-Type for requests that have a body
46-
if (options.body) {
47-
headers['Content-Type'] = 'application/json';
46+
if (token) headers['Authorization'] = `Bearer ${token}`;
47+
if (options.body) headers['Content-Type'] = headers['Content-Type'] || 'application/json';
48+
49+
let res = await fetch(url, { ...options, headers });
50+
if (res.status === 401) {
51+
// Try to refresh and retry once
52+
const refreshed = await keycloakAuth.refreshAccessToken();
53+
token = localStorage.getItem('token');
54+
const retryHeaders: Record<string, string> = { ...headers };
55+
if (refreshed && token) {
56+
retryHeaders['Authorization'] = `Bearer ${token}`;
57+
res = await fetch(url, { ...options, headers: retryHeaders });
58+
}
4859
}
49-
50-
return fetch(url, {
51-
...options,
52-
headers,
53-
});
60+
return res;
5461
};
5562

5663
// NLP parsing function

nodebook-base/server.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { createDataStore } from './data-store.js';
1717
import CNLSuggestionService from './cnl-suggestion-service.js';
1818

1919
// Keycloak authentication integration
20-
const KEYCLOAK_URL = process.env.KEYCLOAK_URL || 'http://keycloak:8080';
20+
const KEYCLOAK_URL = process.env.KEYCLOAK_URL || 'http://localhost:8080';
2121
const KEYCLOAK_REALM = process.env.KEYCLOAK_REALM || 'nodebook';
2222
const KEYCLOAK_CLIENT_ID = process.env.KEYCLOAK_CLIENT_ID || 'nodebook-frontend';
2323
const KEYCLOAK_CLIENT_SECRET = process.env.KEYCLOAK_CLIENT_SECRET || 'nodebook-frontend-secret';
@@ -35,6 +35,7 @@ const auth = {
3535
});
3636

3737
if (!response.ok) {
38+
console.warn(`Keycloak token verification failed: ${response.status} ${response.statusText}`);
3839
return null;
3940
}
4041

@@ -48,6 +49,8 @@ const auth = {
4849
};
4950
} catch (error) {
5051
console.error('Keycloak token verification error:', error);
52+
// In development, if Keycloak is not available, we could fall back to a dev mode
53+
// For now, return null to maintain security
5154
return null;
5255
}
5356
},

0 commit comments

Comments
 (0)