Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e24ee68
code instruction scaffold
mastro993 Dec 18, 2025
6e63e8b
chore: credential vault
mastro993 Dec 19, 2025
b2e0c7c
refactored vault function and added tests
mastro993 Dec 22, 2025
0535f08
change to ES2019
mastro993 Dec 23, 2025
676c616
tests instructions
mastro993 Dec 23, 2025
ce0e5ef
update vault implementation
mastro993 Dec 24, 2025
836afd1
renamed StoredCredential to CredentialMetadata, added CredentialBundl…
mastro993 Dec 24, 2025
b624d93
revert: remove instructions
mastro993 Dec 24, 2025
b79a7ae
chore: update type
mastro993 Dec 27, 2025
499c321
refactor types
mastro993 Jan 2, 2026
22724ac
refactor actions
mastro993 Jan 5, 2026
5078a34
Merge branch 'master' into SIW-2178-credentials-storage-optimization
mastro993 Jan 5, 2026
d590c12
Merge branch 'master' into SIW-2178-credentials-storage-optimization
mastro993 Jan 21, 2026
2e85333
Adds wallet spec version and verification to credentials
mastro993 Feb 5, 2026
a638da6
Simplifies IT Wallet feature detection and cleans up props
mastro993 Feb 5, 2026
613641d
Simplifies PID status mapping for analytics
mastro993 Feb 5, 2026
b013b01
fix: tsc tears
mastro993 Feb 5, 2026
378e425
fix tests
mastro993 Feb 5, 2026
8244b5f
Merge branch 'master' into SIW-3855-flatten-stored-credentials-metadata
mastro993 Feb 5, 2026
353c546
Merge branch 'master' into SIW-2178-credentials-storage-optimization
mastro993 Feb 6, 2026
d8b255c
Refactors credential construction and verification logic
mastro993 Feb 6, 2026
a7f9756
Merge branch 'SIW-3855-flatten-stored-credentials-metadata' into SIW-…
mastro993 Feb 6, 2026
c82157e
wip
mastro993 Feb 6, 2026
e754cee
wip
mastro993 Feb 6, 2026
b120e47
store credentials
mastro993 Feb 9, 2026
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
21 changes: 10 additions & 11 deletions ts/components/SectionStatus/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
import { IOColors } from "@pagopa/io-app-design-system";
import { fireEvent } from "@testing-library/react-native";
import * as O from "fp-ts/lib/Option";
import configureMockStore from "redux-mock-store";
import { IOColors } from "@pagopa/io-app-design-system";
import I18n from "i18next";
import configureMockStore from "redux-mock-store";
import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig";
import { Config } from "../../../../definitions/content/Config";
import {
LevelEnum,
SectionStatus
} from "../../../../definitions/content/SectionStatus";

import { SectionStatusKey } from "../../../store/reducers/backendStatus/sectionStatus";
import { renderScreenWithNavigationStoreContext } from "../../../utils/testWrapper";
import { openWebUrl } from "../../../utils/url";
import SectionStatusComponent from "../index";
import { PersistedFeaturesState } from "../../../features/common/store/reducers";
import { ItWalletState } from "../../../features/itwallet/common/store/reducers";
import { GlobalState } from "../../../store/reducers/types";
import { CredentialType } from "../../../features/itwallet/common/utils/itwMocksUtils";
import { StoredCredential } from "../../../features/itwallet/common/utils/itwTypesUtils";
import { CredentialMetadata } from "../../../features/itwallet/common/utils/itwTypesUtils";
import { ItwCredentialsState } from "../../../features/itwallet/credentials/store/reducers";
import { setLocale } from "../../../i18n";
import { SectionStatusKey } from "../../../store/reducers/backendStatus/sectionStatus";
import { GlobalState } from "../../../store/reducers/types";
import { renderScreenWithNavigationStoreContext } from "../../../utils/testWrapper";
import { openWebUrl } from "../../../utils/url";
import SectionStatusComponent from "../index";

jest.mock("../../../utils/url");

