@smileid/usesmileid 12.0.0-beta01 → 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 +15 -0
- package/README.md +701 -89
- package/dist/camera/camera_defaults.d.ts +14 -9
- package/dist/camera/camera_defaults.d.ts.map +1 -1
- package/dist/camera/camera_defaults.js +11 -9
- package/dist/camera/camera_defaults.js.map +1 -1
- package/dist/camera/orientation_degrees.d.ts +5 -6
- package/dist/camera/orientation_degrees.d.ts.map +1 -1
- package/dist/camera/orientation_degrees.js +5 -6
- package/dist/camera/orientation_degrees.js.map +1 -1
- 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_capture_mode.d.ts +8 -0
- package/dist/core/models/document_capture_mode.d.ts.map +1 -1
- package/dist/core/models/document_capture_mode.js +24 -0
- package/dist/core/models/document_capture_mode.js.map +1 -1
- package/dist/core/models/document_type.d.ts +2 -2
- package/dist/core/models/document_type.d.ts.map +1 -1
- package/dist/core/models/document_type.js +7 -5
- 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/core/models/result.d.ts +9 -8
- package/dist/core/models/result.d.ts.map +1 -1
- package/dist/core/models/result.js +5 -6
- package/dist/core/models/result.js.map +1 -1
- 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/interceptors/smile_integrity_interceptor.d.ts +11 -0
- package/dist/data/api/interceptors/smile_integrity_interceptor.d.ts.map +1 -1
- package/dist/data/api/interceptors/smile_integrity_interceptor.js +13 -0
- package/dist/data/api/interceptors/smile_integrity_interceptor.js.map +1 -1
- package/dist/data/api/interceptors/smile_request_mac_interceptor.d.ts +8 -0
- package/dist/data/api/interceptors/smile_request_mac_interceptor.d.ts.map +1 -1
- package/dist/data/api/interceptors/smile_request_mac_interceptor.js +11 -0
- package/dist/data/api/interceptors/smile_request_mac_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/compression/compressible_asset.d.ts +41 -0
- package/dist/data/compression/compressible_asset.d.ts.map +1 -0
- package/dist/data/compression/compressible_asset.js +34 -0
- package/dist/data/compression/compressible_asset.js.map +1 -0
- package/dist/data/compression/payload_compression_config.d.ts +36 -0
- package/dist/data/compression/payload_compression_config.d.ts.map +1 -0
- package/dist/data/compression/payload_compression_config.js +52 -0
- package/dist/data/compression/payload_compression_config.js.map +1 -0
- package/dist/data/compression/payload_compression_runner.d.ts +29 -0
- package/dist/data/compression/payload_compression_runner.d.ts.map +1 -0
- package/dist/data/compression/payload_compression_runner.js +55 -0
- package/dist/data/compression/payload_compression_runner.js.map +1 -0
- package/dist/data/compression/payload_compressor.d.ts +40 -0
- package/dist/data/compression/payload_compressor.d.ts.map +1 -0
- package/dist/data/compression/payload_compressor.js +126 -0
- package/dist/data/compression/payload_compressor.js.map +1 -0
- package/dist/data/compression/uri_compressible_asset.d.ts +23 -0
- package/dist/data/compression/uri_compressible_asset.d.ts.map +1 -0
- package/dist/data/compression/uri_compressible_asset.js +77 -0
- package/dist/data/compression/uri_compressible_asset.js.map +1 -0
- package/dist/data/dsl/builder/cache_config_builder.d.ts +2 -1
- package/dist/data/dsl/builder/cache_config_builder.d.ts.map +1 -1
- package/dist/data/dsl/builder/cache_config_builder.js +2 -1
- package/dist/data/dsl/builder/cache_config_builder.js.map +1 -1
- package/dist/data/dsl/builder/config_builder.d.ts +40 -14
- package/dist/data/dsl/builder/config_builder.d.ts.map +1 -1
- package/dist/data/dsl/builder/config_builder.js +40 -14
- package/dist/data/dsl/builder/config_builder.js.map +1 -1
- package/dist/data/dsl/builder/interceptor_config_builder.d.ts +9 -7
- package/dist/data/dsl/builder/interceptor_config_builder.d.ts.map +1 -1
- package/dist/data/dsl/builder/interceptor_config_builder.js +9 -7
- package/dist/data/dsl/builder/interceptor_config_builder.js.map +1 -1
- package/dist/data/dsl/builder/retry_config_builder.d.ts +19 -4
- package/dist/data/dsl/builder/retry_config_builder.d.ts.map +1 -1
- package/dist/data/dsl/builder/retry_config_builder.js +21 -6
- package/dist/data/dsl/builder/retry_config_builder.js.map +1 -1
- package/dist/data/dsl/builder/timeout_config_builder.d.ts +4 -0
- package/dist/data/dsl/builder/timeout_config_builder.d.ts.map +1 -1
- package/dist/data/dsl/builder/timeout_config_builder.js +4 -0
- package/dist/data/dsl/builder/timeout_config_builder.js.map +1 -1
- package/dist/data/dsl/use_smile_id_network_builder.d.ts +17 -0
- package/dist/data/dsl/use_smile_id_network_builder.d.ts.map +1 -1
- package/dist/data/dsl/use_smile_id_network_builder.js +17 -0
- package/dist/data/dsl/use_smile_id_network_builder.js.map +1 -1
- package/dist/data/factory/networking_factory.d.ts.map +1 -1
- package/dist/data/factory/networking_factory.js +11 -1
- package/dist/data/factory/networking_factory.js.map +1 -1
- package/dist/data/repository/use_smile_id_repository_impl.d.ts +6 -0
- package/dist/data/repository/use_smile_id_repository_impl.d.ts.map +1 -1
- package/dist/data/repository/use_smile_id_repository_impl.js +82 -8
- package/dist/data/repository/use_smile_id_repository_impl.js.map +1 -1
- package/dist/data/security/request_canonicalizer.d.ts.map +1 -1
- package/dist/data/security/request_canonicalizer.js +14 -2
- package/dist/data/security/request_canonicalizer.js.map +1 -1
- package/dist/data/security/security_policy.d.ts +43 -0
- package/dist/data/security/security_policy.d.ts.map +1 -0
- package/dist/data/security/security_policy.js +61 -0
- package/dist/data/security/security_policy.js.map +1 -0
- 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 +2 -2
- package/dist/data/util/retry_util.d.ts.map +1 -1
- package/dist/data/util/retry_util.js +7 -1
- package/dist/data/util/retry_util.js.map +1 -1
- package/dist/data/util/use_smile_id_token_decoder.d.ts +22 -0
- package/dist/data/util/use_smile_id_token_decoder.d.ts.map +1 -1
- package/dist/data/util/use_smile_id_token_decoder.js +58 -24
- package/dist/data/util/use_smile_id_token_decoder.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/l10n/strings_en.d.ts +2 -1
- package/dist/l10n/strings_en.d.ts.map +1 -1
- package/dist/l10n/strings_en.js +2 -1
- package/dist/l10n/strings_en.js.map +1 -1
- package/dist/l10n/use_smile_id_localizations.d.ts +1 -0
- package/dist/l10n/use_smile_id_localizations.d.ts.map +1 -1
- package/dist/l10n/use_smile_id_localizations.js +3 -0
- package/dist/l10n/use_smile_id_localizations.js.map +1 -1
- package/dist/metadata/builder_configuration.d.ts +44 -0
- package/dist/metadata/builder_configuration.d.ts.map +1 -0
- package/dist/metadata/builder_configuration.js +35 -0
- package/dist/metadata/builder_configuration.js.map +1 -0
- package/dist/metadata/captured_image_properties.d.ts +11 -0
- package/dist/metadata/captured_image_properties.d.ts.map +1 -0
- package/dist/metadata/captured_image_properties.js +11 -0
- package/dist/metadata/captured_image_properties.js.map +1 -0
- package/dist/metadata/device_orientation_collector.d.ts +17 -0
- package/dist/metadata/device_orientation_collector.d.ts.map +1 -0
- package/dist/metadata/device_orientation_collector.js +66 -0
- package/dist/metadata/device_orientation_collector.js.map +1 -0
- package/dist/metadata/geolocation.d.ts +20 -0
- package/dist/metadata/geolocation.d.ts.map +1 -0
- package/dist/metadata/geolocation.js +40 -0
- package/dist/metadata/geolocation.js.map +1 -0
- package/dist/metadata/metadata_configuration_mappers.d.ts +47 -0
- package/dist/metadata/metadata_configuration_mappers.d.ts.map +1 -0
- package/dist/metadata/metadata_configuration_mappers.js +178 -0
- package/dist/metadata/metadata_configuration_mappers.js.map +1 -0
- package/dist/metadata/model_configuration.d.ts +41 -0
- package/dist/metadata/model_configuration.d.ts.map +1 -0
- package/dist/metadata/model_configuration.js +44 -0
- package/dist/metadata/model_configuration.js.map +1 -0
- package/dist/metadata/optional_native_modules.d.ts +79 -3
- package/dist/metadata/optional_native_modules.d.ts.map +1 -1
- package/dist/metadata/optional_native_modules.js +108 -3
- package/dist/metadata/optional_native_modules.js.map +1 -1
- package/dist/metadata/use_smile_id_metadata.d.ts +45 -7
- package/dist/metadata/use_smile_id_metadata.d.ts.map +1 -1
- package/dist/metadata/use_smile_id_metadata.js +85 -13
- package/dist/metadata/use_smile_id_metadata.js.map +1 -1
- package/dist/metadata/use_smile_id_metadata_factory.d.ts +37 -0
- package/dist/metadata/use_smile_id_metadata_factory.d.ts.map +1 -1
- package/dist/metadata/use_smile_id_metadata_factory.js +197 -16
- package/dist/metadata/use_smile_id_metadata_factory.js.map +1 -1
- package/dist/presentation/assets/svg/document_shimmer_strings.d.ts +14 -0
- package/dist/presentation/assets/svg/document_shimmer_strings.d.ts.map +1 -0
- package/dist/presentation/assets/svg/document_shimmer_strings.js +14 -0
- package/dist/presentation/assets/svg/document_shimmer_strings.js.map +1 -0
- package/dist/presentation/assets/svg/instruction_svg_strings.d.ts +12 -4
- package/dist/presentation/assets/svg/instruction_svg_strings.d.ts.map +1 -1
- package/dist/presentation/assets/svg/instruction_svg_strings.js +19 -8
- package/dist/presentation/assets/svg/instruction_svg_strings.js.map +1 -1
- package/dist/presentation/components/helpers/enhanced_smart_selfie_animation_frames.d.ts +0 -5
- package/dist/presentation/components/helpers/enhanced_smart_selfie_animation_frames.d.ts.map +1 -1
- package/dist/presentation/components/helpers/enhanced_smart_selfie_animation_frames.js +0 -5
- package/dist/presentation/components/helpers/enhanced_smart_selfie_animation_frames.js.map +1 -1
- package/dist/presentation/components/icons/index.d.ts +24 -8
- package/dist/presentation/components/icons/index.d.ts.map +1 -1
- package/dist/presentation/components/icons/index.js +31 -11
- package/dist/presentation/components/icons/index.js.map +1 -1
- package/dist/presentation/components/use_smile_id_attribution.d.ts +1 -1
- package/dist/presentation/components/use_smile_id_button.d.ts +2 -2
- package/dist/presentation/components/use_smile_id_button.js +4 -4
- package/dist/presentation/components/use_smile_id_button.js.map +1 -1
- package/dist/presentation/components/use_smile_id_capture_content.d.ts +13 -0
- package/dist/presentation/components/use_smile_id_capture_content.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_capture_content.js +15 -9
- package/dist/presentation/components/use_smile_id_capture_content.js.map +1 -1
- package/dist/presentation/components/use_smile_id_captured_document_image.d.ts +2 -3
- package/dist/presentation/components/use_smile_id_captured_document_image.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_captured_document_image.js +1 -3
- package/dist/presentation/components/use_smile_id_captured_document_image.js.map +1 -1
- package/dist/presentation/components/use_smile_id_document_capture_controls.d.ts +12 -6
- package/dist/presentation/components/use_smile_id_document_capture_controls.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_document_capture_controls.js +59 -16
- package/dist/presentation/components/use_smile_id_document_capture_controls.js.map +1 -1
- package/dist/presentation/components/use_smile_id_document_overlay.d.ts +22 -5
- package/dist/presentation/components/use_smile_id_document_overlay.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_document_overlay.js +80 -40
- package/dist/presentation/components/use_smile_id_document_overlay.js.map +1 -1
- package/dist/presentation/components/use_smile_id_document_shimmer.d.ts +15 -0
- package/dist/presentation/components/use_smile_id_document_shimmer.d.ts.map +1 -0
- package/dist/presentation/components/use_smile_id_document_shimmer.js +23 -0
- package/dist/presentation/components/use_smile_id_document_shimmer.js.map +1 -0
- 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 +9 -6
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_clip.js.map +1 -1
- package/dist/presentation/components/use_smile_id_guideline_thumbnail.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_guideline_thumbnail.js +84 -1
- package/dist/presentation/components/use_smile_id_guideline_thumbnail.js.map +1 -1
- package/dist/presentation/components/use_smile_id_instructions_hero.d.ts +3 -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 +25 -5
- package/dist/presentation/components/use_smile_id_instructions_hero.js.map +1 -1
- package/dist/presentation/components/use_smile_id_oval_border_palette.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_oval_border_palette.js +7 -3
- package/dist/presentation/components/use_smile_id_oval_border_palette.js.map +1 -1
- package/dist/presentation/flow/dsl/builder/config_builder.d.ts +28 -0
- package/dist/presentation/flow/dsl/builder/config_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/builder/config_builder.js +30 -0
- package/dist/presentation/flow/dsl/builder/config_builder.js.map +1 -1
- package/dist/presentation/flow/dsl/builder/ml_builder.d.ts +13 -4
- package/dist/presentation/flow/dsl/builder/ml_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/builder/ml_builder.js +3 -2
- package/dist/presentation/flow/dsl/builder/ml_builder.js.map +1 -1
- package/dist/presentation/flow/dsl/builder/screens_builder.d.ts +110 -12
- package/dist/presentation/flow/dsl/builder/screens_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/builder/screens_builder.js +110 -12
- package/dist/presentation/flow/dsl/builder/screens_builder.js.map +1 -1
- package/dist/presentation/flow/dsl/builder/theme_builder.d.ts +15 -2
- package/dist/presentation/flow/dsl/builder/theme_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/builder/theme_builder.js +15 -2
- package/dist/presentation/flow/dsl/builder/theme_builder.js.map +1 -1
- package/dist/presentation/flow/dsl/use_smile_id_builder.d.ts +6 -4
- package/dist/presentation/flow/dsl/use_smile_id_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/use_smile_id_builder.js.map +1 -1
- package/dist/presentation/flow/dsl/use_smile_id_flow_builder.d.ts +62 -36
- package/dist/presentation/flow/dsl/use_smile_id_flow_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/use_smile_id_flow_builder.js +62 -36
- package/dist/presentation/flow/dsl/use_smile_id_flow_builder.js.map +1 -1
- package/dist/presentation/flow/flow_navigation_manager.d.ts +44 -5
- package/dist/presentation/flow/flow_navigation_manager.d.ts.map +1 -1
- package/dist/presentation/flow/flow_navigation_manager.js +148 -11
- package/dist/presentation/flow/flow_navigation_manager.js.map +1 -1
- package/dist/presentation/flow/model/instruction_guideline.d.ts +9 -0
- package/dist/presentation/flow/model/instruction_guideline.d.ts.map +1 -1
- package/dist/presentation/flow/model/instructions_defaults.d.ts +11 -2
- package/dist/presentation/flow/model/instructions_defaults.d.ts.map +1 -1
- package/dist/presentation/flow/model/instructions_defaults.js +74 -26
- 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 +48 -14
- 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_instructions_screen.js +1 -1
- package/dist/presentation/flow/screen/orchestrated_instructions_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 +3 -9
- package/dist/presentation/flow/screen/orchestrated_preview_screen.js.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_processing_screen.js +3 -3
- package/dist/presentation/flow/screen/orchestrated_processing_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/flow/validation/job_type_validator.d.ts.map +1 -1
- package/dist/presentation/flow/validation/job_type_validator.js +14 -0
- package/dist/presentation/flow/validation/job_type_validator.js.map +1 -1
- package/dist/presentation/screen/helpers/capture_screen_helpers.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/capture_screen_helpers.js +1 -0
- package/dist/presentation/screen/helpers/capture_screen_helpers.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/instructions_screen_helpers.d.ts +1 -0
- package/dist/presentation/screen/helpers/instructions_screen_helpers.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/instructions_screen_helpers.js +6 -2
- package/dist/presentation/screen/helpers/instructions_screen_helpers.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 +14 -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 +21 -3
- package/dist/presentation/screen/use_smile_id_capture_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_capture_screen.js +188 -32
- 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.d.ts +2 -3
- package/dist/presentation/screen/use_smile_id_document_preview_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_document_preview_screen.js +17 -12
- package/dist/presentation/screen/use_smile_id_document_preview_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_instructions_screen.d.ts +2 -0
- package/dist/presentation/screen/use_smile_id_instructions_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_instructions_screen.js +2 -1
- package/dist/presentation/screen/use_smile_id_instructions_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_preview_screen.d.ts +7 -26
- package/dist/presentation/screen/use_smile_id_preview_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_preview_screen.js +10 -20
- package/dist/presentation/screen/use_smile_id_preview_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_processing_screen.d.ts +2 -3
- package/dist/presentation/screen/use_smile_id_processing_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_processing_screen.js +4 -3
- package/dist/presentation/screen/use_smile_id_processing_screen.js.map +1 -1
- package/dist/presentation/theme/theme.d.ts +1 -1
- package/dist/presentation/theme/theme.d.ts.map +1 -1
- package/dist/presentation/theme/theme.js +20 -18
- package/dist/presentation/theme/theme.js.map +1 -1
- package/dist/presentation/utils/force_max_brightness.d.ts +4 -4
- 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 +34 -7
- package/src/__tests__/dsl.test.ts +51 -1
- package/src/__tests__/react_native_mock.tsx +8 -0
- 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/camera/camera_defaults.ts +11 -9
- package/src/camera/orientation_degrees.ts +5 -6
- 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 +7 -5
- package/src/core/models/__tests__/flow_models.test.ts +26 -0
- package/src/core/models/config.ts +22 -0
- package/src/core/models/document_capture_mode.ts +27 -0
- package/src/core/models/document_type.ts +7 -5
- package/src/core/models/global_privacy_control.ts +45 -0
- package/src/core/models/network_config.ts +2 -2
- package/src/core/models/result.ts +9 -8
- 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/__tests__/smile_integrity_interceptor.test.ts +37 -1
- package/src/data/api/interceptors/__tests__/smile_request_mac_interceptor.test.ts +59 -1
- package/src/data/api/interceptors/smile_auth_interceptor.ts +3 -18
- package/src/data/api/interceptors/smile_integrity_interceptor.ts +20 -0
- package/src/data/api/interceptors/smile_request_mac_interceptor.ts +13 -0
- package/src/data/compression/__tests__/payload_compressor.test.ts +200 -0
- package/src/data/compression/__tests__/payload_compressor_real_jpeg.test.ts +226 -0
- package/src/data/compression/compressible_asset.ts +62 -0
- package/src/data/compression/payload_compression_config.ts +53 -0
- package/src/data/compression/payload_compression_runner.ts +102 -0
- package/src/data/compression/payload_compressor.ts +164 -0
- package/src/data/compression/uri_compressible_asset.ts +85 -0
- package/src/data/dsl/builder/__tests__/config_builders.test.ts +62 -0
- package/src/data/dsl/builder/cache_config_builder.ts +3 -1
- package/src/data/dsl/builder/config_builder.ts +45 -14
- package/src/data/dsl/builder/interceptor_config_builder.ts +9 -7
- package/src/data/dsl/builder/retry_config_builder.ts +27 -6
- package/src/data/dsl/builder/timeout_config_builder.ts +7 -0
- package/src/data/dsl/use_smile_id_network_builder.ts +17 -0
- 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/factory/networking_factory.ts +14 -1
- package/src/data/repository/__tests__/network_retries.test.ts +117 -0
- package/src/data/repository/__tests__/use_smile_id_repository.test.ts +1 -1
- package/src/data/repository/use_smile_id_repository_impl.ts +96 -9
- package/src/data/security/__tests__/request_canonicalizer.test.ts +132 -0
- package/src/data/security/__tests__/security_policy.test.ts +96 -0
- package/src/data/security/__tests__/smile_id_crypto_manager.test.ts +18 -0
- package/src/data/security/request_canonicalizer.ts +15 -2
- package/src/data/security/security_policy.ts +70 -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/__tests__/use_smile_id_token_decoder.test.ts +57 -1
- package/src/data/util/retry_util.ts +12 -3
- package/src/data/util/use_smile_id_token_decoder.ts +76 -28
- package/src/index.ts +6 -4
- package/src/l10n/strings_en.ts +2 -1
- package/src/l10n/use_smile_id_localizations.ts +3 -0
- package/src/metadata/__tests__/device_orientation_collector.test.ts +15 -0
- package/src/metadata/__tests__/metadata_configuration_mappers.test.ts +254 -0
- package/src/metadata/__tests__/metadata_configuration_objects.test.ts +86 -0
- package/src/metadata/__tests__/metadata_device_context.test.ts +147 -0
- package/src/metadata/__tests__/metadata_device_os_android.test.ts +18 -0
- package/src/metadata/__tests__/metadata_golden_fixture.json +13 -0
- package/src/metadata/__tests__/metadata_payload_golden.test.ts +193 -0
- package/src/metadata/__tests__/use_smile_id_metadata.test.ts +19 -25
- package/src/metadata/builder_configuration.ts +69 -0
- package/src/metadata/captured_image_properties.ts +10 -0
- package/src/metadata/device_orientation_collector.ts +75 -0
- package/src/metadata/geolocation.ts +46 -0
- package/src/metadata/metadata_configuration_mappers.ts +248 -0
- package/src/metadata/model_configuration.ts +68 -0
- package/src/metadata/optional_native_modules.ts +157 -3
- package/src/metadata/use_smile_id_metadata.ts +140 -17
- package/src/metadata/use_smile_id_metadata_factory.ts +211 -16
- 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 -5575
- 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/assets/svg/document_shimmer_strings.ts +17 -0
- package/src/presentation/assets/svg/instruction_svg_strings.ts +34 -12
- package/src/presentation/components/__tests__/enhanced_smart_selfie_animation_frames.test.ts +1 -3
- package/src/presentation/components/__tests__/use_smile_id_enhanced_smart_selfie_clip.test.tsx +12 -8
- package/src/presentation/components/__tests__/use_smile_id_guideline_thumbnail.test.tsx +34 -1
- package/src/presentation/components/__tests__/use_smile_id_instructions_hero.test.tsx +71 -0
- package/src/presentation/components/__tests__/use_smile_id_oval_border_palette.test.ts +7 -5
- package/src/presentation/components/helpers/enhanced_smart_selfie_animation_frames.ts +0 -6
- package/src/presentation/components/icons/index.tsx +65 -18
- package/src/presentation/components/use_smile_id_attribution.tsx +1 -1
- package/src/presentation/components/use_smile_id_button.tsx +4 -4
- package/src/presentation/components/use_smile_id_capture_content.tsx +36 -12
- package/src/presentation/components/use_smile_id_captured_document_image.tsx +3 -8
- package/src/presentation/components/use_smile_id_document_capture_controls.tsx +103 -39
- package/src/presentation/components/use_smile_id_document_overlay.tsx +134 -44
- package/src/presentation/components/use_smile_id_document_shimmer.tsx +51 -0
- package/src/presentation/components/use_smile_id_enhanced_smart_selfie_clip.tsx +9 -6
- package/src/presentation/components/use_smile_id_guideline_thumbnail.tsx +131 -2
- package/src/presentation/components/use_smile_id_instructions_hero.tsx +111 -60
- package/src/presentation/components/use_smile_id_oval_border_palette.ts +7 -3
- package/src/presentation/flow/__tests__/document_flow_navigation.test.ts +203 -4
- 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 +35 -0
- package/src/presentation/flow/dsl/builder/ml_builder.ts +13 -4
- package/src/presentation/flow/dsl/builder/screens_builder.ts +110 -12
- package/src/presentation/flow/dsl/builder/theme_builder.ts +19 -2
- package/src/presentation/flow/dsl/use_smile_id_builder.tsx +6 -4
- package/src/presentation/flow/dsl/use_smile_id_flow_builder.ts +62 -36
- package/src/presentation/flow/flow_navigation_manager.ts +185 -14
- package/src/presentation/flow/model/instruction_guideline.ts +6 -0
- package/src/presentation/flow/model/instructions_defaults.ts +104 -26
- package/src/presentation/flow/screen/orchestrated_capture_screen.tsx +60 -12
- package/src/presentation/flow/screen/orchestrated_consent_screen.tsx +5 -0
- package/src/presentation/flow/screen/orchestrated_instructions_screen.tsx +1 -0
- package/src/presentation/flow/screen/orchestrated_preview_screen.tsx +4 -14
- package/src/presentation/flow/screen/orchestrated_processing_screen.tsx +3 -3
- 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/__tests__/job_type_validator.test.ts +64 -0
- package/src/presentation/flow/validation/flow_validator.ts +55 -26
- package/src/presentation/flow/validation/job_type_validator.ts +24 -0
- 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__/instructions_screen_helpers.test.ts +15 -3
- 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 +182 -18
- 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_screen_helpers.ts +1 -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/instructions_screen_helpers.ts +7 -2
- package/src/presentation/screen/helpers/scan_state_to_overlay_state.ts +16 -13
- package/src/presentation/screen/helpers/use_capture_orientation_lock.ts +69 -7
- package/src/presentation/screen/use_smile_id_capture_screen.tsx +280 -54
- 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 +33 -23
- package/src/presentation/screen/use_smile_id_instructions_screen.tsx +4 -0
- package/src/presentation/screen/use_smile_id_preview_screen.tsx +21 -53
- package/src/presentation/screen/use_smile_id_processing_screen.tsx +8 -8
- package/src/presentation/theme/theme.ts +21 -19
- package/src/presentation/utils/__tests__/locale_utils.test.ts +46 -5
- package/src/presentation/utils/force_max_brightness.tsx +4 -4
- 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/camera/frame_processor_plugin.d.ts +0 -28
- package/dist/camera/frame_processor_plugin.d.ts.map +0 -1
- package/dist/camera/frame_processor_plugin.js +0 -21
- package/dist/camera/frame_processor_plugin.js.map +0 -1
- package/dist/camera/use_smile_id_frame_processor.d.ts +0 -38
- package/dist/camera/use_smile_id_frame_processor.d.ts.map +0 -1
- package/dist/camera/use_smile_id_frame_processor.js +0 -2
- package/dist/camera/use_smile_id_frame_processor.js.map +0 -1
- package/dist/presentation/components/use_smile_id_document_frame_glyph.d.ts +0 -17
- package/dist/presentation/components/use_smile_id_document_frame_glyph.d.ts.map +0 -1
- package/dist/presentation/components/use_smile_id_document_frame_glyph.js +0 -17
- package/dist/presentation/components/use_smile_id_document_frame_glyph.js.map +0 -1
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_animation.d.ts +0 -24
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_animation.d.ts.map +0 -1
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_animation.js +0 -91
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_animation.js.map +0 -1
- 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/dist/presentation/components/use_smile_id_instruction_card.d.ts +0 -31
- package/dist/presentation/components/use_smile_id_instruction_card.d.ts.map +0 -1
- package/dist/presentation/components/use_smile_id_instruction_card.js +0 -43
- package/dist/presentation/components/use_smile_id_instruction_card.js.map +0 -1
- package/dist/presentation/screen/helpers/use_document_orientation_lock.d.ts +0 -24
- package/dist/presentation/screen/helpers/use_document_orientation_lock.d.ts.map +0 -1
- package/dist/presentation/screen/helpers/use_document_orientation_lock.js +0 -47
- package/dist/presentation/screen/helpers/use_document_orientation_lock.js.map +0 -1
- package/src/presentation/components/use_smile_id_document_frame_glyph.tsx +0 -162
- package/src/presentation/components/use_smile_id_face_silhouette_overlay.tsx +0 -27
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { CacheConfigBuilder } from "../cache_config_builder";
|
|
4
|
+
import { RetryConfigBuilder, RetryStrategy } from "../retry_config_builder";
|
|
5
|
+
|
|
6
|
+
/** Retry/cache DSL builders: pin the documented defaults, frozen output, and overrides. */
|
|
7
|
+
describe("RetryConfigBuilder", () => {
|
|
8
|
+
it("builds a frozen config with the documented defaults", () => {
|
|
9
|
+
const config = new RetryConfigBuilder().build();
|
|
10
|
+
|
|
11
|
+
expect(config).toEqual({
|
|
12
|
+
maxAttempts: 1,
|
|
13
|
+
strategy: RetryStrategy.none,
|
|
14
|
+
initialDelay: 1,
|
|
15
|
+
multiplier: 2,
|
|
16
|
+
maxDelay: 32,
|
|
17
|
+
jitter: 0.2,
|
|
18
|
+
fixedDelay: 1,
|
|
19
|
+
});
|
|
20
|
+
expect(Object.isFrozen(config)).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("forces maxAttempts to 1 for none, whatever the field says", () => {
|
|
24
|
+
const builder = new RetryConfigBuilder();
|
|
25
|
+
builder.maxAttempts = 5;
|
|
26
|
+
|
|
27
|
+
expect(builder.build().maxAttempts).toBe(1);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("applies the attempt budget once a strategy opts in", () => {
|
|
31
|
+
const builder = new RetryConfigBuilder();
|
|
32
|
+
builder.strategy = RetryStrategy.exponential;
|
|
33
|
+
|
|
34
|
+
expect(builder.build().maxAttempts).toBe(3);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("carries overridden fields through build()", () => {
|
|
38
|
+
const builder = new RetryConfigBuilder();
|
|
39
|
+
builder.maxAttempts = 5;
|
|
40
|
+
builder.strategy = RetryStrategy.fixed;
|
|
41
|
+
builder.fixedDelay = 4;
|
|
42
|
+
|
|
43
|
+
const config = builder.build();
|
|
44
|
+
|
|
45
|
+
expect(config.maxAttempts).toBe(5);
|
|
46
|
+
expect(config.strategy).toBe(RetryStrategy.fixed);
|
|
47
|
+
expect(config.fixedDelay).toBe(4);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe("CacheConfigBuilder", () => {
|
|
52
|
+
it("defaults to enabled with a 50 MB ceiling", () => {
|
|
53
|
+
const config = new CacheConfigBuilder().build();
|
|
54
|
+
|
|
55
|
+
expect(config).toEqual({ enabled: true, maxSize: 50 * 1024 * 1024 });
|
|
56
|
+
expect(Object.isFrozen(config)).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("megabytes() converts MB to bytes", () => {
|
|
60
|
+
expect(new CacheConfigBuilder().megabytes(10)).toBe(10 * 1024 * 1024);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -7,8 +7,10 @@ import type { CacheConfig } from "../../../core/models/network_config";
|
|
|
7
7
|
* verification flows without aggressive trimming.
|
|
8
8
|
*/
|
|
9
9
|
export class CacheConfigBuilder {
|
|
10
|
+
/** Whether HTTP response caching is on. */
|
|
10
11
|
enabled = true;
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
/** Maximum on-disk cache size, in bytes. Default 50 MB. */
|
|
12
14
|
maxSize = 50 * 1024 * 1024;
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -18,13 +18,25 @@ import {
|
|
|
18
18
|
* identity.
|
|
19
19
|
*/
|
|
20
20
|
export class PartnerConfigBuilder {
|
|
21
|
+
/** Your Smile ID partner id. Required. */
|
|
21
22
|
partnerId = "";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Optional webhook URL Smile ID calls with the job result. It is also
|
|
26
|
+
* sent as a per-request identity header.
|
|
27
|
+
*/
|
|
22
28
|
callbackUrl = "";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* When true, routes requests to the sandbox environment instead of
|
|
32
|
+
* production. Defaults to false.
|
|
33
|
+
*/
|
|
23
34
|
useSandbox = false;
|
|
35
|
+
|
|
24
36
|
/**
|
|
25
|
-
* Optional
|
|
26
|
-
*
|
|
27
|
-
* KYC submissions when set.
|
|
37
|
+
* Optional free-form key/value pairs echoed back on the job result for
|
|
38
|
+
* your own correlation. Forwarded onto the `partner_params` JSON
|
|
39
|
+
* multipart form part on Enhanced / Biometric KYC submissions when set.
|
|
28
40
|
*/
|
|
29
41
|
partnerParams?: Record<string, string>;
|
|
30
42
|
|
|
@@ -49,8 +61,16 @@ export class PartnerConfigBuilder {
|
|
|
49
61
|
* redaction list with their own proxy-injected headers.
|
|
50
62
|
*/
|
|
51
63
|
export class LoggingConfigBuilder {
|
|
64
|
+
/** Whether HTTP request/response logging is on. */
|
|
52
65
|
enabled = true;
|
|
66
|
+
|
|
67
|
+
/** Logging verbosity: none, basic, headers, or full body. */
|
|
53
68
|
level: LogLevel = LogLevel.basic;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Header names whose values are masked in logs (for example
|
|
72
|
+
* authorization headers).
|
|
73
|
+
*/
|
|
54
74
|
redactHeaders: readonly string[] = [];
|
|
55
75
|
|
|
56
76
|
build(): NetworkLoggingConfig {
|
|
@@ -75,35 +95,46 @@ export class LoggingConfigBuilder {
|
|
|
75
95
|
* omit blocks they don't need.
|
|
76
96
|
*/
|
|
77
97
|
export class ConfigBuilder {
|
|
98
|
+
/**
|
|
99
|
+
* The verification job this flow submits (for example smart-selfie
|
|
100
|
+
* enrollment, biometric KYC, or document verification). Required.
|
|
101
|
+
*/
|
|
78
102
|
jobType?: JobType;
|
|
79
103
|
|
|
80
104
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
105
|
+
* The short-lived authentication token for this session. Your backend
|
|
106
|
+
* obtains it from Smile ID's `/v3/token` endpoint using your API key;
|
|
107
|
+
* the SDK never exchanges credentials itself. Stamped as the
|
|
108
|
+
* `smileid-token` HTTP header on every authenticated request.
|
|
85
109
|
*/
|
|
86
110
|
token = "";
|
|
87
111
|
|
|
88
112
|
/**
|
|
89
|
-
* Optional async
|
|
90
|
-
* with
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* 401 response is surfaced unchanged.
|
|
113
|
+
* Optional async callback invoked when the server rejects the token
|
|
114
|
+
* with a 401. Return a fresh token and the SDK retries the request
|
|
115
|
+
* once with it. The callback receives the token the SDK was using.
|
|
116
|
+
* Concurrent 401s collapse to a single callback invocation via the
|
|
117
|
+
* SDK's shared `TokenHolder`. If the callback throws or the retry also
|
|
118
|
+
* returns 401, the original 401 response is surfaced unchanged.
|
|
96
119
|
*/
|
|
97
120
|
onTokenExpired?: (previousToken: string) => Promise<string>;
|
|
98
121
|
|
|
99
122
|
private _partnerConfig?: PartnerConfigBuilder;
|
|
100
123
|
private _logging?: LoggingConfigBuilder;
|
|
101
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Configures partner identity and per-job environment settings —
|
|
127
|
+
* partner id, callback URL, sandbox mode, and partner params.
|
|
128
|
+
*/
|
|
102
129
|
partnerConfig(block: (p: PartnerConfigBuilder) => void): void {
|
|
103
130
|
if (!this._partnerConfig) this._partnerConfig = new PartnerConfigBuilder();
|
|
104
131
|
block(this._partnerConfig);
|
|
105
132
|
}
|
|
106
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Configures HTTP request/response logging: on/off, verbosity, and
|
|
136
|
+
* redacted headers.
|
|
137
|
+
*/
|
|
107
138
|
logging(block: (l: LoggingConfigBuilder) => void): void {
|
|
108
139
|
if (!this._logging) this._logging = new LoggingConfigBuilder();
|
|
109
140
|
block(this._logging);
|
|
@@ -28,24 +28,26 @@ import {
|
|
|
28
28
|
export class InterceptorConfigBuilder {
|
|
29
29
|
private _interceptors: Interceptor[] = [];
|
|
30
30
|
|
|
31
|
+
/** Appends a custom interceptor to the chain. */
|
|
31
32
|
add(interceptor: Interceptor): void {
|
|
32
33
|
this._interceptors.push(interceptor);
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* JS gzip dependency to
|
|
39
|
-
* [createGzipInterceptor] for the
|
|
37
|
+
* Adds the gzip interceptor, which requests compressed responses by
|
|
38
|
+
* stamping `Accept-Encoding: gzip` on every outbound request.
|
|
39
|
+
* Hint-only — the SDK does not pull in a JS gzip dependency to
|
|
40
|
+
* compress request bodies. See [createGzipInterceptor] for the
|
|
41
|
+
* rationale.
|
|
40
42
|
*/
|
|
41
43
|
gzip(): Interceptor {
|
|
42
44
|
return createGzipInterceptor();
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* `
|
|
48
|
+
* Adds the logging interceptor with the given verbosity. The partner
|
|
49
|
+
* block mutates a `LoggingInterceptorBuilder` carrying `level` and
|
|
50
|
+
* `redactHeaders`.
|
|
49
51
|
*/
|
|
50
52
|
logging(
|
|
51
53
|
configure?: (builder: LoggingInterceptorBuilder) => void,
|
|
@@ -8,23 +8,44 @@ export { RetryStrategy };
|
|
|
8
8
|
/**
|
|
9
9
|
* DSL builder for request retry behaviour.
|
|
10
10
|
*
|
|
11
|
-
* Defaults to
|
|
12
|
-
* 32 s ceiling, ±20% jitter.
|
|
13
|
-
* `strategy = RetryStrategy.fixed`.
|
|
11
|
+
* Defaults to no retry. Set `strategy` to opt in, and the remaining fields
|
|
12
|
+
* then apply: 3 attempts, 1 s initial delay, 32 s ceiling, ±20% jitter.
|
|
13
|
+
* `fixedDelay` is honoured only when `strategy = RetryStrategy.fixed`.
|
|
14
14
|
*/
|
|
15
15
|
export class RetryConfigBuilder {
|
|
16
|
+
/** Attempts per request including the first; applies once `strategy` opts in. */
|
|
16
17
|
maxAttempts = 3;
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
/** Backoff strategy between attempts: exponential, fixed, or none. */
|
|
20
|
+
strategy: RetryStrategy = RetryStrategy.none;
|
|
21
|
+
|
|
22
|
+
/** Delay before the first retry, in seconds (exponential strategy). */
|
|
18
23
|
initialDelay = 1;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Factor by which the delay grows after each attempt (exponential
|
|
27
|
+
* strategy).
|
|
28
|
+
*/
|
|
19
29
|
multiplier = 2;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Upper bound on the delay between attempts, in seconds (exponential
|
|
33
|
+
* strategy).
|
|
34
|
+
*/
|
|
20
35
|
maxDelay = 32;
|
|
21
|
-
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Random fraction between 0 and 1 added to each delay to avoid
|
|
39
|
+
* synchronized retry storms.
|
|
40
|
+
*/
|
|
22
41
|
jitter = 0.2;
|
|
42
|
+
|
|
43
|
+
/** Constant delay between attempts, in seconds (fixed strategy). */
|
|
23
44
|
fixedDelay = 1;
|
|
24
45
|
|
|
25
46
|
build(): RetryConfig {
|
|
26
47
|
return Object.freeze({
|
|
27
|
-
maxAttempts: this.maxAttempts,
|
|
48
|
+
maxAttempts: this.strategy === RetryStrategy.none ? 1 : this.maxAttempts,
|
|
28
49
|
strategy: this.strategy,
|
|
29
50
|
initialDelay: this.initialDelay,
|
|
30
51
|
multiplier: this.multiplier,
|
|
@@ -8,9 +8,16 @@ import type { TimeoutConfig } from "../../../core/models/network_config";
|
|
|
8
8
|
* the end-to-end ceiling for the whole request including retries.
|
|
9
9
|
*/
|
|
10
10
|
export class TimeoutConfigBuilder {
|
|
11
|
+
/** Maximum time to establish a connection, in seconds. */
|
|
11
12
|
connect = 60;
|
|
13
|
+
|
|
14
|
+
/** Maximum time to wait for response data, in seconds. */
|
|
12
15
|
read = 60;
|
|
16
|
+
|
|
17
|
+
/** Maximum time to send request data, in seconds. */
|
|
13
18
|
write = 60;
|
|
19
|
+
|
|
20
|
+
/** Maximum total time for the entire request, in seconds. */
|
|
14
21
|
call = 120;
|
|
15
22
|
|
|
16
23
|
build(): TimeoutConfig {
|
|
@@ -29,26 +29,43 @@ export class UseSmileIDNetworkBuilder {
|
|
|
29
29
|
private _retry?: RetryConfigBuilder;
|
|
30
30
|
private _interceptors?: InterceptorConfigBuilder;
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Configures the job type, authentication token, token-refresh
|
|
34
|
+
* callback, and partner identity for this flow.
|
|
35
|
+
*/
|
|
32
36
|
config(block: (c: ConfigBuilder) => void): void {
|
|
33
37
|
if (!this._config) this._config = new ConfigBuilder();
|
|
34
38
|
block(this._config);
|
|
35
39
|
}
|
|
36
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Configures per-phase HTTP timeouts — connect, read, write, and
|
|
43
|
+
* overall call — in seconds.
|
|
44
|
+
*/
|
|
37
45
|
timeouts(block: (t: TimeoutConfigBuilder) => void): void {
|
|
38
46
|
if (!this._timeouts) this._timeouts = new TimeoutConfigBuilder();
|
|
39
47
|
block(this._timeouts);
|
|
40
48
|
}
|
|
41
49
|
|
|
50
|
+
/** Configures the HTTP response cache (on/off and maximum size). */
|
|
42
51
|
cache(block: (c: CacheConfigBuilder) => void): void {
|
|
43
52
|
if (!this._cache) this._cache = new CacheConfigBuilder();
|
|
44
53
|
block(this._cache);
|
|
45
54
|
}
|
|
46
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Configures automatic retry of failed requests: strategy, attempt
|
|
58
|
+
* count, and backoff.
|
|
59
|
+
*/
|
|
47
60
|
retry(block: (r: RetryConfigBuilder) => void): void {
|
|
48
61
|
if (!this._retry) this._retry = new RetryConfigBuilder();
|
|
49
62
|
block(this._retry);
|
|
50
63
|
}
|
|
51
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Registers additional request/response interceptors, appended to the
|
|
67
|
+
* SDK's interceptor chain.
|
|
68
|
+
*/
|
|
52
69
|
interceptors(block: (i: InterceptorConfigBuilder) => void): void {
|
|
53
70
|
if (!this._interceptors)
|
|
54
71
|
this._interceptors = new InterceptorConfigBuilder();
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
AxiosError,
|
|
4
|
+
type AxiosResponse,
|
|
5
|
+
type InternalAxiosRequestConfig,
|
|
6
|
+
} from "axios";
|
|
7
|
+
|
|
8
|
+
import { JobType } from "../../../core/models/job_type";
|
|
9
|
+
import type { NetworkConfig } from "../../../core/models/network_config";
|
|
10
|
+
import { makeNetworkingFactory } from "../networking_factory";
|
|
11
|
+
import { SmileIDCryptoManager } from "../../security/smile_id_crypto_manager";
|
|
12
|
+
import {
|
|
13
|
+
REQUEST_MAC_HEADER,
|
|
14
|
+
REQUEST_MAC_OPT_IN_KEY,
|
|
15
|
+
REQUEST_TIMESTAMP_HEADER,
|
|
16
|
+
} from "../../api/interceptors/smile_request_mac_interceptor";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Standing-guard composition test for token-refresh × gzip × request-MAC on a
|
|
20
|
+
* 401 → refresh → retry. `TokenRefreshInterceptor` re-issues the config, re-running the whole
|
|
21
|
+
* chain (auth re-stamps the token, MAC re-signs, gzip re-stamps `Accept-Encoding`). If a future
|
|
22
|
+
* change made gzip replace `config.data` with compressed bytes, the MAC would sign a body the
|
|
23
|
+
* canonicalizer no longer sees as FormData → `{}`. Pins the retried MAC against the uncompressed
|
|
24
|
+
* body so that regression fails loud.
|
|
25
|
+
*/
|
|
26
|
+
describe("token-refresh x gzip x request-MAC composition", () => {
|
|
27
|
+
const initialToken = "token-1";
|
|
28
|
+
const refreshedToken = "token-2";
|
|
29
|
+
const signingSecret = "test-signing-secret";
|
|
30
|
+
const cryptoManager = new SmileIDCryptoManager(signingSecret);
|
|
31
|
+
|
|
32
|
+
type FormDataPart = { fieldName: string; string?: string; uri?: string };
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Stand-in for RN's `FormData`. Besides `getParts()` (what the canonicalizer reads), it
|
|
36
|
+
* satisfies axios's `isFormData()` (`Symbol.toStringTag` + `append`) so axios's request
|
|
37
|
+
* transform leaves it untouched instead of JSON-stringifying it.
|
|
38
|
+
*/
|
|
39
|
+
class FakeFormData {
|
|
40
|
+
constructor(private readonly parts: readonly FormDataPart[]) {}
|
|
41
|
+
get [Symbol.toStringTag](): string {
|
|
42
|
+
return "FormData";
|
|
43
|
+
}
|
|
44
|
+
append(): void {
|
|
45
|
+
/* not exercised — only presence is checked by axios's isFormData() */
|
|
46
|
+
}
|
|
47
|
+
getParts(): readonly FormDataPart[] {
|
|
48
|
+
return this.parts;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function submissionBody(): FakeFormData {
|
|
53
|
+
return new FakeFormData([
|
|
54
|
+
{ fieldName: "country", string: "NG" },
|
|
55
|
+
{ fieldName: "partner_params", string: '{"flow":"enhanced"}' },
|
|
56
|
+
{
|
|
57
|
+
fieldName: "selfie_image",
|
|
58
|
+
uri: "data:application/octet-stream;base64,c2VsZmll",
|
|
59
|
+
},
|
|
60
|
+
]);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Flattens the observed AxiosHeaders to a lower-cased record, matching how
|
|
64
|
+
* RequestCanonicalizer lower-cases header names before signing. */
|
|
65
|
+
function headersRecord(
|
|
66
|
+
headers: InternalAxiosRequestConfig["headers"],
|
|
67
|
+
): Record<string, string> {
|
|
68
|
+
const out: Record<string, string> = {};
|
|
69
|
+
for (const [key, value] of Object.entries(
|
|
70
|
+
headers as unknown as Record<string, unknown>,
|
|
71
|
+
)) {
|
|
72
|
+
if (value != null) out[key.toLowerCase()] = String(value);
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function makeConfig(): NetworkConfig {
|
|
78
|
+
return {
|
|
79
|
+
config: {
|
|
80
|
+
jobType: JobType.smartSelfieEnrollment,
|
|
81
|
+
token: initialToken,
|
|
82
|
+
onTokenExpired: async () => refreshedToken,
|
|
83
|
+
partnerConfig: {
|
|
84
|
+
partnerId: "partner-1",
|
|
85
|
+
callbackUrl: "https://partner.example.com/cb",
|
|
86
|
+
useSandbox: true,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
it("signs the refresh-retried request's MAC over the uncompressed submission body", async () => {
|
|
93
|
+
const requestsSeen: InternalAxiosRequestConfig[] = [];
|
|
94
|
+
const { client } = makeNetworkingFactory(makeConfig(), () => signingSecret);
|
|
95
|
+
|
|
96
|
+
// 401 first, 200 on the retry. A custom adapter bypasses axios's validateStatus, so it
|
|
97
|
+
// must reject non-2xx itself for TokenRefreshInterceptor's error handler to see it.
|
|
98
|
+
client.defaults.adapter = (
|
|
99
|
+
requestConfig: InternalAxiosRequestConfig,
|
|
100
|
+
): Promise<AxiosResponse> => {
|
|
101
|
+
requestsSeen.push(requestConfig);
|
|
102
|
+
const isFirstCall = requestsSeen.length === 1;
|
|
103
|
+
const response: AxiosResponse = {
|
|
104
|
+
status: isFirstCall ? 401 : 200,
|
|
105
|
+
statusText: isFirstCall ? "Unauthorized" : "OK",
|
|
106
|
+
data: isFirstCall ? { error: "unauthorized" } : { jobId: "job-1" },
|
|
107
|
+
headers: {},
|
|
108
|
+
config: requestConfig,
|
|
109
|
+
};
|
|
110
|
+
if (isFirstCall) {
|
|
111
|
+
return Promise.reject(
|
|
112
|
+
new AxiosError(
|
|
113
|
+
"Request failed with status code 401",
|
|
114
|
+
AxiosError.ERR_BAD_REQUEST,
|
|
115
|
+
requestConfig,
|
|
116
|
+
undefined,
|
|
117
|
+
response,
|
|
118
|
+
),
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
return Promise.resolve(response);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const body = submissionBody();
|
|
125
|
+
const response = await client.post("/v3/enhanced_kyc", body, {
|
|
126
|
+
[REQUEST_MAC_OPT_IN_KEY]: true,
|
|
127
|
+
} as Partial<InternalAxiosRequestConfig>);
|
|
128
|
+
|
|
129
|
+
expect(response.status).toBe(200);
|
|
130
|
+
expect(requestsSeen).toHaveLength(2);
|
|
131
|
+
|
|
132
|
+
const retried = requestsSeen[1]!;
|
|
133
|
+
const retriedHeaders = headersRecord(retried.headers);
|
|
134
|
+
|
|
135
|
+
expect(retriedHeaders["smileid-token"]).toBe(refreshedToken);
|
|
136
|
+
expect(retriedHeaders["accept-encoding"]).toBe("gzip");
|
|
137
|
+
// gzip is hint-only — it never compresses the body, so no Content-Encoding claim.
|
|
138
|
+
expect(retriedHeaders["content-encoding"]).toBeUndefined();
|
|
139
|
+
|
|
140
|
+
const retriedMac = retriedHeaders[REQUEST_MAC_HEADER];
|
|
141
|
+
const retriedTimestamp = retriedHeaders[REQUEST_TIMESTAMP_HEADER];
|
|
142
|
+
expect(retriedMac).toBeDefined();
|
|
143
|
+
expect(retriedTimestamp).toBeDefined();
|
|
144
|
+
|
|
145
|
+
// Recompute the server-verified MAC over the retried headers and the real body — gzip
|
|
146
|
+
// is hint-only (never replaces config.data), so `body` is the bytes that shipped.
|
|
147
|
+
const expectedMac = await cryptoManager.sign(
|
|
148
|
+
retriedTimestamp!,
|
|
149
|
+
retriedHeaders,
|
|
150
|
+
body,
|
|
151
|
+
);
|
|
152
|
+
expect(retriedMac).toBe(expectedMac);
|
|
153
|
+
|
|
154
|
+
// And it must not match a MAC computed against an empty body — the
|
|
155
|
+
// signature of the regression this test guards against.
|
|
156
|
+
const emptyBodyMac = await cryptoManager.sign(
|
|
157
|
+
retriedTimestamp!,
|
|
158
|
+
retriedHeaders,
|
|
159
|
+
undefined,
|
|
160
|
+
);
|
|
161
|
+
expect(retriedMac).not.toBe(emptyBodyMac);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
@@ -12,6 +12,8 @@ import { SmileIntegrityInterceptor } from "../api/interceptors/smile_integrity_i
|
|
|
12
12
|
import { TokenRefreshInterceptor } from "../api/interceptors/token_refresh_interceptor";
|
|
13
13
|
import { TokenHolder } from "../api/auth/token_holder";
|
|
14
14
|
import { SmileIDCryptoManager } from "../security/smile_id_crypto_manager";
|
|
15
|
+
import { SecurityPolicy } from "../security/security_policy";
|
|
16
|
+
import { decodeSecurityPolicyBitCode } from "../util/use_smile_id_token_decoder";
|
|
15
17
|
import { Attestation, SigningSecretProvider } from "@smileid/usesmileid_bridge";
|
|
16
18
|
import { MissingPartnerConfigException } from "../../core/exception";
|
|
17
19
|
import { UseSmileIDMetadataFactory } from "../../metadata/use_smile_id_metadata_factory";
|
|
@@ -107,6 +109,14 @@ export function makeNetworkingFactory(
|
|
|
107
109
|
// next outgoing request automatically picks up the new token.
|
|
108
110
|
const tokenHolder = new TokenHolder(config.config?.token ?? "");
|
|
109
111
|
|
|
112
|
+
// Server-driven security policy for this flow, decoded from the top-level `policy` claim on the
|
|
113
|
+
// JWT (a sibling of `sdk_config`). Decoding is fail-secure: a malformed token, an absent claim, or an absent
|
|
114
|
+
// bit-code all resolve to "every behaviour active", so a token without the claim keeps the
|
|
115
|
+
// pre-policy behaviour rather than dropping security.
|
|
116
|
+
const securityPolicy = SecurityPolicy.fromBitCode(
|
|
117
|
+
decodeSecurityPolicyBitCode(config.config?.token ?? ""),
|
|
118
|
+
);
|
|
119
|
+
|
|
110
120
|
// 1. Gzip is registered FIRST so it runs LAST on the request path
|
|
111
121
|
// (innermost / closest to the wire). It stamps `Accept-Encoding:
|
|
112
122
|
// gzip` so the server can compress responses (axios
|
|
@@ -128,7 +138,9 @@ export function makeNetworkingFactory(
|
|
|
128
138
|
// request path — it reads the `smileid-request-mac` header the MAC
|
|
129
139
|
// interceptor sets and binds the per-request token to it. Per-request
|
|
130
140
|
// opt-in via `config._useSmileIDAttestation`; pass-through otherwise.
|
|
131
|
-
const integrityInterceptor = new SmileIntegrityInterceptor(
|
|
141
|
+
const integrityInterceptor = new SmileIntegrityInterceptor({
|
|
142
|
+
securityPolicy,
|
|
143
|
+
});
|
|
132
144
|
integrityInterceptor.attach(client);
|
|
133
145
|
|
|
134
146
|
// 4. Request MAC runs after auth (so the `smileid-*` headers + timestamp it
|
|
@@ -138,6 +150,7 @@ export function makeNetworkingFactory(
|
|
|
138
150
|
const cryptoManager = new SmileIDCryptoManager(signingSecret());
|
|
139
151
|
const requestMacInterceptor = new SmileRequestMacInterceptor({
|
|
140
152
|
cryptoManager,
|
|
153
|
+
securityPolicy,
|
|
141
154
|
});
|
|
142
155
|
requestMacInterceptor.attach(client);
|
|
143
156
|
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { AxiosError, AxiosHeaders } from "axios";
|
|
3
|
+
|
|
4
|
+
import { UseSmileIDRepositoryImpl } from "../use_smile_id_repository_impl";
|
|
5
|
+
import {
|
|
6
|
+
RetryStrategy,
|
|
7
|
+
type RetryConfig,
|
|
8
|
+
} from "../../dsl/builder/retry_config_builder";
|
|
9
|
+
import { JobType } from "../../../core/models/job_type";
|
|
10
|
+
import { UseSmileIDMetadata } from "../../../metadata/use_smile_id_metadata";
|
|
11
|
+
import type { EnhancedKycRequest } from "../../model/job_request";
|
|
12
|
+
import type { JobSubmissionResponse } from "../../model/job_submission_response";
|
|
13
|
+
import type { ConsentInformation } from "../../../core/models/params";
|
|
14
|
+
|
|
15
|
+
// This file intentionally does NOT mock axios: it exercises the real retry
|
|
16
|
+
// classifier (`isRetryable` → `axios.isAxiosError`) so a genuine retry happens
|
|
17
|
+
// and `network_retries` can be observed on the stamped metadata.
|
|
18
|
+
|
|
19
|
+
const FIXED_RETRY: RetryConfig = Object.freeze({
|
|
20
|
+
maxAttempts: 2,
|
|
21
|
+
strategy: RetryStrategy.fixed,
|
|
22
|
+
initialDelay: 0,
|
|
23
|
+
multiplier: 1,
|
|
24
|
+
maxDelay: 0,
|
|
25
|
+
jitter: 0,
|
|
26
|
+
fixedDelay: 0,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const CONSENT: ConsentInformation = Object.freeze({
|
|
30
|
+
granted: true,
|
|
31
|
+
grantedAt: "2026-04-30T00:00:00.000Z",
|
|
32
|
+
noticeLanguage: "EN",
|
|
33
|
+
noticePrivacyPolicyUrl: "https://example.test/p",
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const METADATA = new UseSmileIDMetadata({
|
|
37
|
+
sdkVersion: "12.0.1",
|
|
38
|
+
sdk: "react-native-expo",
|
|
39
|
+
deviceOs: "",
|
|
40
|
+
deviceModel: "",
|
|
41
|
+
appName: "",
|
|
42
|
+
sessionId: "test-session-id",
|
|
43
|
+
clientIp: "",
|
|
44
|
+
networkConnection: "",
|
|
45
|
+
carrierInfo: "",
|
|
46
|
+
proxy: false,
|
|
47
|
+
timezone: "",
|
|
48
|
+
locale: "",
|
|
49
|
+
screenResolution: "",
|
|
50
|
+
memoryInfoMb: 0,
|
|
51
|
+
deviceOrientation: "",
|
|
52
|
+
systemArchitecture: "",
|
|
53
|
+
numberOfCameras: 0,
|
|
54
|
+
hostApplication: "",
|
|
55
|
+
proximitySensor: false,
|
|
56
|
+
securityPolicyVersion: "12.0.0",
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
function makeAxiosError(status: number): AxiosError {
|
|
60
|
+
return new AxiosError("boom", `${status}`, undefined, undefined, {
|
|
61
|
+
status,
|
|
62
|
+
statusText: "X",
|
|
63
|
+
data: undefined,
|
|
64
|
+
headers: {},
|
|
65
|
+
config: { headers: new AxiosHeaders() },
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function networkRetriesOf(metadata: UseSmileIDMetadata): string | undefined {
|
|
70
|
+
return metadata.toEntries().find((e) => e.name === "network_retries")?.value;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
describe("UseSmileIDRepositoryImpl — network_retries", () => {
|
|
74
|
+
it("stamps network_retries on the retried attempt and omits it on the first", async () => {
|
|
75
|
+
const response: JobSubmissionResponse = {
|
|
76
|
+
jobId: "job-1",
|
|
77
|
+
userId: "user-1",
|
|
78
|
+
status: "approved",
|
|
79
|
+
message: "ok",
|
|
80
|
+
};
|
|
81
|
+
const seenRetries: (string | undefined)[] = [];
|
|
82
|
+
const enhancedKyc = vi
|
|
83
|
+
.fn()
|
|
84
|
+
.mockImplementation((request: EnhancedKycRequest) => {
|
|
85
|
+
seenRetries.push(networkRetriesOf(request.metadata));
|
|
86
|
+
// Fail the first attempt with a retryable 500, succeed on the retry.
|
|
87
|
+
if (enhancedKyc.mock.calls.length === 1) {
|
|
88
|
+
return Promise.reject(makeAxiosError(500));
|
|
89
|
+
}
|
|
90
|
+
return Promise.resolve(response);
|
|
91
|
+
});
|
|
92
|
+
const stubApi = {
|
|
93
|
+
enhancedKyc,
|
|
94
|
+
biometricKyc: vi.fn(),
|
|
95
|
+
smartSelfieEnrollment: vi.fn(),
|
|
96
|
+
smartSelfieAuthentication: vi.fn(),
|
|
97
|
+
documentVerification: vi.fn(),
|
|
98
|
+
enhancedDocumentVerification: vi.fn(),
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
|
+
} as any;
|
|
101
|
+
const repository = new UseSmileIDRepositoryImpl(stubApi, FIXED_RETRY);
|
|
102
|
+
const request: EnhancedKycRequest = {
|
|
103
|
+
jobType: JobType.enhancedKyc,
|
|
104
|
+
params: { idType: "NIN", idNumber: "1", country: "NG" },
|
|
105
|
+
userDetails: { givenNames: "A", lastName: "B", email: "a@b.test" },
|
|
106
|
+
consent: CONSENT,
|
|
107
|
+
metadata: METADATA,
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const result = await repository.submit(request);
|
|
111
|
+
|
|
112
|
+
expect(result.status).toBe("success");
|
|
113
|
+
expect(enhancedKyc).toHaveBeenCalledTimes(2);
|
|
114
|
+
// First attempt: no retries yet. Retry attempt: one retry preceded it.
|
|
115
|
+
expect(seenRetries).toEqual([undefined, "1"]);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -51,7 +51,7 @@ const CONSENT: ConsentInformation = Object.freeze({
|
|
|
51
51
|
// BVN path short-circuits before the API serializes it, but the field
|
|
52
52
|
// is required on `BaseJobRequest` so the fixture must supply one.
|
|
53
53
|
const METADATA = new UseSmileIDMetadata({
|
|
54
|
-
sdkVersion: "12.0.
|
|
54
|
+
sdkVersion: "12.0.1",
|
|
55
55
|
sdk: "react-native-expo",
|
|
56
56
|
deviceOs: "",
|
|
57
57
|
deviceModel: "",
|