Skip to content

Commit dd04c04

Browse files
committed
Merge branch 'devel' into feature/ILEX-90
2 parents ce0e3c7 + bf7f2d8 commit dd04c04

24 files changed

Lines changed: 862 additions & 230 deletions

nginx/default.conf

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ server {
2424
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
2525
proxy_set_header X-Forwarded-Proto $scheme;
2626
proxy_ssl_verify off;
27+
28+
# CORS headers
29+
add_header Access-Control-Allow-Origin $http_origin always;
30+
add_header Access-Control-Allow-Credentials true always;
2731
}
2832

2933
location ~ ^/([^/]+)/priv/(.*) {
@@ -33,38 +37,88 @@ server {
3337
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
3438
proxy_set_header X-Forwarded-Proto $scheme;
3539
proxy_ssl_verify off;
40+
41+
# CORS headers
42+
add_header Access-Control-Allow-Origin $http_origin always;
43+
add_header Access-Control-Allow-Credentials true always;
44+
add_header Access-Control-Expose-Headers X-Redirect-Location always;
3645
}
3746

3847
location ~ ^/[^/]+/(tmp|ilx)_.*\.(html|ttl|jsonld|n3|owl|csv)$ {
39-
proxy_pass https://uri.olympiangods.org$request_uri;
40-
proxy_set_header Host $host;
48+
proxy_pass https://uri.olympiangods.org;
49+
proxy_set_header Host uri.olympiangods.org;
4150
proxy_set_header X-Real-IP $remote_addr;
4251
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
4352
proxy_set_header X-Forwarded-Proto $scheme;
53+
proxy_ssl_verify off;
54+
55+
# CORS headers
56+
add_header Access-Control-Allow-Origin $http_origin always;
57+
add_header Access-Control-Allow-Credentials true always;
58+
}
4459

60+
location ~ ^/[^/]+/ontologies/uris/.*\.(html|jsonld)$ {
61+
proxy_pass https://uri.olympiangods.org;
62+
proxy_set_header Host uri.olympiangods.org;
63+
proxy_set_header X-Real-IP $remote_addr;
64+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
65+
proxy_set_header X-Forwarded-Proto $scheme;
66+
proxy_ssl_verify off;
67+
4568
# CORS headers
4669
add_header Access-Control-Allow-Origin $http_origin always;
4770
add_header Access-Control-Allow-Credentials true always;
4871
}
4972

5073
location ~ ^/[^/]+/ontologies/uris/.*/spec$ {
51-
proxy_pass https://uri.olympiangods.org$request_uri;
52-
proxy_set_header Host $host;
74+
proxy_pass https://uri.olympiangods.org;
75+
proxy_set_header Host uri.olympiangods.org;
5376
proxy_set_header X-Real-IP $remote_addr;
5477
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
5578
proxy_set_header X-Forwarded-Proto $scheme;
56-
57-
# Forward Authorization header if present
5879
proxy_set_header Authorization $http_authorization;
59-
80+
proxy_ssl_verify off;
81+
82+
# Handle 303 redirects
83+
proxy_intercept_errors on;
84+
error_page 303 = @handle_303;
85+
6086
# CORS headers
6187
add_header Access-Control-Allow-Origin $http_origin always;
6288
add_header Access-Control-Allow-Credentials true always;
6389
add_header Access-Control-Expose-Headers X-Redirect-Location always;
90+
}
6491

65-
# Handle 303 redirects: move Location to X-Redirect-Location
66-
proxy_intercept_errors on;
67-
error_page 303 = @handle_303;
92+
location ~ ^/[^/]+/[^/]+/versions$ {
93+
proxy_pass https://uri.olympiangods.org;
94+
proxy_set_header Host uri.olympiangods.org;
95+
proxy_set_header X-Real-IP $remote_addr;
96+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
97+
proxy_set_header X-Forwarded-Proto $scheme;
98+
proxy_ssl_verify off;
99+
100+
# CORS headers
101+
add_header Access-Control-Allow-Origin $http_origin always;
102+
add_header Access-Control-Allow-Credentials true always;
103+
}
104+
105+
# Handle 303 redirects for spec endpoint
106+
location @handle_303 {
107+
internal;
108+
proxy_pass https://uri.olympiangods.org;
109+
proxy_set_header Host uri.olympiangods.org;
110+
proxy_set_header X-Real-IP $remote_addr;
111+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
112+
proxy_set_header X-Forwarded-Proto $scheme;
113+
proxy_set_header Authorization $http_authorization;
114+
proxy_ssl_verify off;
115+
116+
# Move Location header to X-Redirect-Location
117+
proxy_hide_header Location;
118+
add_header X-Redirect-Location $upstream_http_location always;
119+
add_header Access-Control-Allow-Origin $http_origin always;
120+
add_header Access-Control-Allow-Credentials true always;
121+
add_header Access-Control-Expose-Headers X-Redirect-Location always;
68122
}
69123

70124
location /static/ {

src/App.jsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,21 +126,13 @@ function MainContent() {
126126
}
127127
/>
128128
<Route
129-
path="/search"
129+
path="/:group/search"
130130
element={
131131
<PageContainer>
132132
<SearchResults />
133133
</PageContainer>
134134
}
135135
/>
136-
<Route
137-
path="/view"
138-
element={
139-
<PageContainer>
140-
<SingleTermView />
141-
</PageContainer>
142-
}
143-
/>
144136
<Route
145137
path="/organizations"
146138
element={
@@ -170,7 +162,7 @@ function MainContent() {
170162
}
171163
/>
172164
<Route
173-
path="/dashboard"
165+
path="/:group/dashboard"
174166
element={
175167
<PageContainer>
176168
<Dashboard />
@@ -201,6 +193,14 @@ function MainContent() {
201193
</ProtectedRoute>
202194
}
203195
/>
196+
<Route
197+
path="/:group/:term/:tab?"
198+
element={
199+
<PageContainer>
200+
<SingleTermView />
201+
</PageContainer>
202+
}
203+
/>
204204
</Routes>
205205
</Layout>
206206
</Box>

src/api/endpoints/apiActions.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import { AxiosRequestConfig } from 'axios';
22
import { customInstance } from '../../../mock/mutator/customClient';
3-
import { API_CONFIG } from '../../config';
4-
import { useCookies } from 'react-cookie'
5-
63

74
type SecondParameter<T extends (...args: any) => any> = Parameters<T>[1];
85

@@ -42,4 +39,4 @@ export const createGetRequest = <T = any, P = any>(endpoint: string, contentType
4239
return response;
4340
});
4441
}
45-
}
42+
}