Expand Down Expand Up @@ -65,7 +64,7 @@ const mockSectionStatusState = (
features: {
itWallet: {
credentials: {
credentials: { [CredentialType.PID]: {} as StoredCredential }
credentials: { [CredentialType.PID]: {} as CredentialMetadata }
} as ItwCredentialsState,
issuance: { integrityKeyTag: O.some("key-tag") }
} as ItWalletState
Expand Down Expand Up @@ -187,7 +186,7 @@ describe("Section Status Component should return null", () => {
features: {
itWallet: {
credentials: {
credentials: { [CredentialType.PID]: {} as StoredCredential }
credentials: { [CredentialType.PID]: {} as CredentialMetadata }
} as ItwCredentialsState,
issuance: { integrityKeyTag: O.some("key-tag") }
} as ItWalletState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,16 @@ import { pipe } from "fp-ts/lib/function";
import { GlobalState } from "../../../../store/reducers/types";
import { itwAuthLevelSelector } from "../../common/store/selectors/preferences";
import { getCredentialStatus } from "../../common/utils/itwCredentialStatusUtils";
import { isItwCredential } from "../../common/utils/itwCredentialUtils";
import { CredentialType } from "../../common/utils/itwMocksUtils";
import {
itwCredentialsEidStatusSelector,
itwCredentialsSelector
} from "../../credentials/store/selectors";
import { itwLifecycleIsITWalletValidSelector } from "../../lifecycle/store/selectors";
import { ItwJwtCredentialStatus } from "../../common/utils/itwTypesUtils";
import { mapPIDStatusToMixpanel } from "../utils";
import {
ItwStatus,
ItwPIDStatus,
ItwCredentialMixpanelStatus,
CREDENTIAL_STATUS_MAP
CREDENTIAL_STATUS_MAP,
ItwCredentialMixpanelStatus
} from "../utils/types";
import { ItwBaseProperties } from "./propertyTypes";

Expand All @@ -27,9 +23,10 @@ export const buildItwBaseProperties = (
state: GlobalState
): ItwBaseProperties => {
const isItwL3 = itwLifecycleIsITWalletValidSelector(state);
const pidStatus = itwCredentialsEidStatusSelector(state);

const ITW_STATUS_V2 = getWalletStatus(state);
const ITW_PID = getPIDMixpanelStatus(state, true);
const ITW_STATUS_V2 = itwAuthLevelSelector(state) ?? "not_active";
const ITW_PID = mapPIDStatusToMixpanel(pidStatus);

const ITW_PG_V3 = getMixpanelCredentialStatus(
CredentialType.DRIVING_LICENSE,
Expand All @@ -53,7 +50,7 @@ export const buildItwBaseProperties = (
*/
const v2Props = !isItwL3
? {
ITW_ID_V2: getPIDMixpanelStatus(state, false),
ITW_ID_V2: mapPIDStatusToMixpanel(pidStatus),
ITW_PG_V2: getMixpanelCredentialStatus(
CredentialType.DRIVING_LICENSE,
state
Expand All @@ -79,32 +76,6 @@ export const buildItwBaseProperties = (
};
};

const getWalletStatus = (state: GlobalState): ItwStatus => {
const authLevel = itwAuthLevelSelector(state);
return authLevel ? authLevel : "not_active";
};

/**
* Returns the PID status for Mixpanel analytics.
* - If `isL3` is true → we consider the status from the current L3 PID (IT Wallet).
* - If `isL3` is false → we use the current eID status.
*/
export const getPIDMixpanelStatus = (
state: GlobalState,
isL3: boolean
): ItwPIDStatus =>
pipe(
isL3
? pipe(
itwLifecycleIsITWalletValidSelector(state),
O.fromPredicate(Boolean),
O.chain(() => O.fromNullable(itwCredentialsEidStatusSelector(state)))
)
: O.fromNullable(itwCredentialsEidStatusSelector(state)),
O.map<ItwJwtCredentialStatus, ItwPIDStatus>(mapPIDStatusToMixpanel),
O.getOrElse((): ItwPIDStatus => "not_available")
);

/**
* Returns the Mixpanel status for a credential type, considering IT Wallet.
* - If `isItwL3` is explicitly false, returns `"not_available"`.
Expand All @@ -121,9 +92,6 @@ const getMixpanelCredentialStatus = (
return "not_available";
}
const credential = itwCredentialsSelector(state)[type];
if (isItwL3 && credential && !isItwCredential(credential)) {
return "not_available";
}

return pipe(
O.fromNullable(credential),
Expand Down
17 changes: 8 additions & 9 deletions ts/features/itwallet/analytics/properties/propertyUpdaters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ import {
isMixpanelInstanceInitialized,
registerSuperProperties
} from "../../../../mixpanel";
import { isItwAnalyticsCredential } from "../utils";
import { isItwAnalyticsCredential, mapPIDStatusToMixpanel } from "../utils";
import { itwCredentialsEidStatusSelector } from "../../credentials/store/selectors";
import {
ItwProfileProperties,
forceUpdateItwProfileProperties
} from "./profileProperties";
import {
buildItwBaseProperties,
getPIDMixpanelStatus
} from "./basePropertyBuilder";
import { buildItwBaseProperties } from "./basePropertyBuilder";
import {
ItwSuperProperties,
buildItwSuperProperties,
Expand Down Expand Up @@ -66,15 +64,16 @@ export const updateItwStatusAndPIDProperties = (state: GlobalState) => {
return;
}

const isItwL3 = itwLifecycleIsITWalletValidSelector(state);
const eIDStatus = !isItwL3 ? getPIDMixpanelStatus(state, false) : undefined;
const pidStatus = getPIDMixpanelStatus(state, true);
const pidStatus = itwCredentialsEidStatusSelector(state);

const baseProps = {
ITW_STATUS_V2: authLevel,
ITW_PID: pidStatus
ITW_PID: mapPIDStatusToMixpanel(pidStatus)
};

const isItwL3 = itwLifecycleIsITWalletValidSelector(state);
const eIDStatus = !isItwL3 ? mapPIDStatusToMixpanel(pidStatus) : undefined;

forceUpdateItwProfileProperties({
...baseProps,
...(eIDStatus ? { ITW_ID_V2: eIDStatus } : {})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
handleCredentialStoredAnalytics,
handleCredentialRemovedAnalytics
} from "../credentialAnalyticsHandlers";
import { StoredCredential } from "../../../common/utils/itwTypesUtils";
import { CredentialMetadata } from "../../../common/utils/itwTypesUtils";
import { CredentialType } from "../../../common/utils/itwMocksUtils";

jest.mock("../../properties/propertyUpdaters", () => ({
Expand All @@ -27,35 +27,36 @@ jest.mock("../../properties/propertyUpdaters", () => ({

const expirationClaim = { value: "2100-09-04", name: "exp" };
const jwtExpiration = "2100-09-04T00:00:00.000Z";
const mockedEid: StoredCredential = {
credential: "",
const mockedEid: CredentialMetadata = {
credentialType: CredentialType.PID,
credentialId: "dc_sd_jwt_PersonIdentificationData",
parsedCredential: {
expiry_date: expirationClaim
},
format: "dc+sd-jwt",
keyTag: "1",
issuerConf: {} as StoredCredential["issuerConf"],
issuerConf: {} as CredentialMetadata["issuerConf"],
jwt: {
issuedAt: "2024-09-30T07:32:49.000Z",
expiration: jwtExpiration
}
},
spec_version: "1.0.0"
};
const mockedMdl: StoredCredential = {
credential: "",

const mockedMdl: CredentialMetadata = {
credentialType: CredentialType.DRIVING_LICENSE,
credentialId: "dc_sd_jwt_mDL",
parsedCredential: {
expiry_date: expirationClaim
},
format: "dc+sd-jwt",
keyTag: "2",
issuerConf: {} as StoredCredential["issuerConf"],
issuerConf: {} as CredentialMetadata["issuerConf"],
jwt: {
issuedAt: "2024-09-30T07:32:49.000Z",
expiration: jwtExpiration
}
},
spec_version: "1.0.0"
};

const store: DeepPartial<GlobalState> = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
} from "../properties/propertyUpdaters";
import { getMixPanelCredential } from "../utils";
import { MixPanelCredential } from "../utils/types";
import { StoredCredential } from "../../common/utils/itwTypesUtils";
import { GlobalState } from "../../../../store/reducers/types";
import { CredentialMetadata } from "../../common/utils/itwTypesUtils";

const MIXPANEL_EID_CREDENTIALS: ReadonlySet<MixPanelCredential> = new Set([
"ITW_PID",
Expand Down Expand Up @@ -71,7 +71,7 @@ export function* handleCredentialRemovedAnalytics(
}

function getAnalyticsCredentialFromStored(
credentials: ReadonlyArray<StoredCredential>,
credentials: ReadonlyArray<CredentialMetadata>,
isItwL3: boolean
): MixPanelCredential | undefined {
if (credentials.length === 0) {
Expand Down
2 changes: 1 addition & 1 deletion ts/features/itwallet/analytics/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ItwPIDStatus, MixPanelCredential, CREDENTIALS_MAP } from "./types";
* Maps an PID status to its corresponding Mixpanel tracking status.
*/
export const mapPIDStatusToMixpanel = (
status: ItwJwtCredentialStatus
status: ItwJwtCredentialStatus | undefined
): ItwPIDStatus => {
switch (status) {
case "valid":
Expand Down
Loading
Loading