mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-06 20:23:52 -05:00
[INJIMOB-3193]add preauth and credential offer support (#1949)
[INJIMOB-3058]temp commit2 [INJIMOB-3058]temp commit2 [INJIMOB-3058] add support for pre-auth flow by credential-offer [INJIMOB-3187] animo working chcekpoint Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>
This commit is contained in:
2
.env
2
.env
@@ -2,7 +2,7 @@
|
||||
# eg . npm build android:newlogic --reset-cache
|
||||
|
||||
#MIMOTO_HOST=http://mock.mimoto.newlogic.dev
|
||||
MIMOTO_HOST=https://api.qa-inji.mosip.net
|
||||
MIMOTO_HOST=https://api.qa-inji1.mosip.net
|
||||
|
||||
ESIGNET_HOST=https://esignet.qa-inji.mosip.net
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ fileignoreconfig:
|
||||
- filename: screens/Home/MyVcs/GetIdInputModal.tsx
|
||||
checksum: 5c736ed79a372d0ffa7c02eb33d0dc06edbbb08d120978ff287f5f06cd6c7746
|
||||
- filename: shared/openId4VCI/Utils.ts
|
||||
checksum: 78473ce25cd52c8d07da9ba98683bdb64ae83a9de8fa907c62f2ebeca7dd21dc
|
||||
checksum: 40b9af91348c8c80e4da7920374110d56f3782aa8f1317e211bdea02efb0d943
|
||||
- filename: shared/cryptoutil/cryptoUtil.ts
|
||||
checksum: 281f061ae6eb722c75c2caf2bdfb5b1bf72f292b471318d972c898c5a972c65f
|
||||
- filename: shared/telemetry/TelemetryConstants.js
|
||||
|
||||
@@ -5,6 +5,8 @@ plugins {
|
||||
apply plugin: "com.android.application"
|
||||
apply plugin: "com.facebook.react"
|
||||
apply plugin: "org.sonarqube"
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.force 'androidx.activity:activity-ktx:1.7.1', 'androidx.activity:activity:1.7.0', 'com.fasterxml.jackson.core:jackson-core:2.14.0'
|
||||
@@ -262,6 +264,9 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
|
||||
implementation("io.mosip:inji-openid4vp:0.3.0-SNAPSHOT"){
|
||||
changing = true
|
||||
exclude group: 'org.bouncycastle', module: 'bcpkix-jdk15on'
|
||||
@@ -275,7 +280,7 @@ dependencies {
|
||||
implementation("io.mosip:pixelpass-aar:0.7.0-SNAPSHOT")
|
||||
implementation("io.mosip:secure-keystore:0.3.0")
|
||||
implementation("io.mosip:tuvali:0.5.2")
|
||||
implementation("io.mosip:inji-vci-client:0.3.0-SNAPSHOT")
|
||||
implementation("io.mosip:inji-vci-client:0.4.0-SNAPSHOT")
|
||||
implementation("com.google.code.gson:gson:2.10.1")
|
||||
implementation("io.mosip:vcverifier-aar:1.3.0-SNAPSHOT") {
|
||||
exclude group: 'org.bouncycastle', module: 'bcpkix-jdk15on'
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package io.mosip.residentapp
|
||||
|
||||
import com.facebook.react.bridge.Arguments
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
|
||||
object VCIClientCallbackBridge {
|
||||
private var deferredProof: CompletableDeferred<String>? = null
|
||||
private var deferredAuthCode: CompletableDeferred<String>? = null
|
||||
private var deferredTxCode: CompletableDeferred<String>? = null
|
||||
private var deferredIssuerTrustResponse: CompletableDeferred<Boolean>? = null
|
||||
|
||||
fun createProofDeferred(): CompletableDeferred<String> {
|
||||
deferredProof = CompletableDeferred()
|
||||
return deferredProof!!
|
||||
}
|
||||
|
||||
fun createAuthCodeDeferred(): CompletableDeferred<String> {
|
||||
deferredAuthCode = CompletableDeferred()
|
||||
return deferredAuthCode!!
|
||||
}
|
||||
|
||||
fun createTxCodeDeferred(): CompletableDeferred<String> {
|
||||
deferredTxCode = CompletableDeferred()
|
||||
return deferredTxCode!!
|
||||
}
|
||||
|
||||
fun createIsuerTrustResponseDeferred(): CompletableDeferred<Boolean> {
|
||||
deferredIssuerTrustResponse = CompletableDeferred()
|
||||
return deferredIssuerTrustResponse!!
|
||||
}
|
||||
|
||||
fun emitRequestProof(
|
||||
context: ReactApplicationContext,
|
||||
accessToken: String,
|
||||
cNonce: String?,
|
||||
issuerMetadata: Map<String, *>? = null,
|
||||
credentialConfigurationId: String? = null
|
||||
) {
|
||||
val params =
|
||||
Arguments.createMap().apply {
|
||||
putString("accessToken", accessToken)
|
||||
if (cNonce != null) putString("cNonce", cNonce)
|
||||
if (issuerMetadata != null) {
|
||||
val json = Gson().toJson(issuerMetadata)
|
||||
putString("issuerMetadata", json)
|
||||
}
|
||||
if (credentialConfigurationId != null) {
|
||||
putString("credentialConfigurationId", credentialConfigurationId)
|
||||
}
|
||||
}
|
||||
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||
.emit("onRequestProof", params)
|
||||
}
|
||||
|
||||
fun emitRequestAuthCode(context: ReactApplicationContext, authorizationEndpoint: String) {
|
||||
val params =
|
||||
Arguments.createMap().apply {
|
||||
putString("authorizationEndpoint", authorizationEndpoint)
|
||||
}
|
||||
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||
.emit("onRequestAuthCode", params)
|
||||
}
|
||||
|
||||
fun emitRequestTxCode(
|
||||
context: ReactApplicationContext,
|
||||
inputMode: String?,
|
||||
description: String?,
|
||||
length: Int?
|
||||
) {
|
||||
val params =
|
||||
Arguments.createMap().apply {
|
||||
putString("inputMode", inputMode)
|
||||
putString("description", description)
|
||||
if( length != null)
|
||||
putInt("length", length)
|
||||
}
|
||||
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||
.emit("onRequestTxCode", params)
|
||||
}
|
||||
fun emitRequestIssuerTrust(context: ReactApplicationContext, issuerMetadata: Map<String, *>) {
|
||||
val params =
|
||||
Arguments.createMap().apply {
|
||||
putString("issuerMetadata", Gson().toJson(issuerMetadata))
|
||||
}
|
||||
|
||||
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||
.emit("onCheckIssuerTrust", params)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun completeProof(jwt: String) {
|
||||
deferredProof?.complete(jwt)
|
||||
deferredProof = null
|
||||
}
|
||||
@JvmStatic
|
||||
fun completeAuthCode(code: String) {
|
||||
deferredAuthCode?.complete(code)
|
||||
deferredAuthCode = null
|
||||
}
|
||||
@JvmStatic
|
||||
fun completeTxCode(code: String) {
|
||||
deferredTxCode?.complete(code)
|
||||
deferredTxCode = null
|
||||
}
|
||||
@JvmStatic
|
||||
fun completeIssuerTrustResponse(trusted: Boolean) {
|
||||
deferredIssuerTrustResponse?.complete(trusted)
|
||||
deferredIssuerTrustResponse = null
|
||||
}
|
||||
|
||||
suspend fun awaitProof(): String {
|
||||
return deferredProof?.await() ?: throw IllegalStateException("No proof callback was set")
|
||||
}
|
||||
|
||||
suspend fun awaitAuthCode(): String {
|
||||
return deferredAuthCode?.await()
|
||||
?: throw IllegalStateException("No auth code callback was set")
|
||||
}
|
||||
|
||||
suspend fun awaitTxCode(): String {
|
||||
return deferredTxCode?.await() ?: throw IllegalStateException("No tx code callback was set")
|
||||
}
|
||||
|
||||
suspend fun awaitIssuerTrustResponse(): Boolean {
|
||||
return deferredIssuerTrustResponse?.await()
|
||||
?: throw IllegalStateException("No issuer trust response callback was set")
|
||||
}
|
||||
}
|
||||
@@ -11,27 +11,30 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import java.util.Objects;
|
||||
import io.mosip.residentapp.VCIClientCallbackBridge;
|
||||
import io.mosip.residentapp.VCIClientBridge;
|
||||
|
||||
import io.mosip.vciclient.VCIClient;
|
||||
import io.mosip.vciclient.constants.CredentialFormat;
|
||||
import io.mosip.vciclient.credentialOffer.CredentialOffer;
|
||||
import io.mosip.vciclient.credentialOffer.CredentialOfferService;
|
||||
import io.mosip.vciclient.credentialResponse.CredentialResponse;
|
||||
import io.mosip.vciclient.dto.IssuerMetaData;
|
||||
import io.mosip.vciclient.proof.jwt.JWTProof;
|
||||
|
||||
import io.mosip.vciclient.proof.Proof;
|
||||
import io.mosip.vciclient.issuerMetadata.IssuerMetadata;
|
||||
import io.mosip.vciclient.clientMetadata.ClientMetadata;
|
||||
|
||||
public class InjiVciClientModule extends ReactContextBaseJavaModule {
|
||||
private VCIClient vciClient;
|
||||
private final ReactApplicationContext reactContext;
|
||||
|
||||
public InjiVciClientModule(@Nullable ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void init(String appId) {
|
||||
Log.d("InjiVciClientModule", "Initializing InjiVciClientModule with " + appId);
|
||||
vciClient = new VCIClient(appId);
|
||||
this.reactContext = reactContext;
|
||||
VCIClientBridge.reactContext = this.reactContext;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -41,42 +44,68 @@ public class InjiVciClientModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void requestCredential(ReadableMap issuerMetaData, String jwtProofValue, String accessToken, Promise promise) {
|
||||
try {
|
||||
IssuerMetaData constructedIssuerMetadata ;
|
||||
String issuerMetadataCredentialFormat = issuerMetaData.getString("credentialFormat");
|
||||
if(Objects.equals(issuerMetadataCredentialFormat, CredentialFormat.LDP_VC.getValue())){
|
||||
constructedIssuerMetadata = new IssuerMetaData(
|
||||
issuerMetaData.getString("credentialAudience"),
|
||||
issuerMetaData.getString("credentialEndpoint"),
|
||||
issuerMetaData.getInt("downloadTimeoutInMilliSeconds"),
|
||||
convertReadableArrayToStringArray(issuerMetaData.getArray("credentialType")),
|
||||
CredentialFormat.LDP_VC,null,null);
|
||||
} else if (Objects.equals(issuerMetadataCredentialFormat, CredentialFormat.MSO_MDOC.getValue())) {
|
||||
constructedIssuerMetadata = new IssuerMetaData(
|
||||
issuerMetaData.getString("credentialAudience"),
|
||||
issuerMetaData.getString("credentialEndpoint"),
|
||||
issuerMetaData.getInt("downloadTimeoutInMilliSeconds"),
|
||||
null,
|
||||
CredentialFormat.MSO_MDOC, issuerMetaData.getString("doctype"),
|
||||
issuerMetaData.getMap("claims").toHashMap());
|
||||
} else {
|
||||
throw new IllegalStateException("Unexpected value: " + issuerMetadataCredentialFormat);
|
||||
}
|
||||
|
||||
CredentialResponse response = vciClient.requestCredential(constructedIssuerMetadata, new JWTProof(jwtProofValue)
|
||||
, accessToken);
|
||||
promise.resolve(response.toJsonString());
|
||||
} catch (Exception exception) {
|
||||
promise.reject(exception);
|
||||
}
|
||||
public void init(String appId) {
|
||||
Log.d("InjiVciClientModule", "Initializing InjiVciClientModule with " + appId);
|
||||
vciClient = new VCIClient(appId,reactContext);
|
||||
}
|
||||
|
||||
private String[] convertReadableArrayToStringArray(ReadableArray readableArray) {
|
||||
String[] stringArray = new String[readableArray.size()];
|
||||
for (int i = 0; i < readableArray.size(); i++) {
|
||||
stringArray[i] = readableArray.getString(i);
|
||||
}
|
||||
return stringArray;
|
||||
@ReactMethod
|
||||
public void sendProofFromJS(String jwt) {
|
||||
VCIClientCallbackBridge.completeProof(jwt);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void sendAuthCodeFromJS(String authCode) {
|
||||
VCIClientCallbackBridge.completeAuthCode(authCode);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void sendTxCodeFromJS(String txCode) {
|
||||
VCIClientCallbackBridge.completeTxCode(txCode);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void sendIssuerTrustResponseFromJS(Boolean trusted) {
|
||||
VCIClientCallbackBridge.completeIssuerTrustResponse(trusted);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void requestCredentialByOffer(String credentialOffer,String clientMetadataJson, Promise promise) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
ClientMetadata clientMetadata= new Gson().fromJson(
|
||||
clientMetadataJson, ClientMetadata.class);
|
||||
CredentialResponse response = VCIClientBridge.requestCredentialByOfferSync(vciClient, credentialOffer,clientMetadata);
|
||||
reactContext.runOnUiQueueThread(() -> {
|
||||
promise.resolve(response != null ? response.toJsonString() : null);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
reactContext.runOnUiQueueThread(() -> {
|
||||
promise.reject("OFFER_FLOW_FAILED", e.getMessage(), e);
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void requestCredentialFromTrustedIssuer(String resolvedIssuerMetaJson, String clientMetadataJson, Promise promise) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
IssuerMetadata issuerMetaData = new Gson().fromJson(
|
||||
resolvedIssuerMetaJson, IssuerMetadata.class);
|
||||
ClientMetadata clientMetadata= new Gson().fromJson(
|
||||
clientMetadataJson, ClientMetadata.class);
|
||||
|
||||
CredentialResponse response = VCIClientBridge.requestCredentialFromTrustedIssuerSync(vciClient, issuerMetaData,clientMetadata);
|
||||
|
||||
reactContext.runOnUiQueueThread(() -> {
|
||||
promise.resolve(response != null ? response.toJsonString() : null);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
reactContext.runOnUiQueueThread(() -> {
|
||||
promise.reject("TRUSTED_ISSUER_FAILED", e.getMessage(), e);
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package io.mosip.residentapp
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import io.mosip.vciclient.VCIClient
|
||||
import io.mosip.vciclient.clientMetadata.ClientMetadata
|
||||
import io.mosip.vciclient.credentialResponse.CredentialResponse
|
||||
import io.mosip.vciclient.issuerMetadata.IssuerMetadata
|
||||
import io.mosip.residentapp.VCIClientBridge
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
object VCIClientBridge {
|
||||
|
||||
// Must be set by the Java side (InjiVciClientModule) to emit events to JS
|
||||
lateinit var reactContext: ReactApplicationContext
|
||||
|
||||
@JvmStatic
|
||||
fun requestCredentialByOfferSync(
|
||||
client: VCIClient,
|
||||
offer: String,
|
||||
clientMetaData: ClientMetadata
|
||||
): CredentialResponse? = runBlocking {
|
||||
client.requestCredentialByCredentialOffer(
|
||||
credentialOffer = offer,
|
||||
clientMetadata = clientMetaData,
|
||||
getTxCode = { inputMode, description, length ->
|
||||
VCIClientCallbackBridge.createTxCodeDeferred()
|
||||
VCIClientCallbackBridge.emitRequestTxCode(VCIClientBridge.reactContext,
|
||||
inputMode,
|
||||
description,
|
||||
length
|
||||
)
|
||||
VCIClientCallbackBridge.awaitTxCode()
|
||||
},
|
||||
getProofJwt = { accessToken, cNonce, issuerMetadata, credentialConfigurationId ->
|
||||
VCIClientCallbackBridge.createProofDeferred()
|
||||
VCIClientCallbackBridge.emitRequestProof(
|
||||
VCIClientBridge.reactContext,
|
||||
accessToken,
|
||||
cNonce,
|
||||
issuerMetadata,
|
||||
credentialConfigurationId
|
||||
)
|
||||
VCIClientCallbackBridge.awaitProof()
|
||||
},
|
||||
getAuthCode = { endpoint ->
|
||||
VCIClientCallbackBridge.createAuthCodeDeferred()
|
||||
VCIClientCallbackBridge.emitRequestAuthCode(VCIClientBridge.reactContext, endpoint)
|
||||
VCIClientCallbackBridge.awaitAuthCode()
|
||||
},
|
||||
onCheckIssuerTrust = { issuerMetadata ->
|
||||
VCIClientCallbackBridge.createIsuerTrustResponseDeferred()
|
||||
VCIClientCallbackBridge.emitRequestIssuerTrust(reactContext, issuerMetadata)
|
||||
VCIClientCallbackBridge.awaitIssuerTrustResponse()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun requestCredentialFromTrustedIssuerSync(
|
||||
client: VCIClient,
|
||||
resolvedIssuerMetaData: IssuerMetadata,
|
||||
clientMetaData: ClientMetadata
|
||||
): CredentialResponse? = runBlocking {
|
||||
client.requestCredentialFromTrustedIssuer(
|
||||
issuerMetadata = resolvedIssuerMetaData,
|
||||
clientMetadata = clientMetaData,
|
||||
getProofJwt = { accessToken, cNonce, _, _ ->
|
||||
VCIClientCallbackBridge.createProofDeferred()
|
||||
VCIClientCallbackBridge.emitRequestProof(reactContext, accessToken, cNonce)
|
||||
VCIClientCallbackBridge.awaitProof()
|
||||
},
|
||||
getAuthCode = { authorizationEndpoint ->
|
||||
VCIClientCallbackBridge.createAuthCodeDeferred()
|
||||
VCIClientCallbackBridge.emitRequestAuthCode(reactContext, authorizationEndpoint)
|
||||
VCIClientCallbackBridge.awaitAuthCode()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,13 @@ buildscript {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:8.2")
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath("org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +28,9 @@ buildscript {
|
||||
// @generated begin expo-camera-import - expo prebuild (DO NOT MODIFY) sync-f244f4f3d8bf7229102e8f992b525b8602c74770
|
||||
def expoCameraMavenPath = new File(["node", "--print", "require.resolve('expo-camera/package.json')"].execute(null, rootDir).text.trim(), "../android/maven")
|
||||
allprojects { repositories {
|
||||
mavenLocal()
|
||||
maven{url("https://oss.sonatype.org/content/repositories/snapshots/")}
|
||||
maven{url("https://central.sonatype.com/repository/maven-snapshots/")}
|
||||
maven { url(expoCameraMavenPath) }
|
||||
mavenCentral()
|
||||
maven {url("https://repo.danubetech.com/repository/maven-public/")}
|
||||
|
||||
15
assets/scanIcon.svg
Normal file
15
assets/scanIcon.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.66667 9.33341V2.66675H9.33334V5.33341H5.33334V9.33341H2.66667ZM2.66667 29.3334V22.6667H5.33334V26.6667H9.33334V29.3334H2.66667ZM22.6667 29.3334V26.6667H26.6667V22.6667H29.3333V29.3334H22.6667ZM26.6667 9.33341V5.33341H22.6667V2.66675H29.3333V9.33341H26.6667ZM23.3333 23.3334H25.3333V25.3334H23.3333V23.3334ZM23.3333 19.3334H25.3333V21.3334H23.3333V19.3334ZM21.3333 21.3334H23.3333V23.3334H21.3333V21.3334ZM19.3333 23.3334H21.3333V25.3334H19.3333V23.3334ZM17.3333 21.3334H19.3333V23.3334H17.3333V21.3334ZM21.3333 17.3334H23.3333V19.3334H21.3333V17.3334ZM19.3333 19.3334H21.3333V21.3334H19.3333V19.3334ZM17.3333 17.3334H19.3333V19.3334H17.3333V17.3334ZM25.3333 6.66675V14.6667H17.3333V6.66675H25.3333ZM14.6667 17.3334V25.3334H6.66667V17.3334H14.6667ZM14.6667 6.66675V14.6667H6.66667V6.66675H14.6667ZM12.6667 23.3334V19.3334H8.66667V23.3334H12.6667ZM12.6667 12.6667V8.66675H8.66667V12.6667H12.6667ZM23.3333 12.6667V8.66675H19.3333V12.6667H23.3333Z" fill="url(#paint0_linear_532_832)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_532_832" x1="2.66667" y1="16.0001" x2="29.3333" y2="16.0001" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF5300"/>
|
||||
<stop offset="0.16" stop-color="#FB5103"/>
|
||||
<stop offset="0.31" stop-color="#F04C0F"/>
|
||||
<stop offset="0.46" stop-color="#DE4322"/>
|
||||
<stop offset="0.61" stop-color="#C5363C"/>
|
||||
<stop offset="0.75" stop-color="#A4265F"/>
|
||||
<stop offset="0.9" stop-color="#7C1389"/>
|
||||
<stop offset="1" stop-color="#5B03AD"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -11,13 +11,17 @@ export const PinInput: React.FC<PinInputProps> = props => {
|
||||
const [focusedIndex, setFocusedIndex] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.onDone && values.filter(Boolean).length === inputRefs.length) {
|
||||
props.onDone(values.join(''));
|
||||
const current = values.join('');
|
||||
props.onChange?.(current);
|
||||
|
||||
if (props.autosubmit && props.onDone && values.filter(Boolean).length === inputRefs.length) {
|
||||
props.onDone(current);
|
||||
}
|
||||
}, [state]);
|
||||
}, [values]);
|
||||
|
||||
|
||||
return (
|
||||
<Row width="100%" testID={props.testID} removeClippedSubviews={true}>
|
||||
<Row width={`${(100 / 6) * props.length}%`} testID={props.testID} removeClippedSubviews={true}>
|
||||
{inputRefs.map((input, index) => (
|
||||
<TextInput
|
||||
contextMenuHidden={true}
|
||||
@@ -53,4 +57,6 @@ interface PinInputProps {
|
||||
testID?: string;
|
||||
length: number;
|
||||
onDone?: (value: string) => void;
|
||||
onChange?: (value: string) => void;
|
||||
autosubmit?: boolean;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ export const VCCardView: React.FC<VCItemProps> = ({
|
||||
credentialConfigurationId,
|
||||
vcMetadata: { format },
|
||||
} = verifiableCredentialData;
|
||||
if (vcMetadata.issuerHost) {
|
||||
if (vcMetadata) {
|
||||
getCredentialIssuersWellKnownConfig(
|
||||
issuer,
|
||||
CARD_VIEW_DEFAULT_FIELDS,
|
||||
|
||||
@@ -50,7 +50,7 @@ export const VCDetailView: React.FC<VCItemDetailsProps> = (
|
||||
} else if (
|
||||
props.verifiableCredentialData.vcMetadata.format === VCFormat.mso_mdoc
|
||||
) {
|
||||
const namespaces = verifiableCredential['issuerSigned']['nameSpaces'];
|
||||
const namespaces = verifiableCredential['issuerSigned']?.['nameSpaces'] ?? verifiableCredential['nameSpaces']??{};
|
||||
Object.keys(namespaces).forEach(namespace => {
|
||||
(namespaces[namespace] as Array<Object>).forEach(element => {
|
||||
availableFieldNames.push(
|
||||
@@ -119,7 +119,8 @@ export const VCDetailView: React.FC<VCItemDetailsProps> = (
|
||||
margin={'0 0 0 24'}
|
||||
style={{flex: 1}}>
|
||||
{fieldItemIterator(
|
||||
props.fields,
|
||||
props.fields,
|
||||
props.wellknownFieldsFlag,
|
||||
verifiableCredential,
|
||||
props.wellknown,
|
||||
wellknownDisplayProperty,
|
||||
@@ -141,6 +142,7 @@ export const VCDetailView: React.FC<VCItemDetailsProps> = (
|
||||
{shouldShowHrLine(verifiableCredential) &&
|
||||
fieldItemIterator(
|
||||
DETAIL_VIEW_BOTTOM_SECTION_FIELDS,
|
||||
props.wellknownFieldsFlag,
|
||||
verifiableCredential,
|
||||
props.wellknown,
|
||||
wellknownDisplayProperty,
|
||||
@@ -240,6 +242,7 @@ export const VCDetailView: React.FC<VCItemDetailsProps> = (
|
||||
export interface VCItemDetailsProps {
|
||||
fields: any[];
|
||||
wellknown: any;
|
||||
wellknownFieldsFlag: boolean;
|
||||
credential: VerifiableCredential | Credential;
|
||||
verifiableCredentialData: VerifiableCredentialData;
|
||||
walletBindingResponse?: WalletBindingResponse;
|
||||
|
||||
@@ -154,7 +154,7 @@ export const getFieldName = (
|
||||
}
|
||||
}
|
||||
}
|
||||
return i18n.t(`VcDetails:${field}`);
|
||||
return field;
|
||||
};
|
||||
|
||||
export function getAddressFields() {
|
||||
@@ -181,17 +181,72 @@ function getFullAddress(credential: CredentialSubject) {
|
||||
.filter(Boolean)
|
||||
.join(', ');
|
||||
}
|
||||
const renderFieldRecursively = (
|
||||
key: string,
|
||||
value: any,
|
||||
fieldNameColor: string,
|
||||
fieldValueColor: string,
|
||||
parentKey = '',
|
||||
depth = 0
|
||||
): JSX.Element[] => {
|
||||
const fullKey = parentKey ? `${parentKey}.${key}` : key;
|
||||
|
||||
if (value === null || value === undefined) return [];
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return value.flatMap((item, index) =>
|
||||
renderFieldRecursively(`${key}[${index}]`, item, fieldNameColor,fieldValueColor,parentKey, depth + 1)
|
||||
);
|
||||
} else if (typeof value === 'object') {
|
||||
return Object.entries(value).flatMap(([childKey, childValue]) =>
|
||||
renderFieldRecursively(childKey, childValue, fieldNameColor,fieldValueColor,fullKey, depth + 1)
|
||||
);
|
||||
} else {
|
||||
let displayValue = String(value);
|
||||
// Truncate base64 if it's an image data URI or very long string
|
||||
if (displayValue.startsWith('data:image') || displayValue.length > 100) {
|
||||
displayValue = displayValue.slice(0, 60) + '...';
|
||||
}
|
||||
|
||||
return [
|
||||
<Row
|
||||
key={`extra-${fullKey}`}
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
flex: 1,
|
||||
paddingLeft: depth * 12, // Indent nested levels
|
||||
}}
|
||||
align="space-between"
|
||||
margin="0 8 15 0"
|
||||
>
|
||||
<VCItemField
|
||||
key={`extra-${fullKey}`}
|
||||
fieldName={fullKey}
|
||||
fieldValue={displayValue}
|
||||
fieldNameColor={fieldNameColor}
|
||||
fieldValueColor={fieldValueColor}
|
||||
testID={`extra-${fullKey}`}
|
||||
/>
|
||||
</Row>,
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const fieldItemIterator = (
|
||||
fields: any[],
|
||||
wellknownFieldsFlag: boolean,
|
||||
verifiableCredential: VerifiableCredential | Credential,
|
||||
wellknown: any,
|
||||
display: Display,
|
||||
props: VCItemDetailsProps,
|
||||
) => {
|
||||
): JSX.Element[] => {
|
||||
const fieldNameColor = display.getTextColor(Theme.Colors.DetailsLabel);
|
||||
const fieldValueColor = display.getTextColor(Theme.Colors.Details);
|
||||
return fields.map(field => {
|
||||
|
||||
const renderedFields = new Set<string>();
|
||||
|
||||
const renderedMainFields = fields.map(field => {
|
||||
const fieldName = getFieldName(
|
||||
field,
|
||||
wellknown,
|
||||
@@ -205,16 +260,20 @@ export const fieldItemIterator = (
|
||||
display,
|
||||
props.verifiableCredentialData.vcMetadata.format,
|
||||
);
|
||||
renderedFields.add(field);
|
||||
|
||||
if (
|
||||
(field === 'credentialRegistry' &&
|
||||
CREDENTIAL_REGISTRY_EDIT === 'false') ||
|
||||
!fieldValue
|
||||
)
|
||||
return;
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Row
|
||||
key={field}
|
||||
style={{flexDirection: 'row', flex: 1}}
|
||||
style={{ flexDirection: 'row', flex: 1 }}
|
||||
align="space-between"
|
||||
margin="0 8 15 0">
|
||||
<VCItemField
|
||||
@@ -228,13 +287,83 @@ export const fieldItemIterator = (
|
||||
</Row>
|
||||
);
|
||||
});
|
||||
|
||||
let renderedExtraFields: JSX.Element[] = [];
|
||||
|
||||
if (!wellknownFieldsFlag) {
|
||||
const renderedAll: JSX.Element[] = [];
|
||||
|
||||
// Extra fields from credentialSubject
|
||||
const credentialSubjectFields =
|
||||
(verifiableCredential.credentialSubject as Record<string, any>) || {};
|
||||
|
||||
const renderedSubjectFields = Object.entries(credentialSubjectFields)
|
||||
.filter(([key]) => !renderedFields.has(key))
|
||||
.flatMap(([key, value]) =>
|
||||
renderFieldRecursively(key, value, fieldNameColor, fieldValueColor)
|
||||
);
|
||||
|
||||
renderedAll.push(...renderedSubjectFields);
|
||||
|
||||
// Render fields from nameSpaces (mso_mdoc)
|
||||
const nameSpaces: Record<string, any> =
|
||||
verifiableCredential.nameSpaces ??
|
||||
verifiableCredential.issuerSigned?.nameSpaces ??
|
||||
verifiableCredential.issuerAuth?.nameSpaces ??
|
||||
{};
|
||||
|
||||
const renderedNamespaceFields = Object.entries(nameSpaces).flatMap(
|
||||
([namespace, entries]) => {
|
||||
if (!Array.isArray(entries)) return [];
|
||||
|
||||
return [
|
||||
|
||||
<VCItemField
|
||||
key={`ns-title-${namespace}`}
|
||||
fieldName={(namespace)}
|
||||
fieldValue=""
|
||||
fieldNameColor={fieldNameColor}
|
||||
fieldValueColor={fieldValueColor}
|
||||
testID={`ns-title-${namespace}`}
|
||||
/>,
|
||||
...entries.flatMap((entry, index) => [
|
||||
<VCItemField
|
||||
key={`entry-heading-${namespace}-${index}`}
|
||||
fieldName={"--"}
|
||||
fieldValue=""
|
||||
fieldNameColor={fieldNameColor}
|
||||
fieldValueColor={fieldValueColor}
|
||||
testID={`entry-heading-${namespace}-${index}`}
|
||||
/>,
|
||||
...Object.entries(entry).flatMap(([key, value]) =>
|
||||
renderFieldRecursively(
|
||||
key,
|
||||
value,
|
||||
fieldNameColor,
|
||||
fieldValueColor,
|
||||
`${namespace}[${index}]`,
|
||||
1
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
renderedAll.push(...renderedNamespaceFields);
|
||||
renderedExtraFields = renderedAll;
|
||||
}
|
||||
|
||||
return [...renderedMainFields, ...renderedExtraFields];
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const isVCLoaded = (
|
||||
verifiableCredential: Credential | null,
|
||||
fields: string[],
|
||||
) => {
|
||||
return verifiableCredential != null && fields.length > 0;
|
||||
return verifiableCredential != null
|
||||
};
|
||||
|
||||
export const getMosipLogo = () => {
|
||||
@@ -365,4 +494,4 @@ const ProtectedCurve = {
|
||||
|
||||
const PROOF_TYPE_ALGORITHM_MAP = {
|
||||
[-7]: 'ES256',
|
||||
};
|
||||
};
|
||||
@@ -1,36 +1,39 @@
|
||||
import React from 'react';
|
||||
import {Pressable, View} from 'react-native';
|
||||
import {Theme} from '../ui/styleUtils';
|
||||
import { Pressable, View } from 'react-native';
|
||||
import { Theme } from '../ui/styleUtils';
|
||||
import testIDProps from '../../shared/commonUtil';
|
||||
import {Text} from '../ui';
|
||||
import {displayType} from '../../machines/Issuers/IssuersMachine';
|
||||
import {SvgImage} from '../ui/svg';
|
||||
import { Text } from '../ui';
|
||||
import { displayType } from '../../machines/Issuers/IssuersMachine';
|
||||
import { SvgImage } from '../ui/svg';
|
||||
|
||||
export const Issuer: React.FC<IssuerProps> = (props: IssuerProps) => {
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
accessible={false}
|
||||
{...testIDProps(`issuer-${props.testID}`)}
|
||||
onPress={props.onPress}
|
||||
style={({pressed}) =>
|
||||
style={({ pressed }) =>
|
||||
pressed
|
||||
? [
|
||||
Theme.IssuersScreenStyles.issuerBoxContainerPressed,
|
||||
Theme.Styles.boxShadow,
|
||||
]
|
||||
Theme.IssuersScreenStyles.issuerBoxContainerPressed,
|
||||
Theme.Styles.boxShadow,
|
||||
]
|
||||
: [
|
||||
Theme.IssuersScreenStyles.issuerBoxContainer,
|
||||
Theme.Styles.boxShadow,
|
||||
]
|
||||
Theme.IssuersScreenStyles.issuerBoxContainer,
|
||||
Theme.Styles.boxShadow,
|
||||
]
|
||||
}>
|
||||
<View style={Theme.IssuersScreenStyles.issuerBoxIconContainer}>
|
||||
{SvgImage.IssuerIcon(props)}
|
||||
{props.displayDetails.logo
|
||||
? SvgImage.IssuerIcon(props)
|
||||
: SvgImage.defaultIssuerLogo(props.defaultLogo)}
|
||||
</View>
|
||||
<View style={Theme.IssuersScreenStyles.issuerBoxContent}>
|
||||
<Text
|
||||
testID={`issuerHeading-${props.testID}`}
|
||||
style={Theme.IssuersScreenStyles.issuerHeading}>
|
||||
{props.displayDetails.title}
|
||||
{props.displayDetails.title ?? props.displayDetails.name}
|
||||
</Text>
|
||||
<Text
|
||||
testID={`issuerDescription-${props.testID}`}
|
||||
@@ -46,4 +49,5 @@ export interface IssuerProps {
|
||||
displayDetails: displayType;
|
||||
onPress: () => void;
|
||||
testID: string;
|
||||
defaultLogo?: any;
|
||||
}
|
||||
|
||||
@@ -21,10 +21,12 @@ export const Text: React.FC<TextProps> = (props: TextProps) => {
|
||||
{...testIDProps(props.testID)}
|
||||
style={textStyles}
|
||||
numberOfLines={props.numLines}
|
||||
onTextLayout={props.onTextLayout}
|
||||
ellipsizeMode={props.ellipsizeMode}
|
||||
accessible={props.accessible}
|
||||
onPress={props.onPress}>
|
||||
{props.children}
|
||||
|
||||
</RNText>
|
||||
);
|
||||
};
|
||||
@@ -43,4 +45,5 @@ interface TextProps {
|
||||
style?: StyleProp<TextStyle>;
|
||||
accessible?: boolean | true;
|
||||
onPress?: () => void;
|
||||
onTextLayout?: (e: any) => void;
|
||||
}
|
||||
|
||||
@@ -98,6 +98,11 @@ export class SvgImage {
|
||||
);
|
||||
}
|
||||
|
||||
static defaultIssuerLogo(defaultLogo: any) {
|
||||
const DefaultLogo=defaultLogo
|
||||
return <DefaultLogo/>
|
||||
}
|
||||
|
||||
static starIcon() {
|
||||
return (
|
||||
<StarIcon
|
||||
@@ -593,7 +598,7 @@ export class SvgImage {
|
||||
}
|
||||
|
||||
function getIssuerLogo(props: displayType) {
|
||||
return {uri: props.logo.url};
|
||||
return {uri: props.logo.url || props.logo.uri};
|
||||
}
|
||||
|
||||
interface LogoProps {
|
||||
|
||||
@@ -864,7 +864,7 @@ export const DefaultTheme = {
|
||||
flex: 1,
|
||||
fontSize: 33,
|
||||
fontFamily: 'Inter_600SemiBold',
|
||||
height: 40,
|
||||
height: 50,
|
||||
lineHeight: 28,
|
||||
margin: 8,
|
||||
textAlign: 'center',
|
||||
@@ -876,7 +876,7 @@ export const DefaultTheme = {
|
||||
flex: 1,
|
||||
fontFamily: 'Inter_700Bold',
|
||||
fontSize: 29,
|
||||
height: 40,
|
||||
height: 50,
|
||||
margin: 8,
|
||||
textAlign: 'center',
|
||||
},
|
||||
@@ -1940,6 +1940,120 @@ export const DefaultTheme = {
|
||||
},
|
||||
}),
|
||||
|
||||
TransactionCodeScreenStyle: StyleSheet.create({
|
||||
showMoreButton: {
|
||||
alignItems: 'flex-end',
|
||||
marginTop: 6,
|
||||
marginBottom: 10,
|
||||
marginRight: -Dimensions.get('window').width + 150,
|
||||
fontSize: 12,
|
||||
fontWeight: '600',
|
||||
color: Colors.Grey,
|
||||
},
|
||||
errorView: {
|
||||
backgroundColor: '#FAEFEF',
|
||||
padding: 8,
|
||||
borderRadius: 10,
|
||||
marginBottom: 10,
|
||||
marginTop: 10,
|
||||
width: '80%',
|
||||
},
|
||||
inputStyle: {
|
||||
fontSize: 20,
|
||||
fontWeight: '500',
|
||||
textAlign: 'center',
|
||||
},
|
||||
confirmationModalView: {
|
||||
flex: 1,
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.4)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 40,
|
||||
},
|
||||
confirmationModalContentHeading: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
textAlign: 'center',
|
||||
marginBottom: 5,
|
||||
},
|
||||
confirmationModalContentSubHeading: {
|
||||
fontSize: 14,
|
||||
color: '#888',
|
||||
marginTop: 12,
|
||||
textAlign: 'center',
|
||||
lineHeight: 20,
|
||||
marginBottom: 20,
|
||||
},
|
||||
confirmationModalInnerView: {
|
||||
backgroundColor: 'white',
|
||||
borderRadius: 20,
|
||||
paddingVertical: 35,
|
||||
paddingHorizontal: 24,
|
||||
alignItems: 'center',
|
||||
},
|
||||
}),
|
||||
|
||||
TrustIssuerScreenStyle: StyleSheet.create({
|
||||
modalOverlay: {
|
||||
flex: 1,
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
padding: 20,
|
||||
},
|
||||
modalContainer: {
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 20,
|
||||
width: '100%',
|
||||
padding: 20,
|
||||
alignItems: 'center',
|
||||
},
|
||||
issuerHeader: {
|
||||
padding: 10,
|
||||
alignItems: 'center',
|
||||
marginBottom: 16,
|
||||
},
|
||||
issuerLogo: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
resizeMode: 'contain',
|
||||
},
|
||||
issuerName: {
|
||||
marginTop: 8,
|
||||
fontWeight: 'bold',
|
||||
fontSize: 16,
|
||||
},
|
||||
description: {
|
||||
fontSize: 14,
|
||||
color: '#666',
|
||||
textAlign: 'center',
|
||||
lineHeight: 20,
|
||||
marginBottom: 24,
|
||||
},
|
||||
}),
|
||||
|
||||
AuthWebViewScreenStyle: StyleSheet.create({
|
||||
header: {
|
||||
height: 56,
|
||||
paddingHorizontal: 16,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: '#F5F5F5',
|
||||
borderBottomWidth: 1,
|
||||
borderColor: '#E0E0E0',
|
||||
},
|
||||
headerText: {
|
||||
fontSize: 18,
|
||||
fontWeight: '500',
|
||||
},
|
||||
loader: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
}),
|
||||
|
||||
ICON_SMALL_SIZE: 16,
|
||||
ICON_MID_SIZE: 22,
|
||||
ICON_LARGE_SIZE: 33,
|
||||
|
||||
@@ -1943,6 +1943,118 @@ export const PurpleTheme = {
|
||||
paddingTop: 10,
|
||||
},
|
||||
}),
|
||||
TransactionCodeScreenStyle: StyleSheet.create({
|
||||
showMoreButton: {
|
||||
alignItems: 'flex-end',
|
||||
marginTop: 6,
|
||||
marginBottom: 10,
|
||||
marginRight: -Dimensions.get('window').width + 150,
|
||||
fontSize: 12,
|
||||
fontWeight: '600',
|
||||
color: Colors.Grey,
|
||||
},
|
||||
errorView: {
|
||||
backgroundColor: '#FAEFEF',
|
||||
padding: 8,
|
||||
borderRadius: 10,
|
||||
marginBottom: 10,
|
||||
marginTop: 10,
|
||||
width: '80%',
|
||||
},
|
||||
inputStyle: {
|
||||
fontSize: 20,
|
||||
fontWeight: '500',
|
||||
textAlign: 'center',
|
||||
},
|
||||
confirmationModalView: {
|
||||
flex: 1,
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.4)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 40,
|
||||
},
|
||||
confirmationModalContentHeading: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
textAlign: 'center',
|
||||
marginBottom: 5,
|
||||
},
|
||||
confirmationModalContentSubHeading: {
|
||||
fontSize: 14,
|
||||
color: '#888',
|
||||
marginTop: 12,
|
||||
textAlign: 'center',
|
||||
lineHeight: 20,
|
||||
marginBottom: 20,
|
||||
},
|
||||
confirmationModalInnerView: {
|
||||
backgroundColor: 'white',
|
||||
borderRadius: 20,
|
||||
paddingVertical: 35,
|
||||
paddingHorizontal: 24,
|
||||
alignItems: 'center',
|
||||
},
|
||||
}),
|
||||
TrustIssuerScreenStyle: StyleSheet.create({
|
||||
modalOverlay: {
|
||||
flex: 1,
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
padding: 20,
|
||||
},
|
||||
modalContainer: {
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 20,
|
||||
width: '100%',
|
||||
padding: 20,
|
||||
alignItems: 'center',
|
||||
},
|
||||
issuerHeader: {
|
||||
padding: 10,
|
||||
alignItems: 'center',
|
||||
marginBottom: 16,
|
||||
},
|
||||
issuerLogo: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
resizeMode: 'contain',
|
||||
},
|
||||
issuerName: {
|
||||
marginTop: 8,
|
||||
fontWeight: 'bold',
|
||||
fontSize: 16,
|
||||
},
|
||||
description: {
|
||||
fontSize: 14,
|
||||
color: '#666',
|
||||
textAlign: 'center',
|
||||
lineHeight: 20,
|
||||
marginBottom: 24,
|
||||
},
|
||||
}),
|
||||
|
||||
AuthWebViewScreenStyle: StyleSheet.create({
|
||||
header: {
|
||||
height: 56,
|
||||
paddingHorizontal: 16,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: '#F5F5F5',
|
||||
borderBottomWidth: 1,
|
||||
borderColor: '#E0E0E0',
|
||||
},
|
||||
headerText: {
|
||||
fontSize: 18,
|
||||
fontWeight: '500',
|
||||
},
|
||||
loader: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
}),
|
||||
|
||||
ICON_SMALL_SIZE: 16,
|
||||
ICON_MID_SIZE: 22,
|
||||
|
||||
@@ -10,17 +10,13 @@
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
1E55C2072DB12044009DF38B /* IntentData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E55C2062DB12044009DF38B /* IntentData.swift */; };
|
||||
1E55C20B2DB120C2009DF38B /* RNDeepLinkIntentModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E55C20A2DB120C2009DF38B /* RNDeepLinkIntentModule.swift */; };
|
||||
1E55C20D2DB120E7009DF38B /* RNDeepLinkIntentModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E55C20C2DB120E7009DF38B /* RNDeepLinkIntentModule.m */; };
|
||||
1E6875E92CA554E80086D870 /* OpenID4VP in Frameworks */ = {isa = PBXBuildFile; productRef = 1E6875E82CA554E80086D870 /* OpenID4VP */; };
|
||||
1E6875EB2CA554FD0086D870 /* RNOpenID4VPModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E6875EA2CA554FD0086D870 /* RNOpenID4VPModule.m */; };
|
||||
1E6875ED2CA5550F0086D870 /* RNOpenID4VPModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E6875EC2CA5550F0086D870 /* RNOpenID4VPModule.swift */; };
|
||||
1EED69F92DA913D30042EAFC /* IntentData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EED69F82DA913D30042EAFC /* IntentData.swift */; };
|
||||
1EED69FB2DA914130042EAFC /* RNDeepLinkIntentModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EED69FA2DA914130042EAFC /* RNDeepLinkIntentModule.swift */; };
|
||||
1EED69FD2DA914D00042EAFC /* RNDeepLinkIntentModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EED69FC2DA914D00042EAFC /* RNDeepLinkIntentModule.m */; };
|
||||
34873E472CD8DAF3004DE734 /* VCIClient in Frameworks */ = {isa = PBXBuildFile; productRef = 34873E462CD8DAF3004DE734 /* VCIClient */; };
|
||||
34873E4D2CD8DD11004DE734 /* pixelpass in Frameworks */ = {isa = PBXBuildFile; productRef = 34873E4C2CD8DD11004DE734 /* pixelpass */; };
|
||||
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
|
||||
717E6FEC33D6D8A2F9B01CBC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 1D23B9CD47CFD7F3C87D202F /* PrivacyInfo.xcprivacy */; };
|
||||
73295844242A4AD3AA52D0BE /* noop-file.swift in Sources */ = {isa = PBXBuildFile; fileRef = D98B96A488E54CBDB286B26F /* noop-file.swift */; };
|
||||
@@ -38,6 +34,8 @@
|
||||
9C7CDF3E2C7CBEDE00243A9A /* RNSecureKeystoreModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C7CDF3D2C7CBEDE00243A9A /* RNSecureKeystoreModule.swift */; };
|
||||
9C7CDF432C7CC13500243A9A /* RNSecureKeystoreModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7CDF422C7CC13500243A9A /* RNSecureKeystoreModule.m */; };
|
||||
9CCCA19E2CF87A8400D5A461 /* securekeystore in Frameworks */ = {isa = PBXBuildFile; productRef = 9CCCA19D2CF87A8400D5A461 /* securekeystore */; };
|
||||
9CFB37492DDDC9A000C199A8 /* pixelpass in Frameworks */ = {isa = PBXBuildFile; productRef = 9CFB37482DDDC9A000C199A8 /* pixelpass */; };
|
||||
9CFB374C2DDDC9B500C199A8 /* VCIClient in Frameworks */ = {isa = PBXBuildFile; productRef = 9CFB374B2DDDC9B500C199A8 /* VCIClient */; };
|
||||
B18059E884C0ABDD17F3DC3D /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC715A2D49A985799AEE119 /* ExpoModulesProvider.swift */; };
|
||||
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
|
||||
E86208152C0335C5007C3E24 /* RNVCIClientModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E86208142C0335C5007C3E24 /* RNVCIClientModule.swift */; };
|
||||
@@ -72,9 +70,7 @@
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Inji/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Inji/main.m; sourceTree = "<group>"; };
|
||||
1D23B9CD47CFD7F3C87D202F /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = Inji/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
1E55C2062DB12044009DF38B /* IntentData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentData.swift; sourceTree = "<group>"; };
|
||||
1E55C20A2DB120C2009DF38B /* RNDeepLinkIntentModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNDeepLinkIntentModule.swift; sourceTree = "<group>"; };
|
||||
1E55C20C2DB120E7009DF38B /* RNDeepLinkIntentModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNDeepLinkIntentModule.m; sourceTree = "<group>"; };
|
||||
1E6875EA2CA554FD0086D870 /* RNOpenID4VPModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNOpenID4VPModule.m; sourceTree = "<group>"; };
|
||||
1E6875EC2CA5550F0086D870 /* RNOpenID4VPModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNOpenID4VPModule.swift; sourceTree = "<group>"; };
|
||||
1EED69F82DA913D30042EAFC /* IntentData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentData.swift; sourceTree = "<group>"; };
|
||||
@@ -127,11 +123,11 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
34873E472CD8DAF3004DE734 /* VCIClient in Frameworks */,
|
||||
9CFB374C2DDDC9B500C199A8 /* VCIClient in Frameworks */,
|
||||
9C4850432C3E5873002ECBD5 /* ios-tuvali-library in Frameworks */,
|
||||
1E6875E92CA554E80086D870 /* OpenID4VP in Frameworks */,
|
||||
9CCCA19E2CF87A8400D5A461 /* securekeystore in Frameworks */,
|
||||
34873E4D2CD8DD11004DE734 /* pixelpass in Frameworks */,
|
||||
9CFB37492DDDC9A000C199A8 /* pixelpass in Frameworks */,
|
||||
96905EF65AED1B983A6B3ABC /* libPods-Inji.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -208,6 +204,7 @@
|
||||
D65327D7A22EEC0BE12398D9 /* Pods */,
|
||||
D7E4C46ADA2E9064B798F356 /* ExpoModulesProviders */,
|
||||
462CE07025BF40E9952DCDA0 /* Resources */,
|
||||
9CFB37462DDDC83900C199A8 /* Recovered References */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
@@ -230,6 +227,14 @@
|
||||
name = Inji;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9CFB37462DDDC83900C199A8 /* Recovered References */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1E55C20A2DB120C2009DF38B /* RNDeepLinkIntentModule.swift */,
|
||||
);
|
||||
name = "Recovered References";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BB2F792B24A3F905000567C9 /* Supporting */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -309,9 +314,9 @@
|
||||
packageProductDependencies = (
|
||||
9C4850422C3E5873002ECBD5 /* ios-tuvali-library */,
|
||||
1E6875E82CA554E80086D870 /* OpenID4VP */,
|
||||
34873E462CD8DAF3004DE734 /* VCIClient */,
|
||||
34873E4C2CD8DD11004DE734 /* pixelpass */,
|
||||
9CCCA19D2CF87A8400D5A461 /* securekeystore */,
|
||||
9CFB37482DDDC9A000C199A8 /* pixelpass */,
|
||||
9CFB374B2DDDC9B500C199A8 /* VCIClient */,
|
||||
);
|
||||
productName = Inji;
|
||||
productReference = 13B07F961A680F5B00A75B9A /* Inji.app */;
|
||||
@@ -340,11 +345,11 @@
|
||||
);
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
packageReferences = (
|
||||
34873E4B2CD8DD11004DE734 /* XCRemoteSwiftPackageReference "pixelpass-ios-swift" */,
|
||||
34873E452CD8DAF3004DE734 /* XCRemoteSwiftPackageReference "inji-vci-client-ios-swift" */,
|
||||
9C4850412C3E5873002ECBD5 /* XCRemoteSwiftPackageReference "tuvali-ios-swift" */,
|
||||
1E6875E72CA554E80086D870 /* XCRemoteSwiftPackageReference "inji-openid4vp-ios-swift" */,
|
||||
9CCCA19C2CF87A8400D5A461 /* XCRemoteSwiftPackageReference "secure-keystore-ios-swift" */,
|
||||
9CFB37472DDDC99F00C199A8 /* XCRemoteSwiftPackageReference "pixelpass-ios-swift" */,
|
||||
9CFB374A2DDDC9B500C199A8 /* XCRemoteSwiftPackageReference "inji-vci-client-ios-swift" */,
|
||||
);
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
@@ -592,12 +597,11 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Inji/Inji.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = V2ABX7953Z;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = V2ABX7953Z;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
@@ -829,22 +833,6 @@
|
||||
kind = branch;
|
||||
};
|
||||
};
|
||||
34873E452CD8DAF3004DE734 /* XCRemoteSwiftPackageReference "inji-vci-client-ios-swift" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/mosip/inji-vci-client-ios-swift";
|
||||
requirement = {
|
||||
branch = develop;
|
||||
kind = branch;
|
||||
};
|
||||
};
|
||||
34873E4B2CD8DD11004DE734 /* XCRemoteSwiftPackageReference "pixelpass-ios-swift" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/mosip/pixelpass-ios-swift";
|
||||
requirement = {
|
||||
branch = develop;
|
||||
kind = branch;
|
||||
};
|
||||
};
|
||||
9C4850412C3E5873002ECBD5 /* XCRemoteSwiftPackageReference "tuvali-ios-swift" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/mosip/tuvali-ios-swift/";
|
||||
@@ -861,6 +849,22 @@
|
||||
version = 0.3.0;
|
||||
};
|
||||
};
|
||||
9CFB37472DDDC99F00C199A8 /* XCRemoteSwiftPackageReference "pixelpass-ios-swift" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/mosip/pixelpass-ios-swift/";
|
||||
requirement = {
|
||||
branch = develop;
|
||||
kind = branch;
|
||||
};
|
||||
};
|
||||
9CFB374A2DDDC9B500C199A8 /* XCRemoteSwiftPackageReference "inji-vci-client-ios-swift" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/mosip/inji-vci-client-ios-swift";
|
||||
requirement = {
|
||||
branch = develop;
|
||||
kind = branch;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
@@ -869,16 +873,6 @@
|
||||
package = 1E6875E72CA554E80086D870 /* XCRemoteSwiftPackageReference "inji-openid4vp-ios-swift" */;
|
||||
productName = OpenID4VP;
|
||||
};
|
||||
34873E462CD8DAF3004DE734 /* VCIClient */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 34873E452CD8DAF3004DE734 /* XCRemoteSwiftPackageReference "inji-vci-client-ios-swift" */;
|
||||
productName = VCIClient;
|
||||
};
|
||||
34873E4C2CD8DD11004DE734 /* pixelpass */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 34873E4B2CD8DD11004DE734 /* XCRemoteSwiftPackageReference "pixelpass-ios-swift" */;
|
||||
productName = pixelpass;
|
||||
};
|
||||
9C4850422C3E5873002ECBD5 /* ios-tuvali-library */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 9C4850412C3E5873002ECBD5 /* XCRemoteSwiftPackageReference "tuvali-ios-swift" */;
|
||||
@@ -889,6 +883,16 @@
|
||||
package = 9CCCA19C2CF87A8400D5A461 /* XCRemoteSwiftPackageReference "secure-keystore-ios-swift" */;
|
||||
productName = securekeystore;
|
||||
};
|
||||
9CFB37482DDDC9A000C199A8 /* pixelpass */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 9CFB37472DDDC99F00C199A8 /* XCRemoteSwiftPackageReference "pixelpass-ios-swift" */;
|
||||
productName = pixelpass;
|
||||
};
|
||||
9CFB374B2DDDC9B500C199A8 /* VCIClient */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 9CFB374A2DDDC9B500C199A8 /* XCRemoteSwiftPackageReference "inji-vci-client-ios-swift" */;
|
||||
productName = VCIClient;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
};
|
||||
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"originHash" : "178f6c7c607eeb08b99a4966015d08339500de64791888a2e79d6b7afae53659",
|
||||
"originHash" : "2d4bd4f2ff41823478f56a65a061c28a141105b8447f22a9d1cef51048d33e76",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "alamofire",
|
||||
@@ -51,8 +51,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/mosip/inji-openid4vp-ios-swift",
|
||||
"state" : {
|
||||
"branch" : "release-0.3.x",
|
||||
"revision" : "58ac61a84fdef03b7a1cc9e6f4ba3c4bfd57fe61"
|
||||
"branch" : "develop",
|
||||
"revision" : "c83527449f97c07e6f0a0bec239f9afe477bf216"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -60,8 +60,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/mosip/inji-vci-client-ios-swift",
|
||||
"state" : {
|
||||
"branch" : "release-0.3.x",
|
||||
"revision" : "02f367bd2527f249145393a533f5175918c1fc8a"
|
||||
"branch" : "develop",
|
||||
"revision" : "8a39bbf7805af4c615904090a027fa472e5f4534"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -76,10 +76,10 @@
|
||||
{
|
||||
"identity" : "pixelpass-ios-swift",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/mosip/pixelpass-ios-swift",
|
||||
"location" : "https://github.com/mosip/pixelpass-ios-swift/",
|
||||
"state" : {
|
||||
"branch" : "develop",
|
||||
"revision" : "760438e38e01bd9deb170585f37d7c05c5c1785a"
|
||||
"revision" : "78a8b507f5bd0046e273e3ba962696b44aea0e33"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -128,5 +128,5 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 2
|
||||
"version" : 3
|
||||
}
|
||||
|
||||
203
ios/Podfile.lock
203
ios/Podfile.lock
@@ -1189,6 +1189,27 @@ PODS:
|
||||
- React-Core
|
||||
- react-native-spinkit (1.4.1):
|
||||
- React
|
||||
- react-native-webview (13.13.5):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- hermes-engine
|
||||
- RCT-Folly (= 2024.01.01.00)
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React-Codegen
|
||||
- React-Core
|
||||
- React-debug
|
||||
- React-Fabric
|
||||
- React-featureflags
|
||||
- React-graphics
|
||||
- React-ImageManager
|
||||
- React-NativeModulesApple
|
||||
- React-RCTFabric
|
||||
- React-rendererdebug
|
||||
- React-utils
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- Yoga
|
||||
- React-nativeconfig (0.74.5)
|
||||
- React-NativeModulesApple (0.74.5):
|
||||
- glog
|
||||
@@ -1587,6 +1608,7 @@ DEPENDENCIES:
|
||||
- react-native-rsa-native (from `../node_modules/react-native-rsa-native`)
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
- react-native-spinkit (from `../node_modules/react-native-spinkit`)
|
||||
- react-native-webview (from `../node_modules/react-native-webview`)
|
||||
- React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
|
||||
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
|
||||
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
|
||||
@@ -1798,6 +1820,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native-safe-area-context"
|
||||
react-native-spinkit:
|
||||
:path: "../node_modules/react-native-spinkit"
|
||||
react-native-webview:
|
||||
:path: "../node_modules/react-native-webview"
|
||||
React-nativeconfig:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
React-NativeModulesApple:
|
||||
@@ -1881,33 +1905,33 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73
|
||||
biometric-sdk-react-native: 11925e3af28eecd733efc43670c5d8b4f014cddc
|
||||
biometric-sdk-react-native: d2a3a1279013cc4a7514a1b43fe557eb76e4e4c1
|
||||
BiometricSdk: 303e7329404ea4d922dc14108449d10d21574f77
|
||||
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
|
||||
BVLinearGradient: cb006ba232a1f3e4f341bb62c42d1098c284da70
|
||||
BVLinearGradient: 880f91a7854faff2df62518f0281afb1c60d49a3
|
||||
CatCrypto: a477899b6be4954e75be4897e732da098cc0a5a8
|
||||
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
|
||||
EASClient: 95592393d6d1e60609f0afb373191d918c687b98
|
||||
EXApplication: ec862905fdab3a15bf6bd8ca1a99df7fc02d7762
|
||||
EXConstants: 89d35611505a8ce02550e64e43cd05565da35f9a
|
||||
EXFaceDetector: 917b279228541801bfa8ee22d867594ef84e31de
|
||||
EASClient: 1509a9a6b48b932ec61667644634daf2562983b8
|
||||
EXApplication: c08200c34daca7af7fd76ac4b9d606077410e8ad
|
||||
EXConstants: 409690fbfd5afea964e5e9d6c4eb2c2b59222c59
|
||||
EXFaceDetector: 50810192af3c2b80a53a6778b4e67af78b8e4cd5
|
||||
EXJSONUtils: 30c17fd9cc364d722c0946a550dfbf1be92ef6a4
|
||||
EXManifests: ebb7f551c340c0d06f3ecd9ae662e418bf68417c
|
||||
Expo: ed0a748eb6be0efd2c3df7f6de3f3158a14464c9
|
||||
ExpoAdapterGoogleSignIn: 97fc4b93c6b35837b5a5f2ff8ee5403548c1a4ba
|
||||
ExpoAsset: 286fee7ba711ce66bf20b315e68106b13b8629fc
|
||||
ExpoCamera: cf49d2d121a9f883be0f98dde15a2185a1dd42be
|
||||
ExpoCrypto: c5c052d5f9f668c21975cb4caf072cec23c823fa
|
||||
ExpoFileSystem: 2988caaf68b7cb706e36d382829d99811d9d76a5
|
||||
ExpoFont: 38dddf823e32740c2a9f37c926a33aeca736b5c4
|
||||
ExpoKeepAwake: dd02e65d49f1cfd9194640028ae2857e536eb1c9
|
||||
ExpoLocalAuthentication: b94db59f55df95350223200c746b4ddf0cb7cfc0
|
||||
ExpoLocalization: 1b4195ed48148c7f52ce790d3965cc19483fcbf2
|
||||
ExpoModulesCore: 9ac73e2f60e0ea1d30137ca96cfc8c2aa34ef2b2
|
||||
ExpoWebBrowser: cf10afe886891ab495877dada977fe6c269614a4
|
||||
EXManifests: c1fab4c3237675e7b0299ea8df0bcb14baca4f42
|
||||
Expo: 8c995afb875c15bf8439af0b20bcb9ed8f90d0bd
|
||||
ExpoAdapterGoogleSignIn: 6c55782832b7fbdc2c27dac05ef00445c103b8f3
|
||||
ExpoAsset: 323700f291684f110fb55f0d4022a3362ea9f875
|
||||
ExpoCamera: 929be541d1c1319fcf32f9f5d9df8b97804346b5
|
||||
ExpoCrypto: 156078f266bf28f80ecf5e2a9c3a0d6ffce07a1c
|
||||
ExpoFileSystem: 80bfe850b1f9922c16905822ecbf97acd711dc51
|
||||
ExpoFont: 00756e6c796d8f7ee8d211e29c8b619e75cbf238
|
||||
ExpoKeepAwake: 3b8815d9dd1d419ee474df004021c69fdd316d08
|
||||
ExpoLocalAuthentication: 9e02a56a4cf9868f0052656a93d4c94101a42ed7
|
||||
ExpoLocalization: f04eeec2e35bed01ab61c72ee1768ec04d093d01
|
||||
ExpoModulesCore: 831ece8311a489418746925820bbffdda587d6f4
|
||||
ExpoWebBrowser: 7595ccac6938eb65b076385fd23d035db9ecdc8e
|
||||
EXStructuredHeaders: cb8d1f698e144f4c5547b4c4963e1552f5d2b457
|
||||
EXUpdates: bb1b0790e3b2adfbb193ad6a51c567a4bd2adf9f
|
||||
EXUpdatesInterface: c3a9494c2173db6442c7d5ad4e5b984972760fd3
|
||||
EXUpdates: 52c797a4b71b25315353041c29571cd65ecc7141
|
||||
EXUpdatesInterface: 996527fd7d1a5d271eb523258d603f8f92038f24
|
||||
FBLazyVector: ac12dc084d1c8ec4cc4d7b3cf1b0ebda6dab85af
|
||||
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
|
||||
glog: fdfdfe5479092de0c4bdbebedd9056951f092c4f
|
||||
@@ -1920,7 +1944,7 @@ SPEC CHECKSUMS:
|
||||
GTMAppAuth: 99fb010047ba3973b7026e45393f51f27ab965ae
|
||||
GTMSessionFetcher: 5595ec75acf5be50814f81e9189490412bad82ba
|
||||
hermes-engine: 8c1577f3fdb849cbe7729c2e7b5abc4b845e88f8
|
||||
ImageColors: 869f48b27ca2afb347fd0bada3257a5f698ee55e
|
||||
ImageColors: 88be684570585c07ae2750bff34eb7b78bfc53b4
|
||||
MLImage: a454f9f8ecfd537783a12f9488f5be1a68820829
|
||||
MLKitCommon: 3bc17c6f7d25ce3660f030350b46ae7ec9ebca6e
|
||||
MLKitFaceDetection: 617cb847441868a8bfd4b48d751c9b33c1104948
|
||||
@@ -1928,87 +1952,88 @@ SPEC CHECKSUMS:
|
||||
MMKV: aac95d817a100479445633f2b3ed8961b4ac5043
|
||||
MMKVCore: 9cfef4c48c6c46f66226fc2e4634d78490206a48
|
||||
nanopb: 438bc412db1928dac798aa6fd75726007be04262
|
||||
Permission-BluetoothPeripheral: aa44bde6f52530eb00c0128ee2575b68fe8abdfe
|
||||
Permission-Camera: 78301f2241e8297a80089d2452adbef2add8fe56
|
||||
Permission-LocationAccuracy: 7ee13967dc5272e08172f5afa40c408bf83b6196
|
||||
Permission-LocationWhenInUse: 59523bb3d8b95b267baa172ecbf1f31bc672795a
|
||||
Permission-BluetoothPeripheral: 2b88a131074edafd8a46a5cda4ba610ec986d2fb
|
||||
Permission-Camera: 7ec9ee99704766ff9b90198183387a7f5d82b0c1
|
||||
Permission-LocationAccuracy: a38ddb5c5d0b8e656f3c86e4a500f9bb88bc099d
|
||||
Permission-LocationWhenInUse: 24d97eeb25d8ff9f2232e070f792eeb1360ccaf0
|
||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||
Protobuf: 0c5a9e64f38aed73b5d1ff88a20112ce195cf909
|
||||
RCT-Folly: 5dc73daec3476616d19e8a53f0156176f7b55461
|
||||
RCT-Folly: 02617c592a293bd6d418e0a88ff4ee1f88329b47
|
||||
RCTDeprecation: 3afceddffa65aee666dafd6f0116f1d975db1584
|
||||
RCTRequired: ec1239bc9d8bf63e10fb92bd8b26171a9258e0c1
|
||||
RCTTypeSafety: f5ecbc86c5c5fa163c05acb7a1c5012e15b5f994
|
||||
ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda
|
||||
React: fc9fa7258eff606f44d58c5b233a82dc9cf09018
|
||||
React-callinvoker: e3fab14d69607fb7e8e3a57e5a415aed863d3599
|
||||
React-Codegen: 3963186cb6a4ef21b5e67dcf7badf359867ff6df
|
||||
React-Core: c3f589f104983dec3c3eeec5e70d61aa811bc236
|
||||
React-CoreModules: 864932ddae3ead5af5bfb05f9bbc2cedcb958b39
|
||||
React-cxxreact: bd9146108c44e6dbb99bba4568ce7af0304a2419
|
||||
React-Codegen: 6fa87b7c6b8efcd0cef4bfeaec8c8bc8a6abe75a
|
||||
React-Core: 3a5fd9e781cecf87803e5b091496a606a3df774a
|
||||
React-CoreModules: cbf4707dafab8f9f826ac0c63a07d0bf5d01e256
|
||||
React-cxxreact: 7b188556271e3c7fdf22a04819f6a6225045b9dd
|
||||
React-debug: d30893c49ae1bce4037ea5cd8bb2511d2a38d057
|
||||
React-Fabric: a171830e52baf8ec2b175c6a3791e01bbb92f1fb
|
||||
React-FabricImage: ad154af0067f4b5dc5a41f607e48ee343641e903
|
||||
React-Fabric: 826729dd2304fda9b89ff0a579f60ba2a470bc26
|
||||
React-FabricImage: 2ad1fb8ffa5778eda9ed204a7b3cdd70bc333ce7
|
||||
React-featureflags: 4ae83e72d9a92452793601ac9ac7d2280e486089
|
||||
React-graphics: ed7d57965140168de86835946e8f1210c72c65dc
|
||||
React-hermes: 177b1efdf3b8f10f4ca12b624b83fb4d4ccb2884
|
||||
React-ImageManager: 3a50d0ee0bf81b1a6f23a0c5b30388293bcd6004
|
||||
React-jserrorhandler: dcd62f5ca1c724c19637595ef7f45b78018e758f
|
||||
React-jsi: 0abe1b0881b67caf8d8df6a57778dd0d3bb9d9a5
|
||||
React-jsiexecutor: f6ca8c04f19f6a3acaa9610f7fb728f39d6e3248
|
||||
React-jsinspector: db98771eae84e6f86f0ca5d9dcc572baadbfefc0
|
||||
React-jsitracing: f8367edacc50bb3f9f056a5aeafb8cee5849fafb
|
||||
React-logger: 780b9ee9cec7d44eabc4093de90107c379078cb6
|
||||
React-Mapbuffer: f544f00b98dbdd8cbae96dd2bdb8b47f719976e0
|
||||
react-native-app-auth: 5bf64c0d0e7cbea8ff6ea0b90e4397c8dcfc656a
|
||||
react-native-cloud-storage: ddc959e7ddb08ff18ce9389787aa7254d7f45ee3
|
||||
react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba
|
||||
react-native-image-editor: 29a86ccb509072a429c56abf73c35d63288108e5
|
||||
react-native-location: 70e6bdfe4a98a80ebda57fd5b30994e48d082e99
|
||||
react-native-mmkv-storage: 45287ac5851a967d15f6c59b4a8aee6331bec034
|
||||
react-native-netinfo: 2e3c27627db7d49ba412bfab25834e679db41e21
|
||||
react-native-restart: df7caae89026a8ab2ecdd82839978f657701f51d
|
||||
react-native-rsa-native: a7931cdda1f73a8576a46d7f431378c5550f0c38
|
||||
react-native-safe-area-context: df9763c5de6fa38883028e243a0b60123acb8858
|
||||
react-native-spinkit: 96a74c3519fab0eded2ab8c285f774aa3f4b7944
|
||||
React-graphics: 61a026e1c1e7e20d20ac9fec6f6de631732b233d
|
||||
React-hermes: a7054fbcbda3957e3c5eaad06ef9bf79998d535a
|
||||
React-ImageManager: 2bbd6eb2e696bc680f76f84563e4b87d241614e1
|
||||
React-jserrorhandler: 56fa04d49bfbe54ddfece7916673a73ebfea286b
|
||||
React-jsi: f3ce1dd2e950b6ad12b65ea3ef89168f1b94c584
|
||||
React-jsiexecutor: b4df3a27973d82f9abf3c4bd0f88e042cda25f16
|
||||
React-jsinspector: 97ea746c023687de7313ee289817d6991d596c7d
|
||||
React-jsitracing: 3b6060bbf5317663667e1dd93560c7943ab86ccc
|
||||
React-logger: 257858bd55f3a4e1bc0cf07ddc8fb9faba6f8c7c
|
||||
React-Mapbuffer: 6c1cacdbf40b531f549eba249e531a7d0bfd8e7f
|
||||
react-native-app-auth: 63fa4e58c5bd29aeb974d3a06a23c5858322d533
|
||||
react-native-cloud-storage: 15f24d9b9f175ce07473c3af86b6add72a727c95
|
||||
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
|
||||
react-native-image-editor: b09448ba9171308ff5ac6c9f66f49ad4cbfaee06
|
||||
react-native-location: 5a40ec1cc6abf2f6d94df979f98ec76c3a415681
|
||||
react-native-mmkv-storage: cfb6854594cfdc5f7383a9e464bb025417d1721c
|
||||
react-native-netinfo: bdb108d340cdb41875c9ced535977cac6d2ff321
|
||||
react-native-restart: 45c8dca02491980f2958595333cbccd6877cb57e
|
||||
react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a
|
||||
react-native-safe-area-context: a240ad4b683349e48b1d51fed1611138d1bdad97
|
||||
react-native-spinkit: da294fd828216ad211fe36a5c14c1e09f09e62db
|
||||
react-native-webview: db97533d0b7534225f48ad4e0c313b83cfae8a20
|
||||
React-nativeconfig: ba9a2e54e2f0882cf7882698825052793ed4c851
|
||||
React-NativeModulesApple: 84aaad2b0e546d7b839837ca537f6e72804a4cad
|
||||
React-NativeModulesApple: 8d11ff8955181540585c944cf48e9e7236952697
|
||||
React-perflogger: ed4e0c65781521e0424f2e5e40b40cc7879d737e
|
||||
React-RCTActionSheet: 49d53ff03bb5688ca4606c55859053a0cd129ea5
|
||||
React-RCTAnimation: 3075449f26cb98a52bcbf51cccd0c7954e2a71db
|
||||
React-RCTAppDelegate: 9a419c4dda9dd039ad851411546dd297b930c454
|
||||
React-RCTBlob: e81ab773a8fc1e9dceed953e889f936a7b7b3aa6
|
||||
React-RCTFabric: 47a87a3e3fa751674f7e64d0bcd58976b8c57db9
|
||||
React-RCTImage: d570531201c6dce7b5b63878fa8ecec0cc311c4c
|
||||
React-RCTLinking: af888972b925d2811633d47853c479e88c35eb4d
|
||||
React-RCTNetwork: 5728a06ff595003eca628f43f112a804f4a9a970
|
||||
React-RCTSettings: ba3665b0569714a8aaceee5c7d23b943e333fa55
|
||||
React-RCTText: b733fa984f0336b072e47512898ba91214f66ddb
|
||||
React-RCTVibration: 0cbcbbd8781b6f6123671bae9ee5dd20d621af6c
|
||||
React-rendererdebug: 9fc8f7d0bd19f2a3fe3791982af550b5e1535ff7
|
||||
React-RCTAnimation: 07b4923885c52c397c4ec103924bf6e53b42c73e
|
||||
React-RCTAppDelegate: 316e295076734baf9bdf1bfac7d92ab647aed930
|
||||
React-RCTBlob: 85c57b0d5e667ff8a472163ba3af0628171a64bb
|
||||
React-RCTFabric: 97c1465ded4dc92841f5376a39e43e1b2c455f40
|
||||
React-RCTImage: b965c85bec820e2a9c154b1fb00a2ecdd59a9c92
|
||||
React-RCTLinking: 75f04a5f27c26c4e73a39c50df470820d219df79
|
||||
React-RCTNetwork: c1a9143f4d5778efc92da40d83969d03912ccc24
|
||||
React-RCTSettings: c6800f91c0ecd48868cd5db754b0b0a7f5ffe039
|
||||
React-RCTText: b923e24f9b7250bc4f7ab154c4168ad9f8d8fc9d
|
||||
React-RCTVibration: 08c4f0c917c435b3619386c25a94ee5d64c250f0
|
||||
React-rendererdebug: 3cda04217d9df67b94397ee0ead8ef3d8b7e427b
|
||||
React-rncore: 4013508a2f3fcf46c961919bbbd4bfdda198977e
|
||||
React-RuntimeApple: a852a6e06ab20711658873f39cb10b0033bea19d
|
||||
React-RuntimeCore: 12e5e176c0cb09926f3e6f37403a84d2e0f203a7
|
||||
React-RuntimeApple: 447844a2bdb0a03ffd24e5b4a4b96cfc50325b88
|
||||
React-RuntimeCore: 9b5bffdaccee9b707b1c2694c9044e13ff0bb087
|
||||
React-runtimeexecutor: 0e688aefc14c6bc8601f4968d8d01c3fb6446844
|
||||
React-RuntimeHermes: 80c03a5215520c9733764ba11cbe535053c9746d
|
||||
React-runtimescheduler: 2cbd0f3625b30bba08e8768776107f6f0203159b
|
||||
React-utils: 9fa4e5d0b5e6c6c85c958f19d6ef854337886417
|
||||
ReactCommon: 9f285823dbe955099978d9bff65a7653ca029256
|
||||
RNAppleAuthentication: 445222cf501db405f0b3713593a6d0fecc87fd05
|
||||
RNArgon2: 708e188b7a4d4ec8baf62463927c47abef453a94
|
||||
RNBluetoothStateManager: 221894bb59b22ec8be372740178545d0bbdb1ab6
|
||||
RNCClipboard: efe1b27ad1ea378c60c8c8aabfd130961bbeb474
|
||||
RNCPicker: 15ad063c72ecba748be9edea62a5bdce53090aa6
|
||||
RNDeviceInfo: 98bb51ba1519cd3f19f14e7236b5bb1c312c780f
|
||||
RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8
|
||||
RNGestureHandler: 326e35460fb6c8c64a435d5d739bea90d7ed4e49
|
||||
RNGoogleSignin: bee4a648cf7bfe848b3674b5d487504831a115dd
|
||||
RNLocalize: d024afa9204c13885e61dc88b8190651bcaabac9
|
||||
RNPermissions: 1e3fb35b2ac79aaad28788302ead31ca8230d611
|
||||
RNScreens: a2d8a2555b4653d7a19706eb172f855657ac30d7
|
||||
RNSecureRandom: b64d263529492a6897e236a22a2c4249aa1b53dc
|
||||
RNShare: 694e19d7f74ac4c04de3a8af0649e9ccc03bd8b1
|
||||
RNSVG: 0e7deccab0678200815104223aadd5ca734dd41d
|
||||
RNZipArchive: 2b0d34cfe303447f5b55ae5658ec62f1ebce4ab5
|
||||
React-RuntimeHermes: 4d6ef6bb0f2b0b40d59143317f6b99c82764c959
|
||||
React-runtimescheduler: cfbe85c3510c541ec6dc815c7729b41304b67961
|
||||
React-utils: f242eb7e7889419d979ca0e1c02ccc0ea6e43b29
|
||||
ReactCommon: f7da14a8827b72704169a48c929bcde802698361
|
||||
RNAppleAuthentication: e99eaf3c4c01ad8ecb6125dd6f0cfd98871685b5
|
||||
RNArgon2: 1481820722fd4af1575c09f7fc9ad67c00ee8a42
|
||||
RNBluetoothStateManager: ae6a26260cbdf1827b58bd3bcc563527d61e6488
|
||||
RNCClipboard: 3f0451a8100393908bea5c5c5b16f96d45f30bfc
|
||||
RNCPicker: 3e2c37a8328f368ce14da050cdc8231deb5fc9f9
|
||||
RNDeviceInfo: 59344c19152c4b2b32283005f9737c5c64b42fba
|
||||
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
|
||||
RNGestureHandler: 2282cfbcf86c360d29f44ace393203afd5c6cff7
|
||||
RNGoogleSignin: aac5c1ec73422109dec1da770247a1e410dcc620
|
||||
RNLocalize: 298e85ce16540a11de40c1a588ead39fc5e9a072
|
||||
RNPermissions: f1b49dd05fa9b83993cd05a9ee115247944d8f1a
|
||||
RNScreens: b32a9ff15bea7fcdbe5dff6477bc503f792b1208
|
||||
RNSecureRandom: 07efbdf2cd99efe13497433668e54acd7df49fef
|
||||
RNShare: 0fad69ae2d71de9d1f7b9a43acf876886a6cb99c
|
||||
RNSVG: 43b64ed39c14ce830d840903774154ca0c1f27ec
|
||||
RNZipArchive: ef9451b849c45a29509bf44e65b788829ab07801
|
||||
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
|
||||
sqlite3: 02d1f07eaaa01f80a1c16b4b31dfcbb3345ee01a
|
||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||
@@ -2017,6 +2042,6 @@ SPEC CHECKSUMS:
|
||||
Yoga: 950bbfd7e6f04790fdb51149ed51df41f329fcc8
|
||||
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5
|
||||
|
||||
PODFILE CHECKSUM: 4d2ee2cbf5f1553030d56659748bb7baece24998
|
||||
PODFILE CHECKSUM: a555e3bf20e7a7fbd521747ca919066410e3af18
|
||||
|
||||
COCOAPODS: 1.16.2
|
||||
|
||||
@@ -3,14 +3,34 @@
|
||||
|
||||
@interface RCT_EXTERN_MODULE(InjiVciClient, NSObject)
|
||||
|
||||
RCT_EXTERN_METHOD(init:(NSString *)appId)
|
||||
// Initializes the VCIClient with a traceability ID
|
||||
RCT_EXTERN_METHOD(init:(NSString *)traceabilityId)
|
||||
|
||||
RCT_EXTERN_METHOD(requestCredential:(id)issuerMeta
|
||||
proof:(NSString *)proof
|
||||
accessToken:(NSString *)accessToken
|
||||
// Requests a credential using a credential offer string and client metadata (both as JSON strings)
|
||||
RCT_EXTERN_METHOD(requestCredentialByOffer:(NSString *)credentialOffer
|
||||
clientMetadata:(NSString *)clientMetadata
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject);
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
|
||||
RCT_EXTERN_METHOD(requiresMainQueueSetup:(BOOL))
|
||||
// Requests a credential from a trusted issuer using issuer metadata and client metadata (both as JSON strings)
|
||||
RCT_EXTERN_METHOD(requestCredentialFromTrustedIssuer:(NSString *)issuerMetadata
|
||||
clientMetadata:(NSString *)clientMetadata
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
|
||||
// Sends proof JWT back to native side (in response to onRequestProof)
|
||||
RCT_EXTERN_METHOD(sendProofFromJS:(NSString *)jwtProof)
|
||||
|
||||
// Sends authorization code back to native side (in response to onRequestAuthCode)
|
||||
RCT_EXTERN_METHOD(sendAuthCodeFromJS:(NSString *)authCode)
|
||||
|
||||
// Sends tx_code back to native side (in response to onRequestTxCode)
|
||||
RCT_EXTERN_METHOD(sendTxCodeFromJS:(NSString *)txCode)
|
||||
|
||||
// Sends issuer trust decision (true/false) back to native side (in response to onCheckIssuerTrust)
|
||||
RCT_EXTERN_METHOD(sendIssuerTrustResponseFromJS:(BOOL)isTrusted)
|
||||
|
||||
// Required by React Native
|
||||
RCT_EXTERN_METHOD(requiresMainQueueSetup:(BOOL)isRequired)
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,86 +1,222 @@
|
||||
import Foundation
|
||||
import VCIClient
|
||||
import React
|
||||
import VCIClient
|
||||
|
||||
@objc(InjiVciClient)
|
||||
class RNVCIClientModule: NSObject, RCTBridgeModule {
|
||||
private var vciClient: VCIClient?
|
||||
private var pendingProofContinuation: ((String) -> Void)?
|
||||
private var pendingAuthCodeContinuation: ((String) -> Void)?
|
||||
private var pendingTxCodeContinuation: ((String) -> Void)?
|
||||
private var pendingIssuerTrustDecision: ((Bool) -> Void)?
|
||||
|
||||
private var vciClient: VCIClient?
|
||||
|
||||
static func moduleName() -> String {
|
||||
return "InjiVciClient"
|
||||
}
|
||||
|
||||
@objc
|
||||
func `init`(_ traceabilityId: String) {
|
||||
vciClient = VCIClient(traceabilityId: traceabilityId)
|
||||
static func moduleName() -> String {
|
||||
return "InjiVciClient"
|
||||
}
|
||||
|
||||
@objc
|
||||
func requestCredential(_ issuerMeta: AnyObject, proof: String, accessToken: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
||||
Task {
|
||||
do {
|
||||
guard let issuerMetaDict = issuerMeta as? [String: Any] else {
|
||||
reject(nil, "Invalid issuerMeta format", nil)
|
||||
return
|
||||
}
|
||||
@objc
|
||||
func `init`(_ traceabilityId: String) {
|
||||
vciClient = VCIClient(traceabilityId: traceabilityId)
|
||||
}
|
||||
|
||||
@objc
|
||||
func requestCredentialByOffer(
|
||||
_ credentialOffer: String,
|
||||
clientMetadata: String,
|
||||
resolver resolve: @escaping RCTPromiseResolveBlock,
|
||||
rejecter reject: @escaping RCTPromiseRejectBlock
|
||||
) {
|
||||
Task {
|
||||
do {
|
||||
guard let vciClient = vciClient else {
|
||||
reject(nil, "VCIClient not initialized", nil)
|
||||
return
|
||||
}
|
||||
|
||||
guard let credentialAudience = issuerMetaDict["credentialAudience"] as? String,
|
||||
let credentialEndpoint = issuerMetaDict["credentialEndpoint"] as? String,
|
||||
let downloadTimeoutInMilliseconds = issuerMetaDict["downloadTimeoutInMilliSeconds"] as? Int,
|
||||
let credentialFormatString = issuerMetaDict["credentialFormat"] as? String,
|
||||
let credentialFormat = CredentialFormat(rawValue: credentialFormatString) else {
|
||||
reject(nil, "Invalid issuerMeta format", nil)
|
||||
return
|
||||
}
|
||||
let clientMeta = try parseClientMetadata(from: clientMetadata)
|
||||
|
||||
var issuerMetaObject : IssuerMeta
|
||||
let response = try await vciClient.requestCredentialByCredentialOffer(
|
||||
credentialOffer: credentialOffer,
|
||||
clientMetadata: clientMeta,
|
||||
getTxCode: { inputMode, description, length in
|
||||
try await self.getTxCodeHook(
|
||||
inputMode: inputMode,
|
||||
description: description,
|
||||
length: length
|
||||
)
|
||||
},
|
||||
getProofJwt: { accessToken, cNonce, issuerMetadata, credentialConfigId in
|
||||
try await self.getProofContinuationHook(
|
||||
accessToken: accessToken,
|
||||
cNonce: cNonce,
|
||||
issuerMetadata: issuerMetadata,
|
||||
credentialConfigId: credentialConfigId
|
||||
)
|
||||
},
|
||||
getAuthCode: { authUrl in
|
||||
try await self.getAuthCodeContinuationHook(authUrl: authUrl)
|
||||
},
|
||||
onCheckIssuerTrust: { issuerMetadata in
|
||||
try await self.getIssuerTrustDecisionHook(issuerMetadata: issuerMetadata)
|
||||
}
|
||||
)
|
||||
|
||||
switch credentialFormat {
|
||||
case .ldp_vc:
|
||||
guard let credentialType = issuerMetaDict["credentialType"] as? [String] else {
|
||||
reject(nil, "Invalid issuerMeta format", nil)
|
||||
return
|
||||
}
|
||||
issuerMetaObject = IssuerMeta(
|
||||
credentialAudience: credentialAudience,
|
||||
credentialEndpoint: credentialEndpoint,
|
||||
downloadTimeoutInMilliseconds: downloadTimeoutInMilliseconds,
|
||||
credentialType: credentialType,
|
||||
credentialFormat: credentialFormat
|
||||
)
|
||||
|
||||
case .mso_mdoc:
|
||||
guard let doctype = issuerMetaDict["doctype"] as? String,
|
||||
let claims = issuerMetaDict["claims"] as? [String:Any] else {
|
||||
reject(nil, "Invalid issuerMeta format", nil)
|
||||
return
|
||||
}
|
||||
issuerMetaObject = IssuerMeta(
|
||||
credentialAudience: credentialAudience,
|
||||
credentialEndpoint: credentialEndpoint,
|
||||
downloadTimeoutInMilliseconds: downloadTimeoutInMilliseconds,
|
||||
credentialFormat: .mso_mdoc,
|
||||
docType: doctype,
|
||||
claims: claims
|
||||
)
|
||||
resolve(try response?.toJsonString())
|
||||
} catch {
|
||||
reject(nil, error.localizedDescription, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
func requestCredentialFromTrustedIssuer(
|
||||
_ issuerMetadata: String,
|
||||
clientMetadata: String,
|
||||
resolver resolve: @escaping RCTPromiseResolveBlock,
|
||||
rejecter reject: @escaping RCTPromiseRejectBlock
|
||||
) {
|
||||
Task {
|
||||
do {
|
||||
guard let vciClient = vciClient else {
|
||||
reject(nil, "VCIClient not initialized", nil)
|
||||
return
|
||||
}
|
||||
|
||||
let issuer = try parseIssuerMeta(from: issuerMetadata)
|
||||
let clientMeta = try parseClientMetadata(from: clientMetadata)
|
||||
|
||||
let response = try await vciClient.requestCredentialFromTrustedIssuer(
|
||||
issuerMetadata: issuer,
|
||||
clientMetadata: clientMeta,
|
||||
getProofJwt: { accessToken, cNonce, issuerMetadata, credentialConfigId in
|
||||
try await self.getProofContinuationHook(
|
||||
accessToken: accessToken,
|
||||
cNonce: cNonce,
|
||||
issuerMetadata: issuerMetadata,
|
||||
credentialConfigId: credentialConfigId
|
||||
)
|
||||
},
|
||||
getAuthCode: { authUrl in
|
||||
try await self.getAuthCodeContinuationHook(authUrl: authUrl)
|
||||
}
|
||||
)
|
||||
|
||||
let response = try await vciClient!.requestCredential(issuerMeta: issuerMetaObject, proof: JWTProof(jwt: proof), accessToken: accessToken)!
|
||||
let responseString = try response.toJsonString()
|
||||
resolve(responseString)
|
||||
} catch {
|
||||
reject(nil,error.localizedDescription, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve(try response?.toJsonString())
|
||||
} catch {
|
||||
reject(nil, error.localizedDescription, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
static func requiresMainQueueSetup() -> Bool {
|
||||
return true
|
||||
}
|
||||
private func getProofContinuationHook(
|
||||
accessToken: String,
|
||||
cNonce: String?,
|
||||
issuerMetadata: [String: Any]?,
|
||||
credentialConfigId: String?
|
||||
) async throws -> String {
|
||||
var issuerMetadataJson: String = ""
|
||||
|
||||
if let issuerMetadata = issuerMetadata {
|
||||
if let data = try? JSONSerialization.data(withJSONObject: issuerMetadata, options: []),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
issuerMetadataJson = jsonString
|
||||
}
|
||||
}
|
||||
|
||||
if let bridge = RCTBridge.current() {
|
||||
let payload: [String: Any] = [
|
||||
"accessToken": accessToken,
|
||||
"cNonce": cNonce ?? NSNull(),
|
||||
"issuerMetadata": issuerMetadataJson,
|
||||
"credentialConfigurationId": credentialConfigId ?? NSNull(),
|
||||
]
|
||||
bridge.eventDispatcher().sendAppEvent(withName: "onRequestProof", body: payload)
|
||||
}
|
||||
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
self.pendingProofContinuation = { jwt in continuation.resume(returning: jwt) }
|
||||
}
|
||||
}
|
||||
|
||||
private func getAuthCodeContinuationHook(authUrl: String) async throws -> String {
|
||||
if let bridge = RCTBridge.current() {
|
||||
bridge.eventDispatcher().sendAppEvent(withName: "onRequestAuthCode", body: ["authorizationEndpoint": authUrl])
|
||||
}
|
||||
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
self.pendingAuthCodeContinuation = { code in continuation.resume(returning: code) }
|
||||
}
|
||||
}
|
||||
|
||||
private func getTxCodeHook(inputMode: String?, description: String?, length: Int? ) async throws -> String {
|
||||
if let bridge = RCTBridge.current() {
|
||||
bridge.eventDispatcher().sendAppEvent(withName: "onRequestTxCode", body: [
|
||||
"inputMode": inputMode,
|
||||
"description": description,
|
||||
"length": length
|
||||
])
|
||||
}
|
||||
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
self.pendingTxCodeContinuation = { code in continuation.resume(returning: code) }
|
||||
}
|
||||
}
|
||||
|
||||
private func getIssuerTrustDecisionHook(issuerMetadata: [String: Any]) async throws -> Bool {
|
||||
var metadataJson = ""
|
||||
if let data = try? JSONSerialization.data(withJSONObject: issuerMetadata, options: []),
|
||||
let string = String(data: data, encoding: .utf8) {
|
||||
metadataJson = string
|
||||
}
|
||||
|
||||
if let bridge = RCTBridge.current() {
|
||||
bridge.eventDispatcher().sendAppEvent(withName: "onCheckIssuerTrust", body: ["issuerMetadata": metadataJson])
|
||||
}
|
||||
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
self.pendingIssuerTrustDecision = { decision in continuation.resume(returning: decision) }
|
||||
}
|
||||
}
|
||||
|
||||
@objc(sendProofFromJS:)
|
||||
func sendProofFromJS(_ jwt: String) {
|
||||
pendingProofContinuation?(jwt)
|
||||
pendingProofContinuation = nil
|
||||
}
|
||||
|
||||
@objc(sendAuthCodeFromJS:)
|
||||
func sendAuthCodeFromJS(_ code: String) {
|
||||
pendingAuthCodeContinuation?(code)
|
||||
pendingAuthCodeContinuation = nil
|
||||
}
|
||||
|
||||
@objc(sendTxCodeFromJS:)
|
||||
func sendTxCodeFromJS(_ code: String) {
|
||||
pendingTxCodeContinuation?(code)
|
||||
pendingTxCodeContinuation = nil
|
||||
}
|
||||
|
||||
@objc(sendIssuerTrustResponseFromJS:)
|
||||
func sendIssuerTrustResponseFromJS(_ trusted: Bool) {
|
||||
pendingIssuerTrustDecision?(trusted)
|
||||
pendingIssuerTrustDecision = nil
|
||||
}
|
||||
|
||||
private func parseClientMetadata(from jsonString: String) throws -> ClientMetaData {
|
||||
guard let data = jsonString.data(using: .utf8) else {
|
||||
throw NSError(domain: "Invalid JSON string for clientMetadata", code: 0)
|
||||
}
|
||||
return try JSONDecoder().decode(ClientMetaData.self, from: data)
|
||||
}
|
||||
|
||||
private func parseIssuerMeta(from jsonString: String) throws -> IssuerMetadata {
|
||||
guard let data = jsonString.data(using: .utf8) else {
|
||||
throw NSError(domain: "Invalid JSON string for issuerMetadata", code: 0)
|
||||
}
|
||||
return try JSONDecoder().decode(IssuerMetadata.self, from: data)
|
||||
}
|
||||
|
||||
@objc static func requiresMainQueueSetup() -> Bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,6 +208,9 @@
|
||||
"downloadingCredentials": "تنزيل بيانات الاعتماد"
|
||||
}
|
||||
},
|
||||
"offerTitle": "امسح لتنزيل البطاقة",
|
||||
"offerDescription": "امسح رمز QR لتنزيل بطاقتك فورًا.",
|
||||
"download": "تنزيل البطاقة",
|
||||
"errors": {
|
||||
"noInternetConnection": {
|
||||
"title": "لا يوجد اتصال بالإنترنت",
|
||||
@@ -1045,5 +1048,30 @@
|
||||
"done": "منتهي",
|
||||
"keyManagementTitle": "إدارة المفتاح",
|
||||
"keyManagementDesc": "اختر طريقة إنشاء المفاتيح التي تتماشى مع تفضيلاتك، مما يمنحك السيطرة على أمان بيانات اعتمادك.\nاسحب ورتب المفاتيح، حيث يكون المفتاح العلوي هو الأعلى أولوية."
|
||||
},
|
||||
"authWebView": {
|
||||
"title": "يريد \"{{wallet}}\" استخدام \"{{domain}}\" لتسجيل الدخول",
|
||||
"message": "سيسمح هذا للتطبيق والموقع بمشاركة معلوماتك.",
|
||||
"cancel": "إلغاء",
|
||||
"continue": "تسجيل الدخول"
|
||||
},
|
||||
"cancelDownloadModal": {
|
||||
"heading": "هل تريد إلغاء التنزيل؟",
|
||||
"subHeading": "بمجرد الإلغاء، لن يتم تنزيل بطاقتك وسيتعين عليك إعادة البدء.",
|
||||
"cancel": "لا، سأنتظر",
|
||||
"confirm": "نعم، إلغاء"
|
||||
},
|
||||
"transactionCodeScreen": {
|
||||
"description": "لقد أرسلنا رمز المعاملة إلى بريدك الإلكتروني المسجل",
|
||||
"placeholder": "أدخل رمز المعاملة",
|
||||
"verify": "تحقق",
|
||||
"emptyCodeError": "لا يمكن أن يكون الرمز فارغًا",
|
||||
"invalidCharacters": "يسمح فقط بالأحرف والأرقام",
|
||||
"TransactionCode": "رمز المعاملة"
|
||||
},
|
||||
"trustScreen": {
|
||||
"description": "يرجى التأكد من أن هذه البطاقة من مصدر موثوق قبل التنزيل. بمجرد التنزيل، سيتم حفظها في محفظتك ويمكن استخدامها في أي وقت.",
|
||||
"confirm": "نعم، أثق بهذا",
|
||||
"cancel": "لا، أعدني"
|
||||
}
|
||||
}
|
||||
@@ -209,6 +209,9 @@
|
||||
"downloadingCredentials": "Downloading Credentials"
|
||||
}
|
||||
},
|
||||
"offerTitle": "Scan & Download Card",
|
||||
"offerDescription": "Scan a QR code to instantly download your card.",
|
||||
"download":" Download Card",
|
||||
"errors": {
|
||||
"noInternetConnection": {
|
||||
"title": "No internet connection",
|
||||
@@ -1065,5 +1068,30 @@
|
||||
"done": "Done",
|
||||
"keyManagementTitle": "Key Management",
|
||||
"keyManagementDesc": "Select the key generation method that aligns with your preference, putting you in control of your credential security.\nDrag and arrange the keys, with the top one being your highest priority."
|
||||
},
|
||||
"authWebView": {
|
||||
"title": "“{{wallet}}” Wants to Use “{{domain}}” to Sign In",
|
||||
"message": "This allows the app and website to share information about you.",
|
||||
"cancel": "Cancel",
|
||||
"continue": "Sign In"
|
||||
},
|
||||
"cancelDownloadModal": {
|
||||
"heading": "Do you want to cancel downloading?",
|
||||
"subHeading": "Once cancelled, your card will not be downloaded and you need to reinitiate the download.",
|
||||
"cancel": "No, I’ll wait",
|
||||
"confirm": "Yes, Cancel"
|
||||
},
|
||||
"transactionCodeScreen": {
|
||||
"description": "We’ve sent the transaction code to your registered email Id",
|
||||
"placeholder": "Enter Transaction Code",
|
||||
"verify": "Verify",
|
||||
"emptyCodeError":"Code cannot be empty",
|
||||
"invalidCharacters":"Only letters and numbers are allowed",
|
||||
"TransactionCode": "Transasction Code"
|
||||
},
|
||||
"trustScreen": {
|
||||
"description": "Please make sure this card is from a trusted source before downloading.Once downloaded, it will be saved in your wallet and can be used anytime.",
|
||||
"confirm": "Yes I Trust This",
|
||||
"cancel": "No, Take Me Back"
|
||||
}
|
||||
}
|
||||
@@ -208,6 +208,9 @@
|
||||
"downloadingCredentials": "Nagda-download ng Mga Kredensyal"
|
||||
}
|
||||
},
|
||||
"offerTitle": "I-scan at I-download ang Card",
|
||||
"offerDescription": "I-scan ang QR code para agad ma-download ang iyong card.",
|
||||
"download": "I-download ang Card",
|
||||
"errors": {
|
||||
"noInternetConnection": {
|
||||
"title": "Pakisuri ang iyong koneksyon at subukang muli",
|
||||
@@ -1048,5 +1051,30 @@
|
||||
"done": "Tapos na",
|
||||
"keyManagementTitle": "Pamamahala ng Key",
|
||||
"keyManagementDesc": "Piliin ang paraan ng paggawa ng key na naaayon sa iyong kagustuhan, nagbibigay sa iyo ng kontrol sa seguridad ng iyong kredensyal.\nI-drag at ayusin ang mga key, kung saan ang nasa itaas ay ang may pinakamataas na priyoridad."
|
||||
},
|
||||
"authWebView": {
|
||||
"title": "Gustong gamitin ng \"{{wallet}}\" ang \"{{domain}}\" para mag-sign in",
|
||||
"message": "Pinapayagan nitong magbahagi ng impormasyon ang app at website tungkol sa iyo.",
|
||||
"cancel": "Kanselahin",
|
||||
"continue": "Mag-sign In"
|
||||
},
|
||||
"cancelDownloadModal": {
|
||||
"heading": "Gusto mo bang kanselahin ang pag-download?",
|
||||
"subHeading": "Kapag nakansela, hindi madadownload ang iyong card at kailangan mong simulan muli.",
|
||||
"cancel": "Hindi, maghihintay ako",
|
||||
"confirm": "Oo, Kanselahin"
|
||||
},
|
||||
"transactionCodeScreen": {
|
||||
"description": "Ipinadala na namin ang transaction code sa iyong rehistradong email",
|
||||
"placeholder": "Ilagay ang Transaction Code",
|
||||
"verify": "I-verify",
|
||||
"emptyCodeError": "Hindi puwedeng walang laman ang code",
|
||||
"invalidCharacters": "Mga letra at numero lamang ang pinapayagan",
|
||||
"TransactionCode": "Transaction Code"
|
||||
},
|
||||
"trustScreen": {
|
||||
"description": "Siguraduhin na galing ito sa pinagkakatiwalaang source bago i-download. Kapag na-download, ito'y mase-save sa iyong wallet at maaaring magamit kahit kailan.",
|
||||
"confirm": "Oo, Pinagkakatiwalaan Ko Ito",
|
||||
"cancel": "Hindi, Bumalik Tayo"
|
||||
}
|
||||
}
|
||||
@@ -209,6 +209,9 @@
|
||||
"downloadingCredentials": "क्रेडेंशियल डाउनलोड करना"
|
||||
}
|
||||
},
|
||||
"offerTitle": "स्कैन करें और कार्ड डाउनलोड करें",
|
||||
"offerDescription": "अपना कार्ड तुरंत डाउनलोड करने के लिए QR कोड स्कैन करें।",
|
||||
"download": "कार्ड डाउनलोड करें",
|
||||
"errors": {
|
||||
"noInternetConnection": {
|
||||
"title": "कोई इंटरनेट कनेक्शन नहीं",
|
||||
@@ -1049,5 +1052,30 @@
|
||||
"done": "हो गया",
|
||||
"keyManagementTitle": "कुंजी प्रबंधन",
|
||||
"keyManagementDesc": "अपनी पसंद के अनुसार कुंजी उत्पन्न करने की विधि का चयन करें, जो आपकी क्रेडेंशियल सुरक्षा पर नियंत्रण देती है।\nकुंजियों को खींचें और व्यवस्थित करें, जहाँ शीर्ष कुंजी आपकी उच्चतम प्राथमिकता होगी।"
|
||||
},
|
||||
"authWebView": {
|
||||
"title": "\"{{wallet}}\" \"{{domain}}\" का उपयोग करके साइन इन करना चाहता है",
|
||||
"message": "यह ऐप और वेबसाइट को आपकी जानकारी साझा करने की अनुमति देता है।",
|
||||
"cancel": "रद्द करें",
|
||||
"continue": "साइन इन करें"
|
||||
},
|
||||
"cancelDownloadModal": {
|
||||
"heading": "क्या आप डाउनलोड रद्द करना चाहते हैं?",
|
||||
"subHeading": "रद्द करने पर कार्ड डाउनलोड नहीं होगा और आपको प्रक्रिया दोबारा शुरू करनी होगी।",
|
||||
"cancel": "नहीं, मैं प्रतीक्षा करूंगा",
|
||||
"confirm": "हाँ, रद्द करें"
|
||||
},
|
||||
"transactionCodeScreen": {
|
||||
"description": "हमने लेन-देन कोड आपके पंजीकृत ईमेल पर भेजा है",
|
||||
"placeholder": "लेन-देन कोड दर्ज करें",
|
||||
"verify": "सत्यापित करें",
|
||||
"emptyCodeError": "कोड खाली नहीं हो सकता",
|
||||
"invalidCharacters": "केवल अक्षर और संख्याएँ मान्य हैं",
|
||||
"TransactionCode": "लेन-देन कोड"
|
||||
},
|
||||
"trustScreen": {
|
||||
"description": "डाउनलोड करने से पहले सुनिश्चित करें कि यह कार्ड किसी भरोसेमंद स्रोत से है। डाउनलोड के बाद, यह आपके वॉलेट में सेव हो जाएगा और कभी भी इस्तेमाल किया जा सकता है।",
|
||||
"confirm": "हाँ, मैं इस पर भरोसा करता हूँ",
|
||||
"cancel": "नहीं, मुझे वापस ले चलो"
|
||||
}
|
||||
}
|
||||
@@ -208,6 +208,9 @@
|
||||
"downloadingCredentials": "ರುಜುವಾತುಗಳನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ"
|
||||
}
|
||||
},
|
||||
"offerTitle": "ಸ್ಕ್ಯಾನ್ ಮಾಡಿ ಮತ್ತು ಕಾರ್ಡ್ ಡೌನ್ಲೋಡ್ ಮಾಡಿ",
|
||||
"offerDescription": "ನಿಮ್ಮ ಕಾರ್ಡ್ ಅನ್ನು ತಕ್ಷಣವೇ ಡೌನ್ಲೋಡ್ ಮಾಡಲು QR ಕೋಡ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಿ.",
|
||||
"download": "ಕಾರ್ಡ್ ಡೌನ್ಲೋಡ್ ಮಾಡಿ",
|
||||
"errors": {
|
||||
"noInternetConnection": {
|
||||
"title": "ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವಿಲ್ಲ",
|
||||
@@ -1049,5 +1052,30 @@
|
||||
"done": "ಮುಗಿದಿದೆ",
|
||||
"keyManagementTitle": "ಕೀ ನಿರ್ವಹಣೆ",
|
||||
"keyManagementDesc": "ನಿಮ್ಮ ಆಸ್ತಿಕತೆಗಳಿಗೆ ಸರಿಹೊಂದುವ ಕೀ ಜನನ ವಿಧಾನವನ್ನು ಆಯ್ಕೆಮಾಡಿ, ಇದು ನಿಮ್ಮ ಆಧಾರ ಭದ್ರತೆಯ ಮೇಲೆ ನಿಯಂತ್ರಣವನ್ನು ನೀಡುತ್ತದೆ.\nಕೀಗಳನ್ನು ಎಳೆಯಿರಿ ಮತ್ತು ಜೋಡಿಸಿ, ಮೇಲಿನದು ನಿಮ್ಮ ಅತ್ಯುತ್ತಮ ಆದ್ಯತೆಯಾಗಿ ಇರುತ್ತದೆ."
|
||||
},
|
||||
"authWebView": {
|
||||
"title": "\"{{wallet}}\" \"{{domain}}\" ಅನ್ನು ಬಳಸಿಕೊಂಡು ಸೈನ್ ಇನ್ ಮಾಡಲು ಬಯಸುತ್ತದೆ",
|
||||
"message": "ಇದು ಅಪ್ ಮತ್ತು ವೆಬ್ಸೈಟ್ಗೆ ನಿಮ್ಮ ಬಗ್ಗೆ ಮಾಹಿತಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಅನುಮತಿಸುತ್ತದೆ.",
|
||||
"cancel": "ರದ್ದುಗೊಳಿಸಿ",
|
||||
"continue": "ಸೈನ್ ಇನ್ ಮಾಡಿ"
|
||||
},
|
||||
"cancelDownloadModal": {
|
||||
"heading": "ನೀವು ಡೌನ್ಲೋಡ್ ರದ್ದುಗೊಳಿಸಲು ಬಯಸುವಿರಾ?",
|
||||
"subHeading": "ಒಮ್ಮೆ ರದ್ದು ಮಾಡಿದ ನಂತರ, ನಿಮ್ಮ ಕಾರ್ಡ್ ಡೌನ್ಲೋಡ್ ಆಗುವುದಿಲ್ಲ ಮತ್ತು ನೀವು ಮತ್ತೆ ಪ್ರಾರಂಭಿಸಬೇಕಾಗುತ್ತದೆ.",
|
||||
"cancel": "ಇಲ್ಲ, ನಾನು ನಿರೀಕ್ಷಿಸುತ್ತೇನೆ",
|
||||
"confirm": "ಹೌದು, ರದ್ದುಗೊಳಿಸಿ"
|
||||
},
|
||||
"transactionCodeScreen": {
|
||||
"description": "ನಾವು ವ್ಯವಹಾರದ ಕೋಡ್ ಅನ್ನು ನಿಮ್ಮ ನೋಂದಾಯಿತ ಇಮೇಲ್ಗೆ ಕಳುಹಿಸಿದ್ದೇವೆ",
|
||||
"placeholder": "ವ್ಯವಹಾರದ ಕೋಡ್ ನಮೂದಿಸಿ",
|
||||
"verify": "ಸರಿಪಡಿಸಿ",
|
||||
"emptyCodeError": "ಕೋಡ್ ಖಾಲಿ ಇರಬಾರದು",
|
||||
"invalidCharacters": "ಅಕ್ಷರಗಳು ಮತ್ತು ಸಂಖ್ಯೆಗಳು ಮಾತ್ರ ಅನುಮತಿಸಲಾಗಿದೆ",
|
||||
"TransactionCode": "ವಹಿವಾಟು ಕೋಡ್"
|
||||
},
|
||||
"trustScreen": {
|
||||
"description": "ಡೌನ್ಲೋಡ್ ಮಾಡುವ ಮೊದಲು ಈ ಕಾರ್ಡ್ ನಂಬಿಕಸ್ತ ಮೂಲದಿಂದ ಇದೆಯೆಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ. ಡೌನ್ಲೋಡ್ ಮಾಡಿದ ನಂತರ, ಇದು ನಿಮ್ಮ ವ್ಯಾಲೆಟ್ನಲ್ಲಿ ಉಳಿಯುತ್ತದೆ ಮತ್ತು ಯಾವಾಗ ಬೇಕಾದರೂ ಬಳಸಬಹುದು.",
|
||||
"confirm": "ಹೌದು, ನಾನು ನಂಬುತ್ತೇನೆ",
|
||||
"cancel": "ಇಲ್ಲ, ನನನ್ನು ಹಿಂದಕ್ಕೆ ಕರೆ"
|
||||
}
|
||||
}
|
||||
@@ -208,6 +208,9 @@
|
||||
"downloadingCredentials": "நற்சான்றிதழ்களைப் பதிவிறக்குகிறது"
|
||||
}
|
||||
},
|
||||
"offerTitle": "ஸ்கேன் செய்து கார்டை பதிவிறக்கவும்",
|
||||
"offerDescription": "உங்கள் கார்டை உடனடியாக பதிவிறக்க QR குறியீட்டை ஸ்கேன் செய்யவும்.",
|
||||
"download": "கார்டைப் பதிவிறக்கவும்",
|
||||
"errors": {
|
||||
"noInternetConnection": {
|
||||
"title": "இணைய இணைப்பு இல்லை",
|
||||
@@ -1049,5 +1052,30 @@
|
||||
"done": "முடிந்தது",
|
||||
"keyManagementTitle": "முக்கிய மேலாண்மை",
|
||||
"keyManagementDesc": "உங்கள் விருப்பத்திற்கு ஏற்ப முக்கிய உருவாக்க முறையைத் தேர்ந்தெடுக்கவும், உங்கள் சான்றுத் தனி பாதுகாப்பை நீங்கள் கட்டுப்படுத்துகின்றீர்கள்.\nமேலுள்ள முக்கியம் உங்களின் மிக முக்கிய முன்னுரிமையாக இருக்கும் வகையில், முக்கியங்களை இழுத்து மறு வரிசைப்படுத்தவும்."
|
||||
},
|
||||
"authWebView": {
|
||||
"title": "உங்கள் \"{{wallet}}\" \"{{domain}}\" ஐ உள்நுழைவதற்காக பயன்படுத்த விரும்புகிறது",
|
||||
"message": "இந்த செயலி மற்றும் இணையதளம் உங்கள் தகவல்களை பகிர அனுமதிக்கிறது.",
|
||||
"cancel": "ரத்து செய்",
|
||||
"continue": "உள்நுழையவும்"
|
||||
},
|
||||
"cancelDownloadModal": {
|
||||
"heading": "நீங்கள் பதிவிறக்கத்தை ரத்துசெய்ய விரும்புகிறீர்களா?",
|
||||
"subHeading": "ஒருமுறை ரத்துசெய்தால், உங்கள் அட்டை பதிவிறக்கப்படாது. மீண்டும் தொடங்க வேண்டும்.",
|
||||
"cancel": "இல்லை, நான் காத்திருப்பேன்",
|
||||
"confirm": "ஆம், ரத்துசெய்"
|
||||
},
|
||||
"transactionCodeScreen": {
|
||||
"description": "பரிவரத்து குறியீடு உங்கள் பதிவுசெய்த மின்னஞ்சலுக்கு அனுப்பப்பட்டுள்ளது",
|
||||
"placeholder": "பரிவரத்து குறியீட்டை உள்ளிடவும்",
|
||||
"verify": "சரிபார்க்கவும்",
|
||||
"emptyCodeError": "குறியீடு காலியாக இருக்க முடியாது",
|
||||
"invalidCharacters": "எழுத்துகள் மற்றும் எண்கள் மட்டும் அனுமதிக்கப்படும்",
|
||||
"TransactionCode": "பரிவரத்து குறியீடு"
|
||||
},
|
||||
"trustScreen": {
|
||||
"description": "இந்த அட்டை நம்பகமானதாக இருப்பதை உறுதிசெய்துகொள்ளுங்கள். பதிவிறக்கப்பட்ட பிறகு, இது உங்கள் பணப்பையில் சேமிக்கப்படும் மற்றும் எப்போது வேண்டுமானாலும் பயன்படுத்தலாம்.",
|
||||
"confirm": "ஆம், நம்புகிறேன்",
|
||||
"cancel": "இல்லை, என்னை திரும்ப அழைத்துச் செல்"
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,29 @@
|
||||
import {
|
||||
ErrorMessage,
|
||||
getDisplayObjectForCurrentLanguage,
|
||||
Issuers_Key_Ref,
|
||||
OIDCErrors,
|
||||
selectCredentialRequestKey,
|
||||
} from '../../shared/openId4VCI/Utils';
|
||||
import {
|
||||
MY_VCS_STORE_KEY,
|
||||
REQUEST_TIMEOUT,
|
||||
isIOS,
|
||||
EXPIRED_VC_ERROR_CODE,
|
||||
} from '../../shared/constants';
|
||||
import {assign, send} from 'xstate';
|
||||
import {StoreEvents} from '../store';
|
||||
import {BackupEvents} from '../backupAndRestore/backup/backupMachine';
|
||||
import {getVCMetadata, VCMetadata} from '../../shared/VCMetadata';
|
||||
import {isHardwareKeystoreExists} from '../../shared/cryptoutil/cryptoUtil';
|
||||
import {ActivityLogEvents} from '../activityLog';
|
||||
import { EXPIRED_VC_ERROR_CODE, MY_VCS_STORE_KEY, REQUEST_TIMEOUT, isIOS } from '../../shared/constants';
|
||||
import { assign, send } from 'xstate';
|
||||
import { StoreEvents } from '../store';
|
||||
import { BackupEvents } from '../backupAndRestore/backup/backupMachine';
|
||||
import { getVCMetadata, VCMetadata } from '../../shared/VCMetadata';
|
||||
import { isHardwareKeystoreExists } from '../../shared/cryptoutil/cryptoUtil';
|
||||
import { ActivityLogEvents } from '../activityLog';
|
||||
import {
|
||||
getEndEventData,
|
||||
getImpressionEventData,
|
||||
sendEndEvent,
|
||||
sendImpressionEvent,
|
||||
} from '../../shared/telemetry/TelemetryUtils';
|
||||
import {TelemetryConstants} from '../../shared/telemetry/TelemetryConstants';
|
||||
import {NativeModules} from 'react-native';
|
||||
import {KeyTypes} from '../../shared/cryptoutil/KeyTypes';
|
||||
import {VCActivityLog} from '../../components/ActivityLogEvent';
|
||||
import {isNetworkError} from '../../shared/Utils';
|
||||
import { TelemetryConstants } from '../../shared/telemetry/TelemetryConstants';
|
||||
import { NativeModules } from 'react-native';
|
||||
import { KeyTypes } from '../../shared/cryptoutil/KeyTypes';
|
||||
import { VCActivityLog } from '../../components/ActivityLogEvent';
|
||||
import { isNetworkError } from '../../shared/Utils';
|
||||
import { issuerType } from './IssuersMachine';
|
||||
|
||||
const {RNSecureKeystoreModule} = NativeModules;
|
||||
export const IssuersActions = (model: any) => {
|
||||
@@ -36,7 +33,7 @@ export const IssuersActions = (model: any) => {
|
||||
new VCMetadata({
|
||||
...context.vcMetadata,
|
||||
isVerified: true,
|
||||
isExpired: event.data.verificationErrorCode == EXPIRED_VC_ERROR_CODE,
|
||||
isExpired: event.data.verificationErrorCode == EXPIRED_VC_ERROR_CODE,
|
||||
}),
|
||||
}),
|
||||
resetVerificationResult: assign({
|
||||
@@ -48,7 +45,7 @@ export const IssuersActions = (model: any) => {
|
||||
}),
|
||||
}),
|
||||
setIssuers: model.assign({
|
||||
issuers: (_: any, event: any) => event.data,
|
||||
issuers: (_: any, event: any) => event.data as issuerType[],
|
||||
}),
|
||||
setNoInternet: model.assign({
|
||||
errorMessage: () => ErrorMessage.NO_INTERNET,
|
||||
@@ -230,9 +227,10 @@ export const IssuersActions = (model: any) => {
|
||||
}),
|
||||
|
||||
setSelectedIssuers: model.assign({
|
||||
selectedIssuer: (context: any, event: any) =>
|
||||
context.issuers.find(issuer => issuer.issuer_id === event.id),
|
||||
}),
|
||||
selectedIssuer: (context: any, event: any) => {
|
||||
return context.issuers.find(issuer => issuer.issuer_id === event.id);
|
||||
}
|
||||
}),
|
||||
|
||||
updateIssuerFromWellknown: model.assign({
|
||||
selectedIssuer: (context: any, event: any) => ({
|
||||
@@ -241,24 +239,125 @@ export const IssuersActions = (model: any) => {
|
||||
credential_endpoint: event.data.credential_endpoint,
|
||||
credential_configurations_supported:
|
||||
event.data.credential_configurations_supported,
|
||||
display: event.data.display,
|
||||
authorization_servers: event.data.authorization_servers,
|
||||
}),
|
||||
}),
|
||||
|
||||
updateAuthorizationEndpoint: model.assign({
|
||||
selectedIssuer: (context: any, event: any) => ({
|
||||
...context.selectedIssuer,
|
||||
authorizationEndpoint: event.data,
|
||||
}),
|
||||
setCredential: model.assign({
|
||||
credential: (_: any, event: any) => event.data,
|
||||
}),
|
||||
setQrData: model.assign({
|
||||
qrData: (_: any, event: any) => event.data,
|
||||
}),
|
||||
setCredentialOfferIssuer: model.assign({
|
||||
selectedIssuer: (_:any,event: any) => {
|
||||
console.log("issuer::", event.issuer);
|
||||
return event.issuer;
|
||||
},
|
||||
}),
|
||||
setAccessToken: model.assign({
|
||||
accessToken: (_: any, event: any) => {
|
||||
return event.accessToken;
|
||||
},
|
||||
}),
|
||||
setCNonce: model.assign({
|
||||
cNonce: (_: any, event: any) => {
|
||||
return event.cNonce;
|
||||
},
|
||||
}),
|
||||
setOfferCredentialTypeContexts: model.assign({
|
||||
selectedCredentialType: (context: any, event: any) => {
|
||||
return event.credentialTypes[0];
|
||||
},
|
||||
supportedCredentialTypes: (context: any, event: any) => {
|
||||
return event.credentialTypes;
|
||||
},
|
||||
accessToken: (context: any, event: any) => {
|
||||
return event.accessToken;
|
||||
},
|
||||
cNonce: (context: any, event: any) => {
|
||||
return event.cNonce;
|
||||
},
|
||||
}),
|
||||
setRequestTxCode: model.assign({
|
||||
isTransactionCodeRequested: (_: any, event: any) => {
|
||||
return true;
|
||||
},
|
||||
}),
|
||||
|
||||
resetRequestTxCode: model.assign({
|
||||
isTransactionCodeRequested: (_: any, event: any) => {
|
||||
return false;
|
||||
},
|
||||
}),
|
||||
setCredentialOfferIssuerWellknownResponse: model.assign({
|
||||
selectedIssuerWellknownResponse: (_: any, event: any) => {
|
||||
return event.issuerMetadata;
|
||||
},
|
||||
wellknownKeyTypes: (_: any, event: any) => {
|
||||
const credType = Object.entries(event.credentialTypes)[0][1];
|
||||
const proofTypesSupported = credType.proof_types_supported;
|
||||
if (proofTypesSupported?.jwt) {
|
||||
return proofTypesSupported.jwt
|
||||
.proof_signing_alg_values_supported as string[];
|
||||
} else {
|
||||
return [KeyTypes.RS256] as string[];
|
||||
}
|
||||
},
|
||||
}),
|
||||
updateSelectedIssuerWellknownResponse: model.assign({
|
||||
selectedIssuerWellknownResponse: (_: any, event: any) => event.data,
|
||||
}),
|
||||
setSelectedIssuerId: model.assign({
|
||||
selectedIssuerId: (_: any, event: any) => event.id,
|
||||
}),
|
||||
setTokenResponse: model.assign({
|
||||
tokenResponse: (_: any, event: any) => event.data,
|
||||
setTxCode: model.assign({
|
||||
txCode: (_: any, event: any) => {
|
||||
return event.txCode;
|
||||
},
|
||||
}),
|
||||
setRequestConsentToTrustIssuer: model.assign({
|
||||
isConsentRequested: (_: any, event: any) => {
|
||||
return true;
|
||||
},
|
||||
}),
|
||||
setTxCodeDisplayDetails: model.assign({
|
||||
txCodeInputMode: (_: any, event: any) => event.inputMode,
|
||||
txCodeDescription: (_: any, event: any) => event.description,
|
||||
txCodeLength: (_: any, event: any) => event.length,
|
||||
}),
|
||||
|
||||
setIssuerDisplayDetails: model.assign({
|
||||
issuerLogo: (_: any, event: any) => {
|
||||
const display = getDisplayObjectForCurrentLanguage(
|
||||
event.issuerMetadata.display,
|
||||
);
|
||||
return display.logo.url;
|
||||
},
|
||||
issuerName: (_: any, event: any) => {
|
||||
const display = getDisplayObjectForCurrentLanguage(
|
||||
event.issuerMetadata.display,
|
||||
);
|
||||
return display.name;
|
||||
},
|
||||
}),
|
||||
|
||||
setFlowType: model.assign({
|
||||
isCredentialOfferFlow: (_: any, event: any) => {
|
||||
return true;
|
||||
},
|
||||
}),
|
||||
|
||||
resetFlowType: model.assign({
|
||||
isCredentialOfferFlow: (_: any, event: any) => {
|
||||
return false;
|
||||
},
|
||||
}),
|
||||
|
||||
resetRequestConsentToTrustIssuer: model.assign({
|
||||
isConsentRequested: (_: any, event: any) => {
|
||||
return false;
|
||||
},
|
||||
}),
|
||||
setVerifiableCredential: model.assign({
|
||||
verifiableCredential: (_: any, event: any) => {
|
||||
@@ -339,6 +438,10 @@ export const IssuersActions = (model: any) => {
|
||||
verificationErrorMessage: () => '',
|
||||
}),
|
||||
|
||||
resetQrData: model.assign({
|
||||
qrData: () => '',
|
||||
}),
|
||||
|
||||
sendDownloadingFailedToVcMeta: send(
|
||||
(_: any) => ({
|
||||
type: 'VC_DOWNLOADING_FAILED',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {CredentialTypes} from '../VerifiableCredential/VCMetaMachine/vc';
|
||||
import { CredentialTypes } from '../VerifiableCredential/VCMetaMachine/vc';
|
||||
import { issuerType } from './IssuersMachine';
|
||||
|
||||
export const IssuersEvents = {
|
||||
SELECTED_ISSUER: (id: string) => ({id}),
|
||||
@@ -13,4 +14,24 @@ export const IssuersEvents = {
|
||||
STORE_ERROR: (error: Error, requester?: string) => ({error, requester}),
|
||||
RESET_VERIFY_ERROR: () => ({}),
|
||||
SELECTED_CREDENTIAL_TYPE: (credType: CredentialTypes) => ({credType}),
|
||||
SCAN_CREDENTIAL_OFFER_QR_CODE: () => ({}),
|
||||
QR_CODE_SCANNED: (data: string) => ({data}),
|
||||
AUTH_ENDPOINT_RECEIVED: (authEndpoint: string) => ({authEndpoint}),
|
||||
PROOF_REQUEST: (
|
||||
accessToken: string,
|
||||
cNonce: string | undefined,
|
||||
issuerMetadata: object,
|
||||
issuer: issuerType,
|
||||
credentialtypes: CredentialTypes,
|
||||
) => ({
|
||||
accessToken: accessToken,
|
||||
cNonce: cNonce,
|
||||
issuerMetadata: issuerMetadata,
|
||||
issuer: issuer,
|
||||
credentialtypes: credentialtypes,
|
||||
}),
|
||||
TX_CODE_REQUEST: () => ({}),
|
||||
TX_CODE_RECEIVED: (txCode: string) => ({txCode}),
|
||||
ON_CONSENT_GIVEN: () => ({}),
|
||||
TRUST_ISSUER_CONSENT_REQUEST: (issuerMetadata: object) => ({issuerMetadata})
|
||||
};
|
||||
|
||||
@@ -57,5 +57,8 @@ export const IssuersGuards = () => {
|
||||
const errorMessage = event.data.message;
|
||||
return errorMessage === ErrorMessage.GENERIC;
|
||||
},
|
||||
isCredentialOfferFlow: (context: any) => {
|
||||
return context.isCredentialOfferFlow
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,378 +0,0 @@
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'done.invoke.checkInternet': {
|
||||
type: 'done.invoke.checkInternet';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.checkKeyPair:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.checkKeyPair:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.displayIssuers:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.downloadCredentials:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.downloadIssuerWellknown:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.downloadIssuerWellknown:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.fetchAuthorizationEndpoint:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.fetchAuthorizationEndpoint:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.generateKeyPair:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.performAuthorization.setSelectedKey:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.performAuthorization.setSelectedKey:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.performAuthorization:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.storing:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.storing:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.issuersMachine.verifyingCredential:invocation[0]': {
|
||||
type: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'error.platform.checkInternet': {
|
||||
type: 'error.platform.checkInternet';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.issuersMachine.displayIssuers:invocation[0]': {
|
||||
type: 'error.platform.issuersMachine.displayIssuers:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.issuersMachine.downloadCredentialTypes:invocation[0]': {
|
||||
type: 'error.platform.issuersMachine.downloadCredentialTypes:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.issuersMachine.downloadCredentials:invocation[0]': {
|
||||
type: 'error.platform.issuersMachine.downloadCredentials:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.issuersMachine.downloadIssuerWellknown:invocation[0]': {
|
||||
type: 'error.platform.issuersMachine.downloadIssuerWellknown:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.issuersMachine.fetchAuthorizationEndpoint:invocation[0]': {
|
||||
type: 'error.platform.issuersMachine.fetchAuthorizationEndpoint:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]': {
|
||||
type: 'error.platform.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.issuersMachine.performAuthorization.setSelectedKey:invocation[0]': {
|
||||
type: 'error.platform.issuersMachine.performAuthorization.setSelectedKey:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.issuersMachine.performAuthorization:invocation[0]': {
|
||||
type: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.issuersMachine.verifyingCredential:invocation[0]': {
|
||||
type: 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
checkInternet: 'done.invoke.checkInternet';
|
||||
downloadCredential: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
|
||||
downloadCredentialTypes: 'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]';
|
||||
downloadIssuerWellknown: 'done.invoke.issuersMachine.downloadIssuerWellknown:invocation[0]';
|
||||
downloadIssuersList: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
|
||||
fetchAuthorizationEndpoint: 'done.invoke.issuersMachine.fetchAuthorizationEndpoint:invocation[0]';
|
||||
generateKeyPair: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
|
||||
getKeyOrderList: 'done.invoke.issuersMachine.performAuthorization.setSelectedKey:invocation[0]';
|
||||
getKeyPair: 'done.invoke.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]';
|
||||
getSelectedKey: 'done.invoke.issuersMachine.checkKeyPair:invocation[0]';
|
||||
invokeAuthorization: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
|
||||
isUserSignedAlready: 'done.invoke.issuersMachine.storing:invocation[0]';
|
||||
verifyCredential: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
|
||||
};
|
||||
missingImplementations: {
|
||||
actions:
|
||||
| 'downloadIssuerWellknown'
|
||||
| 'loadKeyPair'
|
||||
| 'logDownloaded'
|
||||
| 'resetError'
|
||||
| 'resetLoadingReason'
|
||||
| 'resetSelectedCredentialType'
|
||||
| 'resetVerificationErrorMessage'
|
||||
| 'resetVerificationResult'
|
||||
| 'sendBackupEvent'
|
||||
| 'sendDownloadingFailedToVcMeta'
|
||||
| 'sendErrorEndEvent'
|
||||
| 'sendImpressionEvent'
|
||||
| 'sendSuccessEndEvent'
|
||||
| 'setCredentialTypeListDownloadFailureError'
|
||||
| 'setCredentialWrapper'
|
||||
| 'setError'
|
||||
| 'setIssuers'
|
||||
| 'setLoadingReasonAsDisplayIssuers'
|
||||
| 'setLoadingReasonAsDownloadingCredentials'
|
||||
| 'setLoadingReasonAsSettingUp'
|
||||
| 'setMetadataInCredentialData'
|
||||
| 'setNetworkOrTechnicalError'
|
||||
| 'setNoInternet'
|
||||
| 'setOIDCConfigError'
|
||||
| 'setPrivateKey'
|
||||
| 'setPublicKey'
|
||||
| 'setSelectedCredentialType'
|
||||
| 'setSelectedIssuerId'
|
||||
| 'setSelectedIssuers'
|
||||
| 'setSelectedKey'
|
||||
| 'setSupportedCredentialTypes'
|
||||
| 'setTokenResponse'
|
||||
| 'setVCMetadata'
|
||||
| 'setVerifiableCredential'
|
||||
| 'setVerificationResult'
|
||||
| 'storeKeyPair'
|
||||
| 'storeVcMetaContext'
|
||||
| 'storeVcsContext'
|
||||
| 'storeVerifiableCredentialData'
|
||||
| 'storeVerifiableCredentialMeta'
|
||||
| 'updateAuthorizationEndpoint'
|
||||
| 'updateIssuerFromWellknown'
|
||||
| 'updateSelectedIssuerWellknownResponse'
|
||||
| 'updateVerificationErrorMessage';
|
||||
delays: never;
|
||||
guards:
|
||||
| 'canSelectIssuerAgain'
|
||||
| 'hasKeyPair'
|
||||
| 'hasUserCancelledBiometric'
|
||||
| 'isCustomSecureKeystore'
|
||||
| 'isGenericError'
|
||||
| 'isInternetConnected'
|
||||
| 'isKeyTypeNotFound'
|
||||
| 'isOIDCConfigError'
|
||||
| 'isOIDCflowCancelled'
|
||||
| 'isSignedIn'
|
||||
| 'isVerificationPendingBecauseOfNetworkIssue'
|
||||
| 'shouldFetchIssuersAgain';
|
||||
services:
|
||||
| 'checkInternet'
|
||||
| 'downloadCredential'
|
||||
| 'downloadCredentialTypes'
|
||||
| 'downloadIssuerWellknown'
|
||||
| 'downloadIssuersList'
|
||||
| 'fetchAuthorizationEndpoint'
|
||||
| 'generateKeyPair'
|
||||
| 'getKeyOrderList'
|
||||
| 'getKeyPair'
|
||||
| 'getSelectedKey'
|
||||
| 'invokeAuthorization'
|
||||
| 'isUserSignedAlready'
|
||||
| 'verifyCredential';
|
||||
};
|
||||
eventsCausingActions: {
|
||||
downloadIssuerWellknown: 'TRY_AGAIN';
|
||||
loadKeyPair: 'done.invoke.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]';
|
||||
logDownloaded:
|
||||
| 'done.invoke.issuersMachine.verifyingCredential:invocation[0]'
|
||||
| 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
resetError:
|
||||
| 'RESET_ERROR'
|
||||
| 'TRY_AGAIN'
|
||||
| 'error.platform.issuersMachine.performAuthorization:invocation[0]';
|
||||
resetLoadingReason:
|
||||
| 'RESET_ERROR'
|
||||
| 'done.invoke.checkInternet'
|
||||
| 'done.invoke.issuersMachine.displayIssuers:invocation[0]'
|
||||
| 'error.platform.issuersMachine.downloadCredentialTypes:invocation[0]'
|
||||
| 'error.platform.issuersMachine.downloadCredentials:invocation[0]'
|
||||
| 'error.platform.issuersMachine.downloadIssuerWellknown:invocation[0]'
|
||||
| 'error.platform.issuersMachine.fetchAuthorizationEndpoint:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization.setSelectedKey:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization:invocation[0]'
|
||||
| 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
resetSelectedCredentialType:
|
||||
| 'CANCEL'
|
||||
| 'error.platform.issuersMachine.downloadCredentials:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization.setSelectedKey:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization:invocation[0]';
|
||||
resetVerificationErrorMessage: 'RESET_VERIFY_ERROR';
|
||||
resetVerificationResult: 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
sendBackupEvent: 'done.invoke.issuersMachine.storing:invocation[0]';
|
||||
sendDownloadingFailedToVcMeta:
|
||||
| 'error.platform.issuersMachine.downloadCredentials:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization.setSelectedKey:invocation[0]';
|
||||
sendErrorEndEvent: 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
sendImpressionEvent: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
|
||||
sendSuccessEndEvent: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
|
||||
setCredentialTypeListDownloadFailureError: 'error.platform.issuersMachine.downloadCredentialTypes:invocation[0]';
|
||||
setCredentialWrapper: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
|
||||
setError:
|
||||
| 'error.platform.issuersMachine.displayIssuers:invocation[0]'
|
||||
| 'error.platform.issuersMachine.downloadCredentials:invocation[0]'
|
||||
| 'error.platform.issuersMachine.fetchAuthorizationEndpoint:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization.setSelectedKey:invocation[0]';
|
||||
setIssuers: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
|
||||
setLoadingReasonAsDisplayIssuers: 'TRY_AGAIN';
|
||||
setLoadingReasonAsDownloadingCredentials:
|
||||
| 'TRY_AGAIN'
|
||||
| 'done.invoke.issuersMachine.generateKeyPair:invocation[0]'
|
||||
| 'done.invoke.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]';
|
||||
setLoadingReasonAsSettingUp:
|
||||
| 'RESET_ERROR'
|
||||
| 'SELECTED_ISSUER'
|
||||
| 'TRY_AGAIN'
|
||||
| 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
|
||||
setMetadataInCredentialData:
|
||||
| 'done.invoke.issuersMachine.verifyingCredential:invocation[0]'
|
||||
| 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
setNetworkOrTechnicalError:
|
||||
| 'error.platform.issuersMachine.downloadIssuerWellknown:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization:invocation[0]';
|
||||
setNoInternet: 'done.invoke.checkInternet';
|
||||
setOIDCConfigError: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
|
||||
setPrivateKey: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
|
||||
setPublicKey: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
|
||||
setSelectedCredentialType: 'SELECTED_CREDENTIAL_TYPE';
|
||||
setSelectedIssuerId: 'SELECTED_ISSUER';
|
||||
setSelectedIssuers: 'SELECTED_ISSUER';
|
||||
setSelectedKey: 'done.invoke.issuersMachine.performAuthorization.setSelectedKey:invocation[0]';
|
||||
setSupportedCredentialTypes: 'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]';
|
||||
setTokenResponse: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
|
||||
setVCMetadata:
|
||||
| 'done.invoke.issuersMachine.verifyingCredential:invocation[0]'
|
||||
| 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
setVerifiableCredential: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
|
||||
setVerificationResult: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
|
||||
storeKeyPair: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
|
||||
storeVcMetaContext:
|
||||
| 'done.invoke.issuersMachine.verifyingCredential:invocation[0]'
|
||||
| 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
storeVcsContext:
|
||||
| 'done.invoke.issuersMachine.verifyingCredential:invocation[0]'
|
||||
| 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
storeVerifiableCredentialData:
|
||||
| 'done.invoke.issuersMachine.verifyingCredential:invocation[0]'
|
||||
| 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
storeVerifiableCredentialMeta:
|
||||
| 'done.invoke.issuersMachine.verifyingCredential:invocation[0]'
|
||||
| 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
updateAuthorizationEndpoint: 'done.invoke.issuersMachine.fetchAuthorizationEndpoint:invocation[0]';
|
||||
updateIssuerFromWellknown: 'done.invoke.issuersMachine.downloadIssuerWellknown:invocation[0]';
|
||||
updateSelectedIssuerWellknownResponse: 'done.invoke.issuersMachine.downloadIssuerWellknown:invocation[0]';
|
||||
updateVerificationErrorMessage: 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {
|
||||
canSelectIssuerAgain: 'TRY_AGAIN';
|
||||
hasKeyPair: 'done.invoke.issuersMachine.checkKeyPair:invocation[0]';
|
||||
hasUserCancelledBiometric:
|
||||
| 'error.platform.issuersMachine.downloadCredentials:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]';
|
||||
isCustomSecureKeystore: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
|
||||
isGenericError: 'error.platform.issuersMachine.downloadCredentials:invocation[0]';
|
||||
isInternetConnected: 'done.invoke.checkInternet';
|
||||
isKeyTypeNotFound: 'error.platform.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]';
|
||||
isOIDCConfigError: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
|
||||
isOIDCflowCancelled: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
|
||||
isSignedIn: 'done.invoke.issuersMachine.storing:invocation[0]';
|
||||
isVerificationPendingBecauseOfNetworkIssue: 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
shouldFetchIssuersAgain: 'TRY_AGAIN';
|
||||
};
|
||||
eventsCausingServices: {
|
||||
checkInternet:
|
||||
| 'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]'
|
||||
| 'done.invoke.issuersMachine.fetchAuthorizationEndpoint:invocation[0]';
|
||||
downloadCredential:
|
||||
| 'done.invoke.issuersMachine.checkKeyPair:invocation[0]'
|
||||
| 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
|
||||
downloadCredentialTypes: 'done.invoke.issuersMachine.downloadIssuerWellknown:invocation[0]';
|
||||
downloadIssuerWellknown: 'SELECTED_ISSUER' | 'TRY_AGAIN';
|
||||
downloadIssuersList: 'CANCEL' | 'TRY_AGAIN' | 'xstate.init';
|
||||
fetchAuthorizationEndpoint: 'SELECTED_CREDENTIAL_TYPE';
|
||||
generateKeyPair: 'done.invoke.issuersMachine.checkKeyPair:invocation[0]';
|
||||
getKeyOrderList: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
|
||||
getKeyPair:
|
||||
| 'TRY_AGAIN'
|
||||
| 'done.invoke.issuersMachine.performAuthorization.setSelectedKey:invocation[0]';
|
||||
getSelectedKey:
|
||||
| 'done.invoke.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]'
|
||||
| 'error.platform.issuersMachine.performAuthorization.getKeyPairFromKeystore:invocation[0]';
|
||||
invokeAuthorization: 'done.invoke.checkInternet';
|
||||
isUserSignedAlready:
|
||||
| 'done.invoke.issuersMachine.verifyingCredential:invocation[0]'
|
||||
| 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
|
||||
verifyCredential: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
|
||||
};
|
||||
matchesStates:
|
||||
| 'checkInternet'
|
||||
| 'checkKeyPair'
|
||||
| 'displayIssuers'
|
||||
| 'done'
|
||||
| 'downloadCredentialTypes'
|
||||
| 'downloadCredentials'
|
||||
| 'downloadCredentials.idle'
|
||||
| 'downloadCredentials.userCancelledBiometric'
|
||||
| 'downloadIssuerWellknown'
|
||||
| 'error'
|
||||
| 'fetchAuthorizationEndpoint'
|
||||
| 'fetchAuthorizationEndpoint.error'
|
||||
| 'fetchAuthorizationEndpoint.idle'
|
||||
| 'generateKeyPair'
|
||||
| 'handleVCVerificationFailure'
|
||||
| 'idle'
|
||||
| 'performAuthorization'
|
||||
| 'performAuthorization.getKeyPairFromKeystore'
|
||||
| 'performAuthorization.idle'
|
||||
| 'performAuthorization.setSelectedKey'
|
||||
| 'performAuthorization.userCancelledBiometric'
|
||||
| 'selectingCredentialType'
|
||||
| 'selectingIssuer'
|
||||
| 'storing'
|
||||
| 'verifyingCredential'
|
||||
| {
|
||||
downloadCredentials?: 'idle' | 'userCancelledBiometric';
|
||||
fetchAuthorizationEndpoint?: 'error' | 'idle';
|
||||
performAuthorization?:
|
||||
| 'getKeyPairFromKeystore'
|
||||
| 'idle'
|
||||
| 'setSelectedKey'
|
||||
| 'userCancelledBiometric';
|
||||
};
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ export const IssuersModel = createModel(
|
||||
{
|
||||
issuers: [] as issuerType[],
|
||||
selectedIssuerId: '' as string,
|
||||
qrData: '' as string,
|
||||
selectedIssuer: {} as issuerType,
|
||||
selectedIssuerWellknownResponse: {} as IssuerWellknownResponse,
|
||||
tokenResponse: {} as AuthorizeResult,
|
||||
@@ -31,6 +32,19 @@ export const IssuersModel = createModel(
|
||||
vcMetadata: {} as VCMetadata,
|
||||
keyType: 'RS256' as string,
|
||||
wellknownKeyTypes: [] as string[],
|
||||
authEndpointToOpen: false as boolean,
|
||||
isTransactionCodeRequested: false as boolean,
|
||||
authEndpoint: '' as string,
|
||||
accessToken: '' as string,
|
||||
txCode: '' as string,
|
||||
cNonce: '' as string,
|
||||
isConsentRequested: false as boolean,
|
||||
issuerLogo: '' as string,
|
||||
issuerName: '' as string,
|
||||
txCodeInputMode: '' as string,
|
||||
txCodeDescription: '' as string,
|
||||
txCodeLength: null as number | null,
|
||||
isCredentialOfferFlow: false as boolean,
|
||||
},
|
||||
{
|
||||
events: IssuersEvents,
|
||||
|
||||
@@ -12,6 +12,14 @@ export function selectSelectedIssuer(state: State) {
|
||||
return state.context.selectedIssuer;
|
||||
}
|
||||
|
||||
export function selectAuthWebViewStatus(state: State) {
|
||||
return state.context.authEndpointToOpen;
|
||||
}
|
||||
|
||||
export function selectAuthEndPoint(state: State) {
|
||||
return state.context.authEndpoint;
|
||||
}
|
||||
|
||||
export function selectErrorMessageType(state: State) {
|
||||
return state.context.errorMessage;
|
||||
}
|
||||
@@ -24,10 +32,37 @@ export function selectIsDownloadCredentials(state: State) {
|
||||
return state.matches('downloadCredentials');
|
||||
}
|
||||
|
||||
export function selectIsTxCodeRequested(state: State) {
|
||||
return state.context.isTransactionCodeRequested;
|
||||
}
|
||||
|
||||
export function selectIsConsentRequested(state: State) {
|
||||
return state.context.isConsentRequested;
|
||||
}
|
||||
export function selectIssuerLogo(state: State) {
|
||||
return state.context.issuerLogo;
|
||||
}
|
||||
|
||||
export function selectIssuerName(state: State) {
|
||||
return state.context.issuerName;
|
||||
}
|
||||
|
||||
export function selectTxCodeDisplayDetails(state: State) {
|
||||
const context = state.context;
|
||||
return {
|
||||
inputMode: context.txCodeInputMode,
|
||||
description: context.txCodeDescription,
|
||||
length: context.txCodeLength,
|
||||
};
|
||||
}
|
||||
|
||||
export function selectIsBiometricCancelled(state: State) {
|
||||
return (
|
||||
state.matches('downloadCredentials.userCancelledBiometric') ||
|
||||
state.matches('performAuthorization.userCancelledBiometric')
|
||||
state.matches('downloadCredentials.keyManagement.userCancelledBiometric') ||
|
||||
state.matches(
|
||||
'credentialDownloadFromOffer.keyManagement.userCancelledBiometric',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -65,3 +100,11 @@ export function selectSelectingCredentialType(state: State) {
|
||||
export function selectSupportedCredentialTypes(state: State) {
|
||||
return state.context.supportedCredentialTypes;
|
||||
}
|
||||
|
||||
export function selectIsQrScanning(state: State) {
|
||||
return state.matches('waitingForQrScan');
|
||||
}
|
||||
|
||||
export function selectCredentialOfferData(state: State) {
|
||||
return state.context.credentialOfferData;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import NetInfo from '@react-native-community/netinfo';
|
||||
import {NativeModules} from 'react-native';
|
||||
import {authorize} from 'react-native-app-auth';
|
||||
import Cloud from '../../shared/CloudBackupAndRestoreUtils';
|
||||
import {CACHED_API} from '../../shared/api';
|
||||
import {
|
||||
@@ -8,21 +7,16 @@ import {
|
||||
generateKeyPair,
|
||||
} from '../../shared/cryptoutil/cryptoUtil';
|
||||
import {
|
||||
constructAuthorizationConfiguration,
|
||||
constructIssuerMetaData,
|
||||
constructProofJWT,
|
||||
hasKeyPair,
|
||||
OIDCErrors,
|
||||
updateCredentialInformation,
|
||||
vcDownloadTimeout,
|
||||
verifyCredentialData,
|
||||
} from '../../shared/openId4VCI/Utils';
|
||||
import {TelemetryConstants} from '../../shared/telemetry/TelemetryConstants';
|
||||
import {
|
||||
getImpressionEventData,
|
||||
sendImpressionEvent,
|
||||
} from '../../shared/telemetry/TelemetryUtils';
|
||||
import {VciClient} from '../../shared/vciClient/VciClient';
|
||||
import {issuerType} from './IssuersMachine';
|
||||
import {setItem} from '../store';
|
||||
import {API_CACHED_STORAGE_KEYS} from '../../shared/constants';
|
||||
|
||||
export const IssuersService = () => {
|
||||
return {
|
||||
@@ -30,106 +24,196 @@ export const IssuersService = () => {
|
||||
return await Cloud.isSignedInAlready();
|
||||
},
|
||||
downloadIssuersList: async () => {
|
||||
return await CACHED_API.fetchIssuers();
|
||||
const trustedIssuersList = await CACHED_API.fetchIssuers();
|
||||
return trustedIssuersList;
|
||||
},
|
||||
checkInternet: async () => await NetInfo.fetch(),
|
||||
downloadIssuerWellknown: async (context: any) => {
|
||||
const wellknownResponse = await CACHED_API.fetchIssuerWellknownConfig(
|
||||
context.selectedIssuer.issuer_id,
|
||||
context.selectedIssuer.credential_issuer_host,
|
||||
context.selectedIssuer.id,
|
||||
context.selectedIssuer.credential_issuer_host
|
||||
? context.selectedIssuer.credential_issuer_host
|
||||
: context.selectedIssuer.credential_issuer,
|
||||
);
|
||||
return wellknownResponse;
|
||||
},
|
||||
downloadCredentialTypes: async (context: any) => {
|
||||
getCredentialTypes: async (context: any) => {
|
||||
const credentialTypes = [];
|
||||
for (const key in context.selectedIssuer
|
||||
.credential_configurations_supported) {
|
||||
credentialTypes.push({
|
||||
id: key,
|
||||
...context.selectedIssuer.credential_configurations_supported[key],
|
||||
});
|
||||
}
|
||||
if (credentialTypes.length == 0)
|
||||
throw new Error(
|
||||
`No credential type found for issuer ${context.selectedIssuer.issuer_id}`,
|
||||
);
|
||||
const selectedIssuer = context.selectedIssuer;
|
||||
|
||||
return credentialTypes;
|
||||
},
|
||||
fetchAuthorizationEndpoint: async (context: any) => {
|
||||
const wellknownResponse = context.selectedIssuerWellknownResponse;
|
||||
const credentialIssuer = wellknownResponse['credential_issuer'];
|
||||
const authorizationServers = wellknownResponse[
|
||||
'authorization_servers'
|
||||
] || [credentialIssuer];
|
||||
const keys =
|
||||
selectedIssuer.credential_configuration_ids ??
|
||||
Object.keys(selectedIssuer.credential_configurations_supported);
|
||||
|
||||
const SUPPORTED_GRANT_TYPES = ['authorization_code'];
|
||||
const DEFAULT_AUTHORIZATION_SERVER_SUPPORTED_GRANT_TYPES = [
|
||||
'authorization_code',
|
||||
'implicit',
|
||||
];
|
||||
|
||||
for (const server of authorizationServers) {
|
||||
try {
|
||||
const authorizationServersMetadata =
|
||||
await CACHED_API.fetchIssuerAuthorizationServerMetadata(server);
|
||||
|
||||
if (
|
||||
(
|
||||
authorizationServersMetadata?.['grant_types_supported'] ||
|
||||
DEFAULT_AUTHORIZATION_SERVER_SUPPORTED_GRANT_TYPES
|
||||
).some(grant => SUPPORTED_GRANT_TYPES.includes(grant))
|
||||
) {
|
||||
return authorizationServersMetadata['authorization_endpoint'];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to fetch metadata for ${server}:`, error);
|
||||
for (const key of keys) {
|
||||
if (selectedIssuer.credential_configurations_supported[key]) {
|
||||
credentialTypes.push({
|
||||
id: key,
|
||||
...selectedIssuer.credential_configurations_supported[key],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
OIDCErrors.AUTHORIZATION_ENDPOINT_DISCOVERY.FAILED_TO_FETCH_AUTHORIZATION_ENDPOINT,
|
||||
);
|
||||
if (credentialTypes.length === 0) {
|
||||
throw new Error(
|
||||
`No credential type found for issuer ${selectedIssuer.issuer_id}`,
|
||||
);
|
||||
}
|
||||
return credentialTypes;
|
||||
},
|
||||
|
||||
downloadCredential: async (context: any) => {
|
||||
const downloadTimeout = await vcDownloadTimeout();
|
||||
const accessToken: string = context.tokenResponse?.accessToken;
|
||||
const proofJWT = await constructProofJWT(
|
||||
context.publicKey,
|
||||
context.privateKey,
|
||||
accessToken,
|
||||
context.selectedIssuer,
|
||||
context.keyType,
|
||||
);
|
||||
let credential = await VciClient.downloadCredential(
|
||||
downloadCredential: (context: any) => async (sendBack: any) => {
|
||||
const navigateToAuthView = (authorizationEndpoint: string) => {
|
||||
sendBack({
|
||||
type: 'AUTH_ENDPOINT_RECEIVED',
|
||||
authEndpoint: authorizationEndpoint,
|
||||
});
|
||||
};
|
||||
const getProofJwt= async (accessToken: string, cNonce: string) => {
|
||||
sendBack({
|
||||
type: 'PROOF_REQUEST',
|
||||
accessToken: accessToken,
|
||||
cNonce: cNonce,
|
||||
})
|
||||
}
|
||||
const credential = await VciClient.requestCredentialFromTrustedIssuer(
|
||||
constructIssuerMetaData(
|
||||
context.selectedIssuer,
|
||||
context.selectedCredentialType,
|
||||
downloadTimeout,
|
||||
),
|
||||
proofJWT,
|
||||
accessToken,
|
||||
);
|
||||
|
||||
console.info(`VC download via ${context.selectedIssuerId} is successful`);
|
||||
return await updateCredentialInformation(context, credential);
|
||||
},
|
||||
invokeAuthorization: async (context: any) => {
|
||||
sendImpressionEvent(
|
||||
getImpressionEventData(
|
||||
TelemetryConstants.FlowType.vcDownload,
|
||||
context.selectedIssuer.issuer_id +
|
||||
TelemetryConstants.Screens.webViewPage,
|
||||
),
|
||||
);
|
||||
return await authorize(
|
||||
constructAuthorizationConfiguration(
|
||||
context.selectedIssuer,
|
||||
context.selectedCredentialType.scope,
|
||||
),
|
||||
{
|
||||
clientId: context.selectedIssuer.client_id,
|
||||
redirectUri: context.selectedIssuer.redirect_uri,
|
||||
},
|
||||
getProofJwt,
|
||||
navigateToAuthView,
|
||||
);
|
||||
return updateCredentialInformation(context, credential);
|
||||
},
|
||||
sendTxCode: async (context: any) => {
|
||||
await VciClient.client.sendTxCodeFromJS(context.txCode);
|
||||
},
|
||||
|
||||
sendConsentGiven: async () => {
|
||||
await VciClient.client.sendIssuerTrustResponseFromJS(true);
|
||||
},
|
||||
|
||||
sendConsentNotGiven: async () => {
|
||||
await VciClient.client.sendIssuerTrustResponseFromJS(false);
|
||||
},
|
||||
|
||||
downloadCredentialFromOffer: (context: any) => async (sendBack: any) => {
|
||||
const navigateToAuthView = (authorizationEndpoint: string) => {
|
||||
sendBack({
|
||||
type: 'AUTH_ENDPOINT_RECEIVED',
|
||||
authEndpoint: authorizationEndpoint,
|
||||
});
|
||||
};
|
||||
const getSignedProofJwt = async (
|
||||
accessToken: string,
|
||||
cNonce: string | null,
|
||||
issuerMetadata: object,
|
||||
credentialConfigurationId: string,
|
||||
) => {
|
||||
console.log("issuerMetadata::", issuerMetadata);
|
||||
let issuer = issuerMetadata as issuerType;
|
||||
issuer.issuer_id = issuer.credential_issuer;
|
||||
await setItem(
|
||||
API_CACHED_STORAGE_KEYS.fetchIssuerWellknownConfig(issuer.issuer_id),
|
||||
issuer,
|
||||
'',
|
||||
);
|
||||
|
||||
let credentialTypes: Array<{id: string; [key: string]: any}> = [];
|
||||
if (
|
||||
issuer.credential_configurations_supported[credentialConfigurationId]
|
||||
) {
|
||||
credentialTypes.push({
|
||||
id: credentialConfigurationId,
|
||||
...issuer.credential_configurations_supported[
|
||||
credentialConfigurationId
|
||||
],
|
||||
});
|
||||
sendBack({
|
||||
type: 'PROOF_REQUEST',
|
||||
accessToken: accessToken,
|
||||
cNonce: cNonce,
|
||||
issuerMetadata: issuerMetadata,
|
||||
issuer: issuer,
|
||||
credentialTypes: credentialTypes,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const getTxCode = async (
|
||||
inputMode: string | undefined,
|
||||
description: string | undefined,
|
||||
length: number | undefined,
|
||||
) => {
|
||||
sendBack({
|
||||
type: 'TX_CODE_REQUEST',
|
||||
inputMode: inputMode,
|
||||
description: description,
|
||||
length: length,
|
||||
});
|
||||
};
|
||||
|
||||
const requesTrustIssuerConsent = async (issuerMetadata: object) => {
|
||||
const issuerMetadataObject = issuerMetadata as issuerType;
|
||||
|
||||
sendBack({
|
||||
type: 'TRUST_ISSUER_CONSENT_REQUEST',
|
||||
issuerMetadata: issuerMetadataObject,
|
||||
});
|
||||
};
|
||||
|
||||
const credential = await VciClient.requestCredentialByOffer(
|
||||
context.qrData,
|
||||
getTxCode,
|
||||
getSignedProofJwt,
|
||||
navigateToAuthView,
|
||||
requesTrustIssuerConsent,
|
||||
);
|
||||
return credential;
|
||||
},
|
||||
updateCredential: async (context: any) => {
|
||||
const credential = await updateCredentialInformation(
|
||||
context,
|
||||
context.credential,
|
||||
);
|
||||
return credential;
|
||||
},
|
||||
|
||||
constructProof: async (context: any) => {
|
||||
const issuerMeta = context.selectedIssuer;
|
||||
const proofJWT = await constructProofJWT(
|
||||
context.publicKey,
|
||||
context.privateKey,
|
||||
context.accessToken,
|
||||
issuerMeta,
|
||||
context.keyType,
|
||||
true,
|
||||
context.cNonce,
|
||||
);
|
||||
await VciClient.client.sendProofFromJS(proofJWT);
|
||||
return proofJWT;
|
||||
},
|
||||
constructProofForTrustedIssuers: async (context: any) => {
|
||||
const issuerMeta = context.selectedIssuer;
|
||||
const proofJWT = await constructProofJWT(
|
||||
context.publicKey,
|
||||
context.privateKey,
|
||||
context.accessToken,
|
||||
issuerMeta,
|
||||
context.keyType,
|
||||
false,
|
||||
context.cNonce,
|
||||
);
|
||||
await VciClient.client.sendProofFromJS(proofJWT);
|
||||
return proofJWT;
|
||||
},
|
||||
|
||||
|
||||
getKeyOrderList: async () => {
|
||||
const {RNSecureKeystoreModule} = NativeModules;
|
||||
@@ -165,6 +249,7 @@ export const IssuersService = () => {
|
||||
if (!verificationResult.isVerified) {
|
||||
throw new Error(verificationResult.verificationErrorCode);
|
||||
}
|
||||
|
||||
return verificationResult;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,118 +1,64 @@
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]': {
|
||||
type: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
isUserSignedAlready: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
|
||||
};
|
||||
missingImplementations: {
|
||||
actions:
|
||||
| 'addVcToInProgressDownloads'
|
||||
| 'getVcItemResponse'
|
||||
| 'loadMyVcs'
|
||||
| 'loadReceivedVcs'
|
||||
| 'logTamperedVCsremoved'
|
||||
| 'prependToMyVcsMetadata'
|
||||
| 'removeDownloadFailedVcsFromStorage'
|
||||
| 'removeDownloadingFailedVcsFromMyVcs'
|
||||
| 'removeVcFromInProgressDownlods'
|
||||
| 'removeVcFromMyVcsMetadata'
|
||||
| 'resetDownloadCreadentialsFailed'
|
||||
| 'resetDownloadCredentialsSuccess'
|
||||
| 'resetDownloadFailedVcs'
|
||||
| 'resetInProgressVcsDownloaded'
|
||||
| 'resetTamperedVcs'
|
||||
| 'resetVerificationErrorMessage'
|
||||
| 'resetVerificationStatus'
|
||||
| 'resetWalletBindingSuccess'
|
||||
| 'sendBackupEvent'
|
||||
| 'setDownloadCreadentialsFailed'
|
||||
| 'setDownloadCredentialsSuccess'
|
||||
| 'setDownloadedVc'
|
||||
| 'setDownloadingFailedVcs'
|
||||
| 'setMyVcs'
|
||||
| 'setReceivedVcs'
|
||||
| 'setUpdatedVcMetadatas'
|
||||
| 'setVerificationErrorMessage'
|
||||
| 'setVerificationStatus'
|
||||
| 'setWalletBindingSuccess'
|
||||
| 'updateMyVcsMetadata';
|
||||
delays: never;
|
||||
guards: 'isAnyVcTampered' | 'isSignedIn';
|
||||
services: 'isUserSignedAlready';
|
||||
};
|
||||
eventsCausingActions: {
|
||||
addVcToInProgressDownloads: 'ADD_VC_TO_IN_PROGRESS_DOWNLOADS';
|
||||
getVcItemResponse: 'GET_VC_ITEM';
|
||||
loadMyVcs:
|
||||
| 'REFRESH_MY_VCS'
|
||||
| 'REFRESH_RECEIVED_VCS'
|
||||
| 'STORE_RESPONSE'
|
||||
| 'VERIFY_VC_FAILED'
|
||||
| 'xstate.init';
|
||||
loadReceivedVcs: 'REFRESH_RECEIVED_VCS' | 'STORE_RESPONSE';
|
||||
logTamperedVCsremoved: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
|
||||
prependToMyVcsMetadata: 'VC_ADDED';
|
||||
removeDownloadFailedVcsFromStorage: 'DELETE_VC';
|
||||
removeDownloadingFailedVcsFromMyVcs: 'STORE_RESPONSE';
|
||||
removeVcFromInProgressDownlods:
|
||||
| 'DOWNLOAD_LIMIT_EXPIRED'
|
||||
| 'REMOVE_VC_FROM_IN_PROGRESS_DOWNLOADS'
|
||||
| 'VERIFY_VC_FAILED';
|
||||
removeVcFromMyVcsMetadata: 'REMOVE_VC_FROM_CONTEXT';
|
||||
resetDownloadCreadentialsFailed: 'RESET_DOWNLOADING_FAILED';
|
||||
resetDownloadCredentialsSuccess: 'RESET_DOWNLOADING_SUCCESS';
|
||||
resetDownloadFailedVcs: 'STORE_RESPONSE';
|
||||
resetInProgressVcsDownloaded: 'RESET_IN_PROGRESS_VCS_DOWNLOADED';
|
||||
resetTamperedVcs: 'REMOVE_TAMPERED_VCS';
|
||||
resetVerificationErrorMessage: 'RESET_VERIFY_ERROR';
|
||||
resetVerificationStatus: 'RESET_VERIFICATION_STATUS';
|
||||
resetWalletBindingSuccess: 'RESET_WALLET_BINDING_SUCCESS';
|
||||
sendBackupEvent: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
|
||||
setDownloadCreadentialsFailed: 'VC_DOWNLOADING_FAILED';
|
||||
setDownloadCredentialsSuccess: 'VC_DOWNLOADED';
|
||||
setDownloadedVc: 'VC_DOWNLOADED';
|
||||
setDownloadingFailedVcs: 'DOWNLOAD_LIMIT_EXPIRED';
|
||||
setMyVcs: 'STORE_RESPONSE';
|
||||
setReceivedVcs: 'STORE_RESPONSE';
|
||||
setUpdatedVcMetadatas: 'VC_METADATA_UPDATED';
|
||||
setVerificationErrorMessage: 'VERIFY_VC_FAILED';
|
||||
setVerificationStatus: 'SET_VERIFICATION_STATUS';
|
||||
setWalletBindingSuccess: 'WALLET_BINDING_SUCCESS';
|
||||
updateMyVcsMetadata: 'VC_METADATA_UPDATED';
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {
|
||||
isAnyVcTampered: 'SHOW_TAMPERED_POPUP';
|
||||
isSignedIn: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
|
||||
};
|
||||
eventsCausingServices: {
|
||||
isUserSignedAlready: 'REMOVE_TAMPERED_VCS';
|
||||
};
|
||||
matchesStates:
|
||||
| 'deletingFailedVcs'
|
||||
| 'ready'
|
||||
| 'ready.myVcs'
|
||||
| 'ready.receivedVcs'
|
||||
| 'ready.showTamperedPopup'
|
||||
| 'ready.tamperedVCs'
|
||||
| 'ready.tamperedVCs.idle'
|
||||
| 'ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion'
|
||||
| {
|
||||
ready?:
|
||||
| 'myVcs'
|
||||
| 'receivedVcs'
|
||||
| 'showTamperedPopup'
|
||||
| 'tamperedVCs'
|
||||
| {tamperedVCs?: 'idle' | 'triggerAutoBackupForTamperedVcDeletion'};
|
||||
};
|
||||
tags: never;
|
||||
}
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]": { type: "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
"isUserSignedAlready": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: "addVcToInProgressDownloads" | "getVcItemResponse" | "loadMyVcs" | "loadReceivedVcs" | "logTamperedVCsremoved" | "prependToMyVcsMetadata" | "removeDownloadFailedVcsFromStorage" | "removeDownloadingFailedVcsFromMyVcs" | "removeVcFromInProgressDownlods" | "removeVcFromMyVcsMetadata" | "resetDownloadCreadentialsFailed" | "resetDownloadCredentialsSuccess" | "resetDownloadFailedVcs" | "resetInProgressVcsDownloaded" | "resetTamperedVcs" | "resetVerificationErrorMessage" | "resetVerificationStatus" | "resetWalletBindingSuccess" | "sendBackupEvent" | "setDownloadCreadentialsFailed" | "setDownloadCredentialsSuccess" | "setDownloadedVc" | "setDownloadingFailedVcs" | "setMyVcs" | "setReceivedVcs" | "setUpdatedVcMetadatas" | "setVerificationErrorMessage" | "setVerificationStatus" | "setWalletBindingSuccess" | "updateMyVcsMetadata";
|
||||
delays: never;
|
||||
guards: "isAnyVcTampered" | "isSignedIn";
|
||||
services: "isUserSignedAlready";
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"addVcToInProgressDownloads": "ADD_VC_TO_IN_PROGRESS_DOWNLOADS";
|
||||
"getVcItemResponse": "GET_VC_ITEM";
|
||||
"loadMyVcs": "REFRESH_MY_VCS" | "REFRESH_RECEIVED_VCS" | "STORE_RESPONSE" | "VERIFY_VC_FAILED" | "xstate.init";
|
||||
"loadReceivedVcs": "REFRESH_RECEIVED_VCS" | "STORE_RESPONSE";
|
||||
"logTamperedVCsremoved": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
|
||||
"prependToMyVcsMetadata": "VC_ADDED";
|
||||
"removeDownloadFailedVcsFromStorage": "DELETE_VC";
|
||||
"removeDownloadingFailedVcsFromMyVcs": "STORE_RESPONSE";
|
||||
"removeVcFromInProgressDownlods": "DOWNLOAD_LIMIT_EXPIRED" | "REMOVE_VC_FROM_IN_PROGRESS_DOWNLOADS" | "VERIFY_VC_FAILED";
|
||||
"removeVcFromMyVcsMetadata": "REMOVE_VC_FROM_CONTEXT";
|
||||
"resetDownloadCreadentialsFailed": "RESET_DOWNLOADING_FAILED";
|
||||
"resetDownloadCredentialsSuccess": "RESET_DOWNLOADING_SUCCESS";
|
||||
"resetDownloadFailedVcs": "STORE_RESPONSE";
|
||||
"resetInProgressVcsDownloaded": "RESET_IN_PROGRESS_VCS_DOWNLOADED";
|
||||
"resetTamperedVcs": "REMOVE_TAMPERED_VCS";
|
||||
"resetVerificationErrorMessage": "RESET_VERIFY_ERROR";
|
||||
"resetVerificationStatus": "RESET_VERIFICATION_STATUS";
|
||||
"resetWalletBindingSuccess": "RESET_WALLET_BINDING_SUCCESS";
|
||||
"sendBackupEvent": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
|
||||
"setDownloadCreadentialsFailed": "VC_DOWNLOADING_FAILED";
|
||||
"setDownloadCredentialsSuccess": "VC_DOWNLOADED";
|
||||
"setDownloadedVc": "VC_DOWNLOADED";
|
||||
"setDownloadingFailedVcs": "DOWNLOAD_LIMIT_EXPIRED";
|
||||
"setMyVcs": "STORE_RESPONSE";
|
||||
"setReceivedVcs": "STORE_RESPONSE";
|
||||
"setUpdatedVcMetadatas": "VC_METADATA_UPDATED";
|
||||
"setVerificationErrorMessage": "VERIFY_VC_FAILED";
|
||||
"setVerificationStatus": "SET_VERIFICATION_STATUS";
|
||||
"setWalletBindingSuccess": "WALLET_BINDING_SUCCESS";
|
||||
"updateMyVcsMetadata": "VC_METADATA_UPDATED";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"isAnyVcTampered": "SHOW_TAMPERED_POPUP";
|
||||
"isSignedIn": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
"isUserSignedAlready": "REMOVE_TAMPERED_VCS";
|
||||
};
|
||||
matchesStates: "deletingFailedVcs" | "ready" | "ready.myVcs" | "ready.receivedVcs" | "ready.showTamperedPopup" | "ready.tamperedVCs" | "ready.tamperedVCs.idle" | "ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion" | { "ready"?: "myVcs" | "receivedVcs" | "showTamperedPopup" | "tamperedVCs" | { "tamperedVCs"?: "idle" | "triggerAutoBackupForTamperedVcDeletion"; }; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ export interface CredentialTypes {
|
||||
proof_types_supported: Object;
|
||||
credential_definition: {
|
||||
type: Object[];
|
||||
context:string[]
|
||||
credentialSubject: CredentialSubject;
|
||||
};
|
||||
doctype: string;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"": { type: "" };
|
||||
"done.invoke.auth.authorized:invocation[0]": { type: "done.invoke.auth.authorized:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.auth.introSlider:invocation[0]": { type: "done.invoke.auth.introSlider:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
"generatePasscodeSalt": "done.invoke.auth.introSlider:invocation[0]";
|
||||
"initializeFaceSdkModel": "done.invoke.auth.authorized:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"requestStoredContext": "BIOMETRIC_CANCELLED" | "xstate.init";
|
||||
"setBiometrics": "SETUP_BIOMETRICS";
|
||||
"setContext": "STORE_RESPONSE";
|
||||
"setInitialDownloadDone": "INITIAL_DOWNLOAD_DONE";
|
||||
"setIsToggleFromSettings": "CHANGE_METHOD";
|
||||
"setLanguage": "SETUP_BIOMETRICS" | "SETUP_PASSCODE";
|
||||
"setOnboardingDone": "ONBOARDING_DONE";
|
||||
"setPasscode": "SETUP_PASSCODE";
|
||||
"setPasscodeSalt": "done.invoke.auth.introSlider:invocation[0]";
|
||||
"setTourGuide": "SET_TOUR_GUIDE";
|
||||
"storeContext": "INITIAL_DOWNLOAD_DONE" | "ONBOARDING_DONE" | "SETUP_BIOMETRICS" | "SETUP_PASSCODE" | "STORE_RESPONSE" | "done.invoke.auth.authorized:invocation[0]" | "done.invoke.auth.introSlider:invocation[0]";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"hasBiometricSet": "";
|
||||
"hasData": "STORE_RESPONSE";
|
||||
"hasLanguageset": "";
|
||||
"hasPasscodeSet": "";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
"generatePasscodeSalt": "SELECT";
|
||||
"initializeFaceSdkModel": "LOGIN" | "SETUP_BIOMETRICS" | "SETUP_PASSCODE";
|
||||
};
|
||||
matchesStates: "authorized" | "checkingAuth" | "init" | "introSlider" | "languagesetup" | "savingDefaults" | "settingUp" | "unauthorized";
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -1,378 +1,134 @@
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'': {type: ''};
|
||||
'done.invoke.QrLogin': {
|
||||
type: 'done.invoke.QrLogin';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.scan.checkStorage:invocation[0]': {
|
||||
type: 'done.invoke.scan.checkStorage:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection': {
|
||||
type: 'xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection';
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
'xstate.stop': {type: 'xstate.stop'};
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
checkBluetoothPermission: 'done.invoke.scan.checkBluetoothPermission.checking:invocation[0]';
|
||||
checkBluetoothState:
|
||||
| 'done.invoke.scan.checkBluetoothState.checking:invocation[0]'
|
||||
| 'done.invoke.scan.recheckBluetoothState.checking:invocation[0]';
|
||||
checkLocationPermission: 'done.invoke.scan.checkingLocationState.checkingPermissionStatus:invocation[0]';
|
||||
checkLocationStatus: 'done.invoke.scan.checkingLocationState.checkLocationService:invocation[0]';
|
||||
checkNearByDevicesPermission: 'done.invoke.scan.checkNearbyDevicesPermission.checking:invocation[0]';
|
||||
checkStorageAvailability: 'done.invoke.scan.checkStorage:invocation[0]';
|
||||
disconnect:
|
||||
| 'done.invoke.scan.clearingConnection:invocation[0]'
|
||||
| 'done.invoke.scan.disconnectDevice:invocation[0]'
|
||||
| 'done.invoke.scan.reviewing.disconnect:invocation[0]';
|
||||
monitorConnection: 'done.invoke.scan:invocation[0]';
|
||||
requestBluetooth: 'done.invoke.scan.checkBluetoothState.requesting:invocation[0]';
|
||||
requestNearByDevicesPermission: 'done.invoke.scan.checkNearbyDevicesPermission.requesting:invocation[0]';
|
||||
requestToEnableLocationPermission: 'done.invoke.scan.checkingLocationState.requestToEnableLocation:invocation[0]';
|
||||
sendVc: 'done.invoke.scan.reviewing.sendingVc:invocation[0]';
|
||||
startConnection: 'done.invoke.scan.connecting:invocation[0]';
|
||||
};
|
||||
missingImplementations: {
|
||||
actions:
|
||||
| 'clearUri'
|
||||
| 'enableLocation'
|
||||
| 'getFaceAuthConsent'
|
||||
| 'loadMetaDataToMemory'
|
||||
| 'loadVCDataToMemory'
|
||||
| 'logFailedVerification'
|
||||
| 'logShared'
|
||||
| 'openAppPermission'
|
||||
| 'openBluetoothSettings'
|
||||
| 'refreshVCs'
|
||||
| 'registerLoggers'
|
||||
| 'removeLoggers'
|
||||
| 'resetFaceCaptureBannerStatus'
|
||||
| 'resetFlowType'
|
||||
| 'resetIsQrLoginViaDeepLink'
|
||||
| 'resetLinkCode'
|
||||
| 'resetOpenID4VPFlowType'
|
||||
| 'resetSelectedVc'
|
||||
| 'resetShowQuickShareSuccessBanner'
|
||||
| 'sendBLEConnectionErrorEvent'
|
||||
| 'sendScanData'
|
||||
| 'sendVCShareFlowCancelEndEvent'
|
||||
| 'sendVCShareFlowTimeoutEndEvent'
|
||||
| 'sendVPScanData'
|
||||
| 'sendVcShareSuccessEvent'
|
||||
| 'sendVcSharingStartEvent'
|
||||
| 'setBleError'
|
||||
| 'setFlowType'
|
||||
| 'setIsQrLoginViaDeepLink'
|
||||
| 'setLinkCode'
|
||||
| 'setLinkCodeFromDeepLink'
|
||||
| 'setOpenId4VPFlowType'
|
||||
| 'setOpenId4VPRef'
|
||||
| 'setQrLoginRef'
|
||||
| 'setQuickShareData'
|
||||
| 'setReadyForBluetoothStateCheck'
|
||||
| 'setReceiverInfo'
|
||||
| 'setSelectedVc'
|
||||
| 'setSenderInfo'
|
||||
| 'setShareLogTypeUnverified'
|
||||
| 'setShareLogTypeVerified'
|
||||
| 'setShowFaceAuthConsent'
|
||||
| 'setShowQuickShareSuccessBanner'
|
||||
| 'setUri'
|
||||
| 'storeLoginItem'
|
||||
| 'storeShowFaceAuthConsent'
|
||||
| 'storingActivityLog'
|
||||
| 'updateFaceCaptureBannerStatus'
|
||||
| 'updateShowFaceAuthConsent';
|
||||
delays: never;
|
||||
guards:
|
||||
| 'isFlowTypeMiniViewShare'
|
||||
| 'isFlowTypeMiniViewShareWithSelfie'
|
||||
| 'isFlowTypeSimpleShare'
|
||||
| 'isIOS'
|
||||
| 'isMinimumStorageRequiredForAuditEntryReached'
|
||||
| 'isOnlineSharing'
|
||||
| 'isOpenIdQr'
|
||||
| 'isQrLogin'
|
||||
| 'isQrLoginViaDeepLinking'
|
||||
| 'isQuickShare'
|
||||
| 'showFaceAuthConsentScreen'
|
||||
| 'uptoAndroid11';
|
||||
services:
|
||||
| 'checkBluetoothPermission'
|
||||
| 'checkBluetoothState'
|
||||
| 'checkLocationPermission'
|
||||
| 'checkLocationStatus'
|
||||
| 'checkNearByDevicesPermission'
|
||||
| 'checkStorageAvailability'
|
||||
| 'disconnect'
|
||||
| 'monitorConnection'
|
||||
| 'requestBluetooth'
|
||||
| 'requestNearByDevicesPermission'
|
||||
| 'requestToEnableLocationPermission'
|
||||
| 'sendVc'
|
||||
| 'startConnection';
|
||||
};
|
||||
eventsCausingActions: {
|
||||
clearUri: '';
|
||||
enableLocation: 'ALLOWED' | 'LOCATION_REQUEST';
|
||||
getFaceAuthConsent:
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection';
|
||||
loadMetaDataToMemory: 'SCAN';
|
||||
loadVCDataToMemory: 'STORE_RESPONSE';
|
||||
logFailedVerification: 'FACE_INVALID';
|
||||
logShared: 'VC_ACCEPTED';
|
||||
openAppPermission: 'GOTO_SETTINGS' | 'LOCATION_REQUEST';
|
||||
openBluetoothSettings: 'GOTO_SETTINGS';
|
||||
refreshVCs: 'STORE_RESPONSE';
|
||||
registerLoggers: '';
|
||||
removeLoggers:
|
||||
| ''
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'DISMISS_QUICK_SHARE_BANNER'
|
||||
| 'QRLOGIN_VIA_DEEP_LINK'
|
||||
| 'RESET'
|
||||
| 'SCREEN_BLUR'
|
||||
| 'xstate.init';
|
||||
resetFaceCaptureBannerStatus: '' | 'ACCEPT_REQUEST' | 'CLOSE_BANNER';
|
||||
resetFlowType:
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'DISMISS_QUICK_SHARE_BANNER'
|
||||
| 'GOTO_HISTORY'
|
||||
| 'QRLOGIN_VIA_DEEP_LINK'
|
||||
| 'RESET'
|
||||
| 'SCREEN_BLUR'
|
||||
| 'xstate.init';
|
||||
resetIsQrLoginViaDeepLink: 'DISMISS' | 'RESET';
|
||||
resetLinkCode:
|
||||
| 'BLE_ERROR'
|
||||
| 'DISMISS'
|
||||
| 'DISMISS_QUICK_SHARE_BANNER'
|
||||
| 'QRLOGIN_VIA_DEEP_LINK'
|
||||
| 'RESET'
|
||||
| 'SCREEN_BLUR'
|
||||
| 'SCREEN_FOCUS'
|
||||
| 'SELECT_VC'
|
||||
| 'xstate.stop';
|
||||
resetOpenID4VPFlowType: 'CANCEL' | 'DISMISS' | 'RETRY' | 'SCREEN_BLUR';
|
||||
resetSelectedVc:
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'DISMISS_QUICK_SHARE_BANNER'
|
||||
| 'GOTO_HISTORY'
|
||||
| 'QRLOGIN_VIA_DEEP_LINK'
|
||||
| 'RESET'
|
||||
| 'SCREEN_BLUR'
|
||||
| 'xstate.init';
|
||||
resetShowQuickShareSuccessBanner: 'DISMISS' | 'DISMISS_QUICK_SHARE_BANNER';
|
||||
sendBLEConnectionErrorEvent: 'BLE_ERROR';
|
||||
sendScanData: '' | 'SCAN';
|
||||
sendVCShareFlowCancelEndEvent: 'CANCEL';
|
||||
sendVCShareFlowTimeoutEndEvent: 'CANCEL' | 'RETRY';
|
||||
sendVPScanData: 'SCAN';
|
||||
sendVcShareSuccessEvent: 'VC_ACCEPTED';
|
||||
sendVcSharingStartEvent: 'SCAN';
|
||||
setBleError: 'BLE_ERROR';
|
||||
setFlowType: 'SELECT_VC';
|
||||
setIsQrLoginViaDeepLink: 'QRLOGIN_VIA_DEEP_LINK';
|
||||
setLinkCode: 'SCAN';
|
||||
setLinkCodeFromDeepLink: 'QRLOGIN_VIA_DEEP_LINK';
|
||||
setOpenId4VPFlowType: 'SCAN';
|
||||
setOpenId4VPRef:
|
||||
| 'CANCEL'
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'DISMISS_QUICK_SHARE_BANNER'
|
||||
| 'QRLOGIN_VIA_DEEP_LINK'
|
||||
| 'RESET'
|
||||
| 'RETRY'
|
||||
| 'SCREEN_BLUR'
|
||||
| 'SCREEN_FOCUS'
|
||||
| 'SELECT_VC'
|
||||
| 'xstate.init';
|
||||
setQrLoginRef: 'QRLOGIN_VIA_DEEP_LINK' | 'SCAN';
|
||||
setQuickShareData: 'SCAN';
|
||||
setReadyForBluetoothStateCheck: 'BLUETOOTH_PERMISSION_ENABLED';
|
||||
setReceiverInfo: 'CONNECTED';
|
||||
setSelectedVc: 'SELECT_VC';
|
||||
setSenderInfo: 'CONNECTED';
|
||||
setShareLogTypeUnverified: 'ACCEPT_REQUEST' | 'CHECK_FLOW_TYPE';
|
||||
setShareLogTypeVerified: 'FACE_VALID';
|
||||
setShowFaceAuthConsent: 'FACE_VERIFICATION_CONSENT';
|
||||
setShowQuickShareSuccessBanner: 'STORE_RESPONSE';
|
||||
setUri: 'SCAN';
|
||||
storeLoginItem: 'done.invoke.QrLogin';
|
||||
storeShowFaceAuthConsent: 'FACE_VERIFICATION_CONSENT';
|
||||
storingActivityLog: 'STORE_RESPONSE';
|
||||
updateFaceCaptureBannerStatus: 'FACE_VALID';
|
||||
updateShowFaceAuthConsent: 'STORE_RESPONSE';
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
CONNECTION_TIMEOUT: 'SCAN';
|
||||
DESTROY_TIMEOUT: '' | 'DISMISS' | 'LOCATION_ENABLED' | 'RETRY';
|
||||
SHARING_TIMEOUT: 'ACCEPT_REQUEST' | 'CHECK_FLOW_TYPE' | 'FACE_VALID';
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
isFlowTypeMiniViewShare: 'CHECK_FLOW_TYPE';
|
||||
isFlowTypeMiniViewShareWithSelfie: 'CHECK_FLOW_TYPE' | 'DISMISS';
|
||||
isFlowTypeSimpleShare: 'CANCEL' | 'CHECK_FLOW_TYPE' | 'DISMISS' | 'RETRY';
|
||||
isIOS: 'BLUETOOTH_STATE_DISABLED' | 'START_PERMISSION_CHECK';
|
||||
isMinimumStorageRequiredForAuditEntryReached: 'done.invoke.scan.checkStorage:invocation[0]';
|
||||
isOnlineSharing: 'SCAN';
|
||||
isOpenIdQr: 'SCAN';
|
||||
isQrLogin: 'SCAN';
|
||||
isQrLoginViaDeepLinking: '' | 'STORE_RESPONSE';
|
||||
isQuickShare: 'SCAN';
|
||||
showFaceAuthConsentScreen: '' | 'VERIFY_AND_ACCEPT_REQUEST';
|
||||
uptoAndroid11: '' | 'START_PERMISSION_CHECK';
|
||||
};
|
||||
eventsCausingServices: {
|
||||
OpenId4VP: 'SCAN';
|
||||
QrLogin: '' | 'SCAN';
|
||||
checkBluetoothPermission:
|
||||
| ''
|
||||
| 'BLUETOOTH_STATE_DISABLED'
|
||||
| 'NEARBY_ENABLED'
|
||||
| 'START_PERMISSION_CHECK';
|
||||
checkBluetoothState: '' | 'APP_ACTIVE';
|
||||
checkLocationPermission: 'LOCATION_ENABLED';
|
||||
checkLocationStatus: '' | 'APP_ACTIVE' | 'LOCATION_REQUEST';
|
||||
checkNearByDevicesPermission: 'APP_ACTIVE' | 'START_PERMISSION_CHECK';
|
||||
checkStorageAvailability:
|
||||
| 'CANCEL'
|
||||
| 'DISMISS'
|
||||
| 'QRLOGIN_VIA_DEEP_LINK'
|
||||
| 'RESET'
|
||||
| 'RETRY'
|
||||
| 'SCREEN_FOCUS'
|
||||
| 'SELECT_VC';
|
||||
disconnect: '' | 'DISMISS' | 'LOCATION_ENABLED' | 'RETRY' | 'SCREEN_BLUR';
|
||||
monitorConnection:
|
||||
| 'DISMISS'
|
||||
| 'QRLOGIN_VIA_DEEP_LINK'
|
||||
| 'SCREEN_BLUR'
|
||||
| 'xstate.init';
|
||||
requestBluetooth: 'BLUETOOTH_STATE_DISABLED';
|
||||
requestNearByDevicesPermission: 'NEARBY_DISABLED';
|
||||
requestToEnableLocationPermission: 'LOCATION_DISABLED';
|
||||
sendVc: 'ACCEPT_REQUEST' | 'CHECK_FLOW_TYPE' | 'FACE_VALID';
|
||||
startConnection: 'SCAN';
|
||||
};
|
||||
matchesStates:
|
||||
| 'bluetoothDenied'
|
||||
| 'bluetoothPermissionDenied'
|
||||
| 'checkBluetoothPermission'
|
||||
| 'checkBluetoothPermission.checking'
|
||||
| 'checkBluetoothPermission.enabled'
|
||||
| 'checkBluetoothState'
|
||||
| 'checkBluetoothState.checking'
|
||||
| 'checkBluetoothState.enabled'
|
||||
| 'checkBluetoothState.requesting'
|
||||
| 'checkFaceAuthConsent'
|
||||
| 'checkNearbyDevicesPermission'
|
||||
| 'checkNearbyDevicesPermission.checking'
|
||||
| 'checkNearbyDevicesPermission.enabled'
|
||||
| 'checkNearbyDevicesPermission.requesting'
|
||||
| 'checkQrLoginViaDeepLink'
|
||||
| 'checkStorage'
|
||||
| 'checkingLocationState'
|
||||
| 'checkingLocationState.LocationPermissionRationale'
|
||||
| 'checkingLocationState.checkLocationService'
|
||||
| 'checkingLocationState.checkingPermissionStatus'
|
||||
| 'checkingLocationState.denied'
|
||||
| 'checkingLocationState.disabled'
|
||||
| 'checkingLocationState.requestToEnableLocation'
|
||||
| 'clearingConnection'
|
||||
| 'connecting'
|
||||
| 'connecting.inProgress'
|
||||
| 'connecting.timeout'
|
||||
| 'decodeQuickShareData'
|
||||
| 'disconnectDevice'
|
||||
| 'disconnected'
|
||||
| 'findingConnection'
|
||||
| 'handlingBleError'
|
||||
| 'inactive'
|
||||
| 'invalid'
|
||||
| 'loadVCS'
|
||||
| 'loadVCS.idle'
|
||||
| 'loadVCS.navigatingToHome'
|
||||
| 'nearByDevicesPermissionDenied'
|
||||
| 'recheckBluetoothState'
|
||||
| 'recheckBluetoothState.checking'
|
||||
| 'recheckBluetoothState.enabled'
|
||||
| 'restrictSharingVc'
|
||||
| 'reviewing'
|
||||
| 'reviewing.accepted'
|
||||
| 'reviewing.cancelling'
|
||||
| 'reviewing.checkFaceAuthConsentForMiniView'
|
||||
| 'reviewing.disconnect'
|
||||
| 'reviewing.faceVerificationConsent'
|
||||
| 'reviewing.idle'
|
||||
| 'reviewing.invalidIdentity'
|
||||
| 'reviewing.navigateToHistory'
|
||||
| 'reviewing.rejected'
|
||||
| 'reviewing.selectingVc'
|
||||
| 'reviewing.sendingVc'
|
||||
| 'reviewing.sendingVc.inProgress'
|
||||
| 'reviewing.sendingVc.sent'
|
||||
| 'reviewing.sendingVc.timeout'
|
||||
| 'reviewing.verifyingIdentity'
|
||||
| 'showQrLogin'
|
||||
| 'showQrLogin.idle'
|
||||
| 'showQrLogin.navigatingToHistory'
|
||||
| 'showQrLogin.navigatingToHome'
|
||||
| 'showQrLogin.storing'
|
||||
| 'startPermissionCheck'
|
||||
| 'startVPSharing'
|
||||
| 'startVPSharing.inProgress'
|
||||
| 'startVPSharing.showError'
|
||||
| 'startVPSharing.success'
|
||||
| 'startVPSharing.timeout'
|
||||
| {
|
||||
checkBluetoothPermission?: 'checking' | 'enabled';
|
||||
checkBluetoothState?: 'checking' | 'enabled' | 'requesting';
|
||||
checkNearbyDevicesPermission?: 'checking' | 'enabled' | 'requesting';
|
||||
checkingLocationState?:
|
||||
| 'LocationPermissionRationale'
|
||||
| 'checkLocationService'
|
||||
| 'checkingPermissionStatus'
|
||||
| 'denied'
|
||||
| 'disabled'
|
||||
| 'requestToEnableLocation';
|
||||
connecting?: 'inProgress' | 'timeout';
|
||||
loadVCS?: 'idle' | 'navigatingToHome';
|
||||
recheckBluetoothState?: 'checking' | 'enabled';
|
||||
reviewing?:
|
||||
| 'accepted'
|
||||
| 'cancelling'
|
||||
| 'checkFaceAuthConsentForMiniView'
|
||||
| 'disconnect'
|
||||
| 'faceVerificationConsent'
|
||||
| 'idle'
|
||||
| 'invalidIdentity'
|
||||
| 'navigateToHistory'
|
||||
| 'rejected'
|
||||
| 'selectingVc'
|
||||
| 'sendingVc'
|
||||
| 'verifyingIdentity'
|
||||
| {sendingVc?: 'inProgress' | 'sent' | 'timeout'};
|
||||
showQrLogin?:
|
||||
| 'idle'
|
||||
| 'navigatingToHistory'
|
||||
| 'navigatingToHome'
|
||||
| 'storing';
|
||||
startVPSharing?: 'inProgress' | 'showError' | 'success' | 'timeout';
|
||||
};
|
||||
tags: never;
|
||||
}
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"": { type: "" };
|
||||
"done.invoke.QrLogin": { type: "done.invoke.QrLogin"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.scan.checkStorage:invocation[0]": { type: "done.invoke.scan.checkStorage:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection": { type: "xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection" };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
"xstate.stop": { type: "xstate.stop" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
"checkBluetoothPermission": "done.invoke.scan.checkBluetoothPermission.checking:invocation[0]";
|
||||
"checkBluetoothState": "done.invoke.scan.checkBluetoothState.checking:invocation[0]" | "done.invoke.scan.recheckBluetoothState.checking:invocation[0]";
|
||||
"checkLocationPermission": "done.invoke.scan.checkingLocationState.checkingPermissionStatus:invocation[0]";
|
||||
"checkLocationStatus": "done.invoke.scan.checkingLocationState.checkLocationService:invocation[0]";
|
||||
"checkNearByDevicesPermission": "done.invoke.scan.checkNearbyDevicesPermission.checking:invocation[0]";
|
||||
"checkStorageAvailability": "done.invoke.scan.checkStorage:invocation[0]";
|
||||
"disconnect": "done.invoke.scan.clearingConnection:invocation[0]" | "done.invoke.scan.disconnectDevice:invocation[0]" | "done.invoke.scan.reviewing.disconnect:invocation[0]";
|
||||
"monitorConnection": "done.invoke.scan:invocation[0]";
|
||||
"requestBluetooth": "done.invoke.scan.checkBluetoothState.requesting:invocation[0]";
|
||||
"requestNearByDevicesPermission": "done.invoke.scan.checkNearbyDevicesPermission.requesting:invocation[0]";
|
||||
"requestToEnableLocationPermission": "done.invoke.scan.checkingLocationState.requestToEnableLocation:invocation[0]";
|
||||
"sendVc": "done.invoke.scan.reviewing.sendingVc:invocation[0]";
|
||||
"startConnection": "done.invoke.scan.connecting:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: "clearUri" | "enableLocation" | "getFaceAuthConsent" | "loadMetaDataToMemory" | "loadVCDataToMemory" | "logFailedVerification" | "logShared" | "openAppPermission" | "openBluetoothSettings" | "refreshVCs" | "registerLoggers" | "removeLoggers" | "resetFaceCaptureBannerStatus" | "resetFlowType" | "resetIsQrLoginViaDeepLink" | "resetLinkCode" | "resetOpenID4VPFlowType" | "resetSelectedVc" | "resetShowQuickShareSuccessBanner" | "sendBLEConnectionErrorEvent" | "sendScanData" | "sendVCShareFlowCancelEndEvent" | "sendVCShareFlowTimeoutEndEvent" | "sendVPScanData" | "sendVcShareSuccessEvent" | "sendVcSharingStartEvent" | "setBleError" | "setFlowType" | "setIsQrLoginViaDeepLink" | "setLinkCode" | "setLinkCodeFromDeepLink" | "setOpenId4VPFlowType" | "setOpenId4VPRef" | "setQrLoginRef" | "setQuickShareData" | "setReadyForBluetoothStateCheck" | "setReceiverInfo" | "setSelectedVc" | "setSenderInfo" | "setShareLogTypeUnverified" | "setShareLogTypeVerified" | "setShowFaceAuthConsent" | "setShowQuickShareSuccessBanner" | "setUri" | "storeLoginItem" | "storeShowFaceAuthConsent" | "storingActivityLog" | "updateFaceCaptureBannerStatus" | "updateShowFaceAuthConsent";
|
||||
delays: never;
|
||||
guards: "isFlowTypeMiniViewShare" | "isFlowTypeMiniViewShareWithSelfie" | "isFlowTypeSimpleShare" | "isIOS" | "isMinimumStorageRequiredForAuditEntryReached" | "isOnlineSharing" | "isOpenIdQr" | "isQrLogin" | "isQrLoginViaDeepLinking" | "isQuickShare" | "showFaceAuthConsentScreen" | "uptoAndroid11";
|
||||
services: "checkBluetoothPermission" | "checkBluetoothState" | "checkLocationPermission" | "checkLocationStatus" | "checkNearByDevicesPermission" | "checkStorageAvailability" | "disconnect" | "monitorConnection" | "requestBluetooth" | "requestNearByDevicesPermission" | "requestToEnableLocationPermission" | "sendVc" | "startConnection";
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"clearUri": "";
|
||||
"enableLocation": "ALLOWED" | "LOCATION_REQUEST";
|
||||
"getFaceAuthConsent": "DISCONNECT" | "DISMISS" | "xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection";
|
||||
"loadMetaDataToMemory": "SCAN";
|
||||
"loadVCDataToMemory": "STORE_RESPONSE";
|
||||
"logFailedVerification": "FACE_INVALID";
|
||||
"logShared": "VC_ACCEPTED";
|
||||
"openAppPermission": "GOTO_SETTINGS" | "LOCATION_REQUEST";
|
||||
"openBluetoothSettings": "GOTO_SETTINGS";
|
||||
"refreshVCs": "STORE_RESPONSE";
|
||||
"registerLoggers": "";
|
||||
"removeLoggers": "" | "DISCONNECT" | "DISMISS" | "DISMISS_QUICK_SHARE_BANNER" | "QRLOGIN_VIA_DEEP_LINK" | "RESET" | "SCREEN_BLUR" | "xstate.init";
|
||||
"resetFaceCaptureBannerStatus": "" | "ACCEPT_REQUEST" | "CLOSE_BANNER";
|
||||
"resetFlowType": "DISCONNECT" | "DISMISS" | "DISMISS_QUICK_SHARE_BANNER" | "GOTO_HISTORY" | "QRLOGIN_VIA_DEEP_LINK" | "RESET" | "SCREEN_BLUR" | "xstate.init";
|
||||
"resetIsQrLoginViaDeepLink": "DISMISS" | "RESET";
|
||||
"resetLinkCode": "BLE_ERROR" | "DISMISS" | "DISMISS_QUICK_SHARE_BANNER" | "QRLOGIN_VIA_DEEP_LINK" | "RESET" | "SCREEN_BLUR" | "SCREEN_FOCUS" | "SELECT_VC" | "xstate.stop";
|
||||
"resetOpenID4VPFlowType": "CANCEL" | "DISMISS" | "RETRY" | "SCREEN_BLUR";
|
||||
"resetSelectedVc": "DISCONNECT" | "DISMISS" | "DISMISS_QUICK_SHARE_BANNER" | "GOTO_HISTORY" | "QRLOGIN_VIA_DEEP_LINK" | "RESET" | "SCREEN_BLUR" | "xstate.init";
|
||||
"resetShowQuickShareSuccessBanner": "DISMISS" | "DISMISS_QUICK_SHARE_BANNER";
|
||||
"sendBLEConnectionErrorEvent": "BLE_ERROR";
|
||||
"sendScanData": "" | "SCAN";
|
||||
"sendVCShareFlowCancelEndEvent": "CANCEL";
|
||||
"sendVCShareFlowTimeoutEndEvent": "CANCEL" | "RETRY";
|
||||
"sendVPScanData": "SCAN";
|
||||
"sendVcShareSuccessEvent": "VC_ACCEPTED";
|
||||
"sendVcSharingStartEvent": "SCAN";
|
||||
"setBleError": "BLE_ERROR";
|
||||
"setFlowType": "SELECT_VC";
|
||||
"setIsQrLoginViaDeepLink": "QRLOGIN_VIA_DEEP_LINK";
|
||||
"setLinkCode": "SCAN";
|
||||
"setLinkCodeFromDeepLink": "QRLOGIN_VIA_DEEP_LINK";
|
||||
"setOpenId4VPFlowType": "SCAN";
|
||||
"setOpenId4VPRef": "CANCEL" | "DISCONNECT" | "DISMISS" | "DISMISS_QUICK_SHARE_BANNER" | "QRLOGIN_VIA_DEEP_LINK" | "RESET" | "RETRY" | "SCREEN_BLUR" | "SCREEN_FOCUS" | "SELECT_VC" | "xstate.init";
|
||||
"setQrLoginRef": "QRLOGIN_VIA_DEEP_LINK" | "SCAN";
|
||||
"setQuickShareData": "SCAN";
|
||||
"setReadyForBluetoothStateCheck": "BLUETOOTH_PERMISSION_ENABLED";
|
||||
"setReceiverInfo": "CONNECTED";
|
||||
"setSelectedVc": "SELECT_VC";
|
||||
"setSenderInfo": "CONNECTED";
|
||||
"setShareLogTypeUnverified": "ACCEPT_REQUEST" | "CHECK_FLOW_TYPE";
|
||||
"setShareLogTypeVerified": "FACE_VALID";
|
||||
"setShowFaceAuthConsent": "FACE_VERIFICATION_CONSENT";
|
||||
"setShowQuickShareSuccessBanner": "STORE_RESPONSE";
|
||||
"setUri": "SCAN";
|
||||
"storeLoginItem": "done.invoke.QrLogin";
|
||||
"storeShowFaceAuthConsent": "FACE_VERIFICATION_CONSENT";
|
||||
"storingActivityLog": "STORE_RESPONSE";
|
||||
"updateFaceCaptureBannerStatus": "FACE_VALID";
|
||||
"updateShowFaceAuthConsent": "STORE_RESPONSE";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
"CONNECTION_TIMEOUT": "SCAN";
|
||||
"DESTROY_TIMEOUT": "" | "DISMISS" | "LOCATION_ENABLED" | "RETRY";
|
||||
"SHARING_TIMEOUT": "ACCEPT_REQUEST" | "CHECK_FLOW_TYPE" | "FACE_VALID";
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"isFlowTypeMiniViewShare": "CHECK_FLOW_TYPE";
|
||||
"isFlowTypeMiniViewShareWithSelfie": "CHECK_FLOW_TYPE" | "DISMISS";
|
||||
"isFlowTypeSimpleShare": "CANCEL" | "CHECK_FLOW_TYPE" | "DISMISS" | "RETRY";
|
||||
"isIOS": "BLUETOOTH_STATE_DISABLED" | "START_PERMISSION_CHECK";
|
||||
"isMinimumStorageRequiredForAuditEntryReached": "done.invoke.scan.checkStorage:invocation[0]";
|
||||
"isOnlineSharing": "SCAN";
|
||||
"isOpenIdQr": "SCAN";
|
||||
"isQrLogin": "SCAN";
|
||||
"isQrLoginViaDeepLinking": "" | "STORE_RESPONSE";
|
||||
"isQuickShare": "SCAN";
|
||||
"showFaceAuthConsentScreen": "" | "VERIFY_AND_ACCEPT_REQUEST";
|
||||
"uptoAndroid11": "" | "START_PERMISSION_CHECK";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
"OpenId4VP": "SCAN";
|
||||
"QrLogin": "" | "SCAN";
|
||||
"checkBluetoothPermission": "" | "BLUETOOTH_STATE_DISABLED" | "NEARBY_ENABLED" | "START_PERMISSION_CHECK";
|
||||
"checkBluetoothState": "" | "APP_ACTIVE";
|
||||
"checkLocationPermission": "LOCATION_ENABLED";
|
||||
"checkLocationStatus": "" | "APP_ACTIVE" | "LOCATION_REQUEST";
|
||||
"checkNearByDevicesPermission": "APP_ACTIVE" | "START_PERMISSION_CHECK";
|
||||
"checkStorageAvailability": "CANCEL" | "DISMISS" | "QRLOGIN_VIA_DEEP_LINK" | "RESET" | "RETRY" | "SCREEN_FOCUS" | "SELECT_VC";
|
||||
"disconnect": "" | "DISMISS" | "LOCATION_ENABLED" | "RETRY" | "SCREEN_BLUR";
|
||||
"monitorConnection": "DISMISS" | "QRLOGIN_VIA_DEEP_LINK" | "SCREEN_BLUR" | "xstate.init";
|
||||
"requestBluetooth": "BLUETOOTH_STATE_DISABLED";
|
||||
"requestNearByDevicesPermission": "NEARBY_DISABLED";
|
||||
"requestToEnableLocationPermission": "LOCATION_DISABLED";
|
||||
"sendVc": "ACCEPT_REQUEST" | "CHECK_FLOW_TYPE" | "FACE_VALID";
|
||||
"startConnection": "SCAN";
|
||||
};
|
||||
matchesStates: "bluetoothDenied" | "bluetoothPermissionDenied" | "checkBluetoothPermission" | "checkBluetoothPermission.checking" | "checkBluetoothPermission.enabled" | "checkBluetoothState" | "checkBluetoothState.checking" | "checkBluetoothState.enabled" | "checkBluetoothState.requesting" | "checkFaceAuthConsent" | "checkNearbyDevicesPermission" | "checkNearbyDevicesPermission.checking" | "checkNearbyDevicesPermission.enabled" | "checkNearbyDevicesPermission.requesting" | "checkQrLoginViaDeepLink" | "checkStorage" | "checkingLocationState" | "checkingLocationState.LocationPermissionRationale" | "checkingLocationState.checkLocationService" | "checkingLocationState.checkingPermissionStatus" | "checkingLocationState.denied" | "checkingLocationState.disabled" | "checkingLocationState.requestToEnableLocation" | "clearingConnection" | "connecting" | "connecting.inProgress" | "connecting.timeout" | "decodeQuickShareData" | "disconnectDevice" | "disconnected" | "findingConnection" | "handlingBleError" | "inactive" | "invalid" | "loadVCS" | "loadVCS.idle" | "loadVCS.navigatingToHome" | "nearByDevicesPermissionDenied" | "recheckBluetoothState" | "recheckBluetoothState.checking" | "recheckBluetoothState.enabled" | "restrictSharingVc" | "reviewing" | "reviewing.accepted" | "reviewing.cancelling" | "reviewing.checkFaceAuthConsentForMiniView" | "reviewing.disconnect" | "reviewing.faceVerificationConsent" | "reviewing.idle" | "reviewing.invalidIdentity" | "reviewing.navigateToHistory" | "reviewing.rejected" | "reviewing.selectingVc" | "reviewing.sendingVc" | "reviewing.sendingVc.inProgress" | "reviewing.sendingVc.sent" | "reviewing.sendingVc.timeout" | "reviewing.verifyingIdentity" | "showQrLogin" | "showQrLogin.idle" | "showQrLogin.navigatingToHistory" | "showQrLogin.navigatingToHome" | "showQrLogin.storing" | "startPermissionCheck" | "startVPSharing" | "startVPSharing.inProgress" | "startVPSharing.showError" | "startVPSharing.success" | "startVPSharing.timeout" | { "checkBluetoothPermission"?: "checking" | "enabled";
|
||||
"checkBluetoothState"?: "checking" | "enabled" | "requesting";
|
||||
"checkNearbyDevicesPermission"?: "checking" | "enabled" | "requesting";
|
||||
"checkingLocationState"?: "LocationPermissionRationale" | "checkLocationService" | "checkingPermissionStatus" | "denied" | "disabled" | "requestToEnableLocation";
|
||||
"connecting"?: "inProgress" | "timeout";
|
||||
"loadVCS"?: "idle" | "navigatingToHome";
|
||||
"recheckBluetoothState"?: "checking" | "enabled";
|
||||
"reviewing"?: "accepted" | "cancelling" | "checkFaceAuthConsentForMiniView" | "disconnect" | "faceVerificationConsent" | "idle" | "invalidIdentity" | "navigateToHistory" | "rejected" | "selectingVc" | "sendingVc" | "verifyingIdentity" | { "sendingVc"?: "inProgress" | "sent" | "timeout"; };
|
||||
"showQrLogin"?: "idle" | "navigatingToHistory" | "navigatingToHome" | "storing";
|
||||
"startVPSharing"?: "inProgress" | "showError" | "success" | "timeout"; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -1,70 +1,46 @@
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'done.invoke.faceScanner.capturing:invocation[0]': {
|
||||
type: 'done.invoke.faceScanner.capturing:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.faceScanner.verifying:invocation[0]': {
|
||||
type: 'done.invoke.faceScanner.verifying:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'error.platform.faceScanner.capturing:invocation[0]': {
|
||||
type: 'error.platform.faceScanner.capturing:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
captureImage: 'done.invoke.faceScanner.capturing:invocation[0]';
|
||||
checkPermission: 'done.invoke.faceScanner.init.checkingPermission:invocation[0]';
|
||||
requestPermission: 'done.invoke.faceScanner.init.requestingPermission:invocation[0]';
|
||||
verifyImage: 'done.invoke.faceScanner.verifying:invocation[0]';
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
openSettings: 'OPEN_SETTINGS';
|
||||
setCameraRef: 'READY';
|
||||
setCaptureError: 'error.platform.faceScanner.capturing:invocation[0]';
|
||||
setCapturedImage: 'done.invoke.faceScanner.capturing:invocation[0]';
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {
|
||||
canRequestPermission: 'DENIED';
|
||||
doesFaceMatch: 'done.invoke.faceScanner.verifying:invocation[0]';
|
||||
};
|
||||
eventsCausingServices: {
|
||||
captureImage: 'CAPTURE';
|
||||
checkPermission: 'APP_FOCUSED' | 'xstate.init';
|
||||
requestPermission: 'DENIED';
|
||||
verifyImage: 'done.invoke.faceScanner.capturing:invocation[0]';
|
||||
};
|
||||
matchesStates:
|
||||
| 'capturing'
|
||||
| 'init'
|
||||
| 'init.checkingPermission'
|
||||
| 'init.permissionDenied'
|
||||
| 'init.permissionGranted'
|
||||
| 'init.requestingPermission'
|
||||
| 'invalid'
|
||||
| 'scanning'
|
||||
| 'valid'
|
||||
| 'verifying'
|
||||
| {
|
||||
init?:
|
||||
| 'checkingPermission'
|
||||
| 'permissionDenied'
|
||||
| 'permissionGranted'
|
||||
| 'requestingPermission';
|
||||
};
|
||||
tags: never;
|
||||
}
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"done.invoke.faceScanner.capturing:invocation[0]": { type: "done.invoke.faceScanner.capturing:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.faceScanner.verifying:invocation[0]": { type: "done.invoke.faceScanner.verifying:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"error.platform.faceScanner.capturing:invocation[0]": { type: "error.platform.faceScanner.capturing:invocation[0]"; data: unknown };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
"captureImage": "done.invoke.faceScanner.capturing:invocation[0]";
|
||||
"checkPermission": "done.invoke.faceScanner.init.checkingPermission:invocation[0]";
|
||||
"requestPermission": "done.invoke.faceScanner.init.requestingPermission:invocation[0]";
|
||||
"verifyImage": "done.invoke.faceScanner.verifying:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"openSettings": "OPEN_SETTINGS";
|
||||
"setCameraRef": "READY";
|
||||
"setCaptureError": "error.platform.faceScanner.capturing:invocation[0]";
|
||||
"setCapturedImage": "done.invoke.faceScanner.capturing:invocation[0]";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"canRequestPermission": "DENIED";
|
||||
"doesFaceMatch": "done.invoke.faceScanner.verifying:invocation[0]";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
"captureImage": "CAPTURE";
|
||||
"checkPermission": "APP_FOCUSED" | "xstate.init";
|
||||
"requestPermission": "DENIED";
|
||||
"verifyImage": "done.invoke.faceScanner.capturing:invocation[0]";
|
||||
};
|
||||
matchesStates: "capturing" | "init" | "init.checkingPermission" | "init.permissionDenied" | "init.permissionGranted" | "init.requestingPermission" | "invalid" | "scanning" | "valid" | "verifying" | { "init"?: "checkingPermission" | "permissionDenied" | "permissionGranted" | "requestingPermission"; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -1,41 +1,83 @@
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'': {type: ''};
|
||||
'xstate.after(INITIAL_FOCUS_DELAY)#pinInput.idle': {
|
||||
type: 'xstate.after(INITIAL_FOCUS_DELAY)#pinInput.idle';
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
};
|
||||
invokeSrcNameMap: {};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
clearInput: 'KEY_PRESS';
|
||||
focusSelected:
|
||||
| 'KEY_PRESS'
|
||||
| 'UPDATE_INPUT'
|
||||
| 'xstate.after(INITIAL_FOCUS_DELAY)#pinInput.idle';
|
||||
selectInput: 'FOCUS_INPUT';
|
||||
selectNextInput: 'UPDATE_INPUT';
|
||||
selectPrevInput: 'KEY_PRESS';
|
||||
updateInput: 'UPDATE_INPUT';
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
INITIAL_FOCUS_DELAY: '' | 'xstate.init';
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
canGoBack: 'KEY_PRESS';
|
||||
hasNextInput: 'UPDATE_INPUT';
|
||||
isBlank: 'UPDATE_INPUT';
|
||||
};
|
||||
eventsCausingServices: {};
|
||||
matchesStates: 'idle' | 'selectingNext' | 'selectingPrev';
|
||||
tags: never;
|
||||
}
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"": { type: "" };
|
||||
"xstate.after(INITIAL_FOCUS_DELAY)#pinInput.idle": { type: "xstate.after(INITIAL_FOCUS_DELAY)#pinInput.idle" };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"clearInput": "KEY_PRESS";
|
||||
"focusSelected": "KEY_PRESS" | "UPDATE_INPUT" | "xstate.after(INITIAL_FOCUS_DELAY)#pinInput.idle";
|
||||
"selectInput": "FOCUS_INPUT";
|
||||
"selectNextInput": "UPDATE_INPUT";
|
||||
"selectPrevInput": "KEY_PRESS";
|
||||
"updateInput": "UPDATE_INPUT";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
"INITIAL_FOCUS_DELAY": "" | "xstate.init";
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"canGoBack": "KEY_PRESS";
|
||||
"hasNextInput": "UPDATE_INPUT";
|
||||
"isBlank": "UPDATE_INPUT";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
|
||||
};
|
||||
matchesStates: "idle" | "selectingNext" | "selectingPrev";
|
||||
tags: never;
|
||||
}
|
||||
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"": { type: "" };
|
||||
"xstate.after(INITIAL_FOCUS_DELAY)#pinInput.idle": { type: "xstate.after(INITIAL_FOCUS_DELAY)#pinInput.idle" };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"clearInput": "KEY_PRESS";
|
||||
"focusSelected": "KEY_PRESS" | "UPDATE_INPUT" | "xstate.after(INITIAL_FOCUS_DELAY)#pinInput.idle";
|
||||
"selectInput": "FOCUS_INPUT";
|
||||
"selectNextInput": "UPDATE_INPUT";
|
||||
"selectPrevInput": "KEY_PRESS";
|
||||
"updateInput": "UPDATE_INPUT";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
"INITIAL_FOCUS_DELAY": "" | "xstate.init";
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"canGoBack": "KEY_PRESS";
|
||||
"hasNextInput": "UPDATE_INPUT";
|
||||
"isBlank": "UPDATE_INPUT";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
|
||||
};
|
||||
matchesStates: "idle" | "selectingNext" | "selectingPrev";
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,59 @@
|
||||
"generateEncryptionKey": "ERROR" | "IGNORE" | "READY";
|
||||
"getEncryptionKey": "TRY_AGAIN";
|
||||
"hasEncryptionKey": never;
|
||||
"store": "KEY_RECEIVED" | "READY" | "done.invoke.store.resettingStorage:invocation[0]";
|
||||
};
|
||||
matchesStates: "checkEncryptionKey" | "checkFreshInstall" | "checkStorageInitialisation" | "clearIosKeys" | "failedReadingKey" | "generatingEncryptionKey" | "gettingEncryptionKey" | "ready" | "resettingStorage";
|
||||
tags: never;
|
||||
}
|
||||
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"done.invoke._store": { type: "done.invoke._store"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.store.checkFreshInstall:invocation[0]": { type: "done.invoke.store.checkFreshInstall:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.store.resettingStorage:invocation[0]": { type: "done.invoke.store.resettingStorage:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"error.platform._store": { type: "error.platform._store"; data: unknown };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
"checkFreshInstall": "done.invoke.store.checkFreshInstall:invocation[0]";
|
||||
"checkStorageInitialisedOrNot": "done.invoke.store.checkStorageInitialisation:invocation[0]";
|
||||
"clear": "done.invoke.store.resettingStorage:invocation[0]";
|
||||
"clearKeys": "done.invoke.store.clearIosKeys:invocation[0]";
|
||||
"generateEncryptionKey": "done.invoke.store.generatingEncryptionKey:invocation[0]";
|
||||
"getEncryptionKey": "done.invoke.store.gettingEncryptionKey:invocation[0]";
|
||||
"hasEncryptionKey": "done.invoke.store.checkEncryptionKey:invocation[0]";
|
||||
"store": "done.invoke._store";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"forwardStoreRequest": "APPEND" | "CLEAR" | "EXPORT" | "FETCH_ALL_WELLKNOWN_CONFIG" | "GET" | "GET_VCS_DATA" | "PREPEND" | "REMOVE" | "REMOVE_ITEMS" | "REMOVE_VC_METADATA" | "RESTORE_BACKUP" | "SET" | "UPDATE";
|
||||
"notifyParent": "KEY_RECEIVED" | "READY" | "done.invoke.store.resettingStorage:invocation[0]";
|
||||
"setEncryptionKey": "KEY_RECEIVED";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"hasData": "done.invoke.store.checkFreshInstall:invocation[0]";
|
||||
"isCustomSecureKeystore": "KEY_RECEIVED";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
"checkFreshInstall": "BIOMETRIC_CANCELLED" | "xstate.init";
|
||||
"checkStorageInitialisedOrNot": "ERROR";
|
||||
"clear": "KEY_RECEIVED";
|
||||
"clearKeys": "done.invoke.store.checkFreshInstall:invocation[0]";
|
||||
"generateEncryptionKey": "ERROR" | "IGNORE" | "READY";
|
||||
"getEncryptionKey": "TRY_AGAIN";
|
||||
"hasEncryptionKey": never;
|
||||
"store": "KEY_RECEIVED" | "READY" | "done.invoke.store.resettingStorage:invocation[0]";
|
||||
};
|
||||
matchesStates: "checkEncryptionKey" | "checkFreshInstall" | "checkStorageInitialisation" | "clearIosKeys" | "failedReadingKey" | "generatingEncryptionKey" | "gettingEncryptionKey" | "ready" | "resettingStorage";
|
||||
|
||||
74
package-lock.json
generated
74
package-lock.json
generated
@@ -94,7 +94,8 @@
|
||||
"react-native-shimmer-placeholder": "^2.0.9",
|
||||
"react-native-spinkit": "^1.5.1",
|
||||
"react-native-svg": "15.2.0",
|
||||
"react-native-vector-icons": "^10.1.0",
|
||||
"react-native-vector-icons": "^10.0.0",
|
||||
"react-native-webview": "^13.13.5",
|
||||
"react-native-zip-archive": "^6.1.0",
|
||||
"react-test-renderer": "^18.2.0",
|
||||
"short-unique-id": "^4.4.4",
|
||||
@@ -13355,7 +13356,8 @@
|
||||
"node_modules/dijkstrajs": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
|
||||
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
|
||||
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dir-glob": {
|
||||
"version": "3.0.1",
|
||||
@@ -13583,11 +13585,6 @@
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/encode-utf8": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz",
|
||||
"integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
|
||||
},
|
||||
"node_modules/encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
@@ -24695,12 +24692,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz",
|
||||
"integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
|
||||
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dijkstrajs": "^1.0.1",
|
||||
"encode-utf8": "^1.0.3",
|
||||
"pngjs": "^5.0.0",
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
@@ -24723,6 +24720,7 @@
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
|
||||
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
@@ -25388,19 +25386,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-qrcode-svg": {
|
||||
"version": "6.3.12",
|
||||
"resolved": "https://registry.npmjs.org/react-native-qrcode-svg/-/react-native-qrcode-svg-6.3.12.tgz",
|
||||
"integrity": "sha512-7Bx23ZdFNJJdVXyW9BJmFWdI5kccjnpotzmL3exkV0irUKTmj51jesxpn5sqtgVdYFE4IUVoGzdS+8qg6Ua9BA==",
|
||||
"version": "6.3.15",
|
||||
"resolved": "https://registry.npmjs.org/react-native-qrcode-svg/-/react-native-qrcode-svg-6.3.15.tgz",
|
||||
"integrity": "sha512-vLuNImGfstE8u+rlF4JfFpq65nPhmByuDG6XUPWh8yp8MgLQX11rN5eQ8nb/bf4OB+V8XoLTJB/AZF2g7jQSSQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.8.0",
|
||||
"qrcode": "^1.5.1",
|
||||
"qrcode": "^1.5.4",
|
||||
"text-encoding": "^0.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": ">=0.63.4",
|
||||
"react-native-svg": ">=13.2.0"
|
||||
"react-native-svg": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-ratings": {
|
||||
@@ -25500,6 +25498,7 @@
|
||||
"version": "15.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.2.0.tgz",
|
||||
"integrity": "sha512-R0E6IhcJfVLsL0lRmnUSm72QO+mTqcAOM5Jb8FVGxJqX3NfJMlMP0YyvcajZiaRR8CqQUpEoqrY25eyZb006kw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"css-select": "^5.1.0",
|
||||
"css-tree": "^1.1.3"
|
||||
@@ -25596,6 +25595,20 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-webview": {
|
||||
"version": "13.13.5",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.13.5.tgz",
|
||||
"integrity": "sha512-MfC2B+woL4Hlj2WCzcb1USySKk+SteXnUKmKktOk/H/AQy5+LuVdkPKm8SknJ0/RxaxhZ48WBoTRGaqgR137hw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"invariant": "2.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-zip-archive": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-zip-archive/-/react-native-zip-archive-6.1.0.tgz",
|
||||
@@ -40537,11 +40550,6 @@
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"encode-utf8": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz",
|
||||
"integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
@@ -48579,12 +48587,11 @@
|
||||
"integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg=="
|
||||
},
|
||||
"qrcode": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz",
|
||||
"integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
|
||||
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
|
||||
"requires": {
|
||||
"dijkstrajs": "^1.0.1",
|
||||
"encode-utf8": "^1.0.3",
|
||||
"pngjs": "^5.0.0",
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
@@ -49235,12 +49242,12 @@
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-qrcode-svg": {
|
||||
"version": "6.3.12",
|
||||
"resolved": "https://registry.npmjs.org/react-native-qrcode-svg/-/react-native-qrcode-svg-6.3.12.tgz",
|
||||
"integrity": "sha512-7Bx23ZdFNJJdVXyW9BJmFWdI5kccjnpotzmL3exkV0irUKTmj51jesxpn5sqtgVdYFE4IUVoGzdS+8qg6Ua9BA==",
|
||||
"version": "6.3.15",
|
||||
"resolved": "https://registry.npmjs.org/react-native-qrcode-svg/-/react-native-qrcode-svg-6.3.15.tgz",
|
||||
"integrity": "sha512-vLuNImGfstE8u+rlF4JfFpq65nPhmByuDG6XUPWh8yp8MgLQX11rN5eQ8nb/bf4OB+V8XoLTJB/AZF2g7jQSSQ==",
|
||||
"requires": {
|
||||
"prop-types": "^15.8.0",
|
||||
"qrcode": "^1.5.1",
|
||||
"qrcode": "^1.5.4",
|
||||
"text-encoding": "^0.7.0"
|
||||
}
|
||||
},
|
||||
@@ -49387,6 +49394,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-native-webview": {
|
||||
"version": "13.13.5",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.13.5.tgz",
|
||||
"integrity": "sha512-MfC2B+woL4Hlj2WCzcb1USySKk+SteXnUKmKktOk/H/AQy5+LuVdkPKm8SknJ0/RxaxhZ48WBoTRGaqgR137hw==",
|
||||
"requires": {
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"invariant": "2.2.4"
|
||||
}
|
||||
},
|
||||
"react-native-zip-archive": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-zip-archive/-/react-native-zip-archive-6.1.0.tgz",
|
||||
|
||||
@@ -99,7 +99,8 @@
|
||||
"react-native-shimmer-placeholder": "^2.0.9",
|
||||
"react-native-spinkit": "^1.5.1",
|
||||
"react-native-svg": "15.2.0",
|
||||
"react-native-vector-icons": "^10.1.0",
|
||||
"react-native-vector-icons": "^10.0.0",
|
||||
"react-native-webview": "^13.13.5",
|
||||
"react-native-zip-archive": "^6.1.0",
|
||||
"react-test-renderer": "^18.2.0",
|
||||
"short-unique-id": "^4.4.4",
|
||||
|
||||
@@ -15,6 +15,7 @@ import {RequestLayout} from '../screens/Request/RequestLayout';
|
||||
import {SplashScreen} from '../screens/SplashScreen';
|
||||
import {RequestStackParamList} from './routesConstants';
|
||||
import {KeyManagementScreen} from '../screens/Settings/KeyManagementScreen';
|
||||
import AuthWebViewScreen from '../screens/AuthWebViewScreen';
|
||||
|
||||
export const baseRoutes: Screen[] = [
|
||||
{
|
||||
@@ -28,6 +29,10 @@ export const baseRoutes: Screen[] = [
|
||||
name: 'KeyManagement',
|
||||
component: KeyManagementScreen,
|
||||
},
|
||||
{
|
||||
name:'AuthView',
|
||||
component:AuthWebViewScreen
|
||||
},
|
||||
{
|
||||
name: 'Language',
|
||||
component: SetupLanguageScreen,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import {t} from 'xstate';
|
||||
import {MainBottomTabParamList} from './routeTypes';
|
||||
|
||||
export const BOTTOM_TAB_ROUTES = {
|
||||
@@ -23,6 +24,10 @@ export const SETTINGS_ROUTES = {
|
||||
KeyManagement: 'KeyManagement' as keyof SettingsStackParamList,
|
||||
};
|
||||
|
||||
export const AUTH_ROUTES = {
|
||||
AuthView: 'AuthView' as keyof AuthStackParamList,
|
||||
};
|
||||
|
||||
export type ScanStackParamList = {
|
||||
ScanScreen: undefined;
|
||||
SendVcScreen: undefined;
|
||||
@@ -38,3 +43,9 @@ export type RequestStackParamList = {
|
||||
export type SettingsStackParamList = {
|
||||
Keymanagement: undefined;
|
||||
};
|
||||
|
||||
export type AuthStackParamList = {
|
||||
authorizationEndpoint: string;
|
||||
clientId: string;
|
||||
redirectUri: string;
|
||||
};
|
||||
|
||||
133
screens/AuthWebViewScreen.tsx
Normal file
133
screens/AuthWebViewScreen.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
||||
import psl from 'psl';
|
||||
import {
|
||||
View,
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
TouchableOpacity,
|
||||
Text, BackHandler
|
||||
} from 'react-native';
|
||||
import { WebView } from 'react-native-webview';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { VciClient } from '../shared/vciClient/VciClient';
|
||||
import { Theme } from '../components/ui/styleUtils';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const AuthWebViewScreen: React.FC<any> = ({ route, navigation }) => {
|
||||
const { authorizationURL, clientId, redirectUri, controller } = route.params;
|
||||
const webViewRef = useRef<WebView>(null);
|
||||
const [showWebView, setShowWebView] = useState(false);
|
||||
const { t } = useTranslation('authWebView');
|
||||
|
||||
const hostName = new URL(authorizationURL).hostname; // example.mosip.net
|
||||
const parsed = psl.parse(hostName);
|
||||
const rootDomain = parsed.domain || hostName;
|
||||
const ALERT_TITLE = t('title', {
|
||||
wallet: "Inji Wallet",
|
||||
domain: rootDomain || 'mosip.net'
|
||||
});
|
||||
const ALERT_MESSAGE = t('message');
|
||||
|
||||
|
||||
const handleBackPress = useCallback(() => {
|
||||
return true;
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!authorizationURL || !clientId || !redirectUri) {
|
||||
console.error('Missing required parameters for authentication');
|
||||
navigation.goBack();
|
||||
return;
|
||||
}
|
||||
|
||||
navigation.setOptions({ gestureEnabled: false });
|
||||
|
||||
const backHandler = BackHandler.addEventListener('hardwareBackPress', handleBackPress);
|
||||
|
||||
Alert.alert(ALERT_TITLE, ALERT_MESSAGE, [
|
||||
{
|
||||
text: t('cancel'),
|
||||
style: 'cancel',
|
||||
onPress: () => {
|
||||
controller.CANCEL();
|
||||
navigation.goBack();
|
||||
},
|
||||
},
|
||||
{
|
||||
text: t('continue'),
|
||||
style: 'default',
|
||||
onPress: () => setShowWebView(true),
|
||||
},
|
||||
]);
|
||||
|
||||
return () => backHandler.remove();
|
||||
}, [authorizationURL, clientId, redirectUri, navigation, controller, handleBackPress]);
|
||||
|
||||
|
||||
const handleNavigationRequest = (request: any) => {
|
||||
const { url } = request;
|
||||
if (url.startsWith(redirectUri)) {
|
||||
try {
|
||||
const uri = new URL(url);
|
||||
const code = uri.searchParams.get('code');
|
||||
|
||||
if (!code) {
|
||||
controller.CANCEL();
|
||||
navigation.goBack();
|
||||
return false;
|
||||
}
|
||||
|
||||
VciClient.client.sendAuthCodeFromJS(code);
|
||||
navigation.goBack();
|
||||
return false;
|
||||
} catch (err: any) {
|
||||
console.error('Error parsing redirect URL:', err);
|
||||
controller.CANCEL();
|
||||
navigation.goBack();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
const Header = () => (
|
||||
<View style={Theme.AuthWebViewScreenStyle.header}>
|
||||
<TouchableOpacity onPress={() => {
|
||||
controller.CANCEL();
|
||||
navigation.goBack();
|
||||
}}>
|
||||
<Ionicons name="arrow-back" size={24} color="black" />
|
||||
</TouchableOpacity>
|
||||
<Text style={Theme.AuthWebViewScreenStyle.headerText}>Authenticate</Text>
|
||||
<View style={{ width: 24 }} />
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<Header />
|
||||
{showWebView && (
|
||||
<WebView
|
||||
ref={webViewRef}
|
||||
originWhitelist={['*']}
|
||||
source={{ uri: authorizationURL }}
|
||||
onShouldStartLoadWithRequest={handleNavigationRequest}
|
||||
startInLoadingState
|
||||
renderLoading={() => (
|
||||
<View style={Theme.AuthWebViewScreenStyle.loader}>
|
||||
<ActivityIndicator size="large" />
|
||||
</View>
|
||||
)}
|
||||
javaScriptEnabled
|
||||
incognito
|
||||
sharedCookiesEnabled={false}
|
||||
thirdPartyCookiesEnabled={false}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default AuthWebViewScreen;
|
||||
@@ -1,136 +1,62 @@
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]': {
|
||||
type: 'done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]': {
|
||||
type: 'done.invoke.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.AddVcModal.requestingCredential:invocation[0]': {
|
||||
type: 'done.invoke.AddVcModal.requestingCredential:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'error.platform.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]': {
|
||||
type: 'error.platform.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]': {
|
||||
type: 'error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.AddVcModal.requestingCredential:invocation[0]': {
|
||||
type: 'error.platform.AddVcModal.requestingCredential:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'xstate.after(100)#AddVcModal.acceptingIdInput.focusing': {
|
||||
type: 'xstate.after(100)#AddVcModal.acceptingIdInput.focusing';
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
requestCredential: 'done.invoke.AddVcModal.requestingCredential:invocation[0]';
|
||||
requestOtp:
|
||||
| 'done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'done.invoke.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]';
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
clearDisplayId: 'CANCEL' | 'SELECT_ID_TYPE' | 'SET_INDIVIDUAL_ID';
|
||||
clearIdError:
|
||||
| 'INPUT_ID'
|
||||
| 'SELECT_ID_TYPE'
|
||||
| 'SET_INDIVIDUAL_ID'
|
||||
| 'VALIDATE_INPUT';
|
||||
clearOtp:
|
||||
| 'SET_INDIVIDUAL_ID'
|
||||
| 'WAIT'
|
||||
| 'done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]'
|
||||
| 'error.platform.AddVcModal.requestingCredential:invocation[0]'
|
||||
| 'xstate.init';
|
||||
focusInput:
|
||||
| 'INPUT_ID'
|
||||
| 'SELECT_ID_TYPE'
|
||||
| 'SET_INDIVIDUAL_ID'
|
||||
| 'VALIDATE_INPUT'
|
||||
| 'error.platform.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]'
|
||||
| 'error.platform.AddVcModal.requestingCredential:invocation[0]'
|
||||
| 'xstate.after(100)#AddVcModal.acceptingIdInput.focusing';
|
||||
forwardToParent: 'CANCEL' | 'DISMISS';
|
||||
resetIdInputRef: 'CANCEL';
|
||||
setDisplayId: 'INPUT_ID' | 'SET_INDIVIDUAL_ID';
|
||||
setEmail:
|
||||
| 'done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'done.invoke.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]';
|
||||
setIdBackendError:
|
||||
| 'error.platform.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]'
|
||||
| 'error.platform.AddVcModal.requestingCredential:invocation[0]';
|
||||
setIdErrorEmpty: 'VALIDATE_INPUT';
|
||||
setIdErrorWrongFormat: 'VALIDATE_INPUT';
|
||||
setIdInputRef: 'READY';
|
||||
setIdType: 'SELECT_ID_TYPE' | 'SET_INDIVIDUAL_ID';
|
||||
setOtp: 'INPUT_OTP';
|
||||
setOtpError: 'error.platform.AddVcModal.requestingCredential:invocation[0]';
|
||||
setPhoneNumber:
|
||||
| 'done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'done.invoke.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]';
|
||||
setRequestId: 'done.invoke.AddVcModal.requestingCredential:invocation[0]';
|
||||
setTransactionId:
|
||||
| 'SET_INDIVIDUAL_ID'
|
||||
| 'error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]'
|
||||
| 'error.platform.AddVcModal.requestingCredential:invocation[0]'
|
||||
| 'xstate.init';
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {
|
||||
isEmptyId: 'VALIDATE_INPUT';
|
||||
isIdInvalid: 'error.platform.AddVcModal.requestingCredential:invocation[0]';
|
||||
isWrongIdFormat: 'VALIDATE_INPUT';
|
||||
};
|
||||
eventsCausingServices: {
|
||||
requestCredential: 'INPUT_OTP';
|
||||
requestOtp: 'RESEND_OTP' | 'VALIDATE_INPUT';
|
||||
};
|
||||
matchesStates:
|
||||
| 'acceptingIdInput'
|
||||
| 'acceptingIdInput.focusing'
|
||||
| 'acceptingIdInput.idle'
|
||||
| 'acceptingIdInput.invalid'
|
||||
| 'acceptingIdInput.invalid.backend'
|
||||
| 'acceptingIdInput.invalid.empty'
|
||||
| 'acceptingIdInput.invalid.format'
|
||||
| 'acceptingIdInput.rendering'
|
||||
| 'acceptingIdInput.requestingOtp'
|
||||
| 'acceptingOtpInput'
|
||||
| 'acceptingOtpInput.idle'
|
||||
| 'acceptingOtpInput.resendOTP'
|
||||
| 'cancelDownload'
|
||||
| 'done'
|
||||
| 'requestingCredential'
|
||||
| {
|
||||
acceptingIdInput?:
|
||||
| 'focusing'
|
||||
| 'idle'
|
||||
| 'invalid'
|
||||
| 'rendering'
|
||||
| 'requestingOtp'
|
||||
| {invalid?: 'backend' | 'empty' | 'format'};
|
||||
acceptingOtpInput?: 'idle' | 'resendOTP';
|
||||
};
|
||||
tags: never;
|
||||
}
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]": { type: "done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]": { type: "done.invoke.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.AddVcModal.requestingCredential:invocation[0]": { type: "done.invoke.AddVcModal.requestingCredential:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"error.platform.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]": { type: "error.platform.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]"; data: unknown };
|
||||
"error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]": { type: "error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]"; data: unknown };
|
||||
"error.platform.AddVcModal.requestingCredential:invocation[0]": { type: "error.platform.AddVcModal.requestingCredential:invocation[0]"; data: unknown };
|
||||
"xstate.after(100)#AddVcModal.acceptingIdInput.focusing": { type: "xstate.after(100)#AddVcModal.acceptingIdInput.focusing" };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
"requestCredential": "done.invoke.AddVcModal.requestingCredential:invocation[0]";
|
||||
"requestOtp": "done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "done.invoke.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"clearDisplayId": "CANCEL" | "SELECT_ID_TYPE" | "SET_INDIVIDUAL_ID";
|
||||
"clearIdError": "INPUT_ID" | "SELECT_ID_TYPE" | "SET_INDIVIDUAL_ID" | "VALIDATE_INPUT";
|
||||
"clearOtp": "SET_INDIVIDUAL_ID" | "WAIT" | "done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]" | "error.platform.AddVcModal.requestingCredential:invocation[0]" | "xstate.init";
|
||||
"focusInput": "INPUT_ID" | "SELECT_ID_TYPE" | "SET_INDIVIDUAL_ID" | "VALIDATE_INPUT" | "error.platform.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]" | "error.platform.AddVcModal.requestingCredential:invocation[0]" | "xstate.after(100)#AddVcModal.acceptingIdInput.focusing";
|
||||
"forwardToParent": "CANCEL" | "DISMISS";
|
||||
"resetIdInputRef": "CANCEL";
|
||||
"setDisplayId": "INPUT_ID" | "SET_INDIVIDUAL_ID";
|
||||
"setEmail": "done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "done.invoke.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]";
|
||||
"setIdBackendError": "error.platform.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]" | "error.platform.AddVcModal.requestingCredential:invocation[0]";
|
||||
"setIdErrorEmpty": "VALIDATE_INPUT";
|
||||
"setIdErrorWrongFormat": "VALIDATE_INPUT";
|
||||
"setIdInputRef": "READY";
|
||||
"setIdType": "SELECT_ID_TYPE" | "SET_INDIVIDUAL_ID";
|
||||
"setOtp": "INPUT_OTP";
|
||||
"setOtpError": "error.platform.AddVcModal.requestingCredential:invocation[0]";
|
||||
"setPhoneNumber": "done.invoke.AddVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "done.invoke.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]";
|
||||
"setRequestId": "done.invoke.AddVcModal.requestingCredential:invocation[0]";
|
||||
"setTransactionId": "SET_INDIVIDUAL_ID" | "error.platform.AddVcModal.acceptingOtpInput.resendOTP:invocation[0]" | "error.platform.AddVcModal.requestingCredential:invocation[0]" | "xstate.init";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"isEmptyId": "VALIDATE_INPUT";
|
||||
"isIdInvalid": "error.platform.AddVcModal.requestingCredential:invocation[0]";
|
||||
"isWrongIdFormat": "VALIDATE_INPUT";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
"requestCredential": "INPUT_OTP";
|
||||
"requestOtp": "RESEND_OTP" | "VALIDATE_INPUT";
|
||||
};
|
||||
matchesStates: "acceptingIdInput" | "acceptingIdInput.focusing" | "acceptingIdInput.idle" | "acceptingIdInput.invalid" | "acceptingIdInput.invalid.backend" | "acceptingIdInput.invalid.empty" | "acceptingIdInput.invalid.format" | "acceptingIdInput.rendering" | "acceptingIdInput.requestingOtp" | "acceptingOtpInput" | "acceptingOtpInput.idle" | "acceptingOtpInput.resendOTP" | "cancelDownload" | "done" | "requestingCredential" | { "acceptingIdInput"?: "focusing" | "idle" | "invalid" | "rendering" | "requestingOtp" | { "invalid"?: "backend" | "empty" | "format"; };
|
||||
"acceptingOtpInput"?: "idle" | "resendOTP"; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -1,131 +1,63 @@
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]': {
|
||||
type: 'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]': {
|
||||
type: 'done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.GetVcModal.requestingUinVid:invocation[0]': {
|
||||
type: 'done.invoke.GetVcModal.requestingUinVid:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'error.platform.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]': {
|
||||
type: 'error.platform.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]': {
|
||||
type: 'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.GetVcModal.requestingUinVid:invocation[0]': {
|
||||
type: 'error.platform.GetVcModal.requestingUinVid:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'xstate.after(100)#GetVcModal.acceptingIdInput.focusing': {
|
||||
type: 'xstate.after(100)#GetVcModal.acceptingIdInput.focusing';
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
requestOtp:
|
||||
| 'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]';
|
||||
requestingUinVid: 'done.invoke.GetVcModal.requestingUinVid:invocation[0]';
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
clearIdError: 'INPUT_ID';
|
||||
clearOtp:
|
||||
| 'DISMISS'
|
||||
| 'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]'
|
||||
| 'error.platform.GetVcModal.requestingUinVid:invocation[0]'
|
||||
| 'xstate.init';
|
||||
focusInput:
|
||||
| 'INPUT_ID'
|
||||
| 'VALIDATE_INPUT'
|
||||
| 'error.platform.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]'
|
||||
| 'error.platform.GetVcModal.requestingUinVid:invocation[0]'
|
||||
| 'xstate.after(100)#GetVcModal.acceptingIdInput.focusing';
|
||||
forwardToParent: 'DISMISS';
|
||||
resetIdInputRef: 'DISMISS';
|
||||
setEmail:
|
||||
| 'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]';
|
||||
setIconColorActivate: 'ACTIVATE_ICON_COLOR';
|
||||
setIconColorDeactivate: 'DEACTIVATE_ICON_COLOR';
|
||||
setId: 'INPUT_ID';
|
||||
setIdBackendError:
|
||||
| 'error.platform.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]'
|
||||
| 'error.platform.GetVcModal.requestingUinVid:invocation[0]';
|
||||
setIdErrorEmpty: 'VALIDATE_INPUT';
|
||||
setIdErrorWrongFormat: 'VALIDATE_INPUT';
|
||||
setIdInputRef: 'READY';
|
||||
setIndividualId: 'done.invoke.GetVcModal.requestingUinVid:invocation[0]';
|
||||
setOtp: 'INPUT_OTP';
|
||||
setOtpError: 'error.platform.GetVcModal.requestingUinVid:invocation[0]';
|
||||
setPhoneNumber:
|
||||
| 'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
|
||||
| 'done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]';
|
||||
setTransactionId:
|
||||
| 'DISMISS'
|
||||
| 'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]'
|
||||
| 'error.platform.GetVcModal.requestingUinVid:invocation[0]'
|
||||
| 'xstate.init';
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {
|
||||
isEmptyId: 'VALIDATE_INPUT';
|
||||
isIdInvalid: 'error.platform.GetVcModal.requestingUinVid:invocation[0]';
|
||||
isWrongIdFormat: 'VALIDATE_INPUT';
|
||||
};
|
||||
eventsCausingServices: {
|
||||
AddVcModal:
|
||||
| 'INPUT_ID'
|
||||
| 'xstate.after(100)#GetVcModal.acceptingIdInput.focusing';
|
||||
requestOtp: 'RESEND_OTP' | 'VALIDATE_INPUT';
|
||||
requestingUinVid: 'INPUT_OTP';
|
||||
};
|
||||
matchesStates:
|
||||
| 'acceptingIdInput'
|
||||
| 'acceptingIdInput.focusing'
|
||||
| 'acceptingIdInput.idle'
|
||||
| 'acceptingIdInput.invalid'
|
||||
| 'acceptingIdInput.invalid.backend'
|
||||
| 'acceptingIdInput.invalid.empty'
|
||||
| 'acceptingIdInput.invalid.format'
|
||||
| 'acceptingIdInput.rendering'
|
||||
| 'acceptingIdInput.requestingOtp'
|
||||
| 'acceptingOtpInput'
|
||||
| 'acceptingOtpInput.idle'
|
||||
| 'acceptingOtpInput.resendOTP'
|
||||
| 'done'
|
||||
| 'requestingUinVid'
|
||||
| {
|
||||
acceptingIdInput?:
|
||||
| 'focusing'
|
||||
| 'idle'
|
||||
| 'invalid'
|
||||
| 'rendering'
|
||||
| 'requestingOtp'
|
||||
| {invalid?: 'backend' | 'empty' | 'format'};
|
||||
acceptingOtpInput?: 'idle' | 'resendOTP';
|
||||
};
|
||||
tags: never;
|
||||
}
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]": { type: "done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]": { type: "done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.GetVcModal.requestingUinVid:invocation[0]": { type: "done.invoke.GetVcModal.requestingUinVid:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"error.platform.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]": { type: "error.platform.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]"; data: unknown };
|
||||
"error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]": { type: "error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]"; data: unknown };
|
||||
"error.platform.GetVcModal.requestingUinVid:invocation[0]": { type: "error.platform.GetVcModal.requestingUinVid:invocation[0]"; data: unknown };
|
||||
"xstate.after(100)#GetVcModal.acceptingIdInput.focusing": { type: "xstate.after(100)#GetVcModal.acceptingIdInput.focusing" };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
"requestOtp": "done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]";
|
||||
"requestingUinVid": "done.invoke.GetVcModal.requestingUinVid:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"clearIdError": "INPUT_ID";
|
||||
"clearOtp": "DISMISS" | "done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]" | "error.platform.GetVcModal.requestingUinVid:invocation[0]" | "xstate.init";
|
||||
"focusInput": "INPUT_ID" | "VALIDATE_INPUT" | "error.platform.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]" | "error.platform.GetVcModal.requestingUinVid:invocation[0]" | "xstate.after(100)#GetVcModal.acceptingIdInput.focusing";
|
||||
"forwardToParent": "DISMISS";
|
||||
"resetIdInputRef": "DISMISS";
|
||||
"setEmail": "done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]";
|
||||
"setIconColorActivate": "ACTIVATE_ICON_COLOR";
|
||||
"setIconColorDeactivate": "DEACTIVATE_ICON_COLOR";
|
||||
"setId": "INPUT_ID";
|
||||
"setIdBackendError": "error.platform.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]" | "error.platform.GetVcModal.requestingUinVid:invocation[0]";
|
||||
"setIdErrorEmpty": "VALIDATE_INPUT";
|
||||
"setIdErrorWrongFormat": "VALIDATE_INPUT";
|
||||
"setIdInputRef": "READY";
|
||||
"setIndividualId": "done.invoke.GetVcModal.requestingUinVid:invocation[0]";
|
||||
"setOtp": "INPUT_OTP";
|
||||
"setOtpError": "error.platform.GetVcModal.requestingUinVid:invocation[0]";
|
||||
"setPhoneNumber": "done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]" | "done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]";
|
||||
"setTransactionId": "DISMISS" | "error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]" | "error.platform.GetVcModal.requestingUinVid:invocation[0]" | "xstate.init";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"isEmptyId": "VALIDATE_INPUT";
|
||||
"isIdInvalid": "error.platform.GetVcModal.requestingUinVid:invocation[0]";
|
||||
"isWrongIdFormat": "VALIDATE_INPUT";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
"AddVcModal": "INPUT_ID" | "xstate.after(100)#GetVcModal.acceptingIdInput.focusing";
|
||||
"requestOtp": "RESEND_OTP" | "VALIDATE_INPUT";
|
||||
"requestingUinVid": "INPUT_OTP";
|
||||
};
|
||||
matchesStates: "acceptingIdInput" | "acceptingIdInput.focusing" | "acceptingIdInput.idle" | "acceptingIdInput.invalid" | "acceptingIdInput.invalid.backend" | "acceptingIdInput.invalid.empty" | "acceptingIdInput.invalid.format" | "acceptingIdInput.rendering" | "acceptingIdInput.requestingOtp" | "acceptingOtpInput" | "acceptingOtpInput.idle" | "acceptingOtpInput.resendOTP" | "done" | "requestingUinVid" | { "acceptingIdInput"?: "focusing" | "idle" | "invalid" | "rendering" | "requestingOtp" | { "invalid"?: "backend" | "empty" | "format"; };
|
||||
"acceptingOtpInput"?: "idle" | "resendOTP"; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@ export const OtpVerificationModal: React.FC<
|
||||
testID="otpVerificationPinInput"
|
||||
length={6}
|
||||
onDone={handleEnteredOtp}
|
||||
autosubmit={true}
|
||||
/>
|
||||
<Column crossAlign="center">
|
||||
<Text
|
||||
|
||||
@@ -69,7 +69,7 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = props => {
|
||||
|
||||
let [fields, setFields] = useState([]);
|
||||
const [wellknown, setWellknown] = useState(null);
|
||||
|
||||
const [wellknownFieldsFlag, setWellknownFieldsFlag] = useState(false);
|
||||
const verifiableCredentialData = controller.verifiableCredentialData;
|
||||
|
||||
useEffect(() => {
|
||||
@@ -82,6 +82,7 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = props => {
|
||||
).then(response => {
|
||||
setWellknown(response.matchingCredentialIssuerMetadata);
|
||||
setFields(response.fields);
|
||||
setWellknownFieldsFlag(response.wellknownFieldsFlag);
|
||||
});
|
||||
}, [verifiableCredentialData?.wellKnown]);
|
||||
|
||||
@@ -152,6 +153,7 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = props => {
|
||||
) : (
|
||||
<VcDetailsContainer
|
||||
fields={fields}
|
||||
wellknownFieldsFlag={wellknownFieldsFlag}
|
||||
wellknown={wellknown}
|
||||
credential={verifiableCredential}
|
||||
credentialWrapper={controller.credential}
|
||||
|
||||
56
screens/Issuers/ConfirmationModal.tsx
Normal file
56
screens/Issuers/ConfirmationModal.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import React from 'react';
|
||||
import { Modal, View, Text, TouchableWithoutFeedback } from 'react-native';
|
||||
import { Button } from '../../components/ui';
|
||||
import { Theme } from '../../components/ui/styleUtils';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface CancelDownloadModalProps {
|
||||
visible: boolean;
|
||||
onCancel: () => void;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
|
||||
export const CancelDownloadModal: React.FC<CancelDownloadModalProps> = ({
|
||||
visible,
|
||||
onCancel,
|
||||
onConfirm,
|
||||
}) => {
|
||||
const {t} = useTranslation('cancelDownloadModal');
|
||||
return (
|
||||
<Modal visible={visible} transparent={true} onRequestClose={onCancel}>
|
||||
<TouchableWithoutFeedback onPress={null}>
|
||||
<View
|
||||
style={Theme.TransactionCodeScreenStyle.confirmationModalView}>
|
||||
<TouchableWithoutFeedback>
|
||||
<View
|
||||
style={Theme.TransactionCodeScreenStyle.confirmationModalInnerView}>
|
||||
<Text testID="cancelDownoadModalHeading" style={Theme.TransactionCodeScreenStyle.confirmationModalContentHeading}>
|
||||
{t('heading')}
|
||||
</Text>
|
||||
<Text
|
||||
testID='cancelDownoadModalSubHeading'
|
||||
style={Theme.TransactionCodeScreenStyle.confirmationModalContentSubHeading}>
|
||||
{t('subHeading')}
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
testID="cancelDownloadModalNoButton"
|
||||
styles={{ marginTop: 24 }}
|
||||
type="gradient"
|
||||
title={t('cancel')}
|
||||
onPress={onCancel}
|
||||
/>
|
||||
<Button
|
||||
testID='cancelDownloadModalYesButton'
|
||||
styles={{ marginTop: 12, marginBottom: -20 }}
|
||||
type="clear"
|
||||
title={t('confirm')}
|
||||
onPress={onConfirm}
|
||||
/>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
@@ -16,16 +16,16 @@ export const CredentialTypeSelectionScreen: React.FC<
|
||||
> = props => {
|
||||
const controller = useIssuerScreenController(props);
|
||||
const {t} = useTranslation('IssuersScreen');
|
||||
const selectedIssuerDisplayObject = getDisplayObjectForCurrentLanguage(
|
||||
controller.selectedIssuer.display,
|
||||
);
|
||||
const selectedIssuerDisplayObject = controller.selectedIssuer.display
|
||||
? getDisplayObjectForCurrentLanguage(controller.selectedIssuer.display)
|
||||
: {};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
testID="credentialTypeSelectionScreen"
|
||||
isVisible={controller.isSelectingCredentialType}
|
||||
arrowLeft={true}
|
||||
headerTitle={selectedIssuerDisplayObject.name}
|
||||
headerTitle={selectedIssuerDisplayObject?.name}
|
||||
headerElevation={2}
|
||||
onDismiss={() => controller.CANCEL()}>
|
||||
<Column style={Theme.IssuersScreenStyles.issuerListOuterContainer}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {useSelector} from '@xstate/react';
|
||||
import { useSelector } from '@xstate/react';
|
||||
import {
|
||||
selectSupportedCredentialTypes,
|
||||
selectErrorMessageType,
|
||||
@@ -14,23 +14,37 @@ import {
|
||||
selectStoring,
|
||||
selectVerificationErrorMessage,
|
||||
selectIsNonGenericError,
|
||||
selectIsQrScanning,
|
||||
selectCredentialOfferData,
|
||||
selectAuthWebViewStatus,
|
||||
selectAuthEndPoint,
|
||||
selectIsTxCodeRequested,
|
||||
selectIsConsentRequested,
|
||||
selectIssuerLogo,
|
||||
selectIssuerName,
|
||||
selectTxCodeDisplayDetails,
|
||||
} from '../../machines/Issuers/IssuersSelectors';
|
||||
import {ActorRefFrom} from 'xstate';
|
||||
import {BOTTOM_TAB_ROUTES} from '../../routes/routesConstants';
|
||||
import {logState} from '../../shared/commonUtil';
|
||||
import {isAndroid} from '../../shared/constants';
|
||||
import { ActorRefFrom } from 'xstate';
|
||||
import { BOTTOM_TAB_ROUTES } from '../../routes/routesConstants';
|
||||
import { logState } from '../../shared/commonUtil';
|
||||
import { isAndroid } from '../../shared/constants';
|
||||
import {
|
||||
IssuerScreenTabEvents,
|
||||
IssuersMachine,
|
||||
} from '../../machines/Issuers/IssuersMachine';
|
||||
import {CredentialTypes} from '../../machines/VerifiableCredential/VCMetaMachine/vc';
|
||||
import { CredentialTypes } from '../../machines/VerifiableCredential/VCMetaMachine/vc';
|
||||
|
||||
export function useIssuerScreenController({route, navigation}) {
|
||||
export function useIssuerScreenController({ route, navigation }) {
|
||||
const service = route.params.service;
|
||||
service.subscribe(logState);
|
||||
|
||||
return {
|
||||
issuers: useSelector(service, selectIssuers),
|
||||
issuerLogo: useSelector(service,selectIssuerLogo),
|
||||
issuerName: useSelector(service,selectIssuerName),
|
||||
isTxCodeRequested: useSelector(service,selectIsTxCodeRequested),
|
||||
txCodeDisplayDetails: useSelector(service,selectTxCodeDisplayDetails),
|
||||
authEndpount: useSelector(service, selectAuthEndPoint),
|
||||
selectedIssuer: useSelector(service, selectSelectedIssuer),
|
||||
errorMessageType: useSelector(service, selectErrorMessageType),
|
||||
isDownloadingCredentials: useSelector(service, selectIsDownloadCredentials),
|
||||
@@ -40,10 +54,16 @@ export function useIssuerScreenController({route, navigation}) {
|
||||
isNonGenericError: useSelector(service, selectIsNonGenericError),
|
||||
loadingReason: useSelector(service, selectLoadingReason),
|
||||
isStoring: useSelector(service, selectStoring),
|
||||
isQrScanning: useSelector(service, selectIsQrScanning),
|
||||
isAuthEndpointToOpen: useSelector(service, selectAuthWebViewStatus),
|
||||
isSelectingCredentialType: useSelector(
|
||||
service,
|
||||
selectSelectingCredentialType,
|
||||
),
|
||||
isConsentRequested: useSelector(
|
||||
service,selectIsConsentRequested
|
||||
),
|
||||
credentialOfferData: useSelector(service, selectCredentialOfferData),
|
||||
supportedCredentialTypes: useSelector(
|
||||
service,
|
||||
selectSupportedCredentialTypes,
|
||||
@@ -61,22 +81,34 @@ export function useIssuerScreenController({route, navigation}) {
|
||||
RESET_ERROR: () => service.send(IssuerScreenTabEvents.RESET_ERROR()),
|
||||
DOWNLOAD_ID: () => {
|
||||
service.send(IssuerScreenTabEvents.DOWNLOAD_ID());
|
||||
navigation.navigate(BOTTOM_TAB_ROUTES.home, {screen: 'HomeScreen'});
|
||||
navigation.navigate(BOTTOM_TAB_ROUTES.home, { screen: 'HomeScreen' });
|
||||
},
|
||||
SELECTED_CREDENTIAL_TYPE: (credType: CredentialTypes) =>
|
||||
service.send(IssuerScreenTabEvents.SELECTED_CREDENTIAL_TYPE(credType)),
|
||||
RESET_VERIFY_ERROR: () => {
|
||||
service.send(IssuerScreenTabEvents.RESET_VERIFY_ERROR());
|
||||
if (isAndroid()) {
|
||||
navigation.navigate(BOTTOM_TAB_ROUTES.home, {screen: 'HomeScreen'});
|
||||
navigation.navigate(BOTTOM_TAB_ROUTES.home, { screen: 'HomeScreen' });
|
||||
} else {
|
||||
setTimeout(
|
||||
() =>
|
||||
navigation.navigate(BOTTOM_TAB_ROUTES.home, {screen: 'HomeScreen'}),
|
||||
navigation.navigate(BOTTOM_TAB_ROUTES.home, { screen: 'HomeScreen' }),
|
||||
0,
|
||||
);
|
||||
}
|
||||
},
|
||||
QR_CODE_SCANNED: (qrData: string) => {
|
||||
service.send(IssuerScreenTabEvents.QR_CODE_SCANNED(qrData));
|
||||
},
|
||||
SCAN_CREDENTIAL_OFFER_QR_CODE: () => {
|
||||
service.send(IssuerScreenTabEvents.SCAN_CREDENTIAL_OFFER_QR_CODE());
|
||||
},
|
||||
TX_CODE_RECEIVED: (txCode: string) => {
|
||||
service.send(IssuerScreenTabEvents.TX_CODE_RECEIVED(txCode));
|
||||
},
|
||||
ON_CONSENT_GIVEN: () => {
|
||||
service.send(IssuerScreenTabEvents.ON_CONSENT_GIVEN());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import React, {useLayoutEffect, useState} from 'react';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
import {FlatList, Pressable} from 'react-native';
|
||||
import {Issuer} from '../../components/openId4VCI/Issuer';
|
||||
import {Error} from '../../components/ui/Error';
|
||||
import {Header} from '../../components/ui/Header';
|
||||
import {Button, Column, Row, Text} from '../../components/ui';
|
||||
import {Theme} from '../../components/ui/styleUtils';
|
||||
import {RootRouteProps} from '../../routes';
|
||||
import {HomeRouteProps} from '../../routes/routeTypes';
|
||||
import {useIssuerScreenController} from './IssuerScreenController';
|
||||
import {Loader} from '../../components/ui/Loader';
|
||||
import {isTranslationKeyFound, removeWhiteSpace} from '../../shared/commonUtil';
|
||||
import React, { useEffect, useLayoutEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FlatList, Pressable, View } from 'react-native';
|
||||
import { Issuer } from '../../components/openId4VCI/Issuer';
|
||||
import { Error } from '../../components/ui/Error';
|
||||
import { Header } from '../../components/ui/Header';
|
||||
import { Button, Column, Row, Text } from '../../components/ui';
|
||||
import { Theme } from '../../components/ui/styleUtils';
|
||||
import { RootRouteProps } from '../../routes';
|
||||
import { HomeRouteProps } from '../../routes/routeTypes';
|
||||
import { useIssuerScreenController } from './IssuerScreenController';
|
||||
import { Loader } from '../../components/ui/Loader';
|
||||
import ScanIcon from '../../assets/scanIcon.svg';
|
||||
import {
|
||||
isTranslationKeyFound,
|
||||
removeWhiteSpace,
|
||||
} from '../../shared/commonUtil';
|
||||
import {
|
||||
ErrorMessage,
|
||||
getDisplayObjectForCurrentLanguage,
|
||||
@@ -22,20 +26,24 @@ import {
|
||||
sendInteractEvent,
|
||||
sendStartEvent,
|
||||
} from '../../shared/telemetry/TelemetryUtils';
|
||||
import {TelemetryConstants} from '../../shared/telemetry/TelemetryConstants';
|
||||
import {MessageOverlay} from '../../components/MessageOverlay';
|
||||
import {SearchBar} from '../../components/ui/SearchBar';
|
||||
import {SvgImage} from '../../components/ui/svg';
|
||||
import {Icon} from 'react-native-elements';
|
||||
import {BannerNotificationContainer} from '../../components/BannerNotificationContainer';
|
||||
import {CredentialTypeSelectionScreen} from './CredentialTypeSelectionScreen';
|
||||
|
||||
import { TelemetryConstants } from '../../shared/telemetry/TelemetryConstants';
|
||||
import { MessageOverlay } from '../../components/MessageOverlay';
|
||||
import { SearchBar } from '../../components/ui/SearchBar';
|
||||
import { SvgImage } from '../../components/ui/svg';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { BannerNotificationContainer } from '../../components/BannerNotificationContainer';
|
||||
import { CredentialTypeSelectionScreen } from './CredentialTypeSelectionScreen';
|
||||
import { QrScanner } from '../../components/QrScanner';
|
||||
import { IssuersModel } from '../../machines/Issuers/IssuersModel';
|
||||
import { AUTH_ROUTES } from '../../routes/routesConstants';
|
||||
import { TransactionCodeModal } from './TransactionCodeScreen';
|
||||
import { TrustIssuerModal } from './TrustIssuerModal';
|
||||
export const IssuersScreen: React.FC<
|
||||
HomeRouteProps | RootRouteProps
|
||||
> = props => {
|
||||
const model = IssuersModel;
|
||||
const controller = useIssuerScreenController(props);
|
||||
const {t} = useTranslation('IssuersScreen');
|
||||
|
||||
const { i18n, t } = useTranslation('IssuersScreen');
|
||||
const issuers = controller.issuers;
|
||||
let [filteredSearchData, setFilteredSearchData] = useState(issuers);
|
||||
const [search, setSearch] = useState('');
|
||||
@@ -62,25 +70,37 @@ export const IssuersScreen: React.FC<
|
||||
header: props => (
|
||||
<Header
|
||||
goBack={props.navigation.goBack}
|
||||
title={t('title')}
|
||||
title={ controller.isQrScanning?t('download'):t('title')}
|
||||
testID="issuersScreenHeader"
|
||||
/>
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
if (controller.isStoring) {
|
||||
props.navigation.goBack();
|
||||
}
|
||||
}, [
|
||||
controller.loadingReason,
|
||||
controller.errorMessageType,
|
||||
controller.isStoring,
|
||||
controller.isQrScanning,
|
||||
]);
|
||||
|
||||
if (controller.isStoring) {
|
||||
props.navigation.goBack();
|
||||
}
|
||||
useEffect(() => {
|
||||
if (controller.isAuthEndpointToOpen) {
|
||||
(props.navigation as any).navigate(AUTH_ROUTES.AuthView, {
|
||||
authorizationURL: controller.authEndpount,
|
||||
clientId: controller.selectedIssuer.client_id ?? "wallet",
|
||||
redirectUri: controller.selectedIssuer.redirect_uri ?? "io.mosip.residentapp.inji://oauthredirect",
|
||||
controller: controller,
|
||||
});
|
||||
}
|
||||
}, [controller.isAuthEndpointToOpen]);
|
||||
|
||||
const onPressHandler = (id: string, protocol: string) => {
|
||||
sendStartEvent(
|
||||
getStartEventData(TelemetryConstants.FlowType.vcDownload, {id: id}),
|
||||
getStartEventData(TelemetryConstants.FlowType.vcDownload, { id: id }),
|
||||
);
|
||||
sendInteractEvent(
|
||||
getInteractEventData(
|
||||
@@ -102,9 +122,9 @@ export const IssuersScreen: React.FC<
|
||||
return (
|
||||
controller.errorMessageType === ErrorMessage.TECHNICAL_DIFFICULTIES ||
|
||||
controller.errorMessageType ===
|
||||
ErrorMessage.CREDENTIAL_TYPE_DOWNLOAD_FAILURE ||
|
||||
ErrorMessage.CREDENTIAL_TYPE_DOWNLOAD_FAILURE ||
|
||||
controller.errorMessageType ===
|
||||
ErrorMessage.AUTHORIZATION_GRANT_TYPE_NOT_SUPPORTED
|
||||
ErrorMessage.AUTHORIZATION_GRANT_TYPE_NOT_SUPPORTED
|
||||
);
|
||||
}
|
||||
|
||||
@@ -140,7 +160,7 @@ export const IssuersScreen: React.FC<
|
||||
const filteredData = issuers.filter(item => {
|
||||
if (
|
||||
getDisplayObjectForCurrentLanguage(item.display)
|
||||
?.title.toLowerCase()
|
||||
?.name.toLowerCase()
|
||||
.includes(searchText.toLowerCase())
|
||||
) {
|
||||
return getDisplayObjectForCurrentLanguage(item.display);
|
||||
@@ -172,10 +192,23 @@ export const IssuersScreen: React.FC<
|
||||
primaryButtonText="goBack"
|
||||
primaryButtonEvent={controller.RESET_VERIFY_ERROR}
|
||||
primaryButtonTestID="goBack"
|
||||
customStyles={{marginTop: '30%'}}
|
||||
customStyles={{ marginTop: '30%' }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (controller.isConsentRequested) {
|
||||
return issuerTrustConsentComponent();
|
||||
}
|
||||
if (controller.isTxCodeRequested) {
|
||||
return <TransactionCodeModal
|
||||
visible={controller.isTxCodeRequested}
|
||||
onDismiss={controller.CANCEL}
|
||||
onVerify={controller.TX_CODE_RECEIVED}
|
||||
inputMode= {controller.txCodeDisplayDetails.inputMode}
|
||||
description={controller.txCodeDisplayDetails.description}
|
||||
length={controller.txCodeDisplayDetails.length}
|
||||
/>
|
||||
}
|
||||
|
||||
if (controller.isBiometricsCancelled) {
|
||||
return (
|
||||
@@ -217,7 +250,7 @@ export const IssuersScreen: React.FC<
|
||||
primaryButtonTestID="tryAgain"
|
||||
primaryButtonText={
|
||||
controller.errorMessageType != ErrorMessage.TECHNICAL_DIFFICULTIES &&
|
||||
controller.errorMessageType !=
|
||||
controller.errorMessageType !=
|
||||
ErrorMessage.AUTHORIZATION_GRANT_TYPE_NOT_SUPPORTED
|
||||
? 'tryAgain'
|
||||
: undefined
|
||||
@@ -236,6 +269,24 @@ export const IssuersScreen: React.FC<
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (controller.isQrScanning) {
|
||||
return qrScannerComponent();
|
||||
}
|
||||
function qrScannerComponent() {
|
||||
return (
|
||||
<Column crossAlign="center">
|
||||
<QrScanner
|
||||
onQrFound={controller.QR_CODE_SCANNED}
|
||||
/>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
function issuerTrustConsentComponent() {
|
||||
return <TrustIssuerModal isVisible={true} issuerLogo={controller.issuerLogo} issuerName={controller.issuerName} onConfirm={controller.ON_CONSENT_GIVEN} onCancel={controller.CANCEL} />
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -279,11 +330,19 @@ export const IssuersScreen: React.FC<
|
||||
}}>
|
||||
{t('description')}
|
||||
</Text>
|
||||
{search === '' && <View style={{ height: 85 }}><Issuer defaultLogo={ScanIcon} displayDetails={{
|
||||
title: t('offerTitle'),
|
||||
locale: i18n.language,
|
||||
description: t('offerDescription'),
|
||||
}} onPress={
|
||||
controller.SCAN_CREDENTIAL_OFFER_QR_CODE
|
||||
} testID={'credentalOfferButton'} /></View>}
|
||||
|
||||
<Column scroll style={Theme.IssuersScreenStyles.issuersContainer}>
|
||||
{controller.issuers.length > 0 && (
|
||||
<FlatList
|
||||
data={filteredSearchData}
|
||||
renderItem={({item}) => (
|
||||
renderItem={({ item }) => (
|
||||
<Issuer
|
||||
testID={removeWhiteSpace(item.issuer_id)}
|
||||
key={item.issuer_id}
|
||||
@@ -306,3 +365,5 @@ export const IssuersScreen: React.FC<
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
214
screens/Issuers/TransactionCodeScreen.tsx
Normal file
214
screens/Issuers/TransactionCodeScreen.tsx
Normal file
@@ -0,0 +1,214 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Column, Text } from '../../components/ui';
|
||||
import { Theme } from '../../components/ui/styleUtils';
|
||||
import {
|
||||
Dimensions,
|
||||
Keyboard,
|
||||
KeyboardAvoidingView, TouchableWithoutFeedback,
|
||||
View,
|
||||
ModalProps
|
||||
} from 'react-native';
|
||||
import { isIOS } from '../../shared/constants';
|
||||
import { SvgImage } from '../../components/ui/svg';
|
||||
import { getScreenHeight } from '../../shared/commonUtil';
|
||||
import { PinInput } from '../../components/PinInput';
|
||||
import { Modal } from '../../components/ui/Modal';
|
||||
import { CancelDownloadModal } from './ConfirmationModal';
|
||||
import { Icon, Input } from 'react-native-elements';
|
||||
|
||||
export const TransactionCodeModal: React.FC<ExtendedModalProps> = props => {
|
||||
const { t } = useTranslation('transactionCodeScreen');
|
||||
const { isSmallScreen, screenHeight } = getScreenHeight();
|
||||
const [transactionCode, setTransactionCode] = useState('');
|
||||
const [errorMessage, setErrorMessage] = useState('');
|
||||
const [showCancelConfirm, setShowCancelConfirm] = useState(false);
|
||||
const [showCode, setShowCode] = useState(false);
|
||||
const [touched, setTouched] = useState(false);
|
||||
const [showFullDescription, setShowFullDescription] = useState(false);
|
||||
const [textLineCount, setTextLineCount] = useState(0);
|
||||
const maxLines = 2;
|
||||
|
||||
|
||||
const validateCode = (code: string): string => {
|
||||
if (!code.trim()) return t('emptyCodeError');
|
||||
if (!/^[a-zA-Z0-9]+$/.test(code)) return t('invalidCharacters');
|
||||
return '';
|
||||
};
|
||||
|
||||
const handleVerify = () => {
|
||||
const error = validateCode(transactionCode);
|
||||
if (error) {
|
||||
setErrorMessage(error);
|
||||
return;
|
||||
}
|
||||
setErrorMessage('');
|
||||
props.onVerify?.(transactionCode);
|
||||
};
|
||||
|
||||
const handleChange = (text: string) => {
|
||||
if (!touched)
|
||||
setTouched(true);
|
||||
setTransactionCode(text);
|
||||
let error;
|
||||
if (touched)
|
||||
error = validateCode(text);
|
||||
setErrorMessage(error);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{showCancelConfirm ? (
|
||||
<CancelDownloadModal onCancel={() => setShowCancelConfirm(false)} onConfirm={props.onDismiss ?? (() => { })} visible={showCancelConfirm} />
|
||||
) : (
|
||||
<Modal isVisible={props.visible ?? false} onDismiss={() => setShowCancelConfirm(true)}>
|
||||
<KeyboardAvoidingView
|
||||
style={
|
||||
isSmallScreen
|
||||
? { flex: 1, paddingHorizontal: 10 }
|
||||
: Theme.Styles.keyboardAvoidStyle
|
||||
}
|
||||
behavior={isIOS() ? 'padding' : 'height'}>
|
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
|
||||
<View style={{ height: 700 }}>
|
||||
<Column
|
||||
crossAlign="center"
|
||||
style={
|
||||
isSmallScreen
|
||||
? null
|
||||
: {
|
||||
maxHeight: screenHeight,
|
||||
flex: 1,
|
||||
justifyContent: 'space-around',
|
||||
marginBottom: 20,
|
||||
}
|
||||
}>
|
||||
{SvgImage.OtpVerificationIcon()}
|
||||
<View>
|
||||
<Column crossAlign="center">
|
||||
<Text
|
||||
testID="otpVerificationHeader"
|
||||
weight="bold"
|
||||
style={Theme.TextStyles.header}>
|
||||
{t('TransactionCode')}
|
||||
</Text>
|
||||
<Text
|
||||
style={{ marginTop: 15 }}
|
||||
testID="otpVerificationDescription"
|
||||
color={Theme.Colors.RetrieveIdLabel}
|
||||
numLines={showFullDescription ? undefined : 2}
|
||||
ellipsizeMode='tail'
|
||||
weight="semibold"
|
||||
size="small"
|
||||
align="center"
|
||||
onTextLayout={(e) => {
|
||||
if (textLineCount !== e.nativeEvent.lines.length) {
|
||||
setTextLineCount(e.nativeEvent.lines.length);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t(
|
||||
`${props.description ||
|
||||
t('description')
|
||||
}`,
|
||||
)}
|
||||
</Text>
|
||||
{textLineCount >= maxLines && <Text
|
||||
onPress={() => setShowFullDescription(prev => !prev)}
|
||||
style={Theme.TransactionCodeScreenStyle.showMoreButton}
|
||||
>
|
||||
{showFullDescription ? t('Show less ↑') : t('Show more ↓')}
|
||||
</Text>}
|
||||
</Column>
|
||||
</View>
|
||||
|
||||
{(props.error || errorMessage) && (
|
||||
<View
|
||||
style={Theme.TransactionCodeScreenStyle.errorView}
|
||||
>
|
||||
<Text
|
||||
testID="otpVerificationError"
|
||||
align="center"
|
||||
color={Theme.Colors.errorMessage}>
|
||||
{errorMessage || props.error}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<View style={{ alignItems: 'center' }}>
|
||||
{((!props.inputMode ||
|
||||
(props.inputMode && props.inputMode === 'numeric')) &&
|
||||
props.length &&
|
||||
props.length <= 6) ? (
|
||||
<>
|
||||
<PinInput
|
||||
testID="pinInput"
|
||||
length={props.length}
|
||||
autosubmit={false}
|
||||
onChange={handleChange}
|
||||
onDone={(code: string) => {
|
||||
const error = validateCode(code);
|
||||
if (error) {
|
||||
setErrorMessage(error);
|
||||
return;
|
||||
}
|
||||
setErrorMessage('');
|
||||
props.onVerify?.(code);
|
||||
props.onDismiss?.();
|
||||
}}
|
||||
/>
|
||||
<Button styles={{ marginTop: 30 }} disabled={transactionCode.length == 0} title={t('verify')} type="gradient" onPress={handleVerify} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Input
|
||||
containerStyle={{
|
||||
width: Dimensions.get('window').width - 80,
|
||||
alignSelf: 'center',
|
||||
}}
|
||||
placeholder={t('placeholder')}
|
||||
placeholderTextColor="#ACACAC"
|
||||
inputContainerStyle={{
|
||||
borderBottomColor: '#C1C1C1',
|
||||
borderBottomWidth: 1,
|
||||
marginBottom: 16,
|
||||
}}
|
||||
inputStyle={Theme.TransactionCodeScreenStyle.inputStyle}
|
||||
maxLength={props.length ?? 30}
|
||||
autoFocus
|
||||
secureTextEntry={!showCode}
|
||||
value={transactionCode}
|
||||
keyboardType={props.inputMode === 'numeric' ? 'numeric' : 'default'}
|
||||
onChangeText={handleChange}
|
||||
rightIcon={
|
||||
<Icon
|
||||
name={showCode ? 'eye-off' : 'eye'}
|
||||
type="feather"
|
||||
size={20}
|
||||
color="#888"
|
||||
onPress={() => setShowCode(prev => !prev)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Button disabled={transactionCode.length == 0} title="Verify" type="gradient" onPress={handleVerify} />
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
</Column>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</KeyboardAvoidingView>
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
interface ExtendedModalProps extends ModalProps {
|
||||
onVerify?: (transactionCode: string) => void;
|
||||
error?: string;
|
||||
description?: string;
|
||||
inputMode?: 'text' | 'numeric';
|
||||
length?: number;
|
||||
}
|
||||
50
screens/Issuers/TrustIssuerModal.tsx
Normal file
50
screens/Issuers/TrustIssuerModal.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
import { Modal, View, Text, Image } from 'react-native';
|
||||
import { Button } from '../../components/ui';
|
||||
import { Theme } from '../../components/ui/styleUtils';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const TrustIssuerModal = ({
|
||||
isVisible,
|
||||
issuerLogo,
|
||||
issuerName,
|
||||
onConfirm,
|
||||
onCancel
|
||||
}: {
|
||||
isVisible: boolean;
|
||||
issuerLogo: any;
|
||||
issuerName: string;
|
||||
onConfirm: () => void;
|
||||
onCancel: () => void;
|
||||
}) => {
|
||||
const { t } = useTranslation('trustScreen');
|
||||
return (
|
||||
<Modal transparent={true} visible={isVisible} animationType="fade">
|
||||
<View
|
||||
style={Theme.TrustIssuerScreenStyle.modalOverlay}>
|
||||
<View
|
||||
style={Theme.TrustIssuerScreenStyle.modalContainer}>
|
||||
|
||||
{(issuerLogo || issuerName) && <View
|
||||
style={Theme.TrustIssuerScreenStyle.issuerHeader}>
|
||||
{issuerLogo && <Image
|
||||
source={{ uri: issuerLogo }}
|
||||
style={Theme.TrustIssuerScreenStyle.issuerLogo}
|
||||
/>}
|
||||
{issuerName && <Text
|
||||
style={Theme.TrustIssuerScreenStyle.issuerName}>
|
||||
{issuerName}
|
||||
</Text>}
|
||||
</View>}
|
||||
|
||||
<Text
|
||||
style={Theme.TrustIssuerScreenStyle.description}>
|
||||
{t('description')}
|
||||
</Text>
|
||||
<Button styles={{ marginBottom: 6 }} type='gradient' title={t('confirm')} onPress={onConfirm} />
|
||||
<Button styles={{ marginBottom: -10 }} type='clear' title={t('cancel')} onPress={onCancel} />
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
@@ -41,6 +41,7 @@ export const API_URLS: ApiUrls = {
|
||||
buildURL: (authorizationServerUrl: string): string =>
|
||||
`${authorizationServerUrl}/.well-known/oauth-authorization-server`,
|
||||
},
|
||||
|
||||
allProperties: {
|
||||
method: 'GET',
|
||||
buildURL: (): `/${string}` => '/v1/mimoto/allProperties',
|
||||
@@ -115,6 +116,14 @@ export const API = {
|
||||
);
|
||||
return response.response.issuers || [];
|
||||
},
|
||||
|
||||
fetchIssuerConfig: async (issuerId: string) => {
|
||||
const response = await request(
|
||||
API_URLS.issuerConfig.method,
|
||||
API_URLS.issuerConfig.buildURL(issuerId),
|
||||
);
|
||||
return response.response;
|
||||
},
|
||||
fetchIssuerWellknownConfig: async (credentialIssuer: string) => {
|
||||
const response = await request(
|
||||
API_URLS.issuerWellknownConfig.method,
|
||||
@@ -122,17 +131,7 @@ export const API = {
|
||||
);
|
||||
return response;
|
||||
},
|
||||
fetchAuthorizationServerMetadata: async (authorizationServerUrl: string) => {
|
||||
const response = await request(
|
||||
API_URLS.authorizationServerMetadataConfig.method,
|
||||
API_URLS.authorizationServerMetadataConfig.buildURL(
|
||||
authorizationServerUrl,
|
||||
),
|
||||
undefined,
|
||||
'',
|
||||
);
|
||||
return response;
|
||||
},
|
||||
|
||||
fetchAllProperties: async () => {
|
||||
const response = await request(
|
||||
API_URLS.allProperties.method,
|
||||
|
||||
@@ -81,6 +81,12 @@ export const SUPPORTED_KEY_TYPES = {
|
||||
'ECC R1': KeyTypes.ES256,
|
||||
RSA: KeyTypes.RS256,
|
||||
};
|
||||
export const KEY_TYPE_TO_JWT_ALG = {
|
||||
[KeyTypes.ED25519]: 'EdDSA',
|
||||
[KeyTypes.ES256K]: 'ES256K',
|
||||
[KeyTypes.ES256]: 'ES256',
|
||||
[KeyTypes.RS256]: 'RS256',
|
||||
};
|
||||
|
||||
export function isAndroid(): boolean {
|
||||
return Platform.OS === 'android';
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
VerifiableCredential,
|
||||
} from '../../machines/VerifiableCredential/VCMetaMachine/vc';
|
||||
import getAllConfigurations, {CACHED_API} from '../api';
|
||||
import {isAndroid, isIOS} from '../constants';
|
||||
import {isAndroid, isIOS, KEY_TYPE_TO_JWT_ALG} from '../constants';
|
||||
import {getJWT} from '../cryptoutil/cryptoUtil';
|
||||
import {isMockVC} from '../Utils';
|
||||
import {
|
||||
@@ -34,7 +34,6 @@ import {KeyTypes} from '../cryptoutil/KeyTypes';
|
||||
import {VCFormat} from '../VCFormat';
|
||||
import {UnsupportedVcFormat} from '../error/UnsupportedVCFormat';
|
||||
import {VCMetadata} from '../VCMetadata';
|
||||
import {UUID} from '../Utils';
|
||||
|
||||
export const Protocols = {
|
||||
OpenId4VCI: 'OpenId4VCI',
|
||||
@@ -71,7 +70,7 @@ export const isActivationNeeded = (issuer: string) => {
|
||||
export const Issuers_Key_Ref = 'OpenId4VCI_KeyPair';
|
||||
|
||||
export const updateCredentialInformation = async (
|
||||
context,
|
||||
context: any,
|
||||
credential: VerifiableCredential,
|
||||
): Promise<CredentialWrapper> => {
|
||||
let processedCredential;
|
||||
@@ -81,14 +80,23 @@ export const updateCredentialInformation = async (
|
||||
context.selectedCredentialType.format,
|
||||
);
|
||||
}
|
||||
const verifiableCredential = {
|
||||
...credential,
|
||||
credentialConfigurationId: context.selectedCredentialType.id,
|
||||
issuerLogo: getDisplayObjectForCurrentLanguage(
|
||||
context.selectedIssuer.display,
|
||||
)?.logo,
|
||||
processedCredential,
|
||||
};
|
||||
let verifiableCredential;
|
||||
try {
|
||||
verifiableCredential = {
|
||||
...credential,
|
||||
credentialConfigurationId: context.selectedCredentialType.id,
|
||||
issuerLogo: getDisplayObjectForCurrentLanguage(
|
||||
context.selectedIssuer.display,
|
||||
)?.logo,
|
||||
processedCredential,
|
||||
};
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'Error occurred while processing credential for rendering',
|
||||
e,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
verifiableCredential,
|
||||
format: context.selectedCredentialType.format,
|
||||
@@ -111,28 +119,14 @@ export const getDisplayObjectForCurrentLanguage = (
|
||||
obj => obj[languageKey] == currentLanguage,
|
||||
)[0];
|
||||
if (!displayType) {
|
||||
displayType = display.filter(obj => obj[languageKey] === 'en')[0];
|
||||
displayType =
|
||||
display.filter(obj => obj[languageKey] === 'en')[0] ||
|
||||
display.filter(obj => obj[languageKey] === 'en-US')[0] ||
|
||||
display[0];
|
||||
}
|
||||
return displayType;
|
||||
};
|
||||
|
||||
export const constructAuthorizationConfiguration = (
|
||||
selectedIssuer: issuerType,
|
||||
supportedScope: string,
|
||||
) => {
|
||||
return {
|
||||
issuer: selectedIssuer.issuer_id,
|
||||
clientId: selectedIssuer.client_id,
|
||||
scopes: [supportedScope],
|
||||
redirectUrl: selectedIssuer.redirect_uri,
|
||||
additionalParameters: {ui_locales: i18n.language},
|
||||
serviceConfiguration: {
|
||||
authorizationEndpoint: selectedIssuer.authorizationEndpoint,
|
||||
tokenEndpoint: selectedIssuer.token_endpoint,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const getCredentialIssuersWellKnownConfig = async (
|
||||
issuer: string | undefined,
|
||||
defaultFields: string[],
|
||||
@@ -141,6 +135,7 @@ export const getCredentialIssuersWellKnownConfig = async (
|
||||
issuerHost: string,
|
||||
) => {
|
||||
let fields: string[] = defaultFields;
|
||||
let wellknownFieldsFlag = false;
|
||||
let matchingWellknownDetails: any;
|
||||
const wellknownResponse = await CACHED_API.fetchIssuerWellknownConfig(
|
||||
issuer!,
|
||||
@@ -169,9 +164,13 @@ export const getCredentialIssuersWellKnownConfig = async (
|
||||
);
|
||||
});
|
||||
} else if (format === VCFormat.ldp_vc) {
|
||||
fields = Object.keys(
|
||||
const ldpFields = Object.keys(
|
||||
matchingWellknownDetails.credential_definition.credentialSubject,
|
||||
);
|
||||
if (ldpFields.length > 0) {
|
||||
fields = ldpFields;
|
||||
wellknownFieldsFlag = true;
|
||||
}
|
||||
} else {
|
||||
console.error(`Unsupported credential format - ${format} found`);
|
||||
throw new UnsupportedVcFormat(format);
|
||||
@@ -186,12 +185,15 @@ export const getCredentialIssuersWellKnownConfig = async (
|
||||
return {
|
||||
matchingCredentialIssuerMetadata: matchingWellknownDetails,
|
||||
fields: fields,
|
||||
wellknownFieldsFlag: false,
|
||||
};
|
||||
}
|
||||
return {
|
||||
matchingCredentialIssuerMetadata: matchingWellknownDetails,
|
||||
wellknownResponse,
|
||||
fields: fields,
|
||||
wellknownFieldsFlag:
|
||||
wellknownFieldsFlag || matchingWellknownDetails?.order?.length > 0,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -217,6 +219,7 @@ export const getDetailedViewFields = async (
|
||||
return {
|
||||
matchingCredentialIssuerMetadata: response.matchingCredentialIssuerMetadata,
|
||||
fields: updatedFieldsList,
|
||||
wellknownFieldsFlag: response.wellknownFieldsFlag,
|
||||
wellknownResponse: response.wellknownResponse,
|
||||
};
|
||||
};
|
||||
@@ -245,7 +248,8 @@ export const OIDCErrors = {
|
||||
|
||||
AUTHORIZATION_ENDPOINT_DISCOVERY: {
|
||||
GRANT_TYPE_NOT_SUPPORTED: 'Grant type not supported by Wallet',
|
||||
FAILED_TO_FETCH_AUTHORIZATION_ENDPOINT: 'Failed to fetch authorization endpoint or grant type not supported by wallet',
|
||||
FAILED_TO_FETCH_AUTHORIZATION_ENDPOINT:
|
||||
'Failed to fetch authorization endpoint or grant type not supported by wallet',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -267,17 +271,24 @@ export async function constructProofJWT(
|
||||
accessToken: string,
|
||||
selectedIssuer: issuerType,
|
||||
keyType: string,
|
||||
isCredentialOfferFlow: boolean,
|
||||
cNonce?: string,
|
||||
): Promise<string> {
|
||||
const jwk = await getJWK(publicKey, keyType);
|
||||
const jwtHeader = {
|
||||
alg: keyType,
|
||||
jwk: await getJWK(publicKey, keyType),
|
||||
alg: KEY_TYPE_TO_JWT_ALG[keyType],
|
||||
typ: 'openid4vci-proof+jwt',
|
||||
};
|
||||
if (isCredentialOfferFlow) {
|
||||
jwtHeader['kid'] = `did:jwk:${base64url(JSON.stringify(jwk))}#0`;
|
||||
} else {
|
||||
jwtHeader['jwk'] = jwk;
|
||||
}
|
||||
const decodedToken = jwtDecode(accessToken);
|
||||
const jwtPayload = {
|
||||
iss: selectedIssuer.client_id,
|
||||
nonce: decodedToken.c_nonce,
|
||||
aud: selectedIssuer.credential_audience,
|
||||
nonce: cNonce ?? decodedToken.c_nonce,
|
||||
aud: selectedIssuer.credential_audience ?? selectedIssuer.credential_issuer,
|
||||
iat: Math.floor(new Date().getTime() / 1000),
|
||||
exp: Math.floor(new Date().getTime() / 1000) + 18000,
|
||||
};
|
||||
@@ -312,7 +323,7 @@ export const getJWK = async (publicKey, keyType) => {
|
||||
}
|
||||
return {
|
||||
...publicKeyJWK,
|
||||
alg: keyType,
|
||||
alg: KEY_TYPE_TO_JWT_ALG[keyType],
|
||||
use: 'sig',
|
||||
};
|
||||
} catch (e) {
|
||||
@@ -387,23 +398,30 @@ export function selectCredentialRequestKey(
|
||||
return keyOrder[index];
|
||||
}
|
||||
}
|
||||
return '';
|
||||
return KeyTypes.ED25519;
|
||||
}
|
||||
|
||||
export const constructIssuerMetaData = (
|
||||
selectedIssuer: issuerType,
|
||||
selectedCredentialType: CredentialTypes,
|
||||
downloadTimeout: Number,
|
||||
scope: string,
|
||||
): Object => {
|
||||
const issuerMeta: Object = {
|
||||
credentialAudience: selectedIssuer.credential_audience,
|
||||
credentialEndpoint: selectedIssuer.credential_endpoint,
|
||||
downloadTimeoutInMilliSeconds: downloadTimeout,
|
||||
credentialFormat: selectedCredentialType.format,
|
||||
credentialFormat: isIOS()
|
||||
? selectedCredentialType.format
|
||||
: selectedCredentialType.format.toUpperCase(),
|
||||
authorizationServers: selectedIssuer['authorization_servers'],
|
||||
tokenEndpoint: selectedIssuer.token_endpoint,
|
||||
scope: scope,
|
||||
};
|
||||
if (selectedCredentialType.format === VCFormat.ldp_vc) {
|
||||
issuerMeta['credentialType'] = selectedCredentialType?.credential_definition
|
||||
?.type ?? ['VerifiableCredential'];
|
||||
if (selectedCredentialType?.credential_definition['@context'])
|
||||
issuerMeta['context'] =
|
||||
selectedCredentialType?.credential_definition['@context'];
|
||||
} else if (selectedCredentialType.format === VCFormat.mso_mdoc) {
|
||||
issuerMeta['doctype'] = selectedCredentialType.doctype;
|
||||
issuerMeta['claims'] = selectedCredentialType.claims;
|
||||
|
||||
@@ -1,19 +1,126 @@
|
||||
import {NativeModules} from 'react-native';
|
||||
import {NativeModules, NativeEventEmitter} from 'react-native';
|
||||
import {__AppId} from '../GlobalVariables';
|
||||
import {constructProofJWT} from '../openId4VCI/Utils';
|
||||
import {issuerType} from '../../machines/Issuers/IssuersMachine';
|
||||
import {VerifiableCredential} from '../../machines/VerifiableCredential/VCMetaMachine/vc';
|
||||
|
||||
const emitter = new NativeEventEmitter(NativeModules.InjiVciClient);
|
||||
|
||||
export class VciClient {
|
||||
static async downloadCredential(
|
||||
issuerMetaData: Object,
|
||||
jwtProof: string,
|
||||
accessToken: string,
|
||||
static get client() {
|
||||
const nativeClient = NativeModules.InjiVciClient;
|
||||
nativeClient.init(__AppId.getValue());
|
||||
return nativeClient;
|
||||
}
|
||||
|
||||
static async requestCredentialByOffer(
|
||||
credentialOffer: string,
|
||||
getTxCode: (
|
||||
inputMode: string | undefined,
|
||||
description: string | undefined,
|
||||
length: number | undefined,
|
||||
) => void,
|
||||
getProofJwt: (
|
||||
accesToken: string,
|
||||
cNonce: string | null,
|
||||
issuerMetadata: object,
|
||||
credentialConfigurationId: string,
|
||||
) => void,
|
||||
navigateToAuthView: (authorizationEndpoint: string) => void,
|
||||
requestTrustIssuerConsent: (issuerMetadata: object) => void,
|
||||
) {
|
||||
const InjiVciClient = NativeModules.InjiVciClient;
|
||||
InjiVciClient.init(__AppId.getValue());
|
||||
const credentialResponse = await InjiVciClient.requestCredential(
|
||||
issuerMetaData,
|
||||
jwtProof,
|
||||
accessToken,
|
||||
const proofListener = emitter.addListener(
|
||||
'onRequestProof',
|
||||
async ({
|
||||
accessToken,
|
||||
cNonce,
|
||||
issuerMetadata,
|
||||
credentialConfigurationId,
|
||||
}) => {
|
||||
getProofJwt(
|
||||
accessToken,
|
||||
cNonce,
|
||||
JSON.parse(issuerMetadata),
|
||||
credentialConfigurationId,
|
||||
);
|
||||
},
|
||||
);
|
||||
return JSON.parse(credentialResponse);
|
||||
|
||||
const authListener = emitter.addListener(
|
||||
'onRequestAuthCode',
|
||||
async ({authorizationEndpoint}) => {
|
||||
navigateToAuthView(authorizationEndpoint);
|
||||
},
|
||||
);
|
||||
const txCodeListener = emitter.addListener(
|
||||
'onRequestTxCode',
|
||||
async ({inputMode, description, length}) => {
|
||||
getTxCode(inputMode, description, length);
|
||||
},
|
||||
);
|
||||
|
||||
const trustIssuerListener = emitter.addListener(
|
||||
'onCheckIssuerTrust',
|
||||
async ({issuerMetadata}) => {
|
||||
const issuerMetadataObject = JSON.parse(issuerMetadata);
|
||||
requestTrustIssuerConsent(issuerMetadataObject);
|
||||
},
|
||||
);
|
||||
let response = '';
|
||||
try {
|
||||
response = await VciClient.client.requestCredentialByOffer(
|
||||
credentialOffer,
|
||||
JSON.stringify({
|
||||
clientId: 'wallet',
|
||||
redirectUri: 'io.mosip.residentapp.inji://oauthredirect',
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Error requesting credential by offer:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
proofListener.remove();
|
||||
authListener.remove();
|
||||
txCodeListener.remove();
|
||||
trustIssuerListener.remove();
|
||||
return JSON.parse(response) as VerifiableCredential;
|
||||
}
|
||||
|
||||
static async requestCredentialFromTrustedIssuer(
|
||||
resolvedIssuerMetaData: Object,
|
||||
clientMetadata: Object,
|
||||
getProofJwt: (accessToken: string, cNonce: string) => Promise<void>,
|
||||
navigateToAuthView: (authorizationEndpoint: string) => void,
|
||||
) {
|
||||
const proofListener = emitter.addListener(
|
||||
'onRequestProof',
|
||||
async ({accessToken, cNonce}) => {
|
||||
getProofJwt(accessToken, cNonce);
|
||||
proofListener.remove();
|
||||
},
|
||||
);
|
||||
|
||||
const authListener = emitter.addListener(
|
||||
'onRequestAuthCode',
|
||||
({authorizationEndpoint}) => {
|
||||
navigateToAuthView(authorizationEndpoint);
|
||||
},
|
||||
);
|
||||
let response = '';
|
||||
try {
|
||||
response = await VciClient.client.requestCredentialFromTrustedIssuer(
|
||||
JSON.stringify(resolvedIssuerMetaData),
|
||||
JSON.stringify(clientMetadata),
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Error requesting credential from trusted issuer:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
proofListener.remove();
|
||||
authListener.remove();
|
||||
|
||||
return JSON.parse(response);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user