Skip to content
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

[#172526356] Adds Screen to explain why CIE login is not available #1769

Merged
merged 23 commits into from
Jun 25, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d6ae4e0
Added information screen to explain why cie login is not supported
CrisTofani May 6, 2020
4e278b1
Fixed style and adds Android check to show further informations
CrisTofani May 6, 2020
786a2f9
Merge branch 'master' into 172526356-no-cie-support-screen
CrisTofani May 6, 2020
a635a86
fix lint error
CrisTofani May 6, 2020
8dd4db0
Merge branch 'master' into 172526356-no-cie-support-screen
CrisTofani May 11, 2020
bec700c
change the icons on list
CrisTofani May 11, 2020
3f4942f
Merge branch 'master' into 172526356-no-cie-support-screen
CrisTofani May 12, 2020
c5de974
Merge branch 'master' into 172526356-no-cie-support-screen
CrisTofani May 12, 2020
05798b8
[#172526356] UI of the information in a separated component
CrisTofani May 13, 2020
f7deed5
Merge branch 'master' into 172526356-no-cie-support-screen
CrisTofani May 13, 2020
d5b26f8
Fix in typos and buttons inverted on landing
CrisTofani May 13, 2020
66da00d
Merge branch '172526356-no-cie-support-screen' of github.com:pagopa/i…
CrisTofani May 13, 2020
4451d59
Merge branch 'master' into 172526356-no-cie-support-screen
Undermaken May 13, 2020
a59ef20
Adds conditional order of the 2 buttons to login
CrisTofani May 14, 2020
6533ccb
Fixes on reducer and components
CrisTofani May 14, 2020
2aa5125
Minor edit on texts
CrisTofani May 14, 2020
b9360fb
Merge branch 'master' into 172526356-no-cie-support-screen
Undermaken May 20, 2020
b2ea415
Merge branch 'master' into 172526356-no-cie-support-screen
CrisTofani May 25, 2020
8ad80c1
Merge branch 'master' into 172526356-no-cie-support-screen
CrisTofani May 25, 2020
e9d8632
Merge branch 'master' into 172526356-no-cie-support-screen
CrisTofani Jun 23, 2020
7e69c33
Merge branch 'master' into 172526356-no-cie-support-screen
CrisTofani Jun 23, 2020
18a18de
Merge branch 'master' into 172526356-no-cie-support-screen
Undermaken Jun 25, 2020
3c88387
Merge branch 'master' into 172526356-no-cie-support-screen
Undermaken Jun 25, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions locales/en/cie/cieNotSupported.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
To login you need to have a device with NFC technology or a device compatible with the current implementation (iOS devices are not yet compatible but will soon become compatible with the new update).
1 change: 1 addition & 0 deletions locales/en/cie/cieNotSupported_android.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Specifically, the cases in which you **cannot** access with an Electronic Identity Card (CIE) on your Android device are:
6 changes: 6 additions & 0 deletions locales/en/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ spid:
line2: Insert your email address to enable it.
authentication:
landing:
cie_unsupported:
title: Accesso con CIE non disponibile
body: !include cie/cieNotSupported.md
android_desc: !include cie/cieNotSupported_android.md
os_version_unsupported: your operating system does not have a version compatible with CIE authentication
nfc_incompatible: your device does not have an NFC antenna compatible with CIE authentication
contentTitleCie: Don't have SPID or CIE?
cie_information_request: !include cie.md
spid_or_cie: To use IO you must have one of these digital tools, which certify your identity.
Expand Down
1 change: 1 addition & 0 deletions locales/it/cie/cieNotSupported.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Per effettuare il login è necessario avere un dispositivo con tecnologia NFC o un dispositivo compatibile con l’attuale implementazione (i dispositivi iOS non sono ancora compatibili ma a breve lo diventeranno con il nuovo aggiornamento).
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Per effettuare il login è necessario avere un dispositivo con tecnologia NFC o un dispositivo compatibile con l’attuale implementazione (i dispositivi iOS non sono ancora compatibili ma a breve lo diventeranno con il nuovo aggiornamento).
Per effettuare il login è necessario avere un dispositivo con tecnologia NFC o un dispositivo compatibile con l’attuale implementazione (i dispositivi iOS non sono ancora compatibili ma a breve lo diventeranno con i prossimi aggiornamenti).

I guess it's more appropriate. In that way the user could expect CIE in iOS on the next release

1 change: 1 addition & 0 deletions locales/it/cie/cieNotSupported_android.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Nello specifico, i casi in cui **non** è possibile accedere con Carta di Identità Elettronica (CIE) su dispositivo Android sono:
6 changes: 6 additions & 0 deletions locales/it/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,12 @@ spid:
line2: Inserisci la tua email per attivarla.
authentication:
landing:
cie_unsupported:
title: Accesso con CIE non disponibile
body: !include cie/cieNotSupported.md
android_desc: !include cie/cieNotSupported_android.md
os_version_unsupported: il tuo sistema operativo non ha una versione compatibile con l'autenticazione tramite CIE
nfc_incompatible: il tuo dispositivo non ha una antenna NFC compatibile con l'autenticazione tramite CIE
contentTitleCie: Non hai SPID o la CIE?
cie_information_request: !include cie.md
spid_or_cie: Per utilizzare IO devi dotarti di uno di questi strumenti digitali, che certificano in maniera certa la tua identità.
Expand Down
45 changes: 44 additions & 1 deletion ts/sagas/cie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import cieManager from "@pagopa/react-native-cie";
import { Millisecond } from "italia-ts-commons/lib/units";
import { SagaIterator } from "redux-saga";
import { call, put, takeLatest } from "redux-saga/effects";
import { cieIsSupported, nfcIsEnabled } from "../store/actions/cie";
import {
cieIsSupported,
hasApiLevelSupport,
hasNFCFeature,
nfcIsEnabled
} from "../store/actions/cie";
import { SagaCallReturnType } from "../types/utils";
import { startTimer } from "../utils/timer";

Expand All @@ -11,6 +16,10 @@ export function* watchCieAuthenticationSaga(): SagaIterator {
yield takeLatest(nfcIsEnabled.request, checkNfcEnablementSaga);
// check if the device is compliant with CIE authentication
yield call(checkCieAvailabilitySaga, cieManager.isCIEAuthenticationSupported);
// check if the device has the API Level compliant with CIE authentication
yield call(checkHasApiLevelSupportSaga, cieManager.hasApiLevelSupport);
// check if the device has the NFC Feature to support CIE authentication
yield call(checkHasNfcFeatureSaga, cieManager.hasNFCFeature);
}

// stop cie manager to listen nfc tags
Expand All @@ -22,6 +31,40 @@ export function* stopCieManager(): SagaIterator {
}
}

/**
* check if the device has the API Level to support CIE authentication
* see https://github.com/pagopa/io-cie-android-sdk/blob/29cc1165bbd3d90d61239369f22ec78b2e4c8f6c/index.js#L155
*/
export function* checkHasApiLevelSupportSaga(
hasApiLevelSupported: typeof cieManager["hasApiLevelSupport"]
): SagaIterator {
try {
const response: SagaCallReturnType<
typeof hasApiLevelSupported
> = yield call(hasApiLevelSupported);
yield put(hasApiLevelSupport.success(response));
} catch (e) {
yield put(hasApiLevelSupport.failure(new Error(e)));
}
}

/**
* check if the device has the NFC Feature to support CIE authentication
* see https://github.com/pagopa/io-cie-android-sdk/blob/29cc1165bbd3d90d61239369f22ec78b2e4c8f6c/index.js#L169
*/
export function* checkHasNfcFeatureSaga(
hasNfcFeatureSupported: typeof cieManager["hasNFCFeature"]
): SagaIterator {
try {
const response: SagaCallReturnType<
typeof hasNfcFeatureSupported
> = yield call(hasNfcFeatureSupported);
yield put(hasNFCFeature.success(response));
} catch (e) {
yield put(hasNFCFeature.failure(new Error(e)));
}
}

/**
* check if the device is compatible with CIE authentication
* see https://github.com/pagopa/io-cie-android-sdk/blob/29cc1165bbd3d90d61239369f22ec78b2e4c8f6c/index.js#L125
Expand Down
128 changes: 109 additions & 19 deletions ts/screens/authentication/LandingScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@
* It includes a carousel with highlights on the app functionalities
*/
import * as pot from "italia-ts-commons/lib/pot";
import { Content, Text, View } from "native-base";
import { Body, Content, List, ListItem, Text, View } from "native-base";
import * as React from "react";
import { StyleSheet } from "react-native";
import { Platform, StyleSheet } from "react-native";
import { NavigationInjectedProps } from "react-navigation";
import { connect } from "react-redux";
import ButtonDefaultOpacity from "../../components/ButtonDefaultOpacity";
import { ContextualHelp } from "../../components/ContextualHelp";
import { DevScreenButton } from "../../components/DevScreenButton";
import { withLightModalContext } from "../../components/helpers/withLightModalContext";
import { HorizontalScroll } from "../../components/HorizontalScroll";
import { LandingCardComponent } from "../../components/LandingCardComponent";
import BaseScreenComponent, {
ContextualHelpPropsMarkdown
} from "../../components/screens/BaseScreenComponent";
import IconFont from "../../components/ui/IconFont";
import { LightModalContextInterface } from "../../components/ui/LightModal";
import Markdown from "../../components/ui/Markdown";
import I18n from "../../i18n";
import { IdentityProvider } from "../../models/IdentityProvider";
import ROUTES from "../../navigation/routes";
Expand All @@ -25,14 +29,20 @@ import {
} from "../../store/actions/authentication";
import { Dispatch } from "../../store/actions/types";
import { isSessionExpiredSelector } from "../../store/reducers/authentication";
import { isCieSupportedSelector } from "../../store/reducers/cie";
import {
hasApiLevelSupportSelector,
hasNFCFeatureSelector,
isCieSupportedSelector
} from "../../store/reducers/cie";
import { GlobalState } from "../../store/reducers/types";
import variables from "../../theme/variables";
import customVariables from "../../theme/variables";
import { ComponentProps } from "../../types/react";
import { isDevEnv } from "../../utils/environment";
import { showToast } from "../../utils/showToast";

type Props = NavigationInjectedProps &
LightModalContextInterface &
ReturnType<typeof mapStateToProps> &
ReturnType<typeof mapDispatchToProps>;

Expand Down Expand Up @@ -89,6 +99,12 @@ const styles = StyleSheet.create({
},
flex: {
flex: 1
},
noCie: {
opacity: 0.35
},
checkboxBackground: {
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems to be not used

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 6533ccb

backgroundColor: "#0073E6"
}
});

