Skip to content

fix: convert publicKey to KeyObject for compatibility with Bun #254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 45 additions & 45 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,84 @@
// Copyright (c) 2023 Apple Inc. Licensed under MIT License.

import fetch from 'node-fetch';
import { CheckTestNotificationResponse, CheckTestNotificationResponseValidator } from './models/CheckTestNotificationResponse';
import { type CheckTestNotificationResponse, CheckTestNotificationResponseValidator } from './models/CheckTestNotificationResponse';
import { ConsumptionRequest } from './models/ConsumptionRequest';
import { Environment } from './models/Environment';
import { ExtendRenewalDateRequest } from './models/ExtendRenewalDateRequest';
import { ExtendRenewalDateResponse, ExtendRenewalDateResponseValidator } from './models/ExtendRenewalDateResponse';
import { HistoryResponse, HistoryResponseValidator } from './models/HistoryResponse';
import { MassExtendRenewalDateRequest } from './models/MassExtendRenewalDateRequest';
import { MassExtendRenewalDateResponse, MassExtendRenewalDateResponseValidator } from './models/MassExtendRenewalDateResponse';
import { MassExtendRenewalDateStatusResponse, MassExtendRenewalDateStatusResponseValidator } from './models/MassExtendRenewalDateStatusResponse';
import { OrderLookupResponse, OrderLookupResponseValidator } from './models/OrderLookupResponse';
import { RefundHistoryResponse, RefundHistoryResponseValidator } from './models/RefundHistoryResponse';
import { SendTestNotificationResponse, SendTestNotificationResponseValidator } from './models/SendTestNotificationResponse';
import { StatusResponse, StatusResponseValidator } from './models/StatusResponse';
import { TransactionHistoryRequest } from './models/TransactionHistoryRequest';
import { TransactionInfoResponse, TransactionInfoResponseValidator } from './models/TransactionInfoResponse';
import { Validator } from './models/Validator';
import type { ExtendRenewalDateRequest } from './models/ExtendRenewalDateRequest';
import { type ExtendRenewalDateResponse, ExtendRenewalDateResponseValidator } from './models/ExtendRenewalDateResponse';
import { type HistoryResponse, HistoryResponseValidator } from './models/HistoryResponse';
import { type MassExtendRenewalDateRequest } from './models/MassExtendRenewalDateRequest';
import { type MassExtendRenewalDateResponse, MassExtendRenewalDateResponseValidator } from './models/MassExtendRenewalDateResponse';
import { type MassExtendRenewalDateStatusResponse, MassExtendRenewalDateStatusResponseValidator } from './models/MassExtendRenewalDateStatusResponse';
import { type OrderLookupResponse, OrderLookupResponseValidator } from './models/OrderLookupResponse';
import { type RefundHistoryResponse, RefundHistoryResponseValidator } from './models/RefundHistoryResponse';
import { type SendTestNotificationResponse, SendTestNotificationResponseValidator } from './models/SendTestNotificationResponse';
import { type StatusResponse, StatusResponseValidator } from './models/StatusResponse';
import { type TransactionHistoryRequest } from './models/TransactionHistoryRequest';
import { type TransactionInfoResponse, TransactionInfoResponseValidator } from './models/TransactionInfoResponse';
import type { Validator } from './models/Validator';
import { Status } from './models/Status';
export { SignedDataVerifier, VerificationException, VerificationStatus } from './jws_verification'
export { ReceiptUtility } from './receipt_utility'
export { AccountTenure } from "./models/AccountTenure"
export { AutoRenewStatus } from './models/AutoRenewStatus'
export { CheckTestNotificationResponse } from './models/CheckTestNotificationResponse'
export { ConsumptionRequest } from './models/ConsumptionRequest'
export type { CheckTestNotificationResponse } from './models/CheckTestNotificationResponse'
export type { ConsumptionRequest } from './models/ConsumptionRequest'
export { ConsumptionStatus } from './models/ConsumptionStatus'
export { Data } from './models/Data'
export type { Data } from './models/Data'
export { DeliveryStatus } from './models/DeliveryStatus'
export { Environment } from './models/Environment'
export { ExpirationIntent } from './models/ExpirationIntent'
export { ExtendReasonCode } from './models/ExtendReasonCode'
export { ExtendRenewalDateRequest } from './models/ExtendRenewalDateRequest'
export { ExtendRenewalDateResponse } from './models/ExtendRenewalDateResponse'
export type { ExtendRenewalDateRequest } from './models/ExtendRenewalDateRequest'
export type { ExtendRenewalDateResponse } from './models/ExtendRenewalDateResponse'
export { SendAttemptResult } from './models/SendAttemptResult'
export { SendAttemptItem } from './models/SendAttemptItem'
export { HistoryResponse } from './models/HistoryResponse'
export type { SendAttemptItem } from './models/SendAttemptItem'
export type { HistoryResponse } from './models/HistoryResponse'
export { InAppOwnershipType } from './models/InAppOwnershipType'
export { JWSRenewalInfoDecodedPayload } from './models/JWSRenewalInfoDecodedPayload'
export { JWSTransactionDecodedPayload } from './models/JWSTransactionDecodedPayload'
export { LastTransactionsItem } from './models/LastTransactionsItem'
export type { JWSRenewalInfoDecodedPayload } from './models/JWSRenewalInfoDecodedPayload'
export type { JWSTransactionDecodedPayload } from './models/JWSTransactionDecodedPayload'
export type { LastTransactionsItem } from './models/LastTransactionsItem'
export { LifetimeDollarsPurchased } from './models/LifetimeDollarsPurchased'
export { LifetimeDollarsRefunded } from './models/LifetimeDollarsRefunded'
export { MassExtendRenewalDateRequest } from './models/MassExtendRenewalDateRequest'
export { MassExtendRenewalDateResponse } from './models/MassExtendRenewalDateResponse'
export { MassExtendRenewalDateStatusResponse } from './models/MassExtendRenewalDateStatusResponse'
export { NotificationHistoryRequest } from './models/NotificationHistoryRequest'
export { NotificationHistoryResponse } from './models/NotificationHistoryResponse'
export { NotificationHistoryResponseItem } from './models/NotificationHistoryResponseItem'
export type { MassExtendRenewalDateRequest } from './models/MassExtendRenewalDateRequest'
export type { MassExtendRenewalDateResponse } from './models/MassExtendRenewalDateResponse'
export type { MassExtendRenewalDateStatusResponse } from './models/MassExtendRenewalDateStatusResponse'
export type { NotificationHistoryRequest } from './models/NotificationHistoryRequest'
export type { NotificationHistoryResponse } from './models/NotificationHistoryResponse'
export type { NotificationHistoryResponseItem } from './models/NotificationHistoryResponseItem'
export { NotificationTypeV2 } from './models/NotificationTypeV2'
export { OfferType } from './models/OfferType'
export { OfferDiscountType } from './models/OfferDiscountType'
export { OrderLookupResponse } from './models/OrderLookupResponse'
export type { OrderLookupResponse } from './models/OrderLookupResponse'
export { OrderLookupStatus } from './models/OrderLookupStatus'
export { Platform } from './models/Platform'
export { PlayTime } from './models/PlayTime'
export { PriceIncreaseStatus } from './models/PriceIncreaseStatus'
export { PurchasePlatform } from './models/PurchasePlatform'
export { RefundHistoryResponse } from './models/RefundHistoryResponse'
export { ResponseBodyV2 } from './models/ResponseBodyV2'
export { ResponseBodyV2DecodedPayload } from './models/ResponseBodyV2DecodedPayload'
export type { RefundHistoryResponse } from './models/RefundHistoryResponse'
export type { ResponseBodyV2 } from './models/ResponseBodyV2'
export type { ResponseBodyV2DecodedPayload } from './models/ResponseBodyV2DecodedPayload'
export { RevocationReason } from './models/RevocationReason'
export { SendTestNotificationResponse } from './models/SendTestNotificationResponse'
export type { SendTestNotificationResponse } from './models/SendTestNotificationResponse'
export { Status } from './models/Status'
export { StatusResponse } from './models/StatusResponse'
export { SubscriptionGroupIdentifierItem } from './models/SubscriptionGroupIdentifierItem'
export type { StatusResponse } from './models/StatusResponse'
export type { SubscriptionGroupIdentifierItem } from './models/SubscriptionGroupIdentifierItem'
export { Subtype } from './models/Subtype'
export { Summary } from './models/Summary'
export { TransactionHistoryRequest, Order, ProductType } from './models/TransactionHistoryRequest'
export { TransactionInfoResponse } from './models/TransactionInfoResponse'
export type { Summary } from './models/Summary'
export { type TransactionHistoryRequest, Order, ProductType } from './models/TransactionHistoryRequest'
export type { TransactionInfoResponse } from './models/TransactionInfoResponse'
export { TransactionReason } from './models/TransactionReason'
export { Type } from './models/Type'
export { UserStatus } from './models/UserStatus'
export { PromotionalOfferSignatureCreator } from './promotional_offer'
export { PromotionalOfferV2SignatureCreator, AdvancedCommerceInAppSignatureCreator, AdvancedCommerceInAppRequest, IntroductoryOfferEligibilitySignatureCreator } from './jws_signature_creator'
export { DecodedSignedData } from './models/DecodedSignedData'
export { AppTransaction } from './models/AppTransaction'
export { PromotionalOfferV2SignatureCreator, AdvancedCommerceInAppSignatureCreator, type AdvancedCommerceInAppRequest, IntroductoryOfferEligibilitySignatureCreator } from './jws_signature_creator'
export type { DecodedSignedData } from './models/DecodedSignedData'
export type { AppTransaction } from './models/AppTransaction'