src/api/endpoints/apiService.ts

Lines changed: 94 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ export interface RegisterRequest {
1616
organization: string
1717
}
1818

19+
interface ForgotPasswordReguest {
20+
username: string;
21+
}
22+
1923
type LabelType =
2024
| string
2125
| { '@value': string; '@language'?: string }
@@ -56,9 +60,9 @@ export const userLogout = (group: string) => {
5660
return createGetRequest<any, any>(endpoint, "application/json")();
5761
};
5862

59-
export const getSelectedTermLabel = async (searchTerm: string): Promise<string | undefined> => {
63+
export const getSelectedTermLabel = async (searchTerm: string, group: string = 'base'): Promise<{ label: string | undefined; actualGroup: string }> => {
6064
try {
61-
const response = await createGetRequest<JsonLdResponse, any>(`/base/${searchTerm}.jsonld`)();
65+
const response = await createGetRequest<JsonLdResponse, any>(`/${group}/${searchTerm}.jsonld`)();
6266

6367
const label = response['@graph']?.[0]?.['rdfs:label'];
6468

@@ -73,10 +77,39 @@ export const getSelectedTermLabel = async (searchTerm: string): Promise<string |
7377
return label?.['@value'] || '';
7478
};
7579

76-
return label ? getLabelValue(label) : undefined
80+
return {
81+
label: label ? getLabelValue(label) : undefined,
82+
actualGroup: group
83+
};
7784
} catch (err: any) {
7885
console.error(err.message);
79-
return undefined;
86+
// If the request fails and we're not already trying 'base', try with 'base' as fallback
87+
if (group !== 'base') {
88+
try {
89+
const fallbackResponse = await createGetRequest<JsonLdResponse, any>(`/base/${searchTerm}.jsonld`)();
90+
const fallbackLabel = fallbackResponse['@graph']?.[0]?.['rdfs:label'];
91+
92+
const getLabelValue = (label: LabelType): string => {
93+
if (typeof label === 'string') return label;
94+
if (Array.isArray(label)) {
95+
const en = label.find(
96+
l => typeof l === 'string' || (typeof l === 'object' && l?.['@language'] === 'en')
97+
);
98+
return typeof en === 'string' ? en : en?.['@value'] || '';
99+
}
100+
return label?.['@value'] || '';
101+
};
102+
103+
return {
104+
label: fallbackLabel ? getLabelValue(fallbackLabel) : undefined,
105+
actualGroup: 'base'
106+
};
107+
} catch (fallbackErr: any) {
108+
console.error('Fallback request also failed:', fallbackErr.message);
109+
return { label: undefined, actualGroup: group };
110+
}
111+
}
112+
return { label: undefined, actualGroup: group };
80113
}
81114
};
82115