Expand Down Expand Up @@ -120,15 +136,86 @@ class LandingScreen extends React.PureComponent<Props> {
}
}

private renderAndroidConditions = () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could it be a component included in its own file?
We should pass to it hasCieApiLevelSupport

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We may create a component for the complete child of the Modal including this block maybe?

          <React.Fragment>
            <Markdown>
              {I18n.t("authentication.landing.cie_unsupported.body")}
            </Markdown>
            {Platform.OS === "android" && this.renderAndroidConditions()}
          </React.Fragment>

we should pass hasCieApiLevelSupport and hasCieNFCFeature too i guess

Copy link
Contributor Author

@CrisTofani CrisTofani May 13, 2020

Choose a reason for hiding this comment

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

@Undermaken
The component is available in #05798b8

return (
<React.Fragment>
<View spacer={true} />
<Markdown>
{I18n.t("authentication.landing.cie_unsupported.android_desc")}
</Markdown>
<View spacer={true} extralarge={true} />
<List>
<ListItem>
<IconFont
name="io-tick-big"
size={16}
color={
this.props.hasCieApiLevelSupport
? customVariables.brandLightGray
: customVariables.contentPrimaryBackground
}
/>
<Body>
<Text>
{I18n.t(
"authentication.landing.cie_unsupported.os_version_unsupported"
)}
</Text>
</Body>
</ListItem>
<ListItem>
<IconFont
name="io-tick-big"
size={16}
color={
this.props.hasCieNFCFeature
? customVariables.brandLightGray
: customVariables.contentPrimaryBackground
}
/>
<Body>
<Text>
{I18n.t(
"authentication.landing.cie_unsupported.nfc_incompatible"
)}
</Text>
</Body>
</ListItem>
</List>
</React.Fragment>
);
};

