Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
65fd3abf
Unverified
Commit
65fd3abf
authored
Jan 18, 2023
by
tom goriunov
Committed by
GitHub
Jan 18, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #508 from blockscout/cors-refactoring
call api from client on preview stands
parents
ffc74fa6
a8343da3
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
48 additions
and
44 deletions
+48
-44
buildUrl.ts
lib/api/buildUrl.ts
+3
-15
isNeedProxy.ts
lib/api/isNeedProxy.ts
+9
-0
nodeFetch.ts
lib/api/nodeFetch.ts
+2
-1
useFetch.tsx
lib/hooks/useFetch.tsx
+0
-1
useGetCsrfToken.tsx
lib/hooks/useGetCsrfToken.tsx
+32
-0
Page.tsx
ui/shared/Page/Page.tsx
+2
-27
No files found.
lib/api/buildUrl.ts
View file @
65fd3abf
...
...
@@ -2,6 +2,7 @@ import { compile } from 'path-to-regexp';
import
appConfig
from
'
configs/app/config
'
;
import
isNeedProxy
from
'
./isNeedProxy
'
;
import
{
RESOURCES
}
from
'
./resources
'
;
import
type
{
ApiResource
,
ResourceName
}
from
'
./resources
'
;
...
...
@@ -10,23 +11,10 @@ export default function buildUrl(
pathParams
?:
Record
<
string
,
string
|
undefined
>
,
queryParams
?:
Record
<
string
,
string
|
Array
<
string
>
|
number
|
undefined
>
,
)
{
// FIXME
// 1. I was not able to figure out how to send CORS with credentials from localhost
// unsuccessfully tried different ways, even custom local dev domain
// so for local development we have to use next.js api as proxy server
// 2. and there is an issue with API and csrf token
// for some reason API will reply with error "Bad request" to any PUT / POST CORS request
// even though valid csrf-token is passed in header
// we also can pass token in request body but in this case API will replay with "Forbidden" error
// @nikitosing said it will take a lot of time to debug this problem on back-end side, maybe he'll change his mind in future :)
// To sum up, we are using next.js proxy for all instances where app host is not the same as API host (incl. localhost)
// will need to change the condition if there are more micro services that need authentication and DB state changes
const
needProxy
=
appConfig
.
host
!==
appConfig
.
api
.
host
;
const
resource
:
ApiResource
=
typeof
_resource
===
'
string
'
?
RESOURCES
[
_resource
]
:
_resource
;
const
baseUrl
=
needProxy
?
appConfig
.
baseUrl
:
(
resource
.
endpoint
||
appConfig
.
api
.
endpoint
);
const
baseUrl
=
isNeedProxy
()
?
appConfig
.
baseUrl
:
(
resource
.
endpoint
||
appConfig
.
api
.
endpoint
);
const
basePath
=
resource
.
basePath
!==
undefined
?
resource
.
basePath
:
appConfig
.
api
.
basePath
;
const
path
=
needProxy
?
'
/node-api/proxy
'
+
basePath
+
resource
.
path
:
basePath
+
resource
.
path
;
const
path
=
isNeedProxy
()
?
'
/node-api/proxy
'
+
basePath
+
resource
.
path
:
basePath
+
resource
.
path
;
const
url
=
new
URL
(
compile
(
path
)(
pathParams
),
baseUrl
);
queryParams
&&
Object
.
entries
(
queryParams
).
forEach
(([
key
,
value
])
=>
{
...
...
lib/api/isNeedProxy.ts
0 → 100644
View file @
65fd3abf
import
appConfig
from
'
configs/app/config
'
;
// FIXME
// I was not able to figure out how to send CORS with credentials from localhost
// unsuccessfully tried different ways, even custom local dev domain
// so for local development we have to use next.js api as proxy server
export
default
function
isNeedProxy
()
{
return
appConfig
.
host
===
'
localhost
'
&&
appConfig
.
host
!==
appConfig
.
api
.
host
;
}
lib/api/nodeFetch.ts
View file @
65fd3abf
...
...
@@ -24,8 +24,9 @@ export default function fetchFactory(
});
return
nodeFetch
(
url
,
{
headers
,
...
init
,
headers
,
body
:
init
?.
body
?
JSON
.
stringify
(
init
.
body
)
:
undefined
,
});
};
}
lib/hooks/useFetch.tsx
View file @
65fd3abf
...
...
@@ -28,7 +28,6 @@ export default function useFetch() {
headers
:
{
...(
hasBody
?
{
'
Content-type
'
:
'
application/json
'
}
:
undefined
),
...
params
?.
headers
,
// ...(token ?
{
'
x-csrf-token
'
:
token
}
:
{}),
},
};
...
...
lib/hooks/useGetCsrfToken.tsx
0 → 100644
View file @
65fd3abf
import
{
useQuery
}
from
'
@tanstack/react-query
'
;
import
buildUrl
from
'
lib/api/buildUrl
'
;
import
isNeedProxy
from
'
lib/api/isNeedProxy
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
*
as
cookies
from
'
lib/cookies
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
export
default
function
useGetCsrfToken
()
{
const
nodeApiFetch
=
useFetch
();
useQuery
(
getResourceKey
(
'
csrf
'
),
async
()
=>
{
if
(
!
isNeedProxy
())
{
const
url
=
buildUrl
(
'
csrf
'
);
const
apiResponse
=
await
fetch
(
url
,
{
credentials
:
'
include
'
});
const
csrfFromHeader
=
apiResponse
.
headers
.
get
(
'
x-bs-account-csrf
'
);
// eslint-disable-next-line no-console
console
.
log
(
'
>>> RESPONSE HEADERS <<<
'
);
// eslint-disable-next-line no-console
console
.
table
([
{
'
content-length
'
:
apiResponse
.
headers
.
get
(
'
content-length
'
),
'
x-bs-account-csrf
'
:
csrfFromHeader
,
}
]);
return
csrfFromHeader
?
{
token
:
csrfFromHeader
}
:
undefined
;
}
return
nodeApiFetch
(
'
/node-api/csrf
'
);
},
{
enabled
:
Boolean
(
cookies
.
get
(
cookies
.
NAMES
.
API_TOKEN
)),
});
}
ui/shared/Page/Page.tsx
View file @
65fd3abf
import
{
Flex
}
from
'
@chakra-ui/react
'
;
import
{
useQuery
}
from
'
@tanstack/react-query
'
;
import
React
from
'
react
'
;
import
appConfig
from
'
configs/app/config
'
;
import
buildUrl
from
'
lib/api/buildUrl
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
*
as
cookies
from
'
lib/cookies
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
useGetCsrfToken
from
'
lib/hooks/useGetCsrfToken
'
;
import
AppError
from
'
ui/shared/AppError/AppError
'
;
import
ErrorBoundary
from
'
ui/shared/ErrorBoundary
'
;
import
ErrorInvalidTxHash
from
'
ui/shared/ErrorInvalidTxHash
'
;
...
...
@@ -27,28 +22,8 @@ const Page = ({
isHomePage
,
renderHeader
,
}:
Props
)
=>
{
const
nodeApiFetch
=
useFetch
();
useQuery
(
getResourceKey
(
'
csrf
'
),
async
()
=>
{
if
(
appConfig
.
host
===
appConfig
.
api
.
host
)
{
const
url
=
buildUrl
(
'
csrf
'
);
const
apiResponse
=
await
fetch
(
url
,
{
credentials
:
'
include
'
});
const
csrfFromHeader
=
apiResponse
.
headers
.
get
(
'
x-bs-account-csrf
'
);
// eslint-disable-next-line no-console
console
.
log
(
'
>>> RESPONSE HEADERS <<<
'
);
// eslint-disable-next-line no-console
console
.
table
([
{
'
content-length
'
:
apiResponse
.
headers
.
get
(
'
content-length
'
),
'
x-bs-account-csrf
'
:
csrfFromHeader
,
}
]);
return
csrfFromHeader
?
{
token
:
csrfFromHeader
}
:
undefined
;
}
return
nodeApiFetch
(
'
/node-api/csrf
'
);
},
{
enabled
:
Boolean
(
cookies
.
get
(
cookies
.
NAMES
.
API_TOKEN
)),
});
useGetCsrfToken
();
const
renderErrorScreen
=
React
.
useCallback
((
error
?:
Error
)
=>
{
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment