jerryshao commented on code in PR #12293:
URL: https://github.com/apache/gravitino/pull/12293#discussion_r4408557832
##########
web-v2/web/src/app/rootLayout/UserSetting.js:
##########
@@ -51,12 +51,17 @@ export default function UserSetting() {
const currentMetalake = searchParams.get('metalake')
const dispatch = useAppDispatch()
const store = useAppSelector(state => state.metalakes)
+ const isAuthReady = !!auth.authType && (auth.authType !== 'oauth' ||
!!auth.authToken)
useEffect(() => {
+ if (!isAuthReady) {
+ return
+ }
+
Review Comment:
[Nit] `UserSetting` is rendered only by `SiteHeader` (`SiteHeader.js:127`),
and `SiteHeader` is mounted once in `rootLayout/Layout.js:38`, so this effect
and the identical one in `SiteHeader.js:44-52` both run for the same state: two
concurrent `GET /api/metalakes` per trigger. The duplication predates this PR,
but the PR adds a second trigger (the auth-ready transition), so each such
transition now costs two more requests, and the two responses arrive as two
separate `fetchMetalakes.fulfilled` actions that each replace `store.metalakes`
and so re-run the URL-defaulting effect at `SiteHeader.js:59-97`.
Since both copies are being touched here, consider keeping the fetch in one
owner (`SiteHeader`) and dropping it from this component.
Verified by: `grep -rn 'UserSetting|SiteHeader' web-v2/web/src` at head
0db3739 shows `Layout.js:38` as the only mount of `SiteHeader` and no user of
`UserSetting` other than `SiteHeader.js:127`; read both files in full.
##########
web-v2/web/src/app/rootLayout/SiteHeader.js:
##########
@@ -38,12 +38,18 @@ export function SiteHeader() {
const dispatch = useAppDispatch()
const store = useAppSelector(state => state.metalakes)
+ const auth = useAppSelector(state => state.auth)
+ const isAuthReady = !!auth.authType && (auth.authType !== 'oauth' ||
!!auth.authToken)
Review Comment:
[Important] This is the third inline copy of the readiness expression:
`UserSetting.js:54` and `src/app/metalakes/page.js:74` carry the same one,
while the authoritative copy is the module-private helper at
`src/lib/store/metalakes/index.js:111-115`, which is used as the `condition` of
`fetchMetalakes` (line 133). That helper is not exported, so the copies can
drift from it, and drift fails silently in exactly the way this PR is fixing:
if the condition is ever tightened (say, to require a credential for `basic`),
a component whose own copy still returns `true` will dispatch, the `condition`
will drop the action, and nothing retries because the component's dependency
never changes again.
Suggest exporting the predicate from the store as a selector (e.g.
`selectIsAuthReady`) and using it at all three call sites. That also gives the
auth-ready transition a surface that can be unit-tested without
`@testing-library/react`, which is not currently a dependency.
Verified by: `grep -rn isAuthReady web-v2/web/src` at head 0db3739 returns
four independent definitions (this line, `UserSetting.js:54`,
`metalakes/page.js:74`, and the store helper); read
`src/lib/store/metalakes/index.js:111-135` and confirmed the helper is declared
`const isAuthReady = state => {...}` with no `export`.
##########
web-v2/web/src/app/rootLayout/SiteHeader.js:
##########
@@ -38,12 +38,18 @@ export function SiteHeader() {
const dispatch = useAppDispatch()
const store = useAppSelector(state => state.metalakes)
+ const auth = useAppSelector(state => state.auth)
+ const isAuthReady = !!auth.authType && (auth.authType !== 'oauth' ||
!!auth.authToken)
useEffect(() => {
+ if (!isAuthReady) {
+ return
+ }
Review Comment:
[Question] The gate requires a token only for `oauth`, so when `authType ===
'basic'` it becomes true as soon as `/configs` resolves, even with no
credential in hand. The request interceptor reads the basic token from
`sessionStorage.accessToken` (`src/lib/utils/axios/index.js:204-212`) and sends
no `Authorization` header when it is missing - which is the normal state of a
freshly opened tab, since `sessionStorage` is per-tab - and the 401 path then
removes the stored tokens and performs a full-page `window.location.href =
'/login'` (`src/lib/utils/axios/index.js:288-308`).
`AuthProvider` sends that same user to `/login` anyway
(`src/lib/provider/session.js:103-110`), so the destination does not change;
what I am unsure about is whether the extra unauthenticated `GET
/api/metalakes` and a hard navigation racing `router.push` are acceptable here,
or whether the gate should also require `!!authToken` for `basic` (and a
`simpleAuthUser` for `simple`, per `index.js:198-203`). Since this PR turns the
predicate from a passive drop into an active trigger, it seems worth settling.
Could you confirm which behaviour is intended?
Verified by: read the request and response interceptors in
`src/lib/utils/axios/index.js` and `initAuth` in `src/lib/provider/session.js`
in full at head 0db3739; no request was executed, the reachability above is
from reading those code paths.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]