private openUnsupportedCIEModal = () => {
this.props.showAnimatedModal(
<ContextualHelp
onClose={this.props.hideModal}
title={I18n.t("authentication.landing.cie_unsupported.title")}
body={() => (
<React.Fragment>
<Markdown>
{I18n.t("authentication.landing.cie_unsupported.body")}
</Markdown>
{Platform.OS === "android" && this.renderAndroidConditions()}
</React.Fragment>
)}
/>
);
};

private navigateToMarkdown = () =>
this.props.navigation.navigate(ROUTES.MARKDOWN);

private navigateToIdpSelection = () =>
this.props.navigation.navigate(ROUTES.AUTHENTICATION_IDP_SELECTION);

private navigateToCiePinScreen = () => {
this.props.dispatchIdpCieSelected();
this.props.navigation.navigate(ROUTES.CIE_PIN_SCREEN);
if (this.props.isCieSupported) {
this.props.dispatchIdpCieSelected();
this.props.navigation.navigate(ROUTES.CIE_PIN_SCREEN);
} else {
this.openUnsupportedCIEModal();
}
};

private navigateToSpidCieInformationRequest = () =>
Expand Down Expand Up @@ -162,18 +249,17 @@ class LandingScreen extends React.PureComponent<Props> {
</Content>

<View footer={true}>
{this.props.isCieSupported && (
<ButtonDefaultOpacity
block={true}
primary={true}
iconLeft={true}
onPress={this.navigateToCiePinScreen}
testID={"landing-button-login-cie"}
>
<IconFont name={"io-cie"} color={variables.colorWhite} />
<Text>{I18n.t("authentication.landing.loginCie")}</Text>
</ButtonDefaultOpacity>
)}
<ButtonDefaultOpacity
style={!this.props.isCieSupported ? styles.noCie : undefined}
block={true}
primary={true}
iconLeft={true}
onPress={this.navigateToCiePinScreen}
testID={"landing-button-login-cie"}
>
<IconFont name={"io-cie"} color={variables.colorWhite} />
<Text>{I18n.t("authentication.landing.loginCie")}</Text>
</ButtonDefaultOpacity>
<View spacer={true} />
<ButtonDefaultOpacity
block={true}
Expand Down Expand Up @@ -206,9 +292,13 @@ class LandingScreen extends React.PureComponent<Props> {

const mapStateToProps = (state: GlobalState) => {
const isCIEAuthenticationSupported = isCieSupportedSelector(state);
const hasApiLevelSupport = hasApiLevelSupportSelector(state);
const hasNFCFeature = hasNFCFeatureSelector(state);
return {
isSessionExpired: isSessionExpiredSelector(state),
isCieSupported: pot.getOrElse(isCIEAuthenticationSupported, false)
isCieSupported: pot.getOrElse(isCIEAuthenticationSupported, false),
hasCieApiLevelSupport: pot.getOrElse(hasApiLevelSupport, false),
hasCieNFCFeature: pot.getOrElse(hasNFCFeature, false)
};
};

Expand All @@ -220,4 +310,4 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
export default connect(
mapStateToProps,
mapDispatchToProps
)(LandingScreen);
)(withLightModalContext(LandingScreen));
14 changes: 14 additions & 0 deletions ts/store/actions/cie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@

import { ActionType, createAsyncAction } from "typesafe-actions";

export const hasApiLevelSupport = createAsyncAction(
"CIE_HAS_API_LEVEL_REQUEST",
"CIE_HAS_API_LEVEL_SUCCESS",
"CIE_HAS_API_LEVEL_FAILURE"
)<void, boolean, Error>();

export const hasNFCFeature = createAsyncAction(
"CIE_HAS_NFC_FEATURE_REQUEST",
"CIE_HAS_NFC_FEATURE_SUCCESS",
"CIE_HAS_NFC_FEATURE_FAILURE"
)<void, boolean, Error>();

export const cieIsSupported = createAsyncAction(
"CIE_IS_SUPPORTED_REQUEST",
"CIE_IS_SUPPORTED_SUCCESS",
Expand All @@ -23,6 +35,8 @@ export const updateReadingState = createAsyncAction(
)<void, string, Error>();

export type CieAuthenticationActions =
| ActionType<typeof hasApiLevelSupport>
| ActionType<typeof hasNFCFeature>
| ActionType<typeof cieIsSupported>
| ActionType<typeof nfcIsEnabled>
| ActionType<typeof updateReadingState>;
32 changes: 32 additions & 0 deletions ts/store/reducers/cie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,25 @@ import * as pot from "italia-ts-commons/lib/pot";
import { getType } from "typesafe-actions";
import {
cieIsSupported,
hasApiLevelSupport,
hasNFCFeature,
nfcIsEnabled,
updateReadingState
} from "../actions/cie";
import { Action } from "../actions/types";
import { GlobalState } from "./types";

export type CieState = {
hasApiLevelSupport: pot.Pot<boolean, Error>;
hasNFCFeature: pot.Pot<boolean, Error>;
isCieSupported: pot.Pot<boolean, Error>;
isNfcEnabled: pot.Pot<boolean, Error>;
readingEvent: pot.Pot<string, Error>;
};

const INITIAL_STATE: CieState = {
hasApiLevelSupport: pot.none,
hasNFCFeature: pot.none,
isCieSupported: pot.none,
isNfcEnabled: pot.none,
readingEvent: pot.none
Expand All @@ -38,6 +44,26 @@ export default function cieReducer(
...state,
isCieSupported: pot.toError(state.isCieSupported, action.payload)
};
case getType(hasApiLevelSupport.success):
return {
...state,
hasApiLevelSupport: pot.some(action.payload)
};
case getType(hasApiLevelSupport.failure):
return {
...state,
hasApiLevelSupport: pot.toError(state.isCieSupported, action.payload)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
hasApiLevelSupport: pot.toError(state.isCieSupported, action.payload)
hasApiLevelSupport: pot.toError(state.hasApiLevelSupport, action.payload)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 6533ccb

};
case getType(hasNFCFeature.success):
return {
...state,
hasNFCFeature: pot.some(action.payload)
};
case getType(hasNFCFeature.failure):
return {
...state,
hasNFCFeature: pot.toError(state.isCieSupported, action.payload)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
hasNFCFeature: pot.toError(state.isCieSupported, action.payload)
hasNFCFeature: pot.toError(state.hasNFCFeature, action.payload)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 6533ccb

};
case getType(nfcIsEnabled.success):
return {
...state,
Expand Down Expand Up @@ -66,6 +92,12 @@ export default function cieReducer(
}

// Selectors
export const hasNFCFeatureSelector = (state: GlobalState) =>
state.cie.hasNFCFeature;

export const hasApiLevelSupportSelector = (state: GlobalState) =>
state.cie.hasApiLevelSupport;

export const isCieSupportedSelector = (state: GlobalState) =>
state.cie.isCieSupported;

Expand Down