Hi,
have you look at this?
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
for my SPA , i 'am using msal for authentification. i got this error :
BrowserAuthError: interaction_in_progress: Interaction is currently in progress. Please ensure that this interaction has been completed before calling an interactive API. For more visit: aka.ms/msaljs/browser-errors.
at BrowserAuthError.AuthError [as constructor] (AuthError.ts:77:1)
at new BrowserAuthError (BrowserAuthError.ts:227:1)
at BrowserAuthError.createInteractionInProgressError (BrowserAuthError.ts:303:1)
at BrowserCacheManager.setInteractionInProgress (BrowserCacheManager.ts:1026:1)
at ClientApplication.preflightInteractiveRequest (ClientApplication.ts:861:1)
at ClientApplication.preflightBrowserEnvironmentCheck (ClientApplication.ts:845:1)
at PublicClientApplication.<anonymous> (ClientApplication.ts:301:1)
at step (gradeVideoWithMsal.jsx:77:1)
at Object.next (gradeVideoWithMsal.jsx:77:1)
at gradeVideoWithMsal.jsx:77:1
this is my index.jsx :
and this is is my app.jsx :
const { instance } = useMsal();
useEffect(() => {
const callbackId = instance.addEventCallback((event) => {
if (
(event.eventType === EventType.LOGIN_SUCCESS ||
event.eventType === EventType.ACQUIRE_TOKEN_SUCCESS) &&
event.payload.account
) {
if (
compareIssuingPolicy(
event.payload.idTokenClaims,
b2cPolicies.names.editProfile
)
) {
// retrieve the account from initial sing-in to the app
const originalSignInAccount = instance
.getAllAccounts()
.find(
(account) =>
account.idTokenClaims.oid === event.payload.idTokenClaims.oid &&
account.idTokenClaims.sub === event.payload.idTokenClaims.sub &&
compareIssuingPolicy(
account.idTokenClaims,
b2cPolicies.names.signUpSignIn
)
);
let signUpSignInFlowRequest = {
authority: b2cPolicies.authorities.signUpSignIn.authority,
account: instance.getActiveAccount(),
};
// silently login again with the signUpSignIn policy
instance.ssoSilent(signUpSignInFlowRequest);
}
if (
compareIssuingPolicy(
event.payload.idTokenClaims,
b2cPolicies.names.forgotPassword
)
) {
let signUpSignInFlowRequest = {
authority: b2cPolicies.authorities.signUpSignIn.authority,
scopes: [
...protectedResources.apiVideo.scopes.read,
...protectedResources.apiVideo.scopes.write,
...protectedResources.apiSpeech.scopes.read,
...protectedResources.apiSpeech.scopes.write,
...protectedResources.apiAdminVideo.scopes.read,
...protectedResources.apiAdminVideo.scopes.write,
],
};
instance.loginRedirect(signUpSignInFlowRequest);
}
}
if (event.eventType === EventType.LOGIN_FAILURE) {
console.log("we are here")
// Check for forgot password error
// Learn more about AAD error codes at https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes
if (event.error && event.error.errorMessage.includes("AADB2C90118")) {
const resetPasswordRequest = {
authority: b2cPolicies.authorities.forgotPassword.authority,
scopes: [],
};
instance.loginRedirect(resetPasswordRequest);
}
}
});
return () => {
if (callbackId) {
instance.removeEventCallback(callbackId);
}
};
// eslint-disable-next-line
}, [instance]);
and this is my navigation bar : in where i handle sign in , navigation bar is a component of home page , which url is http://localhost:3000 which is a correct redirect uri :
export const NavigationBar = () => {
const { instance, inProgress } = useMsal();
let activeAccount;
console.log(inProgress)
if (instance) {
console.log(instance)
activeAccount = instance.getActiveAccount();
}
const userEmail = activeAccount?.idTokenClaims?.emails?.[0]; // Adjust this depending on the actual structure of your idTokenClaims
const emailDomain = userEmail?.split('@')[1];
const handleLoginRedirect = () => {
console.log(inProgress)
instance.loginRedirect(loginRequest).catch((error) => console.log(error));
};
const handleLogoutRedirect = () => {
instance.logoutRedirect();
};
return (
<>
<Navbar style={{ backgroundColor: '#039d90' }} variant="dark" className="navbarStyle">
<a className="navbar-brand" href="/">
XGOL
</a>
<AuthenticatedTemplate>
{emailDomain === 'xgol.pro' ? (
<>
<Nav.Link className="navbarButton" href="/records/processed">
processed speeches
</Nav.Link>
<Nav.Link className="navbarButton" href="/records/unprocessed">
unprocessed speeches
</Nav.Link>
<div className="collapse navbar-collapse justify-content-end">
<DropdownButton
variant="warning"
drop="start"
title={activeAccount && activeAccount.name ? activeAccount.name : 'Unknown'}
>
<Dropdown.Item as="button" onClick={handleLogoutRedirect}>
Sign out using Redirect
</Dropdown.Item>
</DropdownButton>
</div>
</>
) : (
<>
<Nav.Link className="navbarButton" href="/recordSpeech">
Record Video
</Nav.Link>
<Nav.Link className="navbarButton" href="/records">
My videos
</Nav.Link>
<Nav.Link className="navbarButton" href="/addSpeech">
Add Speech
</Nav.Link>
<div className="collapse navbar-collapse justify-content-end">
<DropdownButton
variant="warning"
drop="start"
title={activeAccount && activeAccount.name ? activeAccount.name : 'Unknown'}
>
<Dropdown.Item as="button" onClick={handleLogoutRedirect}>
Sign out using Redirect
</Dropdown.Item>
</DropdownButton>
</div>
</>
)}
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<div className="collapse navbar-collapse justify-content-end">
<DropdownButton variant="secondary" className="ml-auto" drop="start" title="Sign In">
<Dropdown.Item as="button" onClick={handleLoginRedirect}>
Sign in using Redirect
</Dropdown.Item>
</DropdownButton>
</div>
</UnauthenticatedTemplate>
</Navbar>
</>
to fetch some data for my api i have the following hook :
/**
* Custom hook to call a web API using bearer token obtained from MSAL
* @param {PopupRequest} msalRequest
* @returns
*/
const useFetchWithMsal = (msalRequest) => {
const { instance, inProgress } = useMsal();
console.log(inProgress)
const dispatch = useDispatch()
const error = "Unexpected error has occured! Try Later again"
const { result, error: msalError } = useMsalAuthentication(InteractionType.Popup, {
...msalRequest,
account: instance.getActiveAccount(),
redirectUri: '/redirect'
});
/**
* Execute a fetch request with the given options
* @param {string} method: GET, POST, PUT, DELETE
* @param {String} endpoint: The endpoint to call
* @param {Object} data: The data to send to the endpoint, if any
* @returns JSON response
*/
const execute = async (method, endpoint, data = null) => {
if (msalError) {
dispatch(gradeVideoFail(error))
return;
}
if (result) {
try {
let response = null;
dispatch(gradeVideoRequest())
const headers = new Headers();
const bearer = `Bearer ${result.accessToken}`;
headers.append("Authorization", bearer);
if (data) headers.append('Content-Type', 'application/json');
let options = {
method: method,
headers: headers,
body: data ? JSON.stringify(data) : null,
};
response = await (await fetch(endpoint, options)).json();
dispatch(gradeVideoSuccess(response))
if (response.error) {
dispatch(gradeVideoFail(response.error));
} else {
dispatch(gradeVideoSuccess(response))
}
} catch (e) {
dispatch(gradeVideoFail(error))
throw e;
}
}
};
return {
execute: useCallback(execute, [result, msalError,dispatch]), // to avoid infinite calls when inside a `useEffect`
};
};
export default useFetchWithMsal;