Skip to content

DEVPROD-26290 Implement spawn host workflow with OAuth#1536

Merged
ZackarySantana merged 7 commits intomainfrom
token2
Apr 9, 2026
Merged

DEVPROD-26290 Implement spawn host workflow with OAuth#1536
ZackarySantana merged 7 commits intomainfrom
token2

Conversation

@ZackarySantana
Copy link
Copy Markdown
Contributor

@ZackarySantana ZackarySantana commented Apr 7, 2026

DEVPROD-26290

Description

(a 2nd attempt from #1505)

(more context here)

This PR implements the spawn host workflow using OAuth. The demo videos show it best, but essentially users will have to authenticate with Evergreen before using their spawn host, then we can properly set up the spawn host.

Screenshots

This is with jwt enabled (migration of CLI):

Screen.Recording.2026-04-07.at.6.38.47.PM.mov

Testing

Added some tests, deploy to staging.

Evergreen PR

#9915

@ZackarySantana ZackarySantana self-assigned this Apr 7, 2026
@ZackarySantana ZackarySantana requested a review from a team as a code owner April 7, 2026 22:49
Comment on lines +41 to +44
fetchPolicy: "no-cache",
// We poll faster than normal because users expect to see
// faster feedback after performing the authentication flow.
pollInterval: skip ? 0 : FASTER_POLL_INTERVAL,
Copy link
Copy Markdown
Contributor

@athammer athammer Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want network-only instead here or another cache strategy? i think with no-cache we're essentially replicating this interval call with each instance/usage of useUser as we can never use the cache and always reach out to the server which could cause some extra load on the server and some perceived slowness

that's fine if that's behavior we want, but just wanted to call out as it might cause some confusion down the line

Copy link
Copy Markdown
Contributor Author

@ZackarySantana ZackarySantana Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cause some extra load on the server and some perceived slowness

That's a fair point, I think the expected extra load on the server isn't as much as other pages like the waterfall- since it's part of a specific workflow (when the modal is open)- but having a responsive UX post-authentication is important for the overall smoothness of the flow.

I'm not sure what might be the best strategy here to reduce the user's waiting time post-authentication as much as possible and I'm open to suggestions!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to aaron, I'd suggest creating a separate query entirely from useUser so that you can control polling here without having wide ranging impacts!

Copy link
Copy Markdown
Contributor Author

@ZackarySantana ZackarySantana Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I've never written a new query but I think I did it correctly. Please lmk what yall think!
Also, I switched it to one hook + using an enum because I didn't like that there could exist the invalid state of both hooks/values returning true.

return isTokenValid(tokenExpiresAt);
};

export const useUserIsUndergoingAuthentication = (skip: boolean): boolean => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we refetch on focus for useUserHasValidToken, that would mean this could be out of sync until the next poll. dont think it would break anything but might cause some ui inconsistency for FASTER_POLL_INTERVAL/20 seconds

hasValidToken,
hostUptimeWarnings,
isMigration: false,
isUndergoingAuthentication: isUndergoingAuthentication,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could just be isUndergoingAuthentication,

Copy link
Copy Markdown
Contributor

@athammer athammer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

few comments but nothing blocking. looks good!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] We don't really use this filename format, getFormSchema.test.tsx would be fine

Comment on lines +41 to +44
fetchPolicy: "no-cache",
// We poll faster than normal because users expect to see
// faster feedback after performing the authentication flow.
pollInterval: skip ? 0 : FASTER_POLL_INTERVAL,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to aaron, I'd suggest creating a separate query entirely from useUser so that you can control polling here without having wide ranging impacts!

@ZackarySantana ZackarySantana requested a review from sophstad April 8, 2026 17:15
@@ -0,0 +1,6 @@
query UserTokenExchange {
user {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also add userId to the query here? A type's ID is always required when it exists

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] Can you name this useUserTokenExchange.ts? For custom hooks we tend to use that pattern

const { schema, uiSchema } = getFormSchema({
...formSchemaInput,
availableRegions: selectedDistro?.availableRegions ?? [],
// No task loading on volume migration, so we don't need to check for a valid token.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] Comment should be moved above tokenExchangeState I think

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this was a remain from the old impl before enums

Comment on lines +66 to +68
const onFocus = () => void refetch();
window.addEventListener("focus", onFocus);
return () => window.removeEventListener("focus", onFocus);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't you remove the onFocus stuff in the previous PR 👀

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This onFocus stuff is making the UI load instantly when I return, so I figured it was pretty neat 🤷 . What do you think?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, could you use useLazyQuery to start polling on quick? I think that should be a pretty straightforward swap! It also supports polling.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I guess the focus hook may still help with the most instantaneous refetch possible. I do like the idea of useLazyQuery but consider it optional!

UserTokenExchangeQuery,
UserTokenExchangeQueryVariables
>(USER_TOKEN_EXCHANGE, {
skip,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use the skipToken pattern please?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! My bad!

@ZackarySantana ZackarySantana requested a review from sophstad April 9, 2026 14:31
@ZackarySantana ZackarySantana merged commit fa9a9cb into main Apr 9, 2026
22 checks passed
@ZackarySantana ZackarySantana deleted the token2 branch April 9, 2026 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants