Skip to content

Commit

Permalink
feat(IT Wallet): [SIW-1630] Identification through direct integration…
Browse files Browse the repository at this point in the history
… with the CieID app (#6545)

## Short description
This PR introduces direct integration with the CieID app during the
Wallet activation phase. When the CieID app is installed on a user's
device, it will be opened directly to authenticate the user. This flow
is particularly optimized for Android, thanks to
`@pagopa/io-react-native-cieid`.

When the app is not installed, identification will be carried on through
a regular web view.

## List of changes proposed in this pull request
- Created `ItwCieIdLoginScreen` to handle the CieID app:
    - Use `openCieIdApp` on Android
    - Use `Linking` on iOS to directly open CieID
    - Fallback to a regular web view when CieID is not installed 
- Removed `ITW_ISSUANCE_REDIRECT_URI_CIE` and always used the same
redirect URI
- Create a function to serialize `Error` in failure reasons for better
debugging
- Moved a few CIE related constants to `utils/cie.ts` for better reuse

## How to test
> [!NOTE]
> Needs testing on iOS.

Test all the identification methods to ensure no regressions were
introduced.

For CieID, test the following:
- Identification with CieID installed → it should directly open the app
- Identification without CieID → it should ask for CieID credentials in
a web view
  • Loading branch information
gispada authored Dec 16, 2024
1 parent 89e1a80 commit 3ac2969
Show file tree
Hide file tree
Showing 26 changed files with 561 additions and 416 deletions.
1 change: 0 additions & 1 deletion .env.local
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ ITW_EAA_PROVIDER_BASE_URL="https://pre.eaa.wallet.ipzs.it"
ITW_EAA_VERIFIER_BASE_URL="https://pre.verify.wallet.ipzs.it"
ITW_GOOGLE_CLOUD_PROJECT_NUMBER="260468725946"
ITW_ISSUANCE_REDIRECT_URI="https://wallet.io.pagopa.it/index.html"
ITW_ISSUANCE_REDIRECT_URI_CIE="iowalletcie://cb"
# Bypass the check that enforces the identity of the issued eID is the same as the authenticated user
ITW_BYPASS_IDENTITY_MATCH=YES
# Use the test environment for the IDP hint for both CIE and SPID
Expand Down
1 change: 0 additions & 1 deletion .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ ITW_EAA_PROVIDER_BASE_URL="https://eaa.wallet.ipzs.it"
ITW_EAA_VERIFIER_BASE_URL="https://verify.wallet.ipzs.it"
ITW_GOOGLE_CLOUD_PROJECT_NUMBER="260468725946"
ITW_ISSUANCE_REDIRECT_URI="https://wallet.io.pagopa.it/index.html"
ITW_ISSUANCE_REDIRECT_URI_CIE="iowalletcie://cb"
# Bypass the check that enforces the identity of the issued eID is the same as the authenticated user
ITW_BYPASS_IDENTITY_MATCH=NO
# Use the test environment for the IDP hint for both CIE and SPID
Expand Down
2 changes: 0 additions & 2 deletions ts/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,6 @@ export const itwWalletProviderBaseUrl = Config.ITW_WALLET_PROVIDER_BASE_URL;
export const itwGoogleCloudProjectNumber =
Config.ITW_GOOGLE_CLOUD_PROJECT_NUMBER;
export const itWalletIssuanceRedirectUri = Config.ITW_ISSUANCE_REDIRECT_URI;
export const itWalletIssuanceRedirectUriCie =
Config.ITW_ISSUANCE_REDIRECT_URI_CIE;
export const itwPidProviderBaseUrl = Config.ITW_PID_PROVIDER_BASE_URL;
export const itwEaaProviderBaseUrl = Config.ITW_EAA_PROVIDER_BASE_URL;
export const itwEaaVerifierBaseUrl = Config.ITW_EAA_VERIFIER_BASE_URL;
Expand Down
10 changes: 6 additions & 4 deletions ts/features/cieLogin/components/CieIdLoginWebView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ import {
HeaderSecondLevelHookProps,
useHeaderSecondLevel
} from "../../../hooks/useHeaderSecondLevel";
import {
CIE_ID_ERROR,
CIE_ID_ERROR_MESSAGE,
IO_LOGIN_CIE_SOURCE_APP,
IO_LOGIN_CIE_URL_SCHEME
} from "../../../utils/cie";

export type WebViewLoginNavigationProps = {
spidLevel: SpidLevel;
Expand All @@ -55,10 +61,6 @@ const originSchemasWhiteList = [
"iologin://*",
...(isDevEnv ? ["http://*"] : [])
];
const IO_LOGIN_CIE_SOURCE_APP = "iologincie";
const IO_LOGIN_CIE_URL_SCHEME = `${IO_LOGIN_CIE_SOURCE_APP}:`;
const CIE_ID_ERROR = "cieiderror";
const CIE_ID_ERROR_MESSAGE = "cieid_error_message=";

const WHITELISTED_DOMAINS = [
"https://idserver.servizicie.interno.gov.it",
Expand Down
23 changes: 3 additions & 20 deletions ts/features/itwallet/common/utils/itwIssuanceUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import uuid from "react-native-uuid";
import {
itwPidProviderBaseUrl,
itWalletIssuanceRedirectUri,
itwIdpHintTest,
itWalletIssuanceRedirectUriCie
itwIdpHintTest
} from "../../../../config";
import { type IdentificationContext } from "../../machine/eid/context";
import { StoredCredential } from "./itwTypesUtils";
Expand All @@ -26,22 +25,8 @@ type AccessToken = Awaited<

type IssuerConf = Parameters<Credential.Issuance.ObtainCredential>[0];

// This can be any URL, as long as it has http or https as its protocol, otherwise it cannot be managed by the webview.
const CIE_L3_REDIRECT_URI = "https://wallet.io.pagopa.it/index.html";
const CREDENTIAL_TYPE = "PersonIdentificationData";

// Different scheme to avoid conflicts with the scheme handled by io-react-native-login-utils's activity
const getRedirectUri = (identificationMode: IdentificationContext["mode"]) => {
switch (identificationMode) {
case "cieId":
return itWalletIssuanceRedirectUriCie;
case "ciePin":
return CIE_L3_REDIRECT_URI;
default:
return itWalletIssuanceRedirectUri;
}
};

type StartAuthFlowParams = {
walletAttestation: string;
identification: IdentificationContext;
Expand All @@ -66,8 +51,6 @@ const startAuthFlow = async ({

const idpHint = getIdpHint(identification);

const redirectUri = getRedirectUri(identification.mode);

const { issuerUrl, credentialType } = startFlow();

const { issuerConf } = await Credential.Issuance.evaluateIssuerTrust(
Expand All @@ -82,7 +65,7 @@ const startAuthFlow = async ({
credentialType,
{
walletInstanceAttestation: walletAttestation,
redirectUri,
redirectUri: itWalletIssuanceRedirectUri,
wiaCryptoContext
}
);
Expand All @@ -101,7 +84,7 @@ const startAuthFlow = async ({
clientId,
codeVerifier,
credentialDefinition,
redirectUri
redirectUri: itWalletIssuanceRedirectUri
};
};

Expand Down
137 changes: 0 additions & 137 deletions ts/features/itwallet/common/utils/itwOpenUrlAndListenForRedirect.ts

This file was deleted.

13 changes: 13 additions & 0 deletions ts/features/itwallet/common/utils/itwStoreUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { GlobalState } from "../../../../store/reducers/types";
import { type CredentialIssuanceFailure } from "../../machine/credential/failure";
import { type IssuanceFailure } from "../../machine/eid/failure";

interface PollForStoreValueOptions<T> {
getState: () => GlobalState;
Expand Down Expand Up @@ -47,3 +49,14 @@ export const pollForStoreValue = <T>({
}
}, interval);
});

/**
* Serialize failure reasons that are instances of {@link Error}, to be safely stored and displayed.
*/
export const serializeFailureReason = (
failure: IssuanceFailure | CredentialIssuanceFailure
) => ({
...failure,
reason:
failure.reason instanceof Error ? failure.reason.message : failure.reason
});
Loading

0 comments on commit 3ac2969

Please sign in to comment.