@@ -148,43 +181,54 @@ export const createNewOntology = async ({
148181

149182
const headers = {
150183
'Content-Type': 'application/json',
151-
'Authorization': `Bearer ${token}`
184+
'Authorization': `Bearer ${token}`,
152185
};
153186

154187
try {
155-
const postResponse = await createPostRequest<any, any>(endpoint, headers)(data);
156-
157-
// If the POST creates a new location, try fetching it (simulate follow-up GETs from the test)
158-
if (postResponse?.location) {
159-
const getResponse = await fetch(postResponse.location, {
160-
headers: {
161-
Accept: 'application/json',
162-
},
163-
});
164-
165-
// Optionally fetch HTML if needed (like the .html equivalent in the Python test)
166-
const htmlResponse = await fetch(endpoint, {
167-
headers: {
168-
Accept: 'text/html',
169-
},
170-
});
188+
const postResponse = await fetch(endpoint, {
189+
method: 'POST',
190+
headers,
191+
credentials: "include",
192+
body: JSON.stringify(data),
193+
redirect: 'manual',
194+
});
195+
196+
// Check for custom redirect header (all lowercase in fetch)
197+
const redirectLocation = postResponse.headers.get('x-redirect-location');
171198

199+
if (redirectLocation) {
200+
const olympianRedirectLocation = redirectLocation.replace('http://uri.interlex.org','').replace(/\.html$/, '.jsonld');
201+
202+
const getResponse = await fetch(olympianRedirectLocation, { headers: { Authorization: `Bearer ${token}` } });
203+
const jsonResponse = await getResponse.json();
204+
205+
const newOntologyID = jsonResponse?.["@graph"]?.find((object) => object["@type"] === "owl:Ontology")?.["@id"] || null;
206+
172207
return {
173208
created: true,
174-
data: postResponse,
175-
jsonResponse: await getResponse.json(),
176-
htmlAvailable: htmlResponse.ok,
209+
location: olympianRedirectLocation,
210+
newOntologyID: newOntologyID
177211
};
178212
}
179213

214+
// Try to parse the response as JSON (if present)
215+
let jsonResponse: any = null;
216+
try {
217+
jsonResponse = await postResponse.json();
218+
} catch (e) {
219+
// No JSON body, ignore
220+
}
221+
180222
return {
181-
created: true,
182-
data: postResponse,
223+
created: postResponse.ok,
224+
location: endpoint,
225+
jsonResponse,
183226
};
184227
} catch (error: any) {
228+
let errMsg = error?.message ?? String(error);
185229
return {
186230
created: false,
187-
error: error?.response?.data || error.message,
231+
error: errMsg,
188232
};
189233
}
190234
};
@@ -199,12 +243,24 @@ export const retrieveTokenApi = ({ groupname }: { groupname: string }) => {
199243
return createGetRequest<any, any>(endpoint, "application/json")();
200244
};
201245

246+
export const forgotPassword = createPostRequest<any, ForgotPasswordReguest>(API_CONFIG.REAL_API.USER_RECOVER, { "Content-Type": "application/x-www-form-urlencoded" })
247+
202248
export const getMatchTerms = async (group: string, term: string, filters = {}) => {
203249
try {
204250
const response = await createGetRequest<any, any>(`/${group}/${term}.${BASE_EXTENSION}`, "application/json")();
205251
return termParser(response, term);
206252
} catch (err: any) {
207253
console.error(err.message);
254+
// If the request fails and we're not already trying 'base', try with 'base' as fallback
255+
if (group !== 'base') {
256+
try {
257+
const fallbackResponse = await createGetRequest<any, any>(`/base/${term}.${BASE_EXTENSION}`, "application/json")();
258+
return termParser(fallbackResponse, term);
259+
} catch (fallbackErr: any) {
260+
console.error('Fallback request also failed:', fallbackErr.message);
261+
return undefined;
262+
}
263+
}
208264
return undefined;
209265
}
210266
};
@@ -215,6 +271,16 @@ export const getRawData = async (group: string, termID: string, format: string)
215271
return response;
216272
} catch (err: any) {
217273
console.error(err.message);
274+
// If the request fails and we're not already trying 'base', try with 'base' as fallback
275+
if (group !== 'base') {
276+
try {
277+
const fallbackResponse = await createGetRequest<any, any>(`/base/${termID}.${format}`, "application/json")();
278+
return fallbackResponse;
279+
} catch (fallbackErr: any) {
280+
console.error('Fallback request also failed:', fallbackErr.message);
281+
return undefined;
282+
}
283+
}
218284
return undefined;
219285
}
220286
};
@@ -233,4 +299,4 @@ export const getTermDiscussions = async (group: string, variantID: string) => {
233299

234300
export const getVariant = (group: string, term: string) => {
235301
return createGetRequest<any, any>(`/${group}/variant/${term}`, "application/json")();
236-
};
302+
};

0 commit comments

Comments
 (0)