-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Custom auth/alban/react next sample app signin #7624
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
base: custom-auth/main
Are you sure you want to change the base?
Custom auth/alban/react next sample app signin #7624
Conversation
albanx
commented
Mar 8, 2025
- Completed Sign In sample with NextJs
- [Bug] Created Sign Up but not working due to missing exposure of submitCode in the result.state
- Removed correlationId from Fetch client because it is present already in the header
- Removed HTTPS checks in SDK, it is not needed to be handled by JS and blocks local development
Coded Sign Up but not working
…ple-app-signin # Conflicts: # lib/msal-custom-auth/src/core/network_client/http_client/FetchHttpClient.ts
lib/msal-custom-auth/src/core/network_client/custom_auth_api/BaseApiClient.ts
Outdated
Show resolved
Hide resolved
lib/msal-custom-auth/src/core/network_client/http_client/FetchHttpClient.ts
Outdated
Show resolved
Hide resolved
password, | ||
}); | ||
|
||
if (result.error) { |
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.
IMO, it is better to use following check in the if (xxx).
if (result.state?.type === SignInState.Failed)
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.
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.
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.
Check SignUp return result not 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.
setError(""); | ||
setLoading(true); | ||
|
||
try { |
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.
There is no need the type catch here since the SDK is guaranteed no error thrown
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.
there is a await
promise resolve there, meaning that the try catch is a must of the promise rejects
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.
Afaik, the promise rejection only occurs if an error is thrown and not caught inside the method. But as I said, any API in this SDK is guaranteed no error thrown.
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.
A JavaScript promise has 2 statuses: resolve, reject.
The compiler or javascript cannot know that the SDK internally handles all errors of that away reject.
Without the try-catch, any error of the promise would cause the function to immediately throw an exception and potentially crash.
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.
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 didn't get it. If we guarantee the API will never reject the promise or throw an error, is the try catch still necessary?
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.
You can guarantee it, but JavaScript engine cannot know it. No developer can know it, unless the read the source of the SDK itself.
If I read await something
-> that means it can throw an exception.
samples/msal-custom-auth-samples/react-sample-nextjs/src/app/sign-in/page.tsx
Show resolved
Hide resolved
samples/msal-custom-auth-samples/react-sample-nextjs/src/app/sign-up/page.tsx
Outdated
Show resolved
Hide resolved
const [email, setEmail] = useState(""); | ||
const [code, setCode] = useState(""); | ||
const [error, setError] = useState(""); | ||
const [flowState, setFlowState] = useState<any>(null); |
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.
Instead of using any here, It can set as SignInCompleted | SignInFailed | SignInCodeRequired | SignInPasswordRequired
.
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 points out the point I was making, in terms of S of SOLID.
flowState has many responsibilities and if we update the SDK with a new state, the engineer have to update his integration code, resulting in breaking the backward compatibility exactly because it is breaking the O of open close.
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 tried this does not work
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 it doesn't work? Also we can consider using the AuthFlowStateBase since it is better than any.
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.
Similar suggestion: can we use the base class AuthFlowStateBase
or SignUpCompleted | SignUpFailed | SignUpCodeRequired | SignUpPasswordRequired | SignUpAttributesRequired
to replace any
?
samples/msal-custom-auth-samples/react-sample-nextjs/src/app/sign-up/page.tsx
Outdated
Show resolved
Hide resolved
samples/msal-custom-auth-samples/react-sample-nextjs/src/app/sign-up/page.tsx
Show resolved
Hide resolved
…ple-app-signin # Conflicts: # package-lock.json
Do you think we can move this sample app into the repo Kaushik suggested? I am planning the create the PR to MSAL for JS team soon for checking in the changes into the dev branch. If it is possible, it is better to exclude the sample app in that PR. |
Yes I have moved them partially, not the last version. Otherwise I cannot run them in the repo until the package is published. |
setError("Incorrect password"); | ||
} else { | ||
setError("An error occurred during sign in"); | ||
} |
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.
Maybe I misunderstood, but any reason why you didn't use the handleError
function you defined in the utils/index.ts?
setLoading(true); | ||
|
||
try { | ||
const result = await flowState.submitCode(code); |
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.
As discussed earlier, can you double check whether flowState.submitCode(code)
is working?
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 have ran the sign in different times, it works, unless there has been some recent updates.
const [password, setPassword] = useState(""); | ||
const [code, setCode] = useState(""); | ||
const [error, setError] = useState(""); | ||
const [flowState, setFlowState] = useState<any>(null); |
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.
Do you think it is better to use the state base class AuthFlowStateBase
to replace any
?
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.
Or use SignInCompleted | SignInFailed | SignInCodeRequired | SignInPasswordRequired
?
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.
Can be AuthFlowStateBase
, the later one I really do not recommend. This is how developer experience will look with the latest:
const [flowState, SetFlowState] = useState<
checking docs
I see SignInCompleted
, perfect
const [flowState, SetFlowState] = useState<SignInCompleted>(null)
Ahh wait there is more
const [flowState, SetFlowState] = useState<SignInCompleted | SignInFailed>(null)
no wait more types in or
const [flowState, SetFlowState] = useState<SignInCompleted | SignInFailed | SignInCodeRequired >(null)
(how many possible types in OR I should have, I have to check all of them and find out by reading a long boring documentation)
1 month after the SDK releseas version 2.0 ... Ah crap I have to update all my code again
const [flowState, SetFlowState] = useState<SignInCompleted | SignInFailed | SignInCodeRequired | **ANewSignInState** >(null)
if (flowState instanceOf SignInCompleted)
if (flowState instanceOf SignInFailed )
if (flowState instanceOf SignInCodeRequired )
**if (flowState instanceOf ANewSignInState)**
setLoading(true); | ||
|
||
try { | ||
const app = await CustomAuthPublicClientApplication.create(customAuthConfig); |
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.
IMHO, the app can be shared cross the whole application for sign-in, sign-up and sspr. Is it possible we can use the single instance of app in this sample app?
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.
There is no point and need to share the same app instance for different flows that are not connected in the lifecycle of an app. Imagine Sign Up , Sign In and SSPR as different flows that are separated in time and usage , as it happens in every app (a user does not go through the all flows in the same app cycle). Making this flows sharing the same instance it kind of tight them together for no reason.
<div style={styles.container}> | ||
<h2>Sign Up</h2> | ||
{flowState?.type === SignUpState.CodeRequired ? ( | ||
<CodeForm onSubmit={handleCodeSubmit} code={code} setCode={setCode} loading={loading} /> |
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.
May I ask why we don't have the PasswordForm?
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 is SignUp with OTP does not asks for password which I based on the past samples. That is the configuration of the sample tenant. I can add the password field but it will be optional
Reminder: This PR appears to be stale. If this PR is still a work in progress please mark as draft. |