@smileid/usesmileid 12.0.0 → 12.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/core/exception/agent_mode_with_enhanced_liveness_exception.d.ts +11 -0
- package/dist/core/exception/agent_mode_with_enhanced_liveness_exception.d.ts.map +1 -0
- package/dist/core/exception/agent_mode_with_enhanced_liveness_exception.js +17 -0
- package/dist/core/exception/agent_mode_with_enhanced_liveness_exception.js.map +1 -0
- package/dist/core/exception/capture_validation_exceptions.d.ts +1 -0
- package/dist/core/exception/capture_validation_exceptions.d.ts.map +1 -1
- package/dist/core/exception/capture_validation_exceptions.js +1 -0
- package/dist/core/exception/capture_validation_exceptions.js.map +1 -1
- package/dist/core/exception/index.d.ts +1 -0
- package/dist/core/exception/index.d.ts.map +1 -1
- package/dist/core/exception/index.js +1 -0
- package/dist/core/exception/index.js.map +1 -1
- package/dist/core/exception/use_smile_id_error_code.d.ts +1 -0
- package/dist/core/exception/use_smile_id_error_code.d.ts.map +1 -1
- package/dist/core/exception/use_smile_id_error_code.js +1 -0
- package/dist/core/exception/use_smile_id_error_code.js.map +1 -1
- package/dist/core/models/config.d.ts +19 -0
- package/dist/core/models/config.d.ts.map +1 -1
- package/dist/core/models/document_type.d.ts +1 -1
- package/dist/core/models/document_type.d.ts.map +1 -1
- package/dist/core/models/document_type.js +2 -2
- package/dist/core/models/document_type.js.map +1 -1
- package/dist/core/models/global_privacy_control.d.ts +36 -0
- package/dist/core/models/global_privacy_control.d.ts.map +1 -0
- package/dist/core/models/global_privacy_control.js +39 -0
- package/dist/core/models/global_privacy_control.js.map +1 -0
- package/dist/core/models/network_config.d.ts +2 -2
- package/dist/core/models/network_config.js +2 -2
- package/dist/data/api/interceptors/smile_auth_interceptor.d.ts.map +1 -1
- package/dist/data/api/interceptors/smile_auth_interceptor.js +3 -17
- package/dist/data/api/interceptors/smile_auth_interceptor.js.map +1 -1
- package/dist/data/api/smile_id_api.d.ts +1 -1
- package/dist/data/api/smile_id_api.d.ts.map +1 -1
- package/dist/data/dsl/builder/retry_config_builder.d.ts +4 -4
- package/dist/data/dsl/builder/retry_config_builder.d.ts.map +1 -1
- package/dist/data/dsl/builder/retry_config_builder.js +6 -6
- package/dist/data/dsl/builder/retry_config_builder.js.map +1 -1
- package/dist/data/smile_id_urls.d.ts +1 -1
- package/dist/data/smile_id_urls.js +1 -1
- package/dist/data/smile_id_urls.js.map +1 -1
- package/dist/data/util/retry_util.d.ts +1 -1
- package/dist/data/util/retry_util.d.ts.map +1 -1
- package/dist/data/util/retry_util.js +5 -0
- package/dist/data/util/retry_util.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/metadata/builder_configuration.d.ts +5 -0
- package/dist/metadata/builder_configuration.d.ts.map +1 -1
- package/dist/metadata/builder_configuration.js +1 -0
- package/dist/metadata/builder_configuration.js.map +1 -1
- package/dist/metadata/metadata_configuration_mappers.d.ts +2 -3
- package/dist/metadata/metadata_configuration_mappers.d.ts.map +1 -1
- package/dist/metadata/metadata_configuration_mappers.js +13 -6
- package/dist/metadata/metadata_configuration_mappers.js.map +1 -1
- package/dist/metadata/use_smile_id_metadata_factory.d.ts.map +1 -1
- package/dist/metadata/use_smile_id_metadata_factory.js +14 -5
- package/dist/metadata/use_smile_id_metadata_factory.js.map +1 -1
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_clip.d.ts +5 -2
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_clip.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_clip.js +8 -3
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_clip.js.map +1 -1
- package/dist/presentation/components/use_smile_id_instructions_hero.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_instructions_hero.js +8 -3
- package/dist/presentation/components/use_smile_id_instructions_hero.js.map +1 -1
- package/dist/presentation/flow/dsl/builder/config_builder.d.ts +16 -0
- package/dist/presentation/flow/dsl/builder/config_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/builder/config_builder.js +18 -0
- package/dist/presentation/flow/dsl/builder/config_builder.js.map +1 -1
- package/dist/presentation/flow/dsl/builder/screens_builder.d.ts +3 -6
- package/dist/presentation/flow/dsl/builder/screens_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/builder/screens_builder.js +3 -6
- package/dist/presentation/flow/dsl/builder/screens_builder.js.map +1 -1
- package/dist/presentation/flow/flow_navigation_manager.d.ts +5 -1
- package/dist/presentation/flow/flow_navigation_manager.d.ts.map +1 -1
- package/dist/presentation/flow/flow_navigation_manager.js +7 -1
- package/dist/presentation/flow/flow_navigation_manager.js.map +1 -1
- package/dist/presentation/flow/model/instructions_defaults.d.ts.map +1 -1
- package/dist/presentation/flow/model/instructions_defaults.js +1 -1
- package/dist/presentation/flow/model/instructions_defaults.js.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_capture_screen.d.ts.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_capture_screen.js +13 -3
- package/dist/presentation/flow/screen/orchestrated_capture_screen.js.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_consent_screen.d.ts.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_consent_screen.js +3 -1
- package/dist/presentation/flow/screen/orchestrated_consent_screen.js.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_preview_screen.d.ts.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_preview_screen.js +0 -8
- package/dist/presentation/flow/screen/orchestrated_preview_screen.js.map +1 -1
- package/dist/presentation/flow/use_smile_id_flow.d.ts.map +1 -1
- package/dist/presentation/flow/use_smile_id_flow.js +10 -4
- package/dist/presentation/flow/use_smile_id_flow.js.map +1 -1
- package/dist/presentation/flow/validation/flow_validator.d.ts.map +1 -1
- package/dist/presentation/flow/validation/flow_validator.js +42 -20
- package/dist/presentation/flow/validation/flow_validator.js.map +1 -1
- package/dist/presentation/screen/helpers/capture_ui_state.d.ts +6 -6
- package/dist/presentation/screen/helpers/capture_ui_state.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/capture_ui_state.js +19 -19
- package/dist/presentation/screen/helpers/capture_ui_state.js.map +1 -1
- package/dist/presentation/screen/helpers/ess_turn_haptics.d.ts +2 -2
- package/dist/presentation/screen/helpers/ess_turn_haptics.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/ess_turn_haptics.js +6 -6
- package/dist/presentation/screen/helpers/ess_turn_haptics.js.map +1 -1
- package/dist/presentation/screen/helpers/scan_state_to_overlay_state.d.ts +5 -5
- package/dist/presentation/screen/helpers/scan_state_to_overlay_state.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/scan_state_to_overlay_state.js +11 -11
- package/dist/presentation/screen/helpers/scan_state_to_overlay_state.js.map +1 -1
- package/dist/presentation/screen/helpers/use_capture_orientation_lock.d.ts +13 -3
- package/dist/presentation/screen/helpers/use_capture_orientation_lock.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/use_capture_orientation_lock.js +48 -6
- package/dist/presentation/screen/helpers/use_capture_orientation_lock.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_capture_screen.d.ts +4 -2
- package/dist/presentation/screen/use_smile_id_capture_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_capture_screen.js +36 -15
- package/dist/presentation/screen/use_smile_id_capture_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_consent_screen.d.ts +7 -0
- package/dist/presentation/screen/use_smile_id_consent_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_consent_screen.js +6 -5
- package/dist/presentation/screen/use_smile_id_consent_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_document_back_instructions.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_document_back_instructions.js +5 -13
- package/dist/presentation/screen/use_smile_id_document_back_instructions.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_document_preview_screen.js +1 -1
- package/dist/presentation/screen/use_smile_id_document_preview_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_preview_screen.d.ts +1 -21
- package/dist/presentation/screen/use_smile_id_preview_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_preview_screen.js +3 -14
- package/dist/presentation/screen/use_smile_id_preview_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_processing_screen.js +1 -1
- package/dist/presentation/screen/use_smile_id_processing_screen.js.map +1 -1
- package/dist/presentation/utils/locale_utils.d.ts +10 -4
- package/dist/presentation/utils/locale_utils.d.ts.map +1 -1
- package/dist/presentation/utils/locale_utils.js +13 -5
- package/dist/presentation/utils/locale_utils.js.map +1 -1
- package/dist/testing/fake_face_analyzer.d.ts +43 -0
- package/dist/testing/fake_face_analyzer.d.ts.map +1 -0
- package/dist/testing/fake_face_analyzer.js +52 -0
- package/dist/testing/fake_face_analyzer.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +7 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/scenario_expectations.d.ts +28 -0
- package/dist/testing/scenario_expectations.d.ts.map +1 -0
- package/dist/testing/scenario_expectations.js +65 -0
- package/dist/testing/scenario_expectations.js.map +1 -0
- package/dist/testing/scenario_loader.d.ts +11 -0
- package/dist/testing/scenario_loader.d.ts.map +1 -0
- package/dist/testing/scenario_loader.js +64 -0
- package/dist/testing/scenario_loader.js.map +1 -0
- package/dist/testing/scripted_scan_results.d.ts +17 -0
- package/dist/testing/scripted_scan_results.d.ts.map +1 -0
- package/dist/testing/scripted_scan_results.js +52 -0
- package/dist/testing/scripted_scan_results.js.map +1 -0
- package/package.json +11 -4
- package/src/__tests__/dsl.test.ts +51 -1
- package/src/__tests__/setup_react_native.ts +17 -2
- package/src/__tests__/snapshots/__snapshots__/screens_structural.test.tsx.snap +5261 -0
- package/src/__tests__/snapshots/screens_structural.test.tsx +230 -0
- package/src/camera/__tests__/use_smile_id_camera_system.test.ts +103 -0
- package/src/core/exception/__tests__/builder_validation_exceptions.test.ts +67 -0
- package/src/core/exception/agent_mode_with_enhanced_liveness_exception.ts +20 -0
- package/src/core/exception/capture_validation_exceptions.ts +1 -0
- package/src/core/exception/index.ts +1 -0
- package/src/core/exception/use_smile_id_error_code.ts +1 -0
- package/src/core/models/__tests__/document_type.test.ts +2 -2
- package/src/core/models/__tests__/flow_models.test.ts +26 -0
- package/src/core/models/config.ts +22 -0
- package/src/core/models/document_type.ts +2 -2
- package/src/core/models/global_privacy_control.ts +45 -0
- package/src/core/models/network_config.ts +2 -2
- package/src/data/api/__tests__/smile_id_api.test.ts +1 -1
- package/src/data/api/interceptors/__tests__/gzip_interceptor.test.ts +83 -0
- package/src/data/api/interceptors/smile_auth_interceptor.ts +3 -18
- package/src/data/compression/__tests__/payload_compressor_real_jpeg.test.ts +6 -2
- package/src/data/dsl/builder/__tests__/config_builders.test.ts +62 -0
- package/src/data/dsl/builder/retry_config_builder.ts +6 -6
- package/src/data/factory/__tests__/retry_gzip_mac_composition.test.ts +163 -0
- package/src/data/factory/__tests__/signed_job_submission_headers.test.ts +1 -1
- package/src/data/repository/__tests__/network_retries.test.ts +1 -1
- package/src/data/repository/__tests__/use_smile_id_repository.test.ts +1 -1
- package/src/data/security/__tests__/request_canonicalizer.test.ts +132 -0
- package/src/data/smile_id_urls.ts +1 -1
- package/src/data/util/__tests__/retry_util.test.ts +25 -0
- package/src/data/util/retry_util.ts +9 -1
- package/src/index.ts +6 -4
- package/src/metadata/__tests__/metadata_configuration_mappers.test.ts +39 -0
- package/src/metadata/__tests__/metadata_configuration_objects.test.ts +2 -1
- package/src/metadata/__tests__/metadata_device_context.test.ts +3 -3
- package/src/metadata/__tests__/metadata_device_os_android.test.ts +18 -0
- package/src/metadata/__tests__/metadata_golden_fixture.json +1 -1
- package/src/metadata/__tests__/metadata_payload_golden.test.ts +4 -4
- package/src/metadata/__tests__/use_smile_id_metadata.test.ts +1 -1
- package/src/metadata/builder_configuration.ts +6 -0
- package/src/metadata/metadata_configuration_mappers.ts +21 -7
- package/src/metadata/use_smile_id_metadata_factory.ts +17 -6
- package/src/presentation/assets/si_document_green_book_hero_animation.json +1 -4668
- package/src/presentation/assets/si_document_hero_animation.json +1 -4799
- package/src/presentation/assets/si_document_hero_back_animation.json +1 -2039
- package/src/presentation/assets/si_document_passport_hero_animation.json +1 -14491
- package/src/presentation/assets/si_ess_all_directions_hero_animation.json +1 -0
- package/src/presentation/assets/si_ess_animation_all_directions.json +1 -6589
- package/src/presentation/assets/si_selfie_hero_animation.json +1 -1439
- package/src/presentation/assets/si_smile_to_capture_animation.json +1 -1439
- package/src/presentation/components/__tests__/use_smile_id_enhanced_smart_selfie_clip.test.tsx +9 -4
- package/src/presentation/components/__tests__/use_smile_id_instructions_hero.test.tsx +44 -0
- package/src/presentation/components/use_smile_id_enhanced_smart_selfie_clip.tsx +9 -3
- package/src/presentation/components/use_smile_id_instructions_hero.tsx +10 -0
- package/src/presentation/flow/__tests__/document_flow_navigation.test.ts +3 -3
- package/src/presentation/flow/__tests__/flow_navigation_manager.test.ts +49 -0
- package/src/presentation/flow/dsl/builder/__tests__/config_builder.test.ts +25 -0
- package/src/presentation/flow/dsl/builder/config_builder.ts +21 -0
- package/src/presentation/flow/dsl/builder/screens_builder.ts +3 -6
- package/src/presentation/flow/flow_navigation_manager.ts +6 -1
- package/src/presentation/flow/model/instructions_defaults.ts +1 -1
- package/src/presentation/flow/screen/orchestrated_capture_screen.tsx +18 -3
- package/src/presentation/flow/screen/orchestrated_consent_screen.tsx +5 -0
- package/src/presentation/flow/screen/orchestrated_preview_screen.tsx +0 -12
- package/src/presentation/flow/use_smile_id_flow.tsx +11 -4
- package/src/presentation/flow/validation/__tests__/flow_validator.test.ts +61 -1
- package/src/presentation/flow/validation/flow_validator.ts +55 -26
- package/src/presentation/screen/__tests__/capture_ui_state.test.ts +66 -47
- package/src/presentation/screen/__tests__/ess_turn_haptics.test.ts +15 -11
- package/src/presentation/screen/__tests__/scan_state_to_overlay_state.test.ts +47 -27
- package/src/presentation/screen/__tests__/use_smile_id_capture_screen.test.tsx +176 -14
- package/src/presentation/screen/__tests__/use_smile_id_document_back_instructions.test.tsx +1 -1
- package/src/presentation/screen/__tests__/use_smile_id_preview_screen.test.tsx +10 -40
- package/src/presentation/screen/helpers/__tests__/use_capture_orientation_lock.test.tsx +212 -0
- package/src/presentation/screen/helpers/capture_ui_state.ts +27 -27
- package/src/presentation/screen/helpers/ess_turn_haptics.ts +9 -9
- package/src/presentation/screen/helpers/scan_state_to_overlay_state.ts +13 -13
- package/src/presentation/screen/helpers/use_capture_orientation_lock.ts +69 -7
- package/src/presentation/screen/use_smile_id_capture_screen.tsx +47 -19
- package/src/presentation/screen/use_smile_id_consent_screen.tsx +16 -5
- package/src/presentation/screen/use_smile_id_document_back_instructions.tsx +14 -23
- package/src/presentation/screen/use_smile_id_document_preview_screen.tsx +1 -1
- package/src/presentation/screen/use_smile_id_preview_screen.tsx +13 -45
- package/src/presentation/screen/use_smile_id_processing_screen.tsx +1 -1
- package/src/presentation/utils/__tests__/locale_utils.test.ts +46 -5
- package/src/presentation/utils/locale_utils.ts +13 -4
- package/src/testing/__tests__/fake_face_analyzer.test.ts +42 -0
- package/src/testing/__tests__/scenario_expectations.test.ts +110 -0
- package/src/testing/__tests__/scenario_loader.test.ts +64 -0
- package/src/testing/fake_face_analyzer.ts +82 -0
- package/src/testing/index.ts +15 -0
- package/src/testing/scenario_expectations.ts +87 -0
- package/src/testing/scenario_loader.ts +83 -0
- package/src/testing/scripted_scan_results.ts +66 -0
- package/dist/presentation/components/use_smile_id_face_silhouette_overlay.d.ts +0 -15
- package/dist/presentation/components/use_smile_id_face_silhouette_overlay.d.ts.map +0 -1
- package/dist/presentation/components/use_smile_id_face_silhouette_overlay.js +0 -19
- package/dist/presentation/components/use_smile_id_face_silhouette_overlay.js.map +0 -1
- package/src/presentation/components/use_smile_id_face_silhouette_overlay.tsx +0 -27
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { View } from "react-native";
|
|
4
|
+
import { act, create as createRenderer } from "react-test-renderer";
|
|
5
|
+
import { CaptureType } from "../../core/models/ml_config";
|
|
6
|
+
import { UseSmileIDCaptureContent } from "../../presentation/components/use_smile_id_capture_content";
|
|
7
|
+
import type { UseSmileIDCaptureContentState } from "../../presentation/components/use_smile_id_capture_content";
|
|
8
|
+
import { UseSmileIDConsentScreen } from "../../presentation/screen/use_smile_id_consent_screen";
|
|
9
|
+
import { UseSmileIDDocumentBackInstructions } from "../../presentation/screen/use_smile_id_document_back_instructions";
|
|
10
|
+
import { UseSmileIDDocumentPreviewScreen } from "../../presentation/screen/use_smile_id_document_preview_screen";
|
|
11
|
+
import { UseSmileIDInstructionsScreen } from "../../presentation/screen/use_smile_id_instructions_screen";
|
|
12
|
+
import { UseSmileIDPreviewScreen } from "../../presentation/screen/use_smile_id_preview_screen";
|
|
13
|
+
import { UseSmileIDProcessingScreen } from "../../presentation/screen/use_smile_id_processing_screen";
|
|
14
|
+
import { UseSmileIDFaceOverlay } from "../../presentation/components/use_smile_id_face_overlay";
|
|
15
|
+
import { UseSmileIDDocumentOverlay } from "../../presentation/components/use_smile_id_document_overlay";
|
|
16
|
+
import {
|
|
17
|
+
OVERLAY_STATE_COUNT,
|
|
18
|
+
UseSmileIDOverlayState,
|
|
19
|
+
} from "../../presentation/state/use_smile_id_overlay_state";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Structural snapshots: pin the rendered element tree, not pixels (pixels are
|
|
23
|
+
* the Detox lane's job). Keys follow the `<flow>/<screen>/<state>` contract.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
function render(element: React.ReactElement) {
|
|
27
|
+
let tree!: ReturnType<typeof createRenderer>;
|
|
28
|
+
act(() => {
|
|
29
|
+
tree = createRenderer(element);
|
|
30
|
+
});
|
|
31
|
+
return tree;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const CONTAINER = { containerWidth: 390, containerHeight: 520 } as const;
|
|
35
|
+
|
|
36
|
+
const DOCUMENT_STATES = Object.values(UseSmileIDOverlayState).filter((s) =>
|
|
37
|
+
s.startsWith("DOCUMENT_"),
|
|
38
|
+
);
|
|
39
|
+
const FACE_STATES = Object.values(UseSmileIDOverlayState).filter(
|
|
40
|
+
(s) => !s.startsWith("DOCUMENT_"),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
describe("structural snapshots", () => {
|
|
44
|
+
it("pins the overlay state inventory", () => {
|
|
45
|
+
expect(FACE_STATES.length + DOCUMENT_STATES.length).toBe(
|
|
46
|
+
OVERLAY_STATE_COUNT,
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe("selfie/instructions", () => {
|
|
51
|
+
it("selfie/instructions/default", () => {
|
|
52
|
+
const tree = render(
|
|
53
|
+
<UseSmileIDInstructionsScreen
|
|
54
|
+
onBack={() => {}}
|
|
55
|
+
onContinue={() => {}}
|
|
56
|
+
/>,
|
|
57
|
+
);
|
|
58
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe("selfie/capture overlay", () => {
|
|
63
|
+
it.each(FACE_STATES)("selfie/capture/%s", (state) => {
|
|
64
|
+
const tree = render(
|
|
65
|
+
<UseSmileIDFaceOverlay state={state} progress={0.5} {...CONTAINER} />,
|
|
66
|
+
);
|
|
67
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe("document/capture overlay", () => {
|
|
72
|
+
it.each(DOCUMENT_STATES)("document/capture/%s", (state) => {
|
|
73
|
+
const tree = render(
|
|
74
|
+
<UseSmileIDDocumentOverlay state={state} {...CONTAINER} />,
|
|
75
|
+
);
|
|
76
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe("consent", () => {
|
|
81
|
+
it("consent/default", () => {
|
|
82
|
+
const tree = render(
|
|
83
|
+
<UseSmileIDConsentScreen
|
|
84
|
+
partnerName="Acme Bank"
|
|
85
|
+
partnerPrivacyPolicyUrl="https://usesmileid.com/privacy"
|
|
86
|
+
onAllow={() => {}}
|
|
87
|
+
onDeny={() => {}}
|
|
88
|
+
/>,
|
|
89
|
+
);
|
|
90
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe("document/back_instructions", () => {
|
|
95
|
+
it("document/back_instructions/default", () => {
|
|
96
|
+
const tree = render(
|
|
97
|
+
<UseSmileIDDocumentBackInstructions
|
|
98
|
+
documentTypeDisplayName="National ID"
|
|
99
|
+
onCaptureBack={() => {}}
|
|
100
|
+
allowSkip
|
|
101
|
+
onSkip={() => {}}
|
|
102
|
+
onBack={() => {}}
|
|
103
|
+
/>,
|
|
104
|
+
);
|
|
105
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe("document/preview", () => {
|
|
110
|
+
it("document/preview/default", () => {
|
|
111
|
+
const tree = render(
|
|
112
|
+
<UseSmileIDDocumentPreviewScreen
|
|
113
|
+
documentAspectRatio={1.586}
|
|
114
|
+
onAccept={() => {}}
|
|
115
|
+
onReject={() => {}}
|
|
116
|
+
onClose={() => {}}
|
|
117
|
+
/>,
|
|
118
|
+
);
|
|
119
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Composed capture screen: camera slot + overlay + feedback + controls.
|
|
124
|
+
function renderCaptureContent(
|
|
125
|
+
overrides: Partial<UseSmileIDCaptureContentState>,
|
|
126
|
+
) {
|
|
127
|
+
return render(
|
|
128
|
+
<UseSmileIDCaptureContent
|
|
129
|
+
state={{
|
|
130
|
+
captureType: CaptureType.selfie,
|
|
131
|
+
overlayState: UseSmileIDOverlayState.INSTRUCTION,
|
|
132
|
+
enableEnhancedLiveness: false,
|
|
133
|
+
animationDirection: null,
|
|
134
|
+
poseMatched: false,
|
|
135
|
+
feedbackKey: null,
|
|
136
|
+
showCaptureButton: false,
|
|
137
|
+
...overrides,
|
|
138
|
+
}}
|
|
139
|
+
captureProgress={0}
|
|
140
|
+
cameraPreview={<View testID="camera-slot" />}
|
|
141
|
+
onStartCapture={() => {}}
|
|
142
|
+
startCaptureEnabled={true}
|
|
143
|
+
showAttribution={true}
|
|
144
|
+
onManualShutter={() => {}}
|
|
145
|
+
onGalleryUpload={() => {}}
|
|
146
|
+
/>,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
describe("selfie/capture content", () => {
|
|
151
|
+
it("selfie/capture/start_button", () => {
|
|
152
|
+
const tree = renderCaptureContent({
|
|
153
|
+
overlayState: UseSmileIDOverlayState.INSTRUCTION,
|
|
154
|
+
feedbackKey: "si_start_capture_instruction",
|
|
155
|
+
showCaptureButton: true,
|
|
156
|
+
});
|
|
157
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe("document/capture content", () => {
|
|
162
|
+
const DOCUMENT_VARIANTS: ReadonlyArray<
|
|
163
|
+
[string, Partial<UseSmileIDCaptureContentState>]
|
|
164
|
+
> = [
|
|
165
|
+
["card_front", { documentTypeKind: "genericDocument" }],
|
|
166
|
+
["card_back", { documentTypeKind: "genericDocument", isBackSide: true }],
|
|
167
|
+
// TD3 passport data page ratio (125×88 mm).
|
|
168
|
+
["passport", { documentTypeKind: "passport", knownIdAspectRatio: 1.42 }],
|
|
169
|
+
["green_book", { documentTypeKind: "southAfricaGreenBook" }],
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
it.each(DOCUMENT_VARIANTS)("document/capture/%s", (_name, overrides) => {
|
|
173
|
+
const tree = renderCaptureContent({
|
|
174
|
+
captureType: CaptureType.document,
|
|
175
|
+
overlayState: UseSmileIDOverlayState.IDLE,
|
|
176
|
+
knownIdAspectRatio: 1.586,
|
|
177
|
+
showGalleryUpload: true,
|
|
178
|
+
...overrides,
|
|
179
|
+
});
|
|
180
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it("document/capture/manual_shutter", () => {
|
|
184
|
+
const tree = renderCaptureContent({
|
|
185
|
+
captureType: CaptureType.document,
|
|
186
|
+
overlayState: UseSmileIDOverlayState.DOCUMENT_TOO_FAR,
|
|
187
|
+
feedbackKey: "si_document_too_far",
|
|
188
|
+
documentTypeKind: "genericDocument",
|
|
189
|
+
knownIdAspectRatio: 1.586,
|
|
190
|
+
showManualShutter: true,
|
|
191
|
+
showGalleryUpload: true,
|
|
192
|
+
});
|
|
193
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
describe("selfie/preview", () => {
|
|
198
|
+
it("selfie/preview/default", () => {
|
|
199
|
+
const tree = render(<UseSmileIDPreviewScreen />);
|
|
200
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
describe("selfie/processing", () => {
|
|
205
|
+
it("selfie/processing/loading", () => {
|
|
206
|
+
const tree = render(
|
|
207
|
+
<UseSmileIDProcessingScreen state={{ kind: "loading" }} />,
|
|
208
|
+
);
|
|
209
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it("selfie/processing/success", () => {
|
|
213
|
+
const tree = render(
|
|
214
|
+
<UseSmileIDProcessingScreen
|
|
215
|
+
state={{ kind: "success", message: "Verification submitted" }}
|
|
216
|
+
/>,
|
|
217
|
+
);
|
|
218
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("selfie/processing/failed", () => {
|
|
222
|
+
const tree = render(
|
|
223
|
+
<UseSmileIDProcessingScreen
|
|
224
|
+
state={{ kind: "failed", errorMessage: "Network unavailable" }}
|
|
225
|
+
/>,
|
|
226
|
+
);
|
|
227
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Boundary characterization for `UseSmileIDCameraSystem`'s lifecycle state machine
|
|
5
|
+
* (permission gating, running/streaming flags, lens config, listener fan-out). The
|
|
6
|
+
* frame loop is a vision-camera worklet pinned separately by
|
|
7
|
+
* `use_smile_id_frame_stream.test.ts`. Must hold byte-identically across any
|
|
8
|
+
* camera-implementation swap.
|
|
9
|
+
*/
|
|
10
|
+
const permissions = vi.hoisted(() => ({
|
|
11
|
+
getStatus: vi.fn(),
|
|
12
|
+
request: vi.fn(),
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
vi.mock("../camera_permissions", () => ({
|
|
16
|
+
getCameraPermissionStatus: permissions.getStatus,
|
|
17
|
+
requestCameraPermission: permissions.request,
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
import { CameraLens } from "../camera_lens";
|
|
21
|
+
import { UseSmileIDCameraSystem } from "../use_smile_id_camera_system";
|
|
22
|
+
|
|
23
|
+
describe("UseSmileIDCameraSystem — boundary characterization", () => {
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
permissions.getStatus.mockReset();
|
|
26
|
+
permissions.request.mockReset();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("starts idle with the configured lens", () => {
|
|
30
|
+
const system = new UseSmileIDCameraSystem(CameraLens.back);
|
|
31
|
+
const state = system.getState();
|
|
32
|
+
expect(state.isCameraRunning).toBe(false);
|
|
33
|
+
expect(state.isStreaming).toBe(false);
|
|
34
|
+
expect(state.hasPermission).toBe(false);
|
|
35
|
+
expect(state.currentLens).toBe(CameraLens.back);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("start() runs + streams when permission is already granted (no re-prompt)", async () => {
|
|
39
|
+
permissions.getStatus.mockResolvedValue("granted");
|
|
40
|
+
const system = new UseSmileIDCameraSystem();
|
|
41
|
+
await system.start();
|
|
42
|
+
const state = system.getState();
|
|
43
|
+
expect(state.isCameraRunning).toBe(true);
|
|
44
|
+
expect(state.isStreaming).toBe(true);
|
|
45
|
+
expect(state.hasPermission).toBe(true);
|
|
46
|
+
expect(permissions.request).not.toHaveBeenCalled();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("start() prompts when undetermined, then runs on grant", async () => {
|
|
50
|
+
permissions.getStatus.mockResolvedValue("undetermined");
|
|
51
|
+
permissions.request.mockResolvedValue("granted");
|
|
52
|
+
const system = new UseSmileIDCameraSystem();
|
|
53
|
+
await system.start();
|
|
54
|
+
expect(permissions.request).toHaveBeenCalledTimes(1);
|
|
55
|
+
expect(system.getState().isCameraRunning).toBe(true);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("start() stays off when permission is denied", async () => {
|
|
59
|
+
permissions.getStatus.mockResolvedValue("undetermined");
|
|
60
|
+
permissions.request.mockResolvedValue("denied");
|
|
61
|
+
const system = new UseSmileIDCameraSystem();
|
|
62
|
+
await system.start();
|
|
63
|
+
const state = system.getState();
|
|
64
|
+
expect(state.isCameraRunning).toBe(false);
|
|
65
|
+
expect(state.hasPermission).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("start() after release() throws — a released system is unusable", async () => {
|
|
69
|
+
permissions.getStatus.mockResolvedValue("granted");
|
|
70
|
+
const system = new UseSmileIDCameraSystem();
|
|
71
|
+
system.release();
|
|
72
|
+
await expect(system.start()).rejects.toThrow(/after release/);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("stop() pauses running + streaming without releasing (re-startable)", async () => {
|
|
76
|
+
permissions.getStatus.mockResolvedValue("granted");
|
|
77
|
+
const system = new UseSmileIDCameraSystem();
|
|
78
|
+
await system.start();
|
|
79
|
+
system.stop();
|
|
80
|
+
const state = system.getState();
|
|
81
|
+
expect(state.isCameraRunning).toBe(false);
|
|
82
|
+
expect(state.isStreaming).toBe(false);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("configure() swaps the lens and notifies subscribers", () => {
|
|
86
|
+
const system = new UseSmileIDCameraSystem(CameraLens.front);
|
|
87
|
+
const seenLenses: CameraLens[] = [];
|
|
88
|
+
system.subscribe((state) => seenLenses.push(state.currentLens));
|
|
89
|
+
system.configure({ lens: CameraLens.back });
|
|
90
|
+
expect(system.getState().currentLens).toBe(CameraLens.back);
|
|
91
|
+
expect(seenLenses).toContain(CameraLens.back);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("unsubscribe stops further notifications", async () => {
|
|
95
|
+
permissions.getStatus.mockResolvedValue("granted");
|
|
96
|
+
const system = new UseSmileIDCameraSystem();
|
|
97
|
+
const listener = vi.fn();
|
|
98
|
+
const unsubscribe = system.subscribe(listener);
|
|
99
|
+
unsubscribe();
|
|
100
|
+
await system.start();
|
|
101
|
+
expect(listener).not.toHaveBeenCalled();
|
|
102
|
+
});
|
|
103
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { DuplicateScreenTypeException } from "../duplicate_screen_type_exception";
|
|
4
|
+
import { InvalidSelfieCaptureConfigException } from "../invalid_selfie_capture_config_exception";
|
|
5
|
+
import { LivenessFrameCountException } from "../liveness_frame_count_exception";
|
|
6
|
+
import { UseSmileIDErrorCode } from "../use_smile_id_error_code";
|
|
7
|
+
|
|
8
|
+
/** Typed builder/validation exceptions: pin `errorCode`, message, and `errorDetails`. */
|
|
9
|
+
describe("DuplicateScreenTypeException", () => {
|
|
10
|
+
it("names the duplicated type + indices and freezes the details", () => {
|
|
11
|
+
const exception = new DuplicateScreenTypeException({
|
|
12
|
+
screenType: "consent",
|
|
13
|
+
indices: [0, 3],
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
expect(exception).toBeInstanceOf(Error);
|
|
17
|
+
expect(exception.errorCode).toBe(
|
|
18
|
+
UseSmileIDErrorCode.Builder.DuplicateScreenType,
|
|
19
|
+
);
|
|
20
|
+
expect(exception.message).toContain("consent");
|
|
21
|
+
expect(exception.message).toContain("0, 3");
|
|
22
|
+
expect(exception.errorDetails).toEqual({
|
|
23
|
+
screenType: "consent",
|
|
24
|
+
indices: [0, 3],
|
|
25
|
+
});
|
|
26
|
+
expect(Object.isFrozen(exception.errorDetails?.["indices"])).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("LivenessFrameCountException", () => {
|
|
31
|
+
it("reports expected vs actual frame counts", () => {
|
|
32
|
+
const exception = new LivenessFrameCountException({
|
|
33
|
+
expected: 8,
|
|
34
|
+
actual: 3,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
expect(exception.errorCode).toBe(
|
|
38
|
+
UseSmileIDErrorCode.Validation.ConstraintViolation,
|
|
39
|
+
);
|
|
40
|
+
expect(exception.message).toContain("8");
|
|
41
|
+
expect(exception.message).toContain("3");
|
|
42
|
+
expect(exception.errorDetails).toEqual({ expected: 8, actual: 3 });
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe("InvalidSelfieCaptureConfigException", () => {
|
|
47
|
+
it("omits the reason suffix and details when no reason is given", () => {
|
|
48
|
+
const exception = new InvalidSelfieCaptureConfigException();
|
|
49
|
+
|
|
50
|
+
expect(exception.errorCode).toBe(
|
|
51
|
+
UseSmileIDErrorCode.Builder.InvalidSelfieCaptureConfig,
|
|
52
|
+
);
|
|
53
|
+
expect(exception.message).toContain("configuration is missing");
|
|
54
|
+
expect(exception.errorDetails).toBeUndefined();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("appends the reason and carries it in details when provided", () => {
|
|
58
|
+
const exception = new InvalidSelfieCaptureConfigException({
|
|
59
|
+
reason: "minConfidence out of range",
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
expect(exception.message).toContain("minConfidence out of range");
|
|
63
|
+
expect(exception.errorDetails).toEqual({
|
|
64
|
+
reason: "minConfidence out of range",
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { UseSmileIDBuilderException } from "./use_smile_id_builder_exception";
|
|
2
|
+
import { UseSmileIDErrorCode } from "./use_smile_id_error_code";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Agent mode was combined with enhanced liveness. The head-turn challenge is
|
|
6
|
+
* validated for front-camera capture only, so the two options are mutually
|
|
7
|
+
* exclusive.
|
|
8
|
+
*/
|
|
9
|
+
export class AgentModeWithEnhancedLivenessException extends UseSmileIDBuilderException {
|
|
10
|
+
readonly errorCode =
|
|
11
|
+
UseSmileIDErrorCode.Builder.AgentModeWithEnhancedLiveness;
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
14
|
+
super({
|
|
15
|
+
message: "allowAgentMode is not supported with enableEnhancedLiveness",
|
|
16
|
+
suggestedFix:
|
|
17
|
+
"Disable one of them inside selfie { }: allowAgentMode for rear-camera agent capture, or enableEnhancedLiveness for the head-turn challenge",
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Each concrete class lives in its own file; this module keeps the
|
|
4
4
|
* legacy import path stable.
|
|
5
5
|
*/
|
|
6
|
+
export { AgentModeWithEnhancedLivenessException } from "./agent_mode_with_enhanced_liveness_exception";
|
|
6
7
|
export { InvalidSelfieCaptureConfigException } from "./invalid_selfie_capture_config_exception";
|
|
7
8
|
export { InvalidDocumentCaptureConfigException } from "./invalid_document_capture_config_exception";
|
|
8
9
|
export { InvalidMissingCaptureTypeException } from "./invalid_missing_capture_type_exception";
|
|
@@ -43,6 +43,7 @@ export { MissingCaptureForPreviewException } from "./missing_capture_for_preview
|
|
|
43
43
|
export { DuplicateScreenTypeException } from "./duplicate_screen_type_exception";
|
|
44
44
|
|
|
45
45
|
// Capture-config validation (`capture { }` block).
|
|
46
|
+
export { AgentModeWithEnhancedLivenessException } from "./agent_mode_with_enhanced_liveness_exception";
|
|
46
47
|
export { InvalidSelfieCaptureConfigException } from "./invalid_selfie_capture_config_exception";
|
|
47
48
|
export { InvalidDocumentCaptureConfigException } from "./invalid_document_capture_config_exception";
|
|
48
49
|
export { InvalidMissingCaptureTypeException } from "./invalid_missing_capture_type_exception";
|
|
@@ -24,6 +24,7 @@ export const UseSmileIDErrorCode = {
|
|
|
24
24
|
MissingScreenConfiguration: "BUILDER_MISSING_SCREEN_CONFIG",
|
|
25
25
|
DuplicateScreenType: "BUILDER_DUPLICATE_SCREEN",
|
|
26
26
|
InvalidSelfieCaptureConfig: "BUILDER_INVALID_SELFIE_CONFIG",
|
|
27
|
+
AgentModeWithEnhancedLiveness: "BUILDER_AGENT_MODE_WITH_ENHANCED_LIVENESS",
|
|
27
28
|
InvalidDocumentCaptureConfig: "BUILDER_INVALID_DOCUMENT_CONFIG",
|
|
28
29
|
MissingMLConfiguration: "BUILDER_MISSING_ML_CONFIG",
|
|
29
30
|
MissingNetworkConfiguration: "BUILDER_MISSING_NETWORK_CONFIG",
|
|
@@ -15,11 +15,11 @@ describe("DocumentType presets", () => {
|
|
|
15
15
|
});
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
it("Passport is a landscape,
|
|
18
|
+
it("Passport is a landscape, two-sided document", () => {
|
|
19
19
|
expect(DocumentType.Passport).toEqual({
|
|
20
20
|
kind: "passport",
|
|
21
21
|
displayName: "Passport",
|
|
22
|
-
hasBackSide:
|
|
22
|
+
hasBackSide: true,
|
|
23
23
|
orientation: "Landscape",
|
|
24
24
|
knownAspectRatio: 356 / 272,
|
|
25
25
|
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { FlowStep } from "../flow_step";
|
|
4
|
+
import { HEAD_TURN_DIRECTIONS } from "../head_turn_direction";
|
|
5
|
+
|
|
6
|
+
/** FlowStep + head-turn direction order is load-bearing (nav advances through it); pin it. */
|
|
7
|
+
describe("flow model constants", () => {
|
|
8
|
+
it("FlowStep lists the steps in forward-navigation order", () => {
|
|
9
|
+
expect(FlowStep).toEqual([
|
|
10
|
+
"instructions",
|
|
11
|
+
"consent",
|
|
12
|
+
"permission",
|
|
13
|
+
"capture",
|
|
14
|
+
"preview",
|
|
15
|
+
"processing",
|
|
16
|
+
]);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("HEAD_TURN_DIRECTIONS enumerates the three challenge directions in order", () => {
|
|
20
|
+
expect(HEAD_TURN_DIRECTIONS).toEqual([
|
|
21
|
+
"look_left",
|
|
22
|
+
"look_right",
|
|
23
|
+
"look_up",
|
|
24
|
+
]);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type * as ScreenOrientation from "expo-screen-orientation";
|
|
2
|
+
import type { GlobalPrivacyControl } from "./global_privacy_control";
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Global SDK configuration flags. Snapshot produced by
|
|
3
6
|
* `UseSmileIDConfigBuilder.build()` — every field is populated, with
|
|
@@ -33,4 +36,23 @@ export type ConfigOptions = {
|
|
|
33
36
|
* `docs/Architecture.md § Rollout`.
|
|
34
37
|
*/
|
|
35
38
|
readonly allowOfflineMode: boolean;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Partner-declared consent posture (`global_privacy_control`).
|
|
42
|
+
* `GlobalPrivacyControl.OptOut` (the default) forces the opt-out consent
|
|
43
|
+
* layout universally; `OptIn` keeps the legacy regional mechanics.
|
|
44
|
+
*/
|
|
45
|
+
readonly globalPrivacyControl: GlobalPrivacyControl;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Orientation lock the SDK applies when a capture screen leaves the screen.
|
|
49
|
+
* Defaults to `PORTRAIT_UP`, the posture most hosts pin at their root
|
|
50
|
+
* layout; multi-orientation hosts set `DEFAULT` so the flow releases the
|
|
51
|
+
* clamp instead of leaving the app portrait-only after verification.
|
|
52
|
+
*
|
|
53
|
+
* Optional so a hand-written `ConfigOptions` literal still compiles; the
|
|
54
|
+
* builder always populates it, and an absent value takes the same
|
|
55
|
+
* `PORTRAIT_UP` default at the capture screen.
|
|
56
|
+
*/
|
|
57
|
+
readonly exitOrientations?: ScreenOrientation.OrientationLock;
|
|
36
58
|
};
|
|
@@ -34,7 +34,7 @@ const SOUTH_AFRICA_GREEN_BOOK: DocumentType = Object.freeze({
|
|
|
34
34
|
const PASSPORT: DocumentType = Object.freeze({
|
|
35
35
|
kind: "passport",
|
|
36
36
|
displayName: "Passport",
|
|
37
|
-
hasBackSide:
|
|
37
|
+
hasBackSide: true,
|
|
38
38
|
orientation: "Landscape",
|
|
39
39
|
knownAspectRatio: 356 / 272,
|
|
40
40
|
});
|
|
@@ -51,7 +51,7 @@ export type GenericDocumentArgs = {
|
|
|
51
51
|
export const DocumentType = {
|
|
52
52
|
/** South Africa Green Book — booklet-style, single-side, portrait. */
|
|
53
53
|
SouthAfricaGreenBook: SOUTH_AFRICA_GREEN_BOOK,
|
|
54
|
-
/** Passport —
|
|
54
|
+
/** Passport — landscape data page followed by a back-side capture. */
|
|
55
55
|
Passport: PASSPORT,
|
|
56
56
|
/** Catch-all without a preset; defaults to a landscape, two-sided "Document". */
|
|
57
57
|
GenericDocument(args: GenericDocumentArgs = {}): DocumentType {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Partner-declared Global Privacy Control posture for the consent screen
|
|
3
|
+
* (`global_privacy_control` on the wire).
|
|
4
|
+
*
|
|
5
|
+
* Native mobile platforms expose no OS-level equivalent of the web's GPC
|
|
6
|
+
* signal, so the SDK performs no runtime user-signal tracking: the partner
|
|
7
|
+
* declares the posture once at initialization
|
|
8
|
+
* (`b.config((c) => { c.globalPrivacyControl = ...; })`) and it governs
|
|
9
|
+
* every session.
|
|
10
|
+
*
|
|
11
|
+
* Const-object pattern (see `KameraEventType`-style types): enum ergonomics,
|
|
12
|
+
* string wire format.
|
|
13
|
+
*/
|
|
14
|
+
export const GlobalPrivacyControl = {
|
|
15
|
+
/**
|
|
16
|
+
* Default. Forces the opt-out consent layout universally: consent starts
|
|
17
|
+
* granted (pre-selected) for every session regardless of region — the
|
|
18
|
+
* user unticks to opt out. Regional detection is never consulted.
|
|
19
|
+
*/
|
|
20
|
+
OptOut: "opt-out",
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Legacy regional mechanics: consent starts granted outside the EU and
|
|
24
|
+
* starts ungranted (explicit opt-in required) when the device locale is
|
|
25
|
+
* an EU member state.
|
|
26
|
+
*/
|
|
27
|
+
OptIn: "opt-in",
|
|
28
|
+
} as const;
|
|
29
|
+
export type GlobalPrivacyControl =
|
|
30
|
+
(typeof GlobalPrivacyControl)[keyof typeof GlobalPrivacyControl];
|
|
31
|
+
|
|
32
|
+
/** Configuration key this setting is transported under. */
|
|
33
|
+
export const GLOBAL_PRIVACY_CONTROL_WIRE_KEY = "global_privacy_control";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Parses a wire value ("opt-out" / "opt-in"); anything else falls back to
|
|
37
|
+
* the `OptOut` baseline default.
|
|
38
|
+
*/
|
|
39
|
+
export function globalPrivacyControlFromWire(
|
|
40
|
+
value: string | null | undefined,
|
|
41
|
+
): GlobalPrivacyControl {
|
|
42
|
+
return value === GlobalPrivacyControl.OptIn
|
|
43
|
+
? GlobalPrivacyControl.OptIn
|
|
44
|
+
: GlobalPrivacyControl.OptOut;
|
|
45
|
+
}
|
|
@@ -97,10 +97,10 @@ export type CacheConfig = {
|
|
|
97
97
|
};
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
|
-
* Retry strategy.
|
|
100
|
+
* Retry strategy. `none` is the default.
|
|
101
|
+
* - `none`: one attempt, no retry — `maxAttempts` is forced to 1
|
|
101
102
|
* - `exponential`: `delay = min(initialDelay × multiplier^attempt, maxDelay)` plus `±jitter`
|
|
102
103
|
* - `fixed`: constant `fixedDelay` between attempts
|
|
103
|
-
* - `none`: no retry (`maxAttempts: 1`)
|
|
104
104
|
*/
|
|
105
105
|
export enum RetryStrategy {
|
|
106
106
|
exponential = "exponential",
|
|
@@ -109,7 +109,7 @@ const consent: ConsentInformation = Object.freeze({
|
|
|
109
109
|
// builds this and it travels on every `JobRequest`; the API
|
|
110
110
|
// serializes `request.metadata` as the `metadata` multipart part.
|
|
111
111
|
const metadata = new UseSmileIDMetadata({
|
|
112
|
-
sdkVersion: "12.0.
|
|
112
|
+
sdkVersion: "12.0.1",
|
|
113
113
|
sdk: "react-native-expo",
|
|
114
114
|
deviceOs: "",
|
|
115
115
|
deviceModel: "",
|