mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 13:38:01 -05:00
[INJIMOB-3647] refactor: enhance response structure of credential status check (#2147)
* [INJIMOB-3647] refactor: enhance response structure of credential status check (#2145) * [INJIMOB-3647] refactor: udpate vc verifier RN module Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: update reverification logic Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: modify status response structure Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: update response resolving of status check in swift bridge Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: update info logs to print status message Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: modify type from map to record Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: remove unnecessary async function Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: Credential summary result structure Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> --------- Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: change statuslistVC type to record from string Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> --------- Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
This commit is contained in:
committed by
GitHub
parent
ff9ee7184f
commit
dab6c1b9a2
@@ -1,26 +1,25 @@
|
||||
package io.mosip.residentapp;
|
||||
import java.util.*;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.mosip.residentapp.Utils.FormatConverter;
|
||||
import io.mosip.vercred.vcverifier.CredentialsVerifier;
|
||||
import io.mosip.vercred.vcverifier.constants.CredentialFormat;
|
||||
import io.mosip.vercred.vcverifier.data.VerificationResult;
|
||||
import io.mosip.vercred.vcverifier.data.CredentialVerificationSummary;
|
||||
import io.mosip.vercred.vcverifier.data.CredentialStatusResult;
|
||||
import io.mosip.vercred.vcverifier.data.VerificationResult;
|
||||
import io.mosip.vercred.vcverifier.exception.StatusCheckException;
|
||||
|
||||
public class RNVCVerifierModule extends ReactContextBaseJavaModule {
|
||||
|
||||
private CredentialsVerifier credentialsVerifier;
|
||||
private final CredentialsVerifier credentialsVerifier;
|
||||
public RNVCVerifierModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
credentialsVerifier = new CredentialsVerifier();
|
||||
@@ -61,32 +60,27 @@ public void getVerificationSummary(String vc, String format, ReadableArray statu
|
||||
resultMap.putString("verificationMessage", verificationResult.getVerificationMessage());
|
||||
resultMap.putString("verificationErrorCode", verificationResult.getVerificationErrorCode());
|
||||
|
||||
WritableArray statusArray = Arguments.createArray();
|
||||
for (CredentialStatusResult statusResult : summary.getCredentialStatus()) {
|
||||
WritableMap statusMap = Arguments.createMap();
|
||||
statusMap.putString("purpose", statusResult.getPurpose());
|
||||
statusMap.putInt("status", statusResult.getStatus());
|
||||
statusMap.putBoolean("valid", statusResult.getValid());
|
||||
|
||||
WritableMap statusMap = Arguments.createMap();
|
||||
summary.getCredentialStatus().forEach((purpose, statusResult) -> {
|
||||
WritableMap statusEntryMap = Arguments.createMap();
|
||||
statusEntryMap.putBoolean("isValid", statusResult.isValid());
|
||||
StatusCheckException error = statusResult.getError();
|
||||
if (error != null) {
|
||||
WritableMap errorMap = Arguments.createMap();
|
||||
errorMap.putString("message", error.getMessage());
|
||||
errorMap.putString("code", error.getErrorCode().name());
|
||||
statusMap.putMap("error", errorMap);
|
||||
statusEntryMap.putMap("error", errorMap);
|
||||
} else {
|
||||
statusMap.putNull("error");
|
||||
statusEntryMap.putNull("error");
|
||||
}
|
||||
|
||||
statusArray.pushMap(statusMap);
|
||||
}
|
||||
statusMap.putMap(purpose, statusEntryMap);
|
||||
});
|
||||
|
||||
resultMap.putArray("credentialStatus", statusArray);
|
||||
resultMap.putMap("credentialStatus", statusMap);
|
||||
promise.resolve(resultMap);
|
||||
|
||||
} catch (Exception e) {
|
||||
promise.reject("VERIFY_AND_GET_STATUS_ERROR", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,16 +29,19 @@ class VCVerifierModule: NSObject, RCTBridgeModule {
|
||||
let verifier = CredentialsVerifier()
|
||||
let results = try await verifier.getCredentialStatus(credential: credential, format: credentialFormat)
|
||||
|
||||
let responseArray = results.map { result in
|
||||
return [
|
||||
"status": result.status,
|
||||
"purpose": result.purpose,
|
||||
"errorCode": result.error?.errorCode.rawValue,
|
||||
"errorMessage": result.error?.message,
|
||||
"statusListVC": result.statusListVC
|
||||
var response: [String: Any] = [:]
|
||||
for (purpose, credentialStatusResult) in results {
|
||||
let error : [String: Any]? = credentialStatusResult.error != nil ? [
|
||||
"code": credentialStatusResult.error?.errorCode ?? "UNKNOWN_ERROR",
|
||||
"message": credentialStatusResult.error?.message ?? "An unknown error occurred"
|
||||
] : nil
|
||||
response[purpose] = [
|
||||
"isValid": credentialStatusResult.isValid,
|
||||
"statusListVC": credentialStatusResult.statusListVC,
|
||||
"error": error
|
||||
]
|
||||
}
|
||||
resolve(responseArray)
|
||||
resolve(response)
|
||||
} catch {
|
||||
reject("VERIFICATION_FAILED", "Verification threw an error: \(error.localizedDescription)", error)
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@ public struct CredentialsVerifier {
|
||||
|
||||
public init() {}
|
||||
|
||||
public func getCredentialStatus(credential: String, format: StatusCheckCredentialFormat, statusPurposeList: [String] = []) async throws-> [CredentialStatusResult] {
|
||||
public func getCredentialStatus(credential: String, format: StatusCheckCredentialFormat, statusPurposeList: [String] = []) async throws-> [String: CredentialStatusResult] {
|
||||
do {
|
||||
let verifier = CredentialVerifierFactory().get(format: format)
|
||||
let credentialStatusArray = try await verifier.checkStatus(credential: credential, statusPurposes: statusPurposeList)
|
||||
return credentialStatusArray ?? []
|
||||
let credentialStatuses = try await verifier.checkStatus(credential: credential, statusPurposes: statusPurposeList)
|
||||
return credentialStatuses ?? [:]
|
||||
} catch{
|
||||
throw error
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Foundation
|
||||
|
||||
protocol VerifiableCredential {
|
||||
func checkStatus(credential: String, statusPurposes: [String]?) async throws-> [CredentialStatusResult]?
|
||||
func checkStatus(credential: String, statusPurposes: [String]?) async throws-> [String: CredentialStatusResult]
|
||||
}
|
||||
|
||||
@@ -4,19 +4,15 @@ import Gzip
|
||||
// MARK: - Credential Status Result
|
||||
|
||||
public struct CredentialStatusResult {
|
||||
let purpose: String
|
||||
let status: Int
|
||||
let valid: Bool
|
||||
let error: StatusCheckException?
|
||||
let statusListVC: [String: Any]?
|
||||
|
||||
init(purpose: String, status: Int, valid: Bool, error: StatusCheckException?, statusListVC: [String: Any]? = nil) {
|
||||
self.purpose = purpose
|
||||
self.status = status
|
||||
self.valid = valid
|
||||
self.error = error
|
||||
self.statusListVC = statusListVC
|
||||
}
|
||||
let isValid: Bool
|
||||
let statusListVC: [String: Any]?
|
||||
let error: StatusCheckException?
|
||||
|
||||
init(isValid: Bool, statusListVC: [String: Any]? = nil, error: StatusCheckException? = nil) {
|
||||
self.isValid = isValid
|
||||
self.statusListVC = statusListVC
|
||||
self.error = error
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Error Types
|
||||
@@ -24,6 +20,7 @@ public struct CredentialStatusResult {
|
||||
enum StatusCheckErrorCode: String {
|
||||
case rangeError = "RANGE_ERROR"
|
||||
case statusVerificationError = "STATUS_VERIFICATION_ERROR"
|
||||
case invalidCredentialStatus = "INVALID_CREDENTIAL_STATUS"
|
||||
case statusRetrievalError = "STATUS_RETRIEVAL_ERROR"
|
||||
case invalidPurpose = "INVALID_PURPOSE"
|
||||
case invalidIndex = "INVALID_INDEX"
|
||||
@@ -33,7 +30,7 @@ enum StatusCheckErrorCode: String {
|
||||
case unknownError = "UNKNOWN_ERROR"
|
||||
}
|
||||
|
||||
struct StatusCheckException: Error {
|
||||
public struct StatusCheckException: Error {
|
||||
let message: String
|
||||
let errorCode: StatusCheckErrorCode
|
||||
}
|
||||
@@ -49,7 +46,7 @@ final class LdpStatusChecker {
|
||||
self.networkManager = networkManager
|
||||
}
|
||||
|
||||
func getStatuses(credential: String, statusPurposes: [String]? = nil) async throws -> [CredentialStatusResult]? {
|
||||
func getStatuses(credential: String, statusPurposes: [String]? = nil) async throws -> [String: CredentialStatusResult] {
|
||||
guard
|
||||
let data = credential.data(using: .utf8),
|
||||
let vc = try JSONSerialization.jsonObject(with: data) as? [String: Any]
|
||||
@@ -58,24 +55,33 @@ final class LdpStatusChecker {
|
||||
}
|
||||
|
||||
let statusField = vc["credentialStatus"]
|
||||
guard let statusEntries = normalizeStatusField(statusField) else { return nil }
|
||||
guard let statusEntries = normalizeStatusField(statusField) else { throw StatusCheckException(
|
||||
message: "No valid credentialStatus entries found",
|
||||
errorCode: .invalidCredentialStatus
|
||||
) }
|
||||
|
||||
let filteredEntries = filterEntries(statusEntries, statusPurposes)
|
||||
guard !filteredEntries.isEmpty else { return nil }
|
||||
|
||||
var results: [CredentialStatusResult] = []
|
||||
guard !filteredEntries.isEmpty else {
|
||||
print("No matching credentialStatus entries found for purposes: \(statusPurposes ?? [])")
|
||||
return [:]
|
||||
}
|
||||
|
||||
var results: [String: CredentialStatusResult] = [:]
|
||||
|
||||
for entry in filteredEntries {
|
||||
let purpose = (entry["statusPurpose"] as? String)?.lowercased() ?? ""
|
||||
do {
|
||||
let result = try await checkStatusEntry(entry: entry, purpose: purpose)
|
||||
results.append(result)
|
||||
} catch let error as StatusCheckException {
|
||||
results.append(.init(purpose: purpose, status: -1, valid: false, error: error))
|
||||
} catch {
|
||||
let genericError = StatusCheckException(message: error.localizedDescription, errorCode: .unknownError)
|
||||
results.append(.init(purpose: purpose, status: -1, valid: false, error: genericError))
|
||||
}
|
||||
guard let purpose = (entry["statusPurpose"] as? String)?.lowercased(), !purpose.isEmpty else {
|
||||
print("Warning: Skipping entry with missing statusPurpose")
|
||||
continue
|
||||
}
|
||||
do {
|
||||
let result = try await checkStatusEntry(entry: entry, purpose: purpose)
|
||||
results[purpose] = result
|
||||
} catch let error as StatusCheckException {
|
||||
results[purpose] = CredentialStatusResult(isValid: false, statusListVC: nil, error: error)
|
||||
} catch {
|
||||
let genericError = StatusCheckException(message: error.localizedDescription, errorCode: .unknownError)
|
||||
results[purpose] = CredentialStatusResult(isValid: false, statusListVC: nil, error: genericError)
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
@@ -171,6 +177,8 @@ final class LdpStatusChecker {
|
||||
else {
|
||||
throw StatusCheckException(message: "statusMessage count mismatch", errorCode: .statusVerificationError)
|
||||
}
|
||||
|
||||
print("Status message for purpose '\(purpose): \(statusMessage)")
|
||||
}
|
||||
|
||||
let bitSet = try decodeEncodedList(encodedList)
|
||||
@@ -181,7 +189,10 @@ final class LdpStatusChecker {
|
||||
}
|
||||
|
||||
let statusValue = readBits(from: bitSet, start: bitPosition, count: statusSize)
|
||||
return .init(purpose: purpose, status: statusValue, valid: statusValue == 0, error: nil, statusListVC: statusListVC)
|
||||
let isValid = (statusValue == 0)
|
||||
print("Status value for purpose \(purpose) at index \(indexStr): \(statusValue)")
|
||||
|
||||
return .init(isValid: isValid, statusListVC: statusListVC, error: nil)
|
||||
}
|
||||
|
||||
private func readBits(from bitSet: [UInt8], start: Int, count: Int) -> Int {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Foundation
|
||||
|
||||
struct LdpVerifiableCredential: VerifiableCredential {
|
||||
func checkStatus(credential: String, statusPurposes: [String]?) async throws-> [CredentialStatusResult]? {
|
||||
func checkStatus(credential: String, statusPurposes: [String]?) async throws-> [String: CredentialStatusResult] {
|
||||
try await LdpStatusChecker().getStatuses(credential: credential)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import {NativeModules} from 'react-native';
|
||||
|
||||
export type CredentialStatusResult = {
|
||||
status: number;
|
||||
purpose: string;
|
||||
errorCode?: string;
|
||||
errorMessage?: string;
|
||||
statusListVC?: string;
|
||||
isValid: boolean;
|
||||
error?: ErrorResult;
|
||||
statusListVC?: Record<string, any>; // Available only in iOS
|
||||
};
|
||||
|
||||
export type ErrorResult = {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
|
||||
export type VerificationSummaryResult = {
|
||||
verificationStatus: boolean;
|
||||
verificationMessage: string;
|
||||
verificationErrorCode: string;
|
||||
credentialStatus: CredentialStatusResult[];
|
||||
credentialStatus: Record<string, CredentialStatusResult>;
|
||||
};
|
||||
|
||||
class VCVerifier {
|
||||
@@ -33,14 +36,12 @@ class VCVerifier {
|
||||
async getCredentialStatus(
|
||||
credential: any,
|
||||
format: string,
|
||||
): Promise<CredentialStatusResult[]> {
|
||||
): Promise<Record<string, CredentialStatusResult>> {
|
||||
try {
|
||||
const result: CredentialStatusResult[] =
|
||||
await this.vcVerifier.getCredentialStatus(
|
||||
JSON.stringify(credential),
|
||||
format,
|
||||
);
|
||||
return result;
|
||||
return await this.vcVerifier.getCredentialStatus(
|
||||
JSON.stringify(credential),
|
||||
format,
|
||||
);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get credential status: ${error}`);
|
||||
}
|
||||
@@ -51,12 +52,11 @@ class VCVerifier {
|
||||
credentialFormat: string,
|
||||
): Promise<VerificationSummaryResult> {
|
||||
try {
|
||||
const result = await this.vcVerifier.getVerificationSummary(
|
||||
return await this.vcVerifier.getVerificationSummary(
|
||||
credentialString,
|
||||
credentialFormat,
|
||||
[],
|
||||
);
|
||||
return result;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get verification summary: ${error}`);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,10 @@ import {getMosipIdentifier} from '../commonUtil';
|
||||
import {NativeModules} from 'react-native';
|
||||
import {isAndroid, isIOS} from '../constants';
|
||||
import {VCFormat} from '../VCFormat';
|
||||
import VCVerifier, {CredentialStatusResult, VerificationSummaryResult} from '../vcVerifier/VcVerifier';
|
||||
import VCVerifier, {
|
||||
CredentialStatusResult,
|
||||
VerificationSummaryResult,
|
||||
} from '../vcVerifier/VcVerifier';
|
||||
|
||||
// FIXME: Ed25519Signature2018 not fully supported yet.
|
||||
// Ed25519Signature2018 proof type check is not tested with its real credential
|
||||
@@ -62,10 +65,11 @@ async function verifyCredentialForAndroid(
|
||||
typeof verifiableCredential === 'string'
|
||||
? verifiableCredential
|
||||
: JSON.stringify(verifiableCredential);
|
||||
const vcVerifierResult = await VCVerifier.getInstance().getVerificationSummary(
|
||||
credentialString,
|
||||
credentialFormat,
|
||||
);
|
||||
const vcVerifierResult =
|
||||
await VCVerifier.getInstance().getVerificationSummary(
|
||||
credentialString,
|
||||
credentialFormat,
|
||||
);
|
||||
return handleVcVerifierResponse(vcVerifierResult, verifiableCredential);
|
||||
}
|
||||
|
||||
@@ -84,12 +88,13 @@ async function verifyCredentialForIos(
|
||||
Since Digital Bazaar library is not able to verify ProofType: "Ed25519Signature2020",
|
||||
defaulting it to return true until VcVerifier is implemented for iOS.
|
||||
*/
|
||||
let verificationResponse: VerificationResult;
|
||||
let verificationResponse: VerificationResult;
|
||||
if (verifiableCredential.proof.type === ProofType.ED25519_2020) {
|
||||
verificationResponse = createSuccessfulVerificationResult();
|
||||
}
|
||||
else{
|
||||
const purpose = getPurposeFromProof(verifiableCredential.proof.proofPurpose);
|
||||
} else {
|
||||
const purpose = getPurposeFromProof(
|
||||
verifiableCredential.proof.proofPurpose,
|
||||
);
|
||||
const suite = selectVerificationSuite(verifiableCredential.proof);
|
||||
const vcjsOptions = {
|
||||
purpose,
|
||||
@@ -97,19 +102,17 @@ async function verifyCredentialForIos(
|
||||
credential: verifiableCredential,
|
||||
documentLoader: jsonld.documentLoaders.xhr(),
|
||||
};
|
||||
|
||||
|
||||
const result = await vcjs.verifyCredential(vcjsOptions);
|
||||
verificationResponse = handleResponse(result, verifiableCredential);
|
||||
}
|
||||
|
||||
|
||||
if (verificationResponse.isVerified) {
|
||||
const statusArray = await VCVerifier.getInstance().getCredentialStatus(
|
||||
verifiableCredential,
|
||||
credentialFormat,
|
||||
);
|
||||
const isRevoked = await checkIsStatusRevoked(statusArray);
|
||||
verificationResponse.isRevoked = isRevoked;
|
||||
verificationResponse.isRevoked = await checkIsStatusRevoked(statusArray);
|
||||
}
|
||||
return verificationResponse;
|
||||
}
|
||||
@@ -192,7 +195,9 @@ async function handleVcVerifierResponse(
|
||||
verifiableCredential,
|
||||
);
|
||||
}
|
||||
const isRevoked = await checkIsStatusRevoked(verificationResult.credentialStatus)
|
||||
const isRevoked = await checkIsStatusRevoked(
|
||||
verificationResult.credentialStatus,
|
||||
);
|
||||
return {
|
||||
isVerified: verificationResult.verificationStatus,
|
||||
verificationMessage: verificationResult.verificationMessage,
|
||||
@@ -213,48 +218,52 @@ async function handleVcVerifierResponse(
|
||||
}
|
||||
}
|
||||
|
||||
const handleStatusListVCVerification = (
|
||||
status: CredentialStatusResult,
|
||||
type: 'revoked' | 'valid',
|
||||
) => {
|
||||
const isValid = verifyStatusListVC(status.statusListVC);
|
||||
if (!isValid) {
|
||||
throw new Error(
|
||||
`StatusListVC verification failed for ${type} entry ${status.error}`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export async function checkIsStatusRevoked(
|
||||
vcStatus: CredentialStatusResult[],
|
||||
vcStatus: Record<string, CredentialStatusResult>,
|
||||
): Promise<boolean> {
|
||||
if (!vcStatus || vcStatus.length === 0) return false;
|
||||
if (!Object.keys(vcStatus).length) return false;
|
||||
|
||||
const revocationStatuses = vcStatus.filter(
|
||||
s => s.purpose?.toLowerCase() === 'revocation',
|
||||
const revocationStatus = vcStatus['revocation'] as CredentialStatusResult;
|
||||
if (!revocationStatus) return false;
|
||||
|
||||
const {isValid, error} = revocationStatus;
|
||||
|
||||
if (isValid) {
|
||||
// Validate the valid statuses statusList VC for iOS
|
||||
if (isIOS()) {
|
||||
handleStatusListVCVerification(revocationStatus, 'valid');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
console.error(
|
||||
`Credential is revoked. Error: ${error?.code}, Message: ${error?.message}`,
|
||||
);
|
||||
|
||||
let result = false;
|
||||
for (const status of revocationStatuses) {
|
||||
if (status.status > 0) {
|
||||
if (isIOS()) {
|
||||
const isValid = await verifyStatusListVC(status.statusListVC);
|
||||
if (!isValid) {
|
||||
throw new Error(`Revoked statusListVC verification failed`);
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
} else if (status.status < 0) {
|
||||
throw new Error(
|
||||
`Error fetching revocation status : ${status.errorMessage}`,
|
||||
);
|
||||
}
|
||||
// if there is an error fetching revocation status itself, throw error (isValid = false, error = Error)
|
||||
if (error) {
|
||||
throw new Error(
|
||||
`Error fetching revocation status. Error: ${error.code}, Message: ${error.message}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (result) return true;
|
||||
|
||||
// There is no error fetching revocation status, but the status is invalid (isValid = false, error = undefined) - VC is revoked
|
||||
// Validate the valid statuses statusList VC for iOS
|
||||
if (isIOS()) {
|
||||
for (const status of revocationStatuses) {
|
||||
if (status.status === 0) {
|
||||
const isValid = await verifyStatusListVC(status.statusListVC);
|
||||
if (!isValid) {
|
||||
throw new Error(
|
||||
`StatusListVC verification failed for valid entry ${status.errorMessage}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
handleStatusListVCVerification(revocationStatus, 'revoked');
|
||||
}
|
||||
|
||||
return false;
|
||||
// If revocation status is invalid, the credential is revoked
|
||||
return true;
|
||||
}
|
||||
|
||||
function createSuccessfulVerificationResult(): VerificationResult {
|
||||
@@ -310,7 +319,7 @@ export interface VerificationResult {
|
||||
|
||||
//TODO: Implement status list VC verification for iOS.
|
||||
//Currently Digital Bazaar library does not support VC 2.0 status list VC verification.
|
||||
function verifyStatusListVC(statusListVC: string | undefined) {
|
||||
function verifyStatusListVC(statusListVC: Record<string, any> | undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user