-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DCJ-654: Sign-in via OIDC #2667
Conversation
# Conflicts: # src/libs/ajax/Metrics.js
# Conflicts: # src/components/SignInButton.tsx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall looks good, questions relating to tests:
cypress/component/Auth/auth.spec.ts
Outdated
cy.on('fail', (err) => { | ||
return err.message !== Auth.signInError(); | ||
}); | ||
Auth.signIn(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function still seems to be async, does it need to be await
ed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, but await
-ing breaks the test, I think I need to use then
'clientId': 'clientId' | ||
}); | ||
await Auth.initialize(); | ||
Auth.initialize(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function still seems to be async, does it need to be await
ed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was initially confused by this. Cypress gives you a warning if you use async
in beforeEach
:
Cypress Warning: Cypress detected that you returned a promise in a test, but also invoked one or more cy commands inside of that promise.
The test title was:
> Auth Success "before each" hook
While this works in practice, it's often indicative of an anti-pattern. You almost never need to return both a promise and also invoke cy commands.
Cy commands themselves are already promise like, and you can likely avoid the use of the separate Promise.
https://on.cypress.io/returning-promise-and-commands-in-test
@@ -5,7 +5,6 @@ | |||
"hash": "alpha", | |||
"apiUrl": "https://consent.dsde-alpha.broadinstitute.org", | |||
"ontologyApiUrl": "https://consent-ontology.dsde-alpha.broadinstitute.org/", | |||
"clientId": "1020846292598-hd801vsmmbhh97vaf6aar17lu0q2evfj.apps.googleusercontent.com", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought alpha didn't exist anymore? Why do we need this config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This config file name is not important and is, unfortunately, an artifact of our build image process. Originally, it did reference real environment variables. I'll change this in a separate PR/ticket.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created https://broadworkbench.atlassian.net/browse/DCJ-678 to cover this bit of tech debt.
@@ -139,11 +102,15 @@ export const SignInButton = (props: SignInButtonProps) => { | |||
const registerAndRedirectNewUser = async (redirectTo: string, shouldRedirect: boolean) => { | |||
const registeredUser: DuosUser = await User.registerUser(); | |||
setUserRoleStatuses(registeredUser, Storage); | |||
await onSignIn(); | |||
await syncSignInOrRegistrationEvent(eventList.userRegister); | |||
history.push(`/tos_acceptance${shouldRedirect ? `?redirectTo=${redirectTo}` : ''}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why move this line from syncSignInOrRegistrationEvent to here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My goal with syncSignInOrRegistrationEvent
was to isolate the Metrics calls. I wanted that to remain short and focused. Since the history modification is not related to that functionality, I pulled it out so it would be more clear as to where it is being used. What I found in going through this code is that there was a lot of dual-function helper methods that were very confusing to debug, especially the new user registration piece. By isolating functionality, I was better able to log and reason about what was happening in the different cases.
import {unregister} from './registerServiceWorker'; | ||
import {BrowserRouter} from 'react-router-dom'; | ||
|
||
const load = async () => { | ||
unregister(); | ||
await Auth.initialize(); | ||
if (window.location.pathname.startsWith('/redirect-from-oauth')) { | ||
await OidcBroker.getUserManager().signinPopupCallback(window.location.href); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great question. In the original version of this work, there was a whole component dedicated to servicing this single path. This is my attempt to simplify it. In short, it does this:
- The OIDC client calls a popup window with a redirect url here: https://github.com/DataBiosphere/duos-ui/pull/2667/files#diff-c22f0b724cae791bb887d11ce9ada280a1581625e133634e5c2356a5637d6980L42
- The user goes through the auth dance and is redirected to that url, but the popup doesn't go away.
- On reload, we detect the path
- Call the
signinPopupCallback
which does two things- It closes the open popup
- Redirects the user to the original href, which is either the home page, or a sub-page inside the app to which we redirect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to add some comments around this for future devs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall, looks good! Just a couple questions for my own understanding
Addresses
https://broadworkbench.atlassian.net/browse/DCJ-654
Summary
This PR completes the efforts started in #2611 and #2657. This replaces Google Sign-in with Oidc sign-in.
oidc-client-ts
library for sign-inFull Screen
Minimized Screen
Our (current) B2C Tenant Screen
This will be changed to a DUOS version in https://broadworkbench.atlassian.net/browse/DCJ-165
Have you read Terra's Contributing Guide lately? If not, do that first.