import jsonwebtoken = require('jsonwebtoken');
import { NotificationHistoryRequest } from './models/NotificationHistoryRequest';
import { NotificationHistoryResponse, NotificationHistoryResponseValidator } from './models/NotificationHistoryResponse';
import type { NotificationHistoryRequest } from './models/NotificationHistoryRequest';
import { type NotificationHistoryResponse, NotificationHistoryResponseValidator } from './models/NotificationHistoryResponse';
import { URLSearchParams } from 'url';

export class AppStoreServerAPIClient {
34 changes: 21 additions & 13 deletions jws_verification.ts
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
import jsonwebtoken = require('jsonwebtoken');

import base64url from 'base64url';
import { KeyObject, X509Certificate, createHash, verify } from 'crypto';
import { KeyObject, X509Certificate, createHash, verify, webcrypto } from 'crypto';
import { KJUR, X509, ASN1HEX } from 'jsrsasign';
import fetch, { Headers } from 'node-fetch';
import { Environment } from './models/Environment';
@@ -13,6 +13,7 @@ import { JWSRenewalInfoDecodedPayload, JWSRenewalInfoDecodedPayloadValidator } f
import { Validator } from './models/Validator';
import { DecodedSignedData } from './models/DecodedSignedData';
import { AppTransaction, AppTransactionValidator } from './models/AppTransaction';
import { isCryptoKey } from 'util/types';

const MAX_SKEW = 60000

@@ -31,11 +32,11 @@ class CacheValue {

/**
* A class providing utility methods for verifying and decoding App Store signed data.
*
*
* Example Usage:
* ```ts
* const verifier = new SignedDataVerifier([appleRoot, appleRoot2], true, Environment.SANDBOX, "com.example")
*
*
* try {
* const decodedNotification = verifier.verifyAndDecodeNotification("ey...")
* console.log(decodedNotification)
@@ -58,8 +59,8 @@ export class SignedDataVerifier {
protected verifiedPublicKeyCache: { [index: string]: CacheValue }

/**
*
* @param appleRootCertificates A list of DER-encoded root certificates
*
* @param appleRootCertificates A list of DER-encoded root certificates
* @param enableOnlineChecks Whether to enable revocation checking and check expiration using the current date
* @param environment The App Store environment to target for checks
* @param bundleId The app's bundle identifier
@@ -176,6 +177,13 @@ export class SignedDataVerifier {
return decodedAppTransaction
}

protected getKeyFrom(publicKey: KeyObject | webcrypto.CryptoKey){
if (isCryptoKey(publicKey)) {
return KeyObject.from(publicKey)
}
return publicKey
}

protected async verifyJWT<T>(jwt: string, validator: Validator<T>, signedDateExtractor: (decodedJWT: T) => Date): Promise<T> {
let certificateChain;
let decodedJWT
@@ -227,7 +235,7 @@ export class SignedDataVerifier {
if (this.enableOnlineChecks) {
if (cacheKey in this.verifiedPublicKeyCache) {
if (this.verifiedPublicKeyCache[cacheKey].cacheExpiry > new Date().getTime()) {
return this.verifiedPublicKeyCache[cacheKey].publicKey
return this.getKeyFrom(this.verifiedPublicKeyCache[cacheKey].publicKey)
}
}
}
@@ -244,7 +252,7 @@ export class SignedDataVerifier {
}
}
}
return publicKey
return this.getKeyFrom(publicKey)
}

protected async verifyCertificateChainWithoutCaching(trustedRoots: X509Certificate[], leaf: X509Certificate, intermediate: X509Certificate, effectiveDate: Date): Promise<KeyObject> {
@@ -285,13 +293,13 @@ export class SignedDataVerifier {
const request = new KJUR.asn1.ocsp.OCSPRequest({reqList: [{issuerCert: issuer.toString(), subjectCert: cert.toString() , alg: "sha256"}]})
const headers = new Headers()
headers.append('Content-Type', 'application/ocsp-request')

const response = await fetch(matchResult[1], {
headers: headers,
method: 'POST',
body: Buffer.from(request.getEncodedHex(), 'hex')
})

const responseBuffer = await response.buffer()
const parsedResponse = new (KJUR.asn1.ocsp as any).OCSPParser().getOCSPResponse(responseBuffer.toString('hex'))
// The issuer could also be the signer
@@ -337,7 +345,7 @@ export class SignedDataVerifier {
} else {
throw new VerificationException(VerificationStatus.INVALID_CERTIFICATE)
}

// Extract raw responseData
const responseData = ASN1HEX.getTLVbyList(responseBuffer.toString('hex'), 0, [1, 0, 1, 0, 0]) as string
// Verify Payload signed by cert
@@ -349,7 +357,7 @@ export class SignedDataVerifier {
if (!verify(shortAlg, Buffer.from(responseData, 'hex'), signingCert.publicKey, Buffer.from(parsedResponse.sighex, 'hex'))) {
throw new VerificationException(VerificationStatus.FAILURE)
}

for (const singleResponse of parsedResponse.array) {
// Confirm entry is for this cert
const certIdBuilder = new KJUR.asn1.ocsp.CertID() as any
@@ -361,7 +369,7 @@ export class SignedDataVerifier {
// Validate contents
const issueDate = this.parseX509Date(singleResponse.thisupdate)
const nextDate = this.parseX509Date(singleResponse.nextupdate)

if (singleResponse.status.status !== 'good' || new Date().getTime() - MAX_SKEW < issueDate.getTime() || nextDate.getTime() < new Date().getTime() + MAX_SKEW) {
throw new VerificationException(VerificationStatus.FAILURE)
}
@@ -409,4 +417,4 @@ export class VerificationException extends Error {
this.status = status
this.cause = cause
}
}
}
2 changes: 1 addition & 1 deletion models/ExtendRenewalDateRequest.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2023 Apple Inc. Licensed under MIT License.

import { ExtendReasonCode, ExtendReasonCodeValidator } from "./ExtendReasonCode"
import { ExtendReasonCode } from "./ExtendReasonCode"

/**
* The request body that contains subscription-renewal-extension data for an individual subscription.
2 changes: 1 addition & 1 deletion models/MassExtendRenewalDateRequest.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2023 Apple Inc. Licensed under MIT License.

import { ExtendReasonCode, ExtendReasonCodeValidator } from "./ExtendReasonCode";
import { ExtendReasonCode } from "./ExtendReasonCode";

/**
* The request body that contains subscription-renewal-extension data to apply for all eligible active subscribers.
2 changes: 1 addition & 1 deletion models/NotificationTypeV2.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2023 Apple Inc. Licensed under MIT License.

import { StringValidator, Validator } from "./Validator";
import { StringValidator } from "./Validator";

/**
* The type that describes the in-app purchase or external purchase event for which the App Store sends the version 2 notification.
6 changes: 3 additions & 3 deletions tests/unit-tests/jws_verification.test.ts
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ import { readFile, getSignedPayloadVerifierWithDefaultAppAppleId, getDefaultSign

const ROOT_CA_BASE64_ENCODED = "MIIBgjCCASmgAwIBAgIJALUc5ALiH5pbMAoGCCqGSM49BAMDMDYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8wHhcNMjMwMTA1MjEzMDIyWhcNMzMwMTAyMjEzMDIyWjA2MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc+/Bl+gospo6tf9Z7io5tdKdrlN1YdVnqEhEDXDShzdAJPQijamXIMHf8xWWTa1zgoYTxOKpbuJtDplz1XriTaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDRwAwRAIgemWQXnMAdTad2JDJWng9U4uBBL5mA7WI05H7oH7c6iQCIHiRqMjNfzUAyiu9h6rOU/K+iTR0I/3Y/NSWsXHX+acc";
const INTERMEDIATE_CA_BASE64_ENCODED = "MIIBnzCCAUWgAwIBAgIBCzAKBggqhkjOPQQDAzA2MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMB4XDTIzMDEwNTIxMzEwNVoXDTMzMDEwMTIxMzEwNVowRTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRIwEAYDVQQHDAlDdXBlcnRpbm8xFTATBgNVBAoMDEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBUN5V9rKjfRiMAIojEA0Av5Mp0oF+O0cL4gzrTF178inUHugj7Et46NrkQ7hKgMVnjogq45Q1rMs+cMHVNILWqjNTAzMA8GA1UdEwQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMBAGCiqGSIb3Y2QGAgEEAgUAMAoGCCqGSM49BAMDA0gAMEUCIQCmsIKYs41ullssHX4rVveUT0Z7Is5/hLK1lFPTtun3hAIgc2+2RG5+gNcFVcs+XJeEl4GZ+ojl3ROOmll+ye7dynQ=";
const LEAF_CERT_BASE64_ENCODED = "MIIBoDCCAUagAwIBAgIBDDAKBggqhkjOPQQDAzBFMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCUN1cGVydGlubzEVMBMGA1UECgwMSW50ZXJtZWRpYXRlMB4XDTIzMDEwNTIxMzEzNFoXDTMzMDEwMTIxMzEzNFowPTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRIwEAYDVQQHDAlDdXBlcnRpbm8xDTALBgNVBAoMBExlYWYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATitYHEaYVuc8g9AjTOwErMvGyPykPa+puvTI8hJTHZZDLGas2qX1+ErxgQTJgVXv76nmLhhRJH+j25AiAI8iGsoy8wLTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDAQBgoqhkiG92NkBgsBBAIFADAKBggqhkjOPQQDAwNIADBFAiBX4c+T0Fp5nJ5QRClRfu5PSByRvNPtuaTsk0vPB3WAIAIhANgaauAj/YP9s0AkEhyJhxQO/6Q2zouZ+H1CIOehnMzQ";
const LEAF_CERT_BASE64_ENCODED = "MIIBoDCCAUagAwIBAgIBDDAKBggqhkjOPQQDAzBFMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCUN1cGVydGlubzEVMBMGA1UECgwMSW50ZXJtZWRpYXRlMB4XDTIzMDEwNTIxMzEzNFoXDTMzMDEwMTIxMzEzNFowPTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRIwEAYDVQQHDAlDdXBlcnRpbm8xDTALBgNVBAoMBExlYWYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATitYHEaYVuc8g9AjTOwErMvGyPykPa+puvTI8hJTHZZDLGas2qX1+ErxgQTJgVXv76nmLhhRJH+j25AiAI8iGsoy8wLTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDAQBgoqhkiG92NkBgsBBAIFADAKBggqhkjOPQQDAwNIADBFAiBX4c+T0Fp5nJ5QRClRfu5PSByRvNPtuaTsk0vPB3WAIAIhANgaauAj/YP9s0AkEhyJhxQO/6Q2zouZ+H1CIOehnMzQ";

const INTERMEDIATE_CA_INVALID_OID_BASE64_ENCODED = "MIIBnjCCAUWgAwIBAgIBDTAKBggqhkjOPQQDAzA2MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMB4XDTIzMDEwNTIxMzYxNFoXDTMzMDEwMTIxMzYxNFowRTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRIwEAYDVQQHDAlDdXBlcnRpbm8xFTATBgNVBAoMDEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBUN5V9rKjfRiMAIojEA0Av5Mp0oF+O0cL4gzrTF178inUHugj7Et46NrkQ7hKgMVnjogq45Q1rMs+cMHVNILWqjNTAzMA8GA1UdEwQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMBAGCiqGSIb3Y2QGAgIEAgUAMAoGCCqGSM49BAMDA0cAMEQCIFROtTE+RQpKxNXETFsf7Mc0h+5IAsxxo/X6oCC/c33qAiAmC5rn5yCOOEjTY4R1H1QcQVh+eUwCl13NbQxWCuwxxA==";
const LEAF_CERT_FOR_INTERMEDIATE_CA_INVALID_OID_BASE64_ENCODED = "MIIBnzCCAUagAwIBAgIBDjAKBggqhkjOPQQDAzBFMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCUN1cGVydGlubzEVMBMGA1UECgwMSW50ZXJtZWRpYXRlMB4XDTIzMDEwNTIxMzY1OFoXDTMzMDEwMTIxMzY1OFowPTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRIwEAYDVQQHDAlDdXBlcnRpbm8xDTALBgNVBAoMBExlYWYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATitYHEaYVuc8g9AjTOwErMvGyPykPa+puvTI8hJTHZZDLGas2qX1+ErxgQTJgVXv76nmLhhRJH+j25AiAI8iGsoy8wLTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDAQBgoqhkiG92NkBgsBBAIFADAKBggqhkjOPQQDAwNHADBEAiAUAs+gzYOsEXDwQquvHYbcVymyNqDtGw9BnUFp2YLuuAIgXxQ3Ie9YU0cMqkeaFd+lyo0asv9eyzk6stwjeIeOtTU=";
@@ -35,7 +35,7 @@ class SignedJWTVerifierTest extends SignedDataVerifier {

getRootCertificates() {
return this.rootCertificates
}
}
}

describe("Chain Verification Checks", () => {
@@ -271,4 +271,4 @@ describe("Decoding checks", () => {
const notification = await verifier.verifyAndDecodeRenewalInfo(transactionInfo)
expect(notification.environment).toEqual(Environment.SANDBOX)
})
});
});