Skip to content

Commit

Permalink
Merge branch 'master' into SIW-1933-handle-trustmark-qr-code-errors
Browse files Browse the repository at this point in the history
  • Loading branch information
mastro993 authored Jan 7, 2025
2 parents 36a2ed9 + ecd87bc commit 7321141
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,21 @@ exports[`featuresPersistor should match snapshot 1`] = `
"nativeLogin": {
"enabled": true,
},
"spidLogin": {
"nativeLogin": {
"requestInfo": {
"nativeAttempts": 0,
"requestState": "LOADING",
},
},
"standardLogin": {
"requestInfo": {
"requestState": {
"kind": "PotNoneLoading",
},
},
},
},
"testLogin": {
"kind": "idle",
},
Expand Down
8 changes: 7 additions & 1 deletion ts/features/common/store/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,18 @@ import {
landingScreenBannersReducer,
LandingScreenBannerState
} from "../../../landingScreenMultiBanner/store/reducer";
import {
spidLoginReducer,
SpidLoginState
} from "../../../spidLogin/store/reducers";

type LoginFeaturesState = {
testLogin: TestLoginState;
nativeLogin: NativeLoginState;
fastLogin: FastLoginState;
cieLogin: CieLoginState & PersistPartial;
loginInfo: LoginInfoState;
spidLogin: SpidLoginState;
};

export type FeaturesState = {
Expand Down Expand Up @@ -96,7 +101,8 @@ const rootReducer = combineReducers<FeaturesState, Action>({
nativeLogin: nativeLoginReducer,
fastLogin: fastLoginReducer,
cieLogin: cieLoginPersistor,
loginInfo: loginInfoReducer
loginInfo: loginInfoReducer,
spidLogin: spidLoginReducer
}),
wallet: walletReducer,
fims: fimsReducer,
Expand Down
24 changes: 24 additions & 0 deletions ts/features/spidLogin/store/actions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ActionType, createStandardAction } from "typesafe-actions";
import * as pot from "@pagopa/ts-commons/lib/pot";
import { ErrorType, NativeLoginRequestInfo } from "../../types";

export const setNativeLoginRequestInfo = createStandardAction(
"SET_NATIVE_LOGIN_REQUEST_INFO"
)<NativeLoginRequestInfo>();
export const incrementNativeLoginNativeAttempts = createStandardAction(
"INCREMENT_NATIVE_LOGIN_NATIVE_ATTEMPTS"
)();
export const setStandardLoginRequestState = createStandardAction(
"SET_STNDARD_LOGIN_REQUEST_STATE"
)<pot.Pot<true, ErrorType>>();
export const setStandardLoginInLoadingState = createStandardAction(
"SET_STANDARD_LOGIN_IN_LOADING_STATE"
)();
export const resetSpidLoginState = createStandardAction("RESET_LOGIN_STATE")();

export type SpidConfigActions =
| ActionType<typeof setNativeLoginRequestInfo>
| ActionType<typeof incrementNativeLoginNativeAttempts>
| ActionType<typeof setStandardLoginRequestState>
| ActionType<typeof setStandardLoginInLoadingState>
| ActionType<typeof resetSpidLoginState>;
87 changes: 87 additions & 0 deletions ts/features/spidLogin/store/reducers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { getType } from "typesafe-actions";
import * as pot from "@pagopa/ts-commons/lib/pot";
import { Action } from "../../../../store/actions/types";
import { StandardLoginRequestInfo, NativeLoginRequestInfo } from "../../types";
import {
incrementNativeLoginNativeAttempts,
setStandardLoginRequestState,
setNativeLoginRequestInfo,
setStandardLoginInLoadingState,
resetSpidLoginState
} from "../actions";

export type SpidLoginState = {
nativeLogin: {
requestInfo: NativeLoginRequestInfo;
};
standardLogin: {
requestInfo: StandardLoginRequestInfo;
};
};

const spidLoginInitialState: SpidLoginState = {
nativeLogin: {
requestInfo: {
requestState: "LOADING",
nativeAttempts: 0
}
},
standardLogin: {
requestInfo: {
requestState: pot.noneLoading
}
}
};

export const spidLoginReducer = (
state: SpidLoginState = spidLoginInitialState,
action: Action
): SpidLoginState => {
switch (action.type) {
case getType(setNativeLoginRequestInfo):
return {
...state,
nativeLogin: {
...state.nativeLogin,
requestInfo: action.payload
}
};
case getType(incrementNativeLoginNativeAttempts):
return {
...state,
nativeLogin: {
...state.nativeLogin,
requestInfo: {
requestState: "LOADING",
nativeAttempts: state.nativeLogin.requestInfo.nativeAttempts + 1
}
}
};
case getType(setStandardLoginRequestState):
return {
...state,
standardLogin: {
...state.standardLogin,
requestInfo: {
...state.standardLogin.requestInfo,
requestState: action.payload
}
}
};
case getType(setStandardLoginInLoadingState):
return {
...state,
standardLogin: {
...state.standardLogin,
requestInfo: {
...state.standardLogin.requestInfo,
requestState: pot.noneLoading
}
}
};
case getType(resetSpidLoginState):
return spidLoginInitialState;
default:
return state;
}
};
15 changes: 15 additions & 0 deletions ts/features/spidLogin/store/selectors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createSelector } from "reselect";
import { GlobalState } from "../../../../store/reducers/types";

export const spidLoginSelector = (state: GlobalState) =>
state.features.loginFeatures.spidLogin;

export const nativeLoginRequestInfoSelector = createSelector(
spidLoginSelector,
({ nativeLogin }) => nativeLogin.requestInfo
);

export const standardLoginRequestInfoSelector = createSelector(
spidLoginSelector,
({ standardLogin }) => standardLogin.requestInfo
);
26 changes: 26 additions & 0 deletions ts/features/spidLogin/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as pot from "@pagopa/ts-commons/lib/pot";

export enum ErrorType {
"LOADING_ERROR" = "LOADING_ERROR",
"LOGIN_ERROR" = "LOGIN_ERROR"
}

export type RequestInfoPositiveStates = {
requestState: "LOADING" | "AUTHORIZED" | "AUTHORIZING";
nativeAttempts: number;
};

export type RequestInfoError = {
requestState: "ERROR";
errorType: ErrorType;
errorCodeOrMessage?: string;
nativeAttempts: number;
};

export type NativeLoginRequestInfo =
| RequestInfoPositiveStates
| RequestInfoError;

export type StandardLoginRequestInfo = {
requestState: pot.Pot<true, ErrorType>;
};
23 changes: 17 additions & 6 deletions ts/screens/authentication/AuthErrorScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import { useIONavigation } from "../../navigation/params/AppParamsList";
import ROUTES from "../../navigation/routes";
import { CieIdLoginProps } from "../../features/cieLogin/components/CieIdLoginWebView";
import { AuthenticationParamsList } from "../../navigation/params/AuthenticationParamsList";
import { useIODispatch } from "../../store/hooks";
import {
incrementNativeLoginNativeAttempts,
resetSpidLoginState,
setStandardLoginInLoadingState
} from "../../features/spidLogin/store/actions";
import { UnlockAccessProps } from "./UnlockAccessComponent";
import AuthErrorComponent from "./components/AuthErrorComponent";

Expand All @@ -17,12 +23,11 @@ type CommonAuthErrorScreenProps = {

type SpidProps = {
authMethod: "SPID";
onRetry: () => void;
isNativeLogin?: boolean;
};

type CieIdProps = {
authMethod: "CIE_ID";
onRetry?: () => void;
params: CieIdLoginProps;
};

Expand All @@ -40,6 +45,7 @@ const authScreenByAuthMethod = {
};

const AuthErrorScreen = () => {
const dispatch = useIODispatch();
const route =
useRoute<Route<typeof ROUTES.AUTH_ERROR_SCREEN, AuthErrorScreenProps>>();
const { errorCodeOrMessage, authMethod, authLevel } = route.params;
Expand All @@ -61,17 +67,22 @@ const AuthErrorScreen = () => {
}, [authMethod, route.params]);

const onRetry = useCallback(() => {
if (authMethod === "SPID" || authMethod === "CIE_ID") {
route.params.onRetry?.();
if (authMethod === "SPID") {
dispatch(
route.params.isNativeLogin
? incrementNativeLoginNativeAttempts()
: setStandardLoginInLoadingState()
);
}
navigation.navigate(ROUTES.AUTHENTICATION, getNavigationParams());
}, [authMethod, navigation, route.params, getNavigationParams]);
}, [authMethod, navigation, route.params, getNavigationParams, dispatch]);

const onCancel = useCallback(() => {
dispatch(resetSpidLoginState());
navigation.navigate(ROUTES.AUTHENTICATION, {
screen: ROUTES.AUTHENTICATION_LANDING
});
}, [navigation]);
}, [navigation, dispatch]);

return (
<AuthErrorComponent
Expand Down
46 changes: 24 additions & 22 deletions ts/screens/authentication/IdpLoginScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ import {
handleSendAssistanceLog
} from "../../utils/supportAssistance";
import { getUrlBasepath } from "../../utils/url";
import { standardLoginRequestInfoSelector } from "../../features/spidLogin/store/selectors";
import { setStandardLoginRequestState } from "../../features/spidLogin/store/actions";
import { originSchemasWhiteList } from "./originSchemasWhiteList";

enum ErrorType {
Expand Down Expand Up @@ -79,7 +81,9 @@ const styles = StyleSheet.create({
*/
const IdpLoginScreen = () => {
const dispatch = useIODispatch();
const { navigate } = useIONavigation();
// The choice was made to use `replace` instead of `navigate` because the former unmounts the current screen,
// ensuring the re-execution of the `useLollipopLoginSource` hook.
const { replace } = useIONavigation();
const selectedIdp = useIOSelector(selectedIdentityProviderSelector, _isEqual);
const selectedIdpTextData = useIOSelector(
idpContextualHelpDataFromIdSelector(selectedIdp?.id),
Expand All @@ -95,25 +99,27 @@ const IdpLoginScreen = () => {
_isEqual
);

const [requestState, setRequestState] = useState<pot.Pot<true, ErrorType>>(
pot.noneLoading
);
const { requestState } = useIOSelector(standardLoginRequestInfoSelector);
const [errorCodeOrMessage, setErrorCodeOrMessage] = useState<
string | undefined
>(undefined);
const [loginTrace, setLoginTrace] = useState<string | undefined>(undefined);

const setRequestState = useCallback(
(req: pot.Pot<true, ErrorType>) => {
dispatch(setStandardLoginRequestState(req));
},
[dispatch]
);

const handleOnLollipopCheckFailure = useCallback(() => {
setRequestState(pot.noneError(ErrorType.LOGIN_ERROR));
}, []);
}, [setRequestState]);

const idpId = loggedOutWithIdpAuth?.idp.id;
const loginUri = idpId ? getIdpLoginUri(idpId, 2) : undefined;
const {
retryLollipopLogin,
shouldBlockUrlNavigationWhileCheckingLollipop,
webviewSource
} = useLollipopLoginSource(handleOnLollipopCheckFailure, loginUri);
const { shouldBlockUrlNavigationWhileCheckingLollipop, webviewSource } =
useLollipopLoginSource(handleOnLollipopCheckFailure, loginUri);

const choosenTool = useMemo(
() => assistanceToolRemoteConfig(assistanceToolConfig),
Expand All @@ -138,7 +144,7 @@ const IdpLoginScreen = () => {
setRequestState(pot.noneError(ErrorType.LOADING_ERROR));
}
},
[loggedOutWithIdpAuth?.idp.id]
[loggedOutWithIdpAuth?.idp.id, setRequestState]
);

const handleLoginFailure = useCallback(
Expand Down Expand Up @@ -170,7 +176,7 @@ const IdpLoginScreen = () => {
setRequestState(pot.noneError(ErrorType.LOGIN_ERROR));
setErrorCodeOrMessage(code || message);
},
[dispatch, choosenTool, idp]
[dispatch, choosenTool, idp, setRequestState]
);

const handleLoginSuccess = useCallback(
Expand All @@ -183,11 +189,6 @@ const IdpLoginScreen = () => {
[choosenTool, dispatch, idp]
);

const onRetryButtonPressed = useCallback((): void => {
setRequestState(pot.noneLoading);
retryLollipopLogin();
}, [retryLollipopLogin]);

const handleNavigationStateChange = useCallback(
(event: WebViewNavigation) => {
const url = event.url;
Expand All @@ -212,7 +213,7 @@ const IdpLoginScreen = () => {
event.loading || isAssertion ? pot.noneLoading : pot.some(true)
);
},
[dispatch, loginTrace]
[dispatch, loginTrace, setRequestState]
);

const handleShouldStartLoading = useCallback(
Expand Down Expand Up @@ -265,16 +266,17 @@ const IdpLoginScreen = () => {
};

const navigateToAuthErrorScreen = useCallback(() => {
navigate(ROUTES.AUTHENTICATION, {
// The choice was made to use `replace` instead of `navigate` because the former unmounts the current screen,
// ensuring the re-execution of the `useLollipopLoginSource` hook.
replace(ROUTES.AUTHENTICATION, {
screen: ROUTES.AUTH_ERROR_SCREEN,
params: {
errorCodeOrMessage,
authMethod: "SPID",
authLevel: "L2",
onRetry: onRetryButtonPressed
authLevel: "L2"
}
});
}, [errorCodeOrMessage, onRetryButtonPressed, navigate]);
}, [errorCodeOrMessage, replace]);

useEffect(() => {
if (pot.isError(requestState)) {
Expand Down
Loading

0 comments on commit 7321141

Please sign in to comment.