From b76d74c9ca4b9d8882b6ed0a7d81b252a394e2c0 Mon Sep 17 00:00:00 2001 From: Fred Chen Date: Mon, 24 Oct 2022 15:51:35 +0800 Subject: [PATCH 1/2] CU-3q8w246 - Refine the file storage on browser to IndexedDB. --- src/abstractmetadata.ts | 24 +- src/conflicthandle.ts | 6 +- src/credentialmetadata.ts | 16 +- src/defaultconflicthandle.ts | 4 +- src/didbackend.ts | 22 +- src/diddocument.ts | 26 +- src/didentity.ts | 6 +- src/didmetadata.ts | 32 +- src/didstorage.ts | 70 ++-- src/didstore.ts | 192 ++++----- src/didstoremetadata.ts | 28 +- src/file.ts | 124 +++--- src/filesystemstorage.ts | 484 ++++++++++++----------- src/fs.browser.ts | 114 ++++-- src/fs.ts | 123 +++++- src/issuer.ts | 30 +- src/rootidentity.ts | 90 ++--- src/transferticket.ts | 2 +- src/verifiablecredential.ts | 2 +- src/verifiablepresentation.ts | 2 +- tests/src-no-jest/index.ts | 4 +- tests/src/diddocument.test.ts | 58 +-- tests/src/didstore.test.ts | 274 ++++++------- tests/src/idchainoperations.test.ts | 88 ++--- tests/src/issuer.test.ts | 32 +- tests/src/jwt/jwt.test.ts | 6 +- tests/src/mnemonic.test.ts | 10 +- tests/src/rootidentity.test.ts | 36 +- tests/src/transferticket.test.ts | 2 +- tests/src/utils/browserdataimport.ts | 19 +- tests/src/utils/testdata.ts | 112 +++--- tests/src/utils/utils.ts | 24 +- tests/src/verifiablecredential.test.ts | 8 +- tests/src/verifiablepresentation.test.ts | 2 +- 34 files changed, 1124 insertions(+), 948 deletions(-) diff --git a/src/abstractmetadata.ts b/src/abstractmetadata.ts index aeed6591..bbaf8070 100644 --- a/src/abstractmetadata.ts +++ b/src/abstractmetadata.ts @@ -47,7 +47,7 @@ export abstract class AbstractMetadata extends DIDEntity imple * * @param store the DIDStore */ - constructor(store?: DIDStore) { + protected constructor(store?: DIDStore) { super(); this.store = store; this.props = {}; @@ -89,13 +89,13 @@ export abstract class AbstractMetadata extends DIDEntity imple return this.props[name]; } - protected put(name: string, value: JSONValue | Date ) { + protected put(name: string, value: JSONValue | Date ): Promise { if (value === null || value === undefined) delete this.props[name]; else this.props[name] = value instanceof Date ? value.toISOString() : value; - this.save(); + return this.save(); } protected getBoolean(name: string, defaultValue: boolean = false): boolean { @@ -127,10 +127,10 @@ export abstract class AbstractMetadata extends DIDEntity imple return value; } - protected remove(name: string): any { + protected async remove(name: string): Promise { let value = this.props[name]; delete this.props[name]; - this.save(); + await this.save(); return value; } @@ -143,8 +143,8 @@ export abstract class AbstractMetadata extends DIDEntity imple * * @param alias alias string */ - public setAlias(alias: string) { - this.put(AbstractMetadata.ALIAS, alias); + public setAlias(alias: string): Promise { + return this.put(AbstractMetadata.ALIAS, alias); } /** @@ -162,9 +162,9 @@ export abstract class AbstractMetadata extends DIDEntity imple * @param key the key string * @param value the value */ - public setExtra(key: string, value: any) { + public setExtra(key: string, value: any): Promise { checkArgument(key != null && key != "", "Invalid key"); - this.put(AbstractMetadata.USER_EXTRA_PREFIX + key, value); + return this.put(AbstractMetadata.USER_EXTRA_PREFIX + key, value); } /** @@ -193,9 +193,9 @@ export abstract class AbstractMetadata extends DIDEntity imple return this.getDate(AbstractMetadata.USER_EXTRA_PREFIX + key, defaultValue); } - public removeExtra(key: string): string { + public async removeExtra(key: string): Promise { checkArgument(key && key != null, "Invalid key"); - return this.remove(AbstractMetadata.USER_EXTRA_PREFIX + key); + return await this.remove(AbstractMetadata.USER_EXTRA_PREFIX + key); } /** @@ -233,5 +233,5 @@ export abstract class AbstractMetadata extends DIDEntity imple this.props = JSON.parse(JSON.stringify(json)); } - protected abstract save(); + protected abstract save(): Promise; } diff --git a/src/conflicthandle.ts b/src/conflicthandle.ts index 57236754..56be2a5c 100644 --- a/src/conflicthandle.ts +++ b/src/conflicthandle.ts @@ -20,13 +20,13 @@ * SOFTWARE. */ -import type { DIDDocument } from "./internals"; +import type {DIDDocument} from "./internals"; /** * The interface for ConflictHandle to indicate how to resolve the conflict, * if the local document is different with the one resolved from chain. */ - export interface ConflictHandle { +export interface ConflictHandle { /** * The method to merge two did document. * @@ -34,5 +34,5 @@ import type { DIDDocument } from "./internals"; * @param localCopy the document from local device * @return the merged DIDDocument object */ - merge(chainCopy: DIDDocument, localCopy: DIDDocument): DIDDocument; + merge(chainCopy: DIDDocument, localCopy: DIDDocument): Promise; } diff --git a/src/credentialmetadata.ts b/src/credentialmetadata.ts index a6ae59df..d1ba0ec7 100644 --- a/src/credentialmetadata.ts +++ b/src/credentialmetadata.ts @@ -67,8 +67,8 @@ export class CredentialMetadata extends AbstractMetadata implements Cloneable { + return this.put(CredentialMetadata.TXID, txid); } /** @@ -85,10 +85,10 @@ export class CredentialMetadata extends AbstractMetadata implements Cloneable { checkArgument(timestamp != null, "Invalid timestamp"); - this.put(CredentialMetadata.PUBLISHED, timestamp); + return this.put(CredentialMetadata.PUBLISHED, timestamp); } /** @@ -105,8 +105,8 @@ export class CredentialMetadata extends AbstractMetadata implements Cloneable { + return this.put(CredentialMetadata.REVOKED, revoked); } /** @@ -135,10 +135,10 @@ export class CredentialMetadata extends AbstractMetadata implements Cloneable { if (this.attachedStore()) { try { - this.getStore().storeCredentialMetadata(this.id, this); + await this.getStore().storeCredentialMetadata(this.id, this); } catch (e) { // DIDStoreException CredentialMetadata.log.error("INTERNAL - error store metadata for credential {}", this.id); diff --git a/src/defaultconflicthandle.ts b/src/defaultconflicthandle.ts index b475ac91..58ee7713 100644 --- a/src/defaultconflicthandle.ts +++ b/src/defaultconflicthandle.ts @@ -35,7 +35,7 @@ export class DefaultConflictHandle implements ConflictHandle { return DefaultConflictHandle.instance; } - public merge(chainDoc: DIDDocument, localDoc: DIDDocument): DIDDocument { - return localDoc; + public merge(chainDoc: DIDDocument, localDoc: DIDDocument): Promise { + return Promise.resolve(localDoc); } } \ No newline at end of file diff --git a/src/didbackend.ts b/src/didbackend.ts index f05bd612..6e47e57a 100644 --- a/src/didbackend.ts +++ b/src/didbackend.ts @@ -309,11 +309,11 @@ export class DIDBackend { let doc = tx.getRequest().getDocument().clone(); await doc.resolveControllers(); let metadata = doc.getMetadata(); - metadata.setTransactionId(tx.getTransactionId()); - metadata.setSignature(doc.getProof().getSignature()); - metadata.setPublished(tx.getTimestamp()); + await metadata.setTransactionId(tx.getTransactionId()); + await metadata.setSignature(doc.getProof().getSignature()); + await metadata.setPublished(tx.getTimestamp()); if (bio.getStatus().equals(DIDBiographyStatus.DEACTIVATED)) - metadata.setDeactivated(true); + await metadata.setDeactivated(true); return doc; } @@ -367,11 +367,11 @@ export class DIDBackend { let doc = tx.getRequest().getDocument().clone(); await doc.resolveControllers(); let metadata = doc.getMetadata(); - metadata.setTransactionId(tx.getTransactionId()); - metadata.setSignature(doc.getProof().getSignature()); - metadata.setPublished(tx.getTimestamp()); + await metadata.setTransactionId(tx.getTransactionId()); + await metadata.setSignature(doc.getProof().getSignature()); + await metadata.setPublished(tx.getTimestamp()); if (bio.getStatus() == DIDBiographyStatus.DEACTIVATED) - metadata.setDeactivated(true); + await metadata.setDeactivated(true); return doc; } @@ -447,10 +447,10 @@ export class DIDBackend { let vc = tx.getRequest().getCredential(); let metadata = new CredentialMetadata(vc.getId()); - metadata.setTransactionId(tx.getTransactionId()); - metadata.setPublished(tx.getTimestamp()); + await metadata.setTransactionId(tx.getTransactionId()); + await metadata.setPublished(tx.getTimestamp()); if (bio.getStatus() == CredentialBiographyStatus.REVOKED) - metadata.setRevoked(true); + await metadata.setRevoked(true); vc.setMetadata(metadata); return vc; } diff --git a/src/diddocument.ts b/src/diddocument.ts index c8edd3e1..ff105401 100644 --- a/src/diddocument.ts +++ b/src/diddocument.ts @@ -364,14 +364,14 @@ export class DIDDocument extends DIDEntity { * @return the key exists or not * @throws DIDStoreException there is no store */ - public hasPrivateKey(idOrString: DIDURL | string): boolean { + public async hasPrivateKey(idOrString: DIDURL | string): Promise { if (typeof idOrString === "string") idOrString = this.canonicalId(idOrString); checkArgument(idOrString != null, "Invalid publicKey id"); if (this.hasPublicKey(idOrString) && this.getMetadata().attachedStore()) - return this.getMetadata().getStore().containsPrivateKey(idOrString); + return await this.getMetadata().getStore().containsPrivateKey(idOrString); else return false; } @@ -1258,7 +1258,7 @@ export class DIDDocument extends DIDEntity { let deactivated = bio.getStatus() == DIDBiographyStatus.DEACTIVATED; if (deactivated) - this.getMetadata().setDeactivated(deactivated); + await this.getMetadata().setDeactivated(deactivated); return deactivated; } @@ -1605,7 +1605,7 @@ export class DIDDocument extends DIDEntity { key = doc.canonicalId(keyid); let store = doc.getMetadata().getStore(); - if (!store.containsPrivateKey(key)) + if (!await store.containsPrivateKey(key)) return null; let hk = HDKey.deserialize(await store.loadPrivateKey(key, password)); @@ -1795,7 +1795,7 @@ export class DIDDocument extends DIDEntity { let resolvedDoc = await this.getSubject().resolve(true); if (resolvedDoc != null) { if (await resolvedDoc.isDeactivated()) { - this.getMetadata().setDeactivated(true); + await this.getMetadata().setDeactivated(true); DIDDocument.log.error("Publish failed because DID is deactivated."); throw new DIDDeactivatedException(this.getSubject().toString() + " is deactivated"); @@ -1868,8 +1868,8 @@ export class DIDDocument extends DIDEntity { } if (resolvedSignature != null) - this.getMetadata().setPreviousSignature(resolvedSignature); - this.getMetadata().setSignature(this.getProof().getSignature()); + await this.getMetadata().setPreviousSignature(resolvedSignature); + await this.getMetadata().setSignature(this.getProof().getSignature()); } // TODO: to be remove in the future @@ -1903,7 +1903,7 @@ export class DIDDocument extends DIDEntity { let resolvedDoc = await DIDBackend.getInstance().resolveUntrustedDid(this.getSubject(), true); if (resolvedDoc != null) { if (await resolvedDoc.isDeactivated()) { - this.getMetadata().setDeactivated(true); + await this.getMetadata().setDeactivated(true); DIDDocument.log.error("Publish failed because DID is deactivated."); throw new DIDDeactivatedException(this.getSubject().toString() + " is deactivated"); @@ -1929,8 +1929,8 @@ export class DIDDocument extends DIDEntity { } if (resolvedSignature != null) - this.getMetadata().setPreviousSignature(resolvedSignature); - this.getMetadata().setSignature(this.getProof().getSignature()); + await this.getMetadata().setPreviousSignature(resolvedSignature); + await this.getMetadata().setSignature(this.getProof().getSignature()); } @@ -2851,7 +2851,7 @@ export namespace DIDDocument { * @param force the owner of public key * @return the DID Document Builder object */ - public removePublicKey(id: DIDURL | string, force = false): Builder { + public async removePublicKey(id: DIDURL | string, force = false): Promise { this.checkNotSealed(); checkArgument(id != null, "Invalid publicKey id"); @@ -2879,7 +2879,7 @@ export namespace DIDDocument { try { // TODO: should delete the loosed private key when store the document if (this.document.getMetadata().attachedStore()) - this.document.getMetadata().getStore().deletePrivateKey(id); + await this.document.getMetadata().getStore().deletePrivateKey(id); } catch (ignore) { // DIDStoreException Builder.log.error("INTERNAL - Remove private key", ignore); @@ -3196,7 +3196,7 @@ export namespace DIDDocument { "Invalid publicKey id"); checkArgument(storepass && storepass != null, "Invalid storepass"); - let issuer = new Issuer(this.document); + let issuer = await Issuer.create(this.document); let cb = issuer.issueFor(this.document.getSubject()); if (expirationDate == null) diff --git a/src/didentity.ts b/src/didentity.ts index 9e32bde1..c43d0d03 100644 --- a/src/didentity.ts +++ b/src/didentity.ts @@ -76,6 +76,10 @@ export abstract class DIDEntity { * @throws DIDSyntaxException if a parse error occurs */ protected static deserialize>(source: JSONObject | string, type: (new () => T), context: DID = null): T { + return this.deserializeWithObj(source, new type(), context); + } + + protected static deserializeWithObj>(source: JSONObject | string, obj: T, context: DID = null): T { checkArgument(source && source !== "", "Invalid JSON content"); let content: JSONObject; @@ -85,9 +89,7 @@ export abstract class DIDEntity { content = source; } - let obj = new type(); obj.fromJSON(content, context); - return obj; } diff --git a/src/didmetadata.ts b/src/didmetadata.ts index 25af6c06..361f4ee3 100644 --- a/src/didmetadata.ts +++ b/src/didmetadata.ts @@ -56,16 +56,16 @@ export class DIDMetadata extends AbstractMetadata implements Cloneable { + return this.put(DIDMetadata.ROOT_IDENTITY, id); } public getRootIdentityId(): string { return this.get(DIDMetadata.ROOT_IDENTITY) as string; } - public setIndex(index: number) { - this.put(DIDMetadata.INDEX, index); + public setIndex(index: number): Promise { + return this.put(DIDMetadata.INDEX, index); } public getIndex(): number { @@ -77,8 +77,8 @@ export class DIDMetadata extends AbstractMetadata implements Cloneable { + return this.put(DIDMetadata.TXID, txid); } /** @@ -95,8 +95,8 @@ export class DIDMetadata extends AbstractMetadata implements Cloneable { + return this.put(DIDMetadata.PREV_SIGNATURE, signature); } /** @@ -113,8 +113,8 @@ export class DIDMetadata extends AbstractMetadata implements Cloneable { + return this.put(DIDMetadata.SIGNATURE, signature); } /** @@ -131,8 +131,8 @@ export class DIDMetadata extends AbstractMetadata implements Cloneable { + return this.put(DIDMetadata.PUBLISHED, timestamp); } /** @@ -153,8 +153,8 @@ export class DIDMetadata extends AbstractMetadata implements Cloneable { + return this.put(DIDMetadata.DEACTIVATED, deactivated); } /** @@ -181,10 +181,10 @@ export class DIDMetadata extends AbstractMetadata implements Cloneable { if (this.attachedStore()) { try { - this.getStore().storeDidMetadata(this.did, this); + await this.getStore().storeDidMetadata(this.did, this); } catch (e) { if (e instanceof DIDStoreException) console.log("INTERNAL - error store metadata for DID {}", this.did); diff --git a/src/didstorage.ts b/src/didstorage.ts index cebb21d1..3b565f89 100644 --- a/src/didstorage.ts +++ b/src/didstorage.ts @@ -49,11 +49,11 @@ export interface ReEncryptor { export interface DIDStorage { getLocation(): string; - storeMetadata(metadata: DIDStoreMetadata); + storeMetadata(metadata: DIDStoreMetadata): Promise; - loadMetadata(): DIDStoreMetadata; + loadMetadata(): Promise; - storeRootIdentityMetadata(id: string, metadata: RootIdentity.Metadata); + storeRootIdentityMetadata(id: string, metadata: RootIdentity.Metadata): Promise; /** * Load DID Metadata. @@ -62,7 +62,7 @@ export interface DIDStorage { * @return the meta data * @throws DIDStorageException DIDStorage error. */ - loadRootIdentityMetadata(id: string): RootIdentity.Metadata; + loadRootIdentityMetadata(id: string): Promise; /** * Save the raw root identity to the storage. @@ -74,7 +74,7 @@ export interface DIDStorage { * @param index the index hint for DID deriving * @throws DIDStorageException if an error occurred when accessing the DID storage */ - storeRootIdentity(id: string, mnemonic: string, privateKey: string, publicKey: string, index: number); + storeRootIdentity(id: string, mnemonic: string, privateKey: string, publicKey: string, index: number): Promise; /** * Read the RootIdentity object from the storage. @@ -83,13 +83,13 @@ export interface DIDStorage { * @return the RootIdentity object * @throws DIDStorageException if an error occurred when accessing the DID storage */ - loadRootIdentity(id: string): RootIdentity; + loadRootIdentity(id: string): Promise; - containsRootIdentity(id: string): boolean; + containsRootIdentity(id: string): Promise; - updateRootIdentityIndex(id: string, index: number); + updateRootIdentityIndex(id: string, index: number): Promise; - loadRootIdentityPrivateKey(id: string): string; + loadRootIdentityPrivateKey(id: string): Promise; /** * Read the mnemonic that generate the RootIdentity. @@ -98,13 +98,13 @@ export interface DIDStorage { * @return the mnemonic string or null if not exists * @throws DIDStorageException if an error occurred when accessing the DID storage */ - loadRootIdentityMnemonic(id: string): string; + loadRootIdentityMnemonic(id: string): Promise; - deleteRootIdentity(id: string): boolean; + deleteRootIdentity(id: string): Promise; - listRootIdentities(): RootIdentity[]; + listRootIdentities(): Promise; - containsRootIdenities(): boolean; + containsRootIdenities(): Promise; /** * Save the DID metadata object to this storage. @@ -113,7 +113,7 @@ export interface DIDStorage { * @param metadata a DIDMetadata object * @throws DIDStorageException if an error occurred when accessing the DID storage */ - storeDidMetadata(did: DID, metadata: DIDMetadata); + storeDidMetadata(did: DID, metadata: DIDMetadata): Promise; /** * Read the DID metadata object from this storage. @@ -122,7 +122,7 @@ export interface DIDStorage { * @return the DIDMetadata object * @throws DIDStorageException if an error occurred when accessing the DID storage */ - loadDidMetadata(did: DID): DIDMetadata; + loadDidMetadata(did: DID): Promise; /** * Save the DID document to this storage. @@ -130,7 +130,7 @@ export interface DIDStorage { * @param doc a DIDDocument object * @throws DIDStorageException if an error occurred when accessing the DID storage */ - storeDid(doc: DIDDocument); + storeDid(doc: DIDDocument): Promise; /** * Read the DID document from this storage. @@ -149,7 +149,7 @@ export interface DIDStorage { * the returned value is false if deleting is failed. * @throws DIDStorageException DIDStorage error. */ - deleteDid(did: DID): boolean; + deleteDid(did: DID): Promise; /** * List all DIDs according to the specified condition. @@ -157,7 +157,7 @@ export interface DIDStorage { * @return the DID array. * @throws DIDStorageException DIDStorage error. */ - listDids(): DID[]; + listDids(): Promise; /** * Check whether this storage contains the specificed did. @@ -165,7 +165,7 @@ export interface DIDStorage { * @return true if contains the specificed did, false otherwise * @throws DIDStorageException DIDStorage error. */ - containsDid(did: DID): boolean; + containsDid(did: DID): Promise; /** * Check whether this storage contains the dids. @@ -173,7 +173,7 @@ export interface DIDStorage { * @return true if contains did object, false otherwise * @throws DIDStorageException DIDStorage error. */ - containsDids(): boolean; + containsDids(): Promise; /** * Save the credential's metadata to this storage. @@ -182,7 +182,7 @@ export interface DIDStorage { * @param metadata the credential's metadata object * @throws DIDStorageException if an error occurred when accessing the DID storage */ - storeCredentialMetadata(id: DIDURL, metadata: CredentialMetadata); + storeCredentialMetadata(id: DIDURL, metadata: CredentialMetadata): Promise; /** * Read the credential's metadata object from this storage. @@ -191,7 +191,7 @@ export interface DIDStorage { * @return the credential's metadata object * @throws DIDStorageException if an error occurred when accessing the DID storage */ - loadCredentialMetadata(id: DIDURL): CredentialMetadata; + loadCredentialMetadata(id: DIDURL): Promise; /** * Save the credential object to this storage. @@ -199,7 +199,7 @@ export interface DIDStorage { * @param credential a VerifiableCredential object * @throws DIDStorageException if an error occurred when accessing the DID storage */ - storeCredential(credential: VerifiableCredential); + storeCredential(credential: VerifiableCredential): Promise; /** * Read the specified credential object from this storage. @@ -208,7 +208,7 @@ export interface DIDStorage { * @return the VerifiableCredential object * @throws DIDStorageException if an error occurred when accessing the DID storage */ - loadCredential(id: DIDURL): VerifiableCredential; + loadCredential(id: DIDURL): Promise; /** * Check whether this storage contains the specified credential. @@ -217,7 +217,7 @@ export interface DIDStorage { * @return true if contains credential object, false otherwise * @throws DIDStorageException if an error occurred when accessing the DID storage */ - containsCredential(id: DIDURL): boolean; + containsCredential(id: DIDURL): Promise; /** * Check whether this storage contains the credentials that owned by the @@ -228,7 +228,7 @@ export interface DIDStorage { * false otherwise * @throws DIDStorageException if an error occurred when accessing the DID storage */ - containsCredentials(did: DID): boolean; + containsCredentials(did: DID): Promise; /** * Delete the specified credential from this storage. @@ -237,7 +237,7 @@ export interface DIDStorage { * @return true if the credential exists and deleted successful, false otherwise * @throws DIDStorageException if an error occurred when accessing the DID storage */ - deleteCredential(id: DIDURL): boolean; + deleteCredential(id: DIDURL): Promise; /** * List the Credentials owned the specified DID. @@ -246,9 +246,9 @@ export interface DIDStorage { * @return the Credential array owned the specified DID. * @throws DIDStorageException DIDStorage error. */ - listCredentials(did: DID): DIDURL[]; + listCredentials(did: DID): Promise; - containsPrivateKey(id: DIDURL): boolean; + containsPrivateKey(id: DIDURL): Promise; /** * Save the encrypted private key to this storage. * @@ -256,7 +256,7 @@ export interface DIDStorage { * @param privateKey the encrypted private key * @throws DIDStorageException if an error occurred when accessing the DID storage */ - storePrivateKey(id: DIDURL, privateKey: string); + storePrivateKey(id: DIDURL, privateKey: string): Promise; /** * Read the encrypted private key from this storage @@ -265,7 +265,7 @@ export interface DIDStorage { * @return the encrypted private key * @throws DIDStorageException if an error occurred when accessing the DID storage */ - loadPrivateKey(id: DIDURL): string; + loadPrivateKey(id: DIDURL): Promise; /** * Check whether this storage contains the private key that owned by the @@ -276,7 +276,7 @@ export interface DIDStorage { * false otherwise * @throws DIDStorageException if an error occurred when accessing the DID storage */ - containsPrivateKeys(did: DID): boolean; + containsPrivateKeys(did: DID): Promise; /** * Delete the specific private key from this storage. @@ -285,7 +285,7 @@ export interface DIDStorage { * @return true if the key exists and deleted successful, false otherwise * @throws DIDStorageException if an error occurred when accessing the DID storage */ - deletePrivateKey(id: DIDURL): boolean; + deletePrivateKey(id: DIDURL): Promise; /** * List the private keys owned the specified DID. @@ -294,7 +294,7 @@ export interface DIDStorage { * @return the private key array owned the specified DID. * @throws DIDStorageException DIDStorage error. */ - listPrivateKeys(did: DID): DIDURL[]; + listPrivateKeys(did: DID): Promise; /** * Change password for DIDStore. @@ -302,5 +302,5 @@ export interface DIDStorage { * @param reEncryptor the ReEncryptor handle * @throws DIDStorageException DIDStorage error. */ - changePassword(reEncryptor: ReEncryptor); + changePassword(reEncryptor: ReEncryptor): Promise; } diff --git a/src/didstore.ts b/src/didstore.ts index d322427f..1076c4b2 100644 --- a/src/didstore.ts +++ b/src/didstore.ts @@ -164,7 +164,7 @@ export class DIDStore { return newSecret; } - private encrypt(input: Buffer, passwd: string): string { + private async encrypt(input: Buffer, passwd: string): Promise { let fingerprint = this.metadata.getFingerprint(); let currentFingerprint = DIDStore.calcFingerprint(passwd); @@ -174,24 +174,24 @@ export class DIDStore { let result = DIDStore.encryptToBase64(input, passwd); if (fingerprint == null || fingerprint === "") - this.metadata.setFingerprint(currentFingerprint); + await this.metadata.setFingerprint(currentFingerprint); return result; } - private decrypt(input: string, passwd: string): Buffer { + private async decrypt(input: string, passwd: string): Promise { let fingerprint = this.metadata.getFingerprint(); let currentFingerprint = DIDStore.calcFingerprint(passwd); let result = DIDStore.decryptFromBase64(input, passwd); if (fingerprint == null || fingerprint === "") - this.metadata.setFingerprint(currentFingerprint); + await this.metadata.setFingerprint(currentFingerprint); return result; } - public storeRootIdentity(identity: RootIdentity, storepass: string = undefined) { + public async storeRootIdentity(identity: RootIdentity, storepass: string = undefined): Promise { checkArgument(identity != null, "Invalid identity"); if (storepass !== undefined) { @@ -199,33 +199,33 @@ export class DIDStore { let encryptedMnemonic = null; if (identity.getMnemonic() != null) - encryptedMnemonic = this.encrypt(Buffer.from(identity.getMnemonic(), 'utf8'), storepass); + encryptedMnemonic = await this.encrypt(Buffer.from(identity.getMnemonic(), 'utf8'), storepass); - let encryptedPrivateKey = this.encrypt(identity.getRootPrivateKey().serialize(), storepass); + let encryptedPrivateKey = await this.encrypt(identity.getRootPrivateKey().serialize(), storepass); let publicKey = identity.getPreDerivedPublicKey().serializePublicKeyBase58(); - this.storage.storeRootIdentity(identity.getId(), encryptedMnemonic, + await this.storage.storeRootIdentity(identity.getId(), encryptedMnemonic, encryptedPrivateKey, publicKey, identity.getIndex()); if (this.metadata.getDefaultRootIdentity() == null) - this.metadata.setDefaultRootIdentity(identity.getId()); + await this.metadata.setDefaultRootIdentity(identity.getId()); this.cache.invalidate(DIDStore.Key.forRootIdentity(identity.getId())); this.cache.invalidate(DIDStore.Key.forRootIdentityPrivateKey(identity.getId())); } else { - this.storage.updateRootIdentityIndex(identity.getId(), identity.getIndex()); + await this.storage.updateRootIdentityIndex(identity.getId(), identity.getIndex()); } } - public setDefaultRootIdentity(identity: RootIdentity) { + public async setDefaultRootIdentity(identity: RootIdentity): Promise { checkArgument(identity != null, "Invalid identity"); - if (!this.containsRootIdentity(identity.getId())) + if (!await this.containsRootIdentity(identity.getId())) throw new IllegalArgumentException("Invalid identity, not exists in the store"); - this.metadata.setDefaultRootIdentity(identity.getId()); + return this.metadata.setDefaultRootIdentity(identity.getId()); } /** @@ -239,14 +239,14 @@ export class DIDStore { if (id === undefined) { id = this.metadata.getDefaultRootIdentity(); if (id == null || id === "") { - let ids = this.storage.listRootIdentities(); + let ids = await this.storage.listRootIdentities(); if (ids.length != 1) { return null; } else { let identity = ids[0]; let identityMetadata = await this.loadRootIdentityMetadata(identity.getId()); identity.setMetadata(identityMetadata); - this.metadata.setDefaultRootIdentity(identity.getId()); + await this.metadata.setDefaultRootIdentity(identity.getId()); return identity; } } @@ -256,7 +256,7 @@ export class DIDStore { try { let value = await this.cache.getAsync(DIDStore.Key.forRootIdentity(id), async () => { - let identity = this.storage.loadRootIdentity(id); + let identity = await this.storage.loadRootIdentity(id); if (identity != null) { identity.setMetadata(await this.loadRootIdentityMetadata(id)); return { value: identity }; @@ -279,7 +279,7 @@ export class DIDStore { * the returned value if false if private identity doesnot exist. * @throws DIDStoreException Unsupport the specified store type. */ - public containsRootIdentity(id: string): boolean { + public containsRootIdentity(id: string): Promise { checkArgument(id != null && id !== "", "Invalid id"); return this.storage.containsRootIdentity(id); } @@ -291,21 +291,21 @@ export class DIDStore { * @return the mnemonic string * @throws DIDStoreException there is no mnemonic in DID Store. */ - public exportRootIdentityMnemonic(id: string, storepass: string): string | null { + public async exportRootIdentityMnemonic(id: string, storepass: string): Promise { checkArgument(id != null && id !== "", "Invalid id"); checkArgument(storepass != null && storepass !== "", "Invalid storepass"); - let encryptedMnemonic = this.storage.loadRootIdentityMnemonic(id); + let encryptedMnemonic = await this.storage.loadRootIdentityMnemonic(id); if (encryptedMnemonic != null) - return new String(this.decrypt(encryptedMnemonic, storepass)).valueOf(); + return new String(await this.decrypt(encryptedMnemonic, storepass)).valueOf(); else return null; } - public containsRootIdentityMnemonic(id: string): boolean { + public async containsRootIdentityMnemonic(id: string): Promise { checkArgument(id != null && id !== "", "Invalid id"); - let encryptedMnemonic = this.storage.loadRootIdentityMnemonic(id); + let encryptedMnemonic = await this.storage.loadRootIdentityMnemonic(id); return encryptedMnemonic != null; } @@ -316,15 +316,15 @@ export class DIDStore { * @return the HDKey object(private identity) * @throws DIDStoreException there is invalid private identity in DIDStore. */ - private loadRootIdentityPrivateKey(id: string, storepass: string): HDKey { + private async loadRootIdentityPrivateKey(id: string, storepass: string): Promise { try { - let value = this.cache.get(DIDStore.Key.forRootIdentityPrivateKey(id), () => { - let encryptedKey = this.storage.loadRootIdentityPrivateKey(id); + let value = await this.cache.getAsync(DIDStore.Key.forRootIdentityPrivateKey(id), async () => { + let encryptedKey = await this.storage.loadRootIdentityPrivateKey(id); return { value: encryptedKey != null ? encryptedKey : DIDStore.NULL }; }); if (value !== DIDStore.NULL) { - let keyData = this.decrypt(value, storepass); + let keyData = await this.decrypt(value, storepass); return HDKey.deserialize(keyData); } else { return null; @@ -341,12 +341,12 @@ export class DIDStore { /** * @Internal (tag for docs) */ - public derive(id: string, path: string, storepass: string): HDKey { + public async derive(id: string, path: string, storepass: string): Promise { checkArgument(id != null && id !== "", "Invalid identity"); checkArgument(path != null && path !== "", "Invalid path"); checkArgument(storepass != null && storepass !== "", "Invalid storepass"); - let rootPrivateKey = this.loadRootIdentityPrivateKey(id, storepass); + let rootPrivateKey = await this.loadRootIdentityPrivateKey(id, storepass); if (!rootPrivateKey) throw new DIDStoreCryptoException("Unable to load root private key for id " + id + ". Null private key returned."); @@ -355,13 +355,13 @@ export class DIDStore { return key; } - public deleteRootIdentity(id: string): boolean { + public async deleteRootIdentity(id: string): Promise { checkArgument(id != null && id !== "", "Invalid id"); - let success = this.storage.deleteRootIdentity(id); + let success = await this.storage.deleteRootIdentity(id); if (success) { if (this.metadata.getDefaultRootIdentity() != null && this.metadata.getDefaultRootIdentity() === id) - this.metadata.setDefaultRootIdentity(null); + await this.metadata.setDefaultRootIdentity(null); this.cache.invalidate(DIDStore.Key.forRootIdentity(id)); this.cache.invalidate(DIDStore.Key.forRootIdentityPrivateKey(id)); @@ -371,7 +371,7 @@ export class DIDStore { } public async listRootIdentities(): Promise { - let ids = this.storage.listRootIdentities(); + let ids = await this.storage.listRootIdentities(); for (let id of ids) { let identityMetadata = await this.loadRootIdentityMetadata(id.getId()); @@ -381,15 +381,15 @@ export class DIDStore { return ids; } - public containsRootIdentities(): boolean { + public containsRootIdentities(): Promise { return this.storage.containsRootIdenities(); } - public storeRootIdentityMetadata(id: string, metadata: RootIdentity.Metadata) { + public async storeRootIdentityMetadata(id: string, metadata: RootIdentity.Metadata): Promise { checkArgument(id != null && id !== "", "Invalid id"); checkArgument(metadata != null, "Invalid metadata"); - this.storage.storeRootIdentityMetadata(id, metadata); + await this.storage.storeRootIdentityMetadata(id, metadata); } protected async loadRootIdentityMetadata(id: string): Promise { @@ -415,13 +415,13 @@ export class DIDStore { public async storeDid(doc: DIDDocument): Promise { checkArgument(doc != null, "Invalid doc"); - this.storage.storeDid(doc); + await this.storage.storeDid(doc); if (doc.getStore() != this) { let metadata = await this.loadDidMetadata(doc.getSubject()); doc.getMetadata().merge(metadata); doc.getMetadata().attachStore(this); } - this.storeDidMetadata(doc.getSubject(), doc.getMetadata()); + await this.storeDidMetadata(doc.getSubject(), doc.getMetadata()); for (let vc of doc.getCredentials()) await this.storeCredential(vc); @@ -471,7 +471,7 @@ export class DIDStore { * the returned value is false if the specified DID is not in the DIDStore. * @throws DIDStoreException DIDStore error. */ - public containsDid(didOrString: DID | string): boolean { + public containsDid(didOrString: DID | string): Promise { checkArgument(didOrString != null, "Invalid did"); let did: DID; @@ -490,7 +490,7 @@ export class DIDStore { * the returned value is false if there is no DID in the DIDStore. * @throws DIDStoreException DIDStore error. */ - public containsDids(): boolean { + public containsDids(): Promise { return this.storage.containsDids(); } @@ -501,11 +501,11 @@ export class DIDStore { * @param metadata the meta data * @throws DIDStoreException DIDStore error. */ - public storeDidMetadata(did: DID, metadata: DIDMetadata) { + public async storeDidMetadata(did: DID, metadata: DIDMetadata): Promise { checkArgument(did != null, "Invalid did"); checkArgument(metadata != null, "Invalid metadata"); - this.storage.storeDidMetadata(did, metadata); + await this.storage.storeDidMetadata(did, metadata); metadata.attachStore(this); this.cache.put(DIDStore.Key.forDidMetadata(did), metadata); @@ -549,7 +549,7 @@ export class DIDStore { * the returned value is false if deleting is failed. * @throws DIDStoreException DIDStore error. */ - public deleteDid(didOrString: DID | string): boolean { + public async deleteDid(didOrString: DID | string): Promise { checkArgument(didOrString != null, "Invalid did"); let did: DID; @@ -558,7 +558,7 @@ export class DIDStore { else did = DID.from(didOrString); - let success = this.storage.deleteDid(did); + let success = await this.storage.deleteDid(did); if (success) { this.cache.invalidate(DIDStore.Key.forDidDocument(did)); @@ -580,7 +580,7 @@ export class DIDStore { * @throws DIDStoreException DIDStore error. */ public async listDids(): Promise { - let dids = this.storage.listDids(); + let dids = await this.storage.listDids(); for (let did of dids) { let metadata = await this.loadDidMetadata(did); if (metadata == null) { @@ -622,13 +622,13 @@ export class DIDStore { public async storeCredential(credential: VerifiableCredential): Promise { checkArgument(credential != null, "Invalid credential"); - this.storage.storeCredential(credential); + await this.storage.storeCredential(credential); if (credential.getMetadata().getStore() != this) { let metadata = await this.loadCredentialMetadata(credential.getId()); credential.getMetadata().merge(metadata); credential.getMetadata().attachStore(this); } - this.storeCredentialMetadata(credential.getId(), credential.getMetadata()); + await this.storeCredentialMetadata(credential.getId(), credential.getMetadata()); this.cache.put(DIDStore.Key.forCredential(credential.getId()), credential); } @@ -674,7 +674,7 @@ export class DIDStore { * the returned value is false if there is credentials owned the specific DID. * @throws DIDStoreException DIDStore error. */ - public containsCredential(idOrString: DIDURL | string): boolean { + public containsCredential(idOrString: DIDURL | string): Promise { checkArgument(idOrString != null, "Invalid credential id"); let id = DIDURL.from(idOrString); @@ -690,7 +690,7 @@ export class DIDStore { * @return the returned value is true if there is no credential owned the specific DID. * @throws DIDStoreException DIDStore error. */ - public containsCredentials(did: DID): boolean { + public containsCredentials(did: DID): Promise { checkArgument(did != null, "Invalid did"); return this.storage.containsCredentials(did); } @@ -702,12 +702,12 @@ export class DIDStore { * @param metadata the meta data for Credential * @throws DIDStoreException DIDStore error. */ - public storeCredentialMetadata(id: DIDURL, metadata: CredentialMetadata) { + public async storeCredentialMetadata(id: DIDURL, metadata: CredentialMetadata): Promise { checkArgument(id != null, "Invalid credential id"); checkArgument(id.isQualified(), "Unqualified credential id"); checkArgument(metadata != null, "Invalid credential metadata"); - this.storage.storeCredentialMetadata(id, metadata); + await this.storage.storeCredentialMetadata(id, metadata); metadata.attachStore(this); this.cache.put(DIDStore.Key.forCredentialMetadata(id), metadata); @@ -752,13 +752,13 @@ export class DIDStore { * the returned value is false if there is credentials owned the specific DID. * @throws DIDStoreException DIDStore error. */ - public deleteCredential(idOrString: DIDURL | string): boolean { + public async deleteCredential(idOrString: DIDURL | string): Promise { checkArgument(idOrString != null, "Invalid credential id"); let id = DIDURL.from(idOrString); checkArgument(id.isQualified(), "Unqualified credential id"); - let success = this.storage.deleteCredential(id); + let success = await this.storage.deleteCredential(id); if (success) { this.cache.invalidate(DIDStore.Key.forCredential(id)); this.cache.invalidate(DIDStore.Key.forCredentialMetadata(id)); @@ -783,7 +783,7 @@ export class DIDStore { else did = DID.from(didOrString); - let ids = this.storage.listCredentials(did); + let ids = await this.storage.listCredentials(did); for (let id of ids) { let metadata = await this.loadCredentialMetadata(id); if (metadata == null) { @@ -839,7 +839,7 @@ export class DIDStore { * @param storepass the password for DIDStore * @throws DIDStoreException DIDStore error. */ - public storePrivateKey(idOrString: DIDURL | string, privateKey: Buffer, storepass: string) { + public async storePrivateKey(idOrString: DIDURL | string, privateKey: Buffer, storepass: string): Promise { checkArgument(idOrString != null, "Invalid private key id"); let id = DIDURL.from(idOrString); @@ -848,8 +848,8 @@ export class DIDStore { checkArgument(privateKey != null && privateKey.length != 0, "Invalid private key"); checkArgument(storepass != null && storepass !== "", "Invalid storepass"); - let encryptedKey = this.encrypt(privateKey, storepass); - this.storage.storePrivateKey(id, encryptedKey); + let encryptedKey = await this.encrypt(privateKey, storepass); + await this.storage.storePrivateKey(id, encryptedKey); this.cache.put(DIDStore.Key.forDidPrivateKey(id), encryptedKey); } @@ -860,11 +860,11 @@ export class DIDStore { * @param id the identifier of key * @throws DIDStoreException DIDStore error. */ - public storeLazyPrivateKey(id: DIDURL) { + public async storeLazyPrivateKey(id: DIDURL): Promise { checkArgument(id != null, "Invalid private key id"); checkArgument(id.isQualified(), "Unqualified private key id"); - this.storage.storePrivateKey(id, DIDStore.DID_LAZY_PRIVATEKEY); + await this.storage.storePrivateKey(id, DIDStore.DID_LAZY_PRIVATEKEY); this.cache.put(DIDStore.Key.forDidPrivateKey(id), DIDStore.DID_LAZY_PRIVATEKEY); } @@ -882,8 +882,8 @@ export class DIDStore { checkArgument(storepass && storepass != null, "Invalid storepass"); try { - let value = this.cache.get(DIDStore.Key.forDidPrivateKey(id), () => { - let key = this.storage.loadPrivateKey(id); + let value = await this.cache.getAsync(DIDStore.Key.forDidPrivateKey(id), async () => { + let key = await this.storage.loadPrivateKey(id); return { value: key != null ? key : DIDStore.NULL }; @@ -895,7 +895,7 @@ export class DIDStore { if (value === DIDStore.DID_LAZY_PRIVATEKEY) return await RootIdentity.lazyCreateDidPrivateKey(id, this, storepass); else - return this.decrypt(value, storepass); + return await this.decrypt(value, storepass); } } catch(e) { throw new DIDStoreException("Load did private key failed."); @@ -910,7 +910,7 @@ export class DIDStore { * the returned value is false if there is no private keys owned the specified key. * @throws DIDStoreException DIDStore error. */ - public containsPrivateKey(idOrString: DIDURL | string): boolean { + public containsPrivateKey(idOrString: DIDURL | string): Promise { checkArgument(idOrString != null, "Invalid private key id"); let id = DIDURL.from(idOrString); @@ -927,7 +927,7 @@ export class DIDStore { * the returned value is false if there is no private keys owned the specified DID. * @throws DIDStoreException DIDStore error. */ - public containsPrivateKeys(didOrString: DID | string): boolean { + public containsPrivateKeys(didOrString: DID | string): Promise { checkArgument(didOrString != null, "Invalid did"); let did : DID; @@ -947,12 +947,12 @@ export class DIDStore { * the returned value is false if deleting private keys failed. * @throws DIDStoreException DIDStore error. */ - public deletePrivateKey(idOrString: DIDURL | string): boolean { + public async deletePrivateKey(idOrString: DIDURL | string): Promise { checkArgument(idOrString != null, "Invalid private key id"); let id = DIDURL.from(idOrString); - let success = this.storage.deletePrivateKey(id); + let success = await this.storage.deletePrivateKey(id); if (success) this.cache.invalidate(DIDStore.Key.forDidPrivateKey(id)); @@ -993,21 +993,21 @@ export class DIDStore { * @param newPassword the new password * @throws DIDStoreException DIDStore error. */ - public changePassword(oldPassword: string, newPassword: string) { + public async changePassword(oldPassword: string, newPassword: string): Promise { checkArgument(oldPassword != null && oldPassword !== "", "Invalid old password"); checkArgument(newPassword != null && newPassword !== "", "Invalid new password"); - this.storage.changePassword({ + await this.storage.changePassword({ reEncrypt: (data) => { return DIDStore.reEncrypt(data, oldPassword, newPassword); } }); - this.metadata.setFingerprint(DIDStore.calcFingerprint(newPassword)); + await this.metadata.setFingerprint(DIDStore.calcFingerprint(newPassword)); this.cache.invalidateAll(); } - public async synchronize(handle: ConflictHandle = null) { + public async synchronize(handle: ConflictHandle = null): Promise { if (handle == null) handle = DefaultConflictHandle.getInstance(); @@ -1016,7 +1016,7 @@ export class DIDStore { await identity.synchronize(handle); } - let dids = this.storage.listDids(); + let dids = await this.storage.listDids(); for (let did of dids) { let localDoc = await this.storage.loadDid(did); if (localDoc.isCustomizedDid()) { @@ -1038,7 +1038,7 @@ export class DIDStore { did.toString()); // Local copy was modified - finalDoc = handle.merge(resolvedDoc, localDoc); + finalDoc = await handle.merge(resolvedDoc, localDoc); if (finalDoc == null || !finalDoc.getSubject().equals(did)) { log.error("Conflict handle merge the DIDDocument error."); throw new DIDStoreException("deal with local modification error."); @@ -1050,17 +1050,17 @@ export class DIDStore { localDoc.getMetadata().attachStore(this); let metadata = finalDoc.getMetadata(); - metadata.setPublished(resolvedDoc.getMetadata().getPublished()); - metadata.setSignature(resolvedDoc.getProof().getSignature()); + await metadata.setPublished(resolvedDoc.getMetadata().getPublished()); + await metadata.setSignature(resolvedDoc.getProof().getSignature()); if (resolvedDoc.getMetadata().isDeactivated()) - metadata.setDeactivated(true); + await metadata.setDeactivated(true); metadata.attachStore(this); - this.storage.storeDid(finalDoc); + await this.storage.storeDid(finalDoc); } - let vcIds = this.storage.listCredentials(did); + let vcIds = await this.storage.listCredentials(did); for (let vcId of vcIds) { let localVc = await this.storage.loadCredential(vcId); @@ -1069,7 +1069,7 @@ export class DIDStore { continue; resolvedVc.getMetadata().merge(localVc.getMetadata()); - this.storage.storeCredential(resolvedVc); + await this.storage.storeCredential(resolvedVc); } } } @@ -1095,7 +1095,7 @@ export class DIDStore { let de = new DIDStore.DIDExport(did); de.setDocument(doc); - if (this.storage.containsCredentials(did)) { + if (await this.storage.containsCredentials(did)) { let ids = Array.from(await this.listCredentials(did)); ids.sort(); for (let id of ids) { @@ -1107,14 +1107,14 @@ export class DIDStore { } } - if (this.storage.containsPrivateKeys(did)) { + if (await this.storage.containsPrivateKeys(did)) { let pks = doc.getPublicKeys(); for (let pk of pks) { if (!pk.getController().equals(did)) continue; let id = pk.getId(); - let key = this.storage.loadPrivateKey(id); + let key = await this.storage.loadPrivateKey(id); if (key != null) { log.debug("Exporting private key {}...", id.toString()); de.addPrivatekey(id, key, storepass, password); @@ -1126,7 +1126,7 @@ export class DIDStore { return de.serialize(true); } - public importDid(data: string, password: string, storepass: string): void { + public async importDid(data: string, password: string, storepass: string): Promise { checkArgument(data != null && data !== "", "Invalid import data"); checkArgument(password != null && password !== "", "Invalid password"); checkArgument(storepass != null && storepass !== "", "Invalid storepass"); @@ -1135,36 +1135,36 @@ export class DIDStore { de.verify(password); let doc = de.getDocument(); - this.storage.storeDid(doc); - this.storage.storeDidMetadata(doc.getSubject(), doc.getMetadata()); + await this.storage.storeDid(doc); + await this.storage.storeDidMetadata(doc.getSubject(), doc.getMetadata()); let vcs = de.getCredentials(); for (let vc of vcs) { - this.storage.storeCredential(vc); - this.storage.storeCredentialMetadata(vc.getId(), vc.getMetadata()); + await this.storage.storeCredential(vc); + await this.storage.storeCredentialMetadata(vc.getId(), vc.getMetadata()); } let sks = de.getPrivateKeys(); for (let sk of sks) - this.storage.storePrivateKey(sk.getId(), sk.getKey(password, storepass)); + await this.storage.storePrivateKey(sk.getId(), sk.getKey(password, storepass)); return null; } - public exportRootIdentity(id: string, password: string, storepass: string): string { + public async exportRootIdentity(id: string, password: string, storepass: string): Promise { checkArgument(id != null && id !== "", "Invalid id"); checkArgument(password != null && password !== "", "Invalid password"); checkArgument(storepass != null && storepass !== "", "Invalid storepass"); let rie = new DIDStore.RootIdentityExport(); - let mnemonic = this.storage.loadRootIdentityMnemonic(id); + let mnemonic = await this.storage.loadRootIdentityMnemonic(id); if (mnemonic !== null) rie.setMnemonic(mnemonic, storepass, password); - rie.setPirvateKey(this.storage.loadRootIdentityPrivateKey(id), storepass, password); + rie.setPirvateKey(await this.storage.loadRootIdentityPrivateKey(id), storepass, password); - let rootidentity = this.storage.loadRootIdentity(id); + let rootidentity = await this.storage.loadRootIdentity(id); rie.setPublicKey(rootidentity.getPreDerivedPublicKey().serializePublicKeyBase58()); rie.setIndex(rootidentity.getIndex()); @@ -1175,7 +1175,7 @@ export class DIDStore { return rie.serialize(true); } - public importRootIdentity(data: string, password: string, storepass: string): void { + public async importRootIdentity(data: string, password: string, storepass: string): Promise { checkArgument(data != null && data !== "", "Invalid import data"); checkArgument(password != null && password !== "", "Invalid password"); checkArgument(storepass != null && storepass !== "", "Invalid storepass"); @@ -1189,11 +1189,11 @@ export class DIDStore { let hk = HDKey.deserializeBase58(publicKey); let id = RootIdentity.getId(hk.serializePublicKey()); - this.storage.storeRootIdentity(id, encryptedMnemonic, encryptedPrivateKey, + await this.storage.storeRootIdentity(id, encryptedMnemonic, encryptedPrivateKey, publicKey, rie.getIndex()); if (rie.isDefault() && this.metadata.getDefaultRootIdentity() == null) - this.metadata.setDefaultRootIdentity(id); + await this.metadata.setDefaultRootIdentity(id); return null; } @@ -1218,11 +1218,11 @@ export class DIDStore { } let file = new File(zipFile); - file.createFile(); + await file.createFile(); try { let content = await zip.generateAsync({ type: "nodebuffer", platform: "UNIX" }); - writeFileSync(zipFile, content, { mode: 0o644, flag: "w+" }); + await writeFileSync(zipFile, content, { mode: 0o644, flag: "w+" }); } catch (e) { throw new MalformedExportDataException(e); } @@ -1263,7 +1263,7 @@ export class DIDStore { } if (fingerprint == null || fingerprint == "") - this.metadata.setFingerprint(currentFingerprint); + await this.metadata.setFingerprint(currentFingerprint); } } diff --git a/src/didstoremetadata.ts b/src/didstoremetadata.ts index b5a61fbf..05a5e167 100644 --- a/src/didstoremetadata.ts +++ b/src/didstoremetadata.ts @@ -38,10 +38,15 @@ export class DIDStoreMetadata extends AbstractMetadata { private static DEFAULT_ROOT_IDENTITY = "defaultRootIdentity"; private static log = new Logger("DIDStoreMetadata"); - constructor(store: DIDStore = null) { + protected constructor(store: DIDStore = null) { super(store); - this.put(DIDStoreMetadata.TYPE, DIDStoreMetadata.DID_STORE_TYPE); - this.put(DIDStoreMetadata.VERSION, DIDStoreMetadata.DID_STORE_VERSION); + } + + public static async create(store: DIDStore = null): Promise { + const metadata = new DIDStoreMetadata(store); + await metadata.put(DIDStoreMetadata.TYPE, DIDStoreMetadata.DID_STORE_TYPE); + await metadata.put(DIDStoreMetadata.VERSION, DIDStoreMetadata.DID_STORE_VERSION); + return metadata; } public getType(): string { @@ -52,28 +57,28 @@ export class DIDStoreMetadata extends AbstractMetadata { return this.getInteger(DIDStoreMetadata.VERSION, -1); } - public setFingerprint(fingerprint: string) { + public setFingerprint(fingerprint: string): Promise { checkArgument(fingerprint != null && fingerprint != "", "Invalid fingerprint"); - this.put(DIDStoreMetadata.FINGERPRINT, fingerprint); + return this.put(DIDStoreMetadata.FINGERPRINT, fingerprint); } public getFingerprint(): string { return this.get(DIDStoreMetadata.FINGERPRINT) as string; } - public setDefaultRootIdentity(id: string) { - this.put(DIDStoreMetadata.DEFAULT_ROOT_IDENTITY, id); + public setDefaultRootIdentity(id: string): Promise { + return this.put(DIDStoreMetadata.DEFAULT_ROOT_IDENTITY, id); } public getDefaultRootIdentity(): string { return this.get(DIDStoreMetadata.DEFAULT_ROOT_IDENTITY) as string; } - protected save() { + protected async save(): Promise { if (this.attachedStore()) { try { - this.getStore().storage.storeMetadata(this); + await this.getStore().storage.storeMetadata(this); } catch (e) { if (e instanceof DIDStoreException) DIDStoreMetadata.log.error("INTERNAL - error store metadata for DIDStore"); @@ -82,9 +87,10 @@ export class DIDStoreMetadata extends AbstractMetadata { } } - public static parse(content: string | JSONObject, context = null): DIDStoreMetadata { + public static async parse(content: string | JSONObject, context = null): Promise { try { - return DIDEntity.deserialize(content, DIDStoreMetadata, context); + let metadata = await DIDStoreMetadata.create(); + return DIDEntity.deserializeWithObj(content, metadata, context); } catch (e) { // DIDSyntaxException if (e instanceof MalformedMetadataException) diff --git a/src/file.ts b/src/file.ts index f6407268..7bd17bf5 100644 --- a/src/file.ts +++ b/src/file.ts @@ -21,9 +21,10 @@ */ import path from "path"; - -//import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmdirSync, statSync, writeFileSync } from "./fs"; import * as fs from "./fs"; +import {Logger} from "./logger"; + +const log = new Logger("File"); /** * Internal class mimicing Java File class in order to reduce the divergence with Java implementation @@ -38,7 +39,7 @@ import * as fs from "./fs"; export class File { // Exported, for test cases only public static SEPARATOR = "/"; - private fullPath: string; + private readonly fullPath: string; private fileStats?: fs.Stats; public constructor(path: File | string, subpath?: string) { @@ -53,40 +54,40 @@ import * as fs from "./fs"; this.fullPath = fullPath; } - public static exists(file: File | string): boolean { + public static async exists(file: File | string): Promise { if (typeof file === "string") file = new File(file); - return file.exists(); + return await file.exists(); } - public static isFile(file: File | string): boolean { + public static async isFile(file: File | string): Promise { if (typeof file === "string") file = new File(file); - return file.isFile(); + return await file.isFile(); } - public static isDirectory(file: File | string): boolean { + public static async isDirectory(file: File | string): Promise { if (typeof file === "string") file = new File(file); - return file.isDirectory(); + return await file.isDirectory(); } - private getStats(): fs.Stats { + private async getStats(): Promise { if (this.fileStats) return this.fileStats; - return this.exists() ? fs.statSync(this.fullPath) : null; + return await this.exists() ? await fs.statSync(this.fullPath) : null; } - public exists(): boolean { - return fs.existsSync(this.fullPath); + public async exists(): Promise { + return await fs.existsSync(this.fullPath); } // Entry size in bytes - public length(): number { - return this.exists() ? this.getStats().size : 0; + public async length(): Promise { + return await this.exists() ? (await this.getStats()).size : 0; } public getAbsolutePath(): string { @@ -119,67 +120,66 @@ import * as fs from "./fs"; return ""; } - public isDirectory(): boolean { - return this.exists() ? this.getStats().isDirectory() : false; + public async isDirectory(): Promise { + return await this.exists() ? (await this.getStats()).isDirectory() : false; } - public isFile(): boolean { - return this.exists() ? this.getStats().isFile() : false; + public async isFile(): Promise { + return await this.exists() ? (await this.getStats()).isFile() : false; } /** * Lists all file names in this directory. */ - public list(): string[] { - return this.exists() && this.getStats().isDirectory() ? fs.readdirSync(this.fullPath) : null; + public async list(): Promise { + return await this.exists() && (await this.getStats()).isDirectory() ? await fs.readdirSync(this.fullPath) : null; } /** * Lists all files (as File) in this directory. */ - public listFiles(): File[] { - if (!this.exists() || !this.getStats().isDirectory()) { + public async listFiles(): Promise { + if (!(await this.exists()) || !(await this.getStats()).isDirectory()) { return null; } let files: File[] = []; - this.list().forEach((fileName)=>{ + (await this.list()).forEach((fileName)=>{ files.push(new File(this.getAbsolutePath()+"/"+fileName)); }); return files; } - public writeText(content: string) { - if (!this.exists() || this.getStats().isFile()) { - fs.writeFileSync(this.fullPath, content, { encoding: "utf-8" }); + public async writeText(content: string): Promise { + if (!(await this.exists()) || (await this.getStats()).isFile()) { + await fs.writeFileSync(this.fullPath, content, { encoding: "utf-8" }); } } - public readText(): string { - return this.exists() ? fs.readFileSync(this.fullPath, { encoding: "utf-8" }) : null; - return null; + public async readText(): Promise { + return await this.exists() ? await fs.readFileSync(this.fullPath, { encoding: "utf-8" }) : null; } - public rename(newName: string) { - if (this.exists()) { + public async rename(newName: string): Promise { + if (await this.exists()) { let targetName = this.fullPath.includes(File.SEPARATOR) && !newName.includes(File.SEPARATOR) ? this.getParentDirectoryName + File.SEPARATOR + newName : newName; - fs.renameSync(this.fullPath, targetName); + await fs.renameSync(this.fullPath, targetName); } } - public createFile(overwrite?: boolean) { + public async createFile(overwrite?: boolean): Promise { let replace = overwrite ? overwrite : false; - if (!this.exists() || replace) { - fs.writeFileSync(this.fullPath, "", { encoding: "utf-8" }); + if (!(await this.exists()) || replace) { + await fs.writeFileSync(this.fullPath, "", { encoding: "utf-8" }); this.fileStats = undefined; } } - public createDirectory(overwrite?: boolean) { + public async createDirectory(overwrite?: boolean): Promise { let replace = overwrite ? overwrite : false; - if (!this.exists() || replace) { + if (!(await this.exists()) || replace) { //mkdirSync(this.fullPath, { "recursive": true }); - this.mkdirpath(this.fullPath); + await this.mkdirpath(this.fullPath); this.fileStats = undefined; } } @@ -188,19 +188,19 @@ import * as fs from "./fs"; * Internal reimplementation of mkdir because even if nodejs now has a "recursive" option, * browserfs localstorage driver doesn't. */ - private mkdirpath(dirPath: string) + private async mkdirpath(dirPath: string): Promise { - if(!fs.existsSync(dirPath)){ + if(!(await fs.existsSync(dirPath))){ try { - fs.mkdirSync(dirPath); + await fs.mkdirSync(dirPath); } catch(e) { let dirname = path.dirname(dirPath); if (dirname !== dirPath) { - this.mkdirpath(dirname); - this.mkdirpath(dirPath); + await this.mkdirpath(dirname); + await this.mkdirpath(dirPath); } else { // We reached the root path. Folder creation has failed for some reason, so we @@ -214,12 +214,12 @@ import * as fs from "./fs"; /** * Deletes this file from storage. */ - public delete() { - if (this.exists()) { - if (this.isDirectory()) - this.deleteDirectory(this.fullPath); + public async delete(): Promise { + if (await this.exists()) { + if (await this.isDirectory()) + await this.deleteDirectory(this.fullPath); else - fs.unlinkSync(this.fullPath); + await fs.unlinkSync(this.fullPath); this.fileStats = undefined; } } @@ -228,19 +228,19 @@ import * as fs from "./fs"; * Internal reimplementation of rmdir because even if nodejs now has a "resursive" option, * browserfs localstorage driver doesn't. */ - private deleteDirectory(directoryPath: string) { - if (fs.existsSync(directoryPath)) { - fs.readdirSync(directoryPath).forEach((file, index) => { - const curPath = path.join(directoryPath, file); - if (fs.lstatSync(curPath).isDirectory()) { - // recurse - this.deleteDirectory(curPath); - } else { - // delete file - fs.unlinkSync(curPath); - } - }); - fs.rmdirSync(directoryPath); + private async deleteDirectory(directoryPath: string): Promise { + if (await fs.existsSync(directoryPath)) { + for (const file of await fs.readdirSync(directoryPath)) { + const curPath = path.join(directoryPath, file); + if ((await fs.lstatSync(curPath)).isDirectory()) { + // recurse + await this.deleteDirectory(curPath); + } else { + // delete file + await fs.unlinkSync(curPath); + } + } + await fs.rmdirSync(directoryPath); } } diff --git a/src/filesystemstorage.ts b/src/filesystemstorage.ts index 896eca16..fc83c713 100644 --- a/src/filesystemstorage.ts +++ b/src/filesystemstorage.ts @@ -112,19 +112,19 @@ export class FileSystemStorage implements DIDStorage { } public async init(): Promise { - if (this.storeRoot.exists()) + if (await this.storeRoot.exists()) await this.checkStore(); else - this.initializeStore(); + await this.initializeStore(); } - private initializeStore() { + private async initializeStore(): Promise { try { log.debug("Initializing DID store at {}", this.storeRoot.getAbsolutePath()); - this.storeRoot.createDirectory(); - let metadata = new DIDStoreMetadata(); - let file = this.getFile(true, this.currentDataDir, FileSystemStorage.METADATA); - file.writeText(metadata.serialize()); + await this.storeRoot.createDirectory(); + let metadata = await DIDStoreMetadata.create(); + let file = await this.getFile(true, this.currentDataDir, FileSystemStorage.METADATA); + await file.writeText(metadata.serialize()); } catch (e) { // IOException log.error("Initialize DID store error", e); @@ -132,23 +132,23 @@ export class FileSystemStorage implements DIDStorage { } } - private checkStore(): void { + private async checkStore(): Promise { log.debug("Checking DID store at {}", this.storeRoot.getAbsolutePath()); - if (this.storeRoot.isFile()) { + if (await this.storeRoot.isFile()) { log.error("Path {} not a directory", this.storeRoot.getAbsolutePath()); throw new DIDStorageException("Invalid DIDStore \"" + this.storeRoot.getAbsolutePath() + "\"."); } - this.postOperations(); + await this.postOperations(); let file: File = this.getDir(this.currentDataDir); - if (!file.exists()) { - let storeRootFiles = this.storeRoot.list(); + if (!(await file.exists())) { + let storeRootFiles = await this.storeRoot.list(); if (storeRootFiles == null || storeRootFiles.length == 0) { // if an empty folder - this.initializeStore(); + await this.initializeStore(); return; } else { log.error("Path {} cannot be initialized as DID Store because it's not empty", this.storeRoot.getAbsolutePath()); @@ -157,21 +157,21 @@ export class FileSystemStorage implements DIDStorage { } } - if (!file.isDirectory()) { + if (!(await file.isDirectory())) { log.error("Path {} is not a DID store, missing data directory", this.storeRoot.getAbsolutePath()); throw new DIDStorageException("Invalid DIDStore \"" + this.storeRoot.getAbsolutePath() + "\"."); } - let metadataFile = this.getFile(false, this.currentDataDir, FileSystemStorage.METADATA); - if (!metadataFile.exists() || !metadataFile.isFile()) { + let metadataFile = await this.getFile(false, this.currentDataDir, FileSystemStorage.METADATA); + if (!(await metadataFile.exists()) || !(await metadataFile.isFile())) { log.error("Path {} not a DID store, missing store metadata", this.storeRoot.getAbsolutePath()); throw new DIDStorageException("Invalid DIDStore \"" + this.storeRoot.getAbsolutePath() + "\"."); } try { - let metadataContent = metadataFile.readText(); - let metadata = DIDStoreMetadata.parse(metadataContent); + let metadataContent = await metadataFile.readText(); + let metadata = await DIDStoreMetadata.parse(metadataContent); if (metadata.getType() !== DIDStoreMetadata.DID_STORE_TYPE) throw new DIDStorageException("Unknown DIDStore type"); @@ -195,9 +195,9 @@ export class FileSystemStorage implements DIDStorage { return DIDURL.from(path, did); } - private static copyFile(src: File, dest: File) { + private static async copyFile(src: File, dest: File): Promise { // Copy content - dest.writeText(src.readText()); + await dest.writeText(await src.readText()); } /** @@ -206,7 +206,7 @@ export class FileSystemStorage implements DIDStorage { * - If the file already exists, it is overwritten (deleted) * - Intermediate folders are created if missing */ - private getFile(create: boolean, ...path: string[]): File { + private async getFile(create: boolean, ...path: string[]): Promise { let file: File = null; let relPath = this.storeRoot.getAbsolutePath(); @@ -215,7 +215,7 @@ export class FileSystemStorage implements DIDStorage { } file = new File(relPath); if (create) - file.getParentDirectory().createDirectory(); + await file.getParentDirectory().createDirectory(); return file; } @@ -233,26 +233,26 @@ export class FileSystemStorage implements DIDStorage { return this.storeRoot; } - public storeMetadata(metadata: DIDStoreMetadata) { + public async storeMetadata(metadata: DIDStoreMetadata): Promise { try { - let file = this.getFile(true, this.currentDataDir, FileSystemStorage.METADATA); + let file = await this.getFile(true, this.currentDataDir, FileSystemStorage.METADATA); if (metadata == null || metadata.isEmpty()) - file.delete(); + await file.delete(); else - file.writeText(metadata.serialize()); + await file.writeText(metadata.serialize()); } catch (e) { // IOException throw new DIDStorageException("Store DIDStore metadata error", e); } } - public loadMetadata(): DIDStoreMetadata { + public async loadMetadata(): Promise { try { - let file = this.getFile(false, this.currentDataDir, FileSystemStorage.METADATA); + let file = await this.getFile(false, this.currentDataDir, FileSystemStorage.METADATA); let metadata: DIDStoreMetadata = null; - if (file.exists()) - metadata = DIDStoreMetadata.parse(file.readText()); + if (await file.exists()) + metadata = await DIDStoreMetadata.parse(await file.readText()); return metadata; } catch (e) { @@ -261,34 +261,34 @@ export class FileSystemStorage implements DIDStorage { } } - private getRootIdentityFile(id: string, file: string, create: boolean): File { - return this.getFile(create, this.currentDataDir, FileSystemStorage.ROOT_IDENTITIES_DIR, id, file); + private async getRootIdentityFile(id: string, file: string, create: boolean): Promise { + return await this.getFile(create, this.currentDataDir, FileSystemStorage.ROOT_IDENTITIES_DIR, id, file); } private getRootIdentityDir(id: string): File { return this.getDir(this.currentDataDir, FileSystemStorage.ROOT_IDENTITIES_DIR, id); } - public storeRootIdentityMetadata(id: string, metadata: RootIdentity.Metadata) { + public async storeRootIdentityMetadata(id: string, metadata: RootIdentity.Metadata): Promise { try { - let file = this.getRootIdentityFile(id, FileSystemStorage.METADATA, true); + let file = await this.getRootIdentityFile(id, FileSystemStorage.METADATA, true); if (metadata == null || metadata.isEmpty()) - file.delete(); + await file.delete(); else - file.writeText(metadata.serialize()); + await file.writeText(metadata.serialize()); } catch (e) { // IOException throw new DIDStorageException("Store root identity metadata error: " + id, e); } } - public loadRootIdentityMetadata(id: string): RootIdentity.Metadata { + public async loadRootIdentityMetadata(id: string): Promise { try { - let file = this.getRootIdentityFile(id, FileSystemStorage.METADATA, false); + let file = await this.getRootIdentityFile(id, FileSystemStorage.METADATA, false); let metadata: RootIdentity.Metadata = null; - if (file.exists()) - metadata = RootIdentity.Metadata.parse(file.readText()); + if (await file.exists()) + metadata = RootIdentity.Metadata.parse(await file.readText()); return metadata; } catch (e) { @@ -297,43 +297,43 @@ export class FileSystemStorage implements DIDStorage { } } - public storeRootIdentity(id: string, mnemonic: string, privateKey: string, - publicKey: string, index: number) { + public async storeRootIdentity(id: string, mnemonic: string, privateKey: string, + publicKey: string, index: number): Promise { try { let file: File; if (mnemonic != null) { - file = this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_MNEMONIC_FILE, true); - file.writeText(mnemonic); + file = await this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_MNEMONIC_FILE, true); + await file.writeText(mnemonic); } if (privateKey != null) { - file = this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_PRIVATEKEY_FILE, true); - file.writeText(privateKey); + file = await this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_PRIVATEKEY_FILE, true); + await file.writeText(privateKey); } if (publicKey != null) { - file = this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_PUBLICKEY_FILE, true); - file.writeText(publicKey); + file = await this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_PUBLICKEY_FILE, true); + await file.writeText(publicKey); } - file = this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_INDEX_FILE, true); - file.writeText(index.toFixed()); + file = await this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_INDEX_FILE, true); + await file.writeText(index.toFixed()); } catch (e) { // IOException throw new DIDStorageException("Store root identity error: " + id, e); } } - public loadRootIdentity(id: string): RootIdentity { + public async loadRootIdentity(id: string): Promise { try { - let file = this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_PUBLICKEY_FILE, false); - if (!file.exists()) + let file = await this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_PUBLICKEY_FILE, false); + if (!(await file.exists())) return null; - let publicKey = file.readText(); - file = this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_INDEX_FILE, false); - let index = Number.parseInt(file.readText()); + let publicKey = await file.readText(); + file = await this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_INDEX_FILE, false); + let index = Number.parseInt(await file.readText()); return RootIdentity.createFromPreDerivedPublicKey(publicKey, index); } catch (e) { @@ -342,57 +342,57 @@ export class FileSystemStorage implements DIDStorage { } } - public containsRootIdentity(id: string): boolean { + public containsRootIdentity(id: string): Promise { let dir = this.getRootIdentityDir(id); return dir.exists(); } - public updateRootIdentityIndex(id: string, index: number) { + public async updateRootIdentityIndex(id: string, index: number): Promise { try { - let file = this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_INDEX_FILE, false); - file.writeText("" + index); + let file = await this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_INDEX_FILE, false); + await file.writeText("" + index); } catch (e) { // IOException throw new DIDStorageException("Update index for indentiy error: " + id, e); } } - public loadRootIdentityPrivateKey(id: string): string { + public async loadRootIdentityPrivateKey(id: string): Promise { // TODO: support multiple named identity try { - let file = this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_PRIVATEKEY_FILE, false); - if (!file.exists()) + let file = await this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_PRIVATEKEY_FILE, false); + if (!(await file.exists())) return null; - return file.readText(); + return await file.readText(); } catch (e) { // IOException throw new DIDStorageException("Load private key for identity error: " + id, e); } } - public deleteRootIdentity(id: string): boolean { + public async deleteRootIdentity(id: string): Promise { let dir = this.getRootIdentityDir(id); - if (dir.exists()) { - dir.delete(); + if (await dir.exists()) { + await dir.delete(); return true; } else { return false; } } - public listRootIdentities(): RootIdentity[] { + public async listRootIdentities(): Promise { let dir = this.getDir(this.currentDataDir, FileSystemStorage.ROOT_IDENTITIES_DIR); - if (!dir.exists()) + if (!(await dir.exists())) return []; - let children = dir.listFiles().filter((file) => { - if (!file.isDirectory()) + let children = (await dir.listFiles()).filter(async (file) => { + if (!(await file.isDirectory())) return false; let sk = new File(file, FileSystemStorage.ROOT_IDENTITY_PRIVATEKEY_FILE); - return (sk.exists() && sk.isFile()); + return await sk.exists() && await sk.isFile(); }); if (children == null || children.length == 0) @@ -400,67 +400,72 @@ export class FileSystemStorage implements DIDStorage { let ids: RootIdentity[] = []; for (let id of children) { - let identity = this.loadRootIdentity(id.getName()); + let identity = await this.loadRootIdentity(id.getName()); ids.push(identity); } return ids; } - public containsRootIdenities(): boolean { + public async containsRootIdenities(): Promise { let dir = this.getDir(this.currentDataDir, FileSystemStorage.ROOT_IDENTITIES_DIR); - if (!dir.exists()) + if (!(await dir.exists())) return false; - let children = dir.listFiles().filter((file) => { - return file.isDirectory(); - }); + const files = await dir.listFiles(); + if (!files) + return false; - return (children != null && children.length > 0); + for (const file of files) { + if (await file.isDirectory()) + return true; + } + + return false; } - public loadRootIdentityMnemonic(id: string): string { + public async loadRootIdentityMnemonic(id: string): Promise { try { - let file = this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_MNEMONIC_FILE, false); - return file.readText(); + let file = await this.getRootIdentityFile(id, FileSystemStorage.ROOT_IDENTITY_MNEMONIC_FILE, false); + return await file.readText(); } catch (e) { // IOException throw new DIDStorageException("Load mnemonic for identity error: " + id, e); } } - private getDidFile(did: DID, create: boolean): File { - return this.getFile(create, this.currentDataDir, FileSystemStorage.DID_DIR, did.getMethodSpecificId(), FileSystemStorage.DOCUMENT_FILE); + private async getDidFile(did: DID, create: boolean): Promise { + return await this.getFile(create, this.currentDataDir, FileSystemStorage.DID_DIR, did.getMethodSpecificId(), FileSystemStorage.DOCUMENT_FILE); } - private getDidMetadataFile(did: DID, create: boolean): File { - return this.getFile(create, this.currentDataDir, FileSystemStorage.DID_DIR, did.getMethodSpecificId(), FileSystemStorage.METADATA); + private async getDidMetadataFile(did: DID, create: boolean): Promise { + return await this.getFile(create, this.currentDataDir, FileSystemStorage.DID_DIR, did.getMethodSpecificId(), FileSystemStorage.METADATA); } private getDidDir(did: DID): File { return this.getDir(this.currentDataDir, FileSystemStorage.DID_DIR, did.getMethodSpecificId()); } - public storeDidMetadata(did: DID, metadata: DIDMetadata) { + public async storeDidMetadata(did: DID, metadata: DIDMetadata): Promise { try { - let file = this.getDidMetadataFile(did, true); + let file = await this.getDidMetadataFile(did, true); if (metadata == null || metadata.isEmpty()) - file.delete(); + await file.delete(); else - file.writeText(metadata.serialize()); + await file.writeText(metadata.serialize()); } catch (e) { // IOException throw new DIDStorageException("Store DID metadata error: " + did, e); } } - public loadDidMetadata(did: DID): DIDMetadata { + public async loadDidMetadata(did: DID): Promise { try { - let file = this.getDidMetadataFile(did, false); + let file = await this.getDidMetadataFile(did, false); let metadata: DIDMetadata = null; - if (file.exists()) - metadata = DIDMetadata.parse(file.readText()); + if (await file.exists()) + metadata = DIDMetadata.parse(await file.readText()); return metadata; } catch (e) { @@ -469,10 +474,10 @@ export class FileSystemStorage implements DIDStorage { } } - public storeDid(doc: DIDDocument) { + public async storeDid(doc: DIDDocument): Promise { try { - let file = this.getDidFile(doc.getSubject(), true); - file.writeText(doc.serialize(true)); + let file = await this.getDidFile(doc.getSubject(), true); + await file.writeText(doc.serialize(true)); } catch (e) { // IOException throw new DIDStorageException("Store DID document error: " + doc.getSubject(), e); @@ -481,75 +486,74 @@ export class FileSystemStorage implements DIDStorage { public async loadDid(did: DID): Promise { try { - let file = this.getDidFile(did, false); - if (!file.exists()) + let file = await this.getDidFile(did, false); + if (!(await file.exists())) return null; - return await DIDDocument.parseAsync(file.readText()); + return await DIDDocument.parseAsync(await file.readText()); } catch (e) { // DIDSyntaxException | IOException throw new DIDStorageException("Load DID document error: " + did, e); } } - public deleteDid(did: DID): boolean { + public async deleteDid(did: DID): Promise { let dir = this.getDidDir(did); - if (dir.exists()) { - dir.delete(); + if (await dir.exists()) { + await dir.delete(); return true; } else { return false; } } - public listDids(): DID[] { + public async listDids(): Promise { let dir = this.getDir(this.currentDataDir, FileSystemStorage.DID_DIR); - if (!dir.exists()) - return []; - - let children = dir.listFiles().filter((file) => { - if (!file.isDirectory()) - return false; - - let doc = new File(file, FileSystemStorage.DOCUMENT_FILE); - return (doc.exists() && doc.isFile()); - }); - - if (children == null || children.length == 0) + if (!(await dir.exists())) return []; let dids: DID[] = []; - for (let didRoot of children) { - let did = new DID(DID.METHOD, didRoot.getName()); - dids.push(did); + const files = await dir.listFiles(); + if (files) { + for (const file of files) { + if (!(await file.isDirectory())) + continue; + + const didRoot = new File(file, FileSystemStorage.DOCUMENT_FILE); + if (await didRoot.exists() && await didRoot.isFile()) + dids.push(new DID(DID.METHOD, didRoot.getName())); + } } - return dids; } - public containsDid(did: DID): boolean { + public containsDid(did: DID): Promise { let dir = this.getDidDir(did); return dir.exists(); } - public containsDids(): boolean { + public async containsDids(): Promise { let dir = this.getDir(this.currentDataDir, FileSystemStorage.DID_DIR); - if (!dir.exists()) + if (!(await dir.exists())) return false; - let children = dir.listFiles().filter((file) => { - return file.isDirectory(); - }); + const files = await dir.listFiles(); + if (!files) + return false; - return children == null ? false : children.length > 0; + for (const file of files) { + if (await file.isDirectory()) + return true; + } + return false; } - private getCredentialFile(id: DIDURL, create: boolean): File { + private getCredentialFile(id: DIDURL, create: boolean): Promise { return this.getFile(create, this.currentDataDir, FileSystemStorage.DID_DIR, id.getDid().getMethodSpecificId(), FileSystemStorage.CREDENTIALS_DIR, FileSystemStorage.toPath(id), FileSystemStorage.CREDENTIAL_FILE); } - private getCredentialMetadataFile(id: DIDURL, create: boolean): File { + private getCredentialMetadataFile(id: DIDURL, create: boolean): Promise { return this.getFile(create, this.currentDataDir, FileSystemStorage.DID_DIR, id.getDid().getMethodSpecificId(), FileSystemStorage.CREDENTIALS_DIR, FileSystemStorage.toPath(id), FileSystemStorage.METADATA); } @@ -563,82 +567,87 @@ export class FileSystemStorage implements DIDStorage { return this.getDir(this.currentDataDir, FileSystemStorage.DID_DIR, did.getMethodSpecificId(), FileSystemStorage.CREDENTIALS_DIR); } - public storeCredentialMetadata(id: DIDURL, metadata: CredentialMetadata) { + public async storeCredentialMetadata(id: DIDURL, metadata: CredentialMetadata): Promise { try { - let file = this.getCredentialMetadataFile(id, true); + let file = await this.getCredentialMetadataFile(id, true); if (metadata == null || metadata.isEmpty()) - file.delete(); + await file.delete(); else - file.writeText(metadata.serialize()); + await file.writeText(metadata.serialize()); } catch (e) { // IOException throw new DIDStorageException("Store credential metadata error: " + id, e); } } - public loadCredentialMetadata(id: DIDURL): CredentialMetadata { + public async loadCredentialMetadata(id: DIDURL): Promise { try { - let file = this.getCredentialMetadataFile(id, false); - if (!file.exists()) + let file = await this.getCredentialMetadataFile(id, false); + if (!(await file.exists())) return null; - return CredentialMetadata.parse(file.readText()); + return CredentialMetadata.parse(await file.readText()); } catch (e) { // DIDSyntaxException | IOException throw new DIDStorageException("Load credential metadata error: " + id, e); } } - public storeCredential(credential: VerifiableCredential) { + public async storeCredential(credential: VerifiableCredential): Promise { try { - let file = this.getCredentialFile(credential.getId(), true); - file.writeText(credential.serialize(true)); + let file = await this.getCredentialFile(credential.getId(), true); + await file.writeText(credential.serialize(true)); } catch (e) { // IOException throw new DIDStorageException("Store credential error: " + credential.getId(), e); } } - public loadCredential(id: DIDURL): VerifiableCredential { + public async loadCredential(id: DIDURL): Promise { try { - let file = this.getCredentialFile(id, false); - if (!file.exists()) + let file = await this.getCredentialFile(id, false); + if (!(await file.exists())) return null; - return VerifiableCredential.parse(file.readText()); + return VerifiableCredential.parse(await file.readText()); } catch (e) { // DIDSyntaxException | IOException throw new DIDStorageException("Load credential error: " + id, e); } } - public containsCredential(id: DIDURL): boolean { + public containsCredential(id: DIDURL): Promise { let dir = this.getCredentialDir(id); return dir.exists(); } - public containsCredentials(did: DID): boolean { + public async containsCredentials(did: DID): Promise { let dir = this.getCredentialsDir(did); - if (!dir.exists()) + if (!(await dir.exists())) return false; - let creds = dir.listFiles().filter((file) => { - return file.isDirectory(); - }); + const files = await dir.listFiles(); + if (!files) + return false; - return creds == null ? false : creds.length > 0; + for (const file of files) { + if (await file.isDirectory()) { + return true; + } + } + return false; } - public deleteCredential(id: DIDURL): boolean { + public async deleteCredential(id: DIDURL): Promise { let dir = this.getCredentialDir(id); - if (dir.exists()) { - dir.delete(); + if (await dir.exists()) { + await dir.delete(); // Remove the credentials directory is no credential exists. dir = this.getCredentialsDir(id.getDid()); - if (dir.list().length == 0) - dir.delete(); + if ((await dir.list()).length == 0) + await dir.delete(); return true; } else { @@ -646,30 +655,28 @@ export class FileSystemStorage implements DIDStorage { } } - public listCredentials(did: DID): DIDURL[] { + public async listCredentials(did: DID): Promise { let dir = this.getCredentialsDir(did); - if (!dir.exists()) - return []; - - let children = dir.listFiles().filter((file) => { - if(!file.isDirectory()) - return false; - - let vc = new File(file, FileSystemStorage.CREDENTIAL_FILE); - return (vc.exists() && vc.isFile()); - }); - - if (children == null || children.length == 0) + if (!(await dir.exists())) return []; let credentials: DIDURL[] = []; - for (let credential of children) - credentials.push(FileSystemStorage.toDIDURL(did, credential.getName())); - + const files = await dir.listFiles(); + if (files) { + for (const file of files) { + if(!(await file.isDirectory())) + continue; + + let vc = new File(file, FileSystemStorage.CREDENTIAL_FILE); + if (await vc.exists() && await vc.isFile()) { + credentials.push(FileSystemStorage.toDIDURL(did, vc.getName())); + } + } + } return credentials; } - private getPrivateKeyFile(id: DIDURL, create: boolean): File { + private getPrivateKeyFile(id: DIDURL, create: boolean): Promise { return this.getFile(create, this.currentDataDir, FileSystemStorage.DID_DIR, id.getDid().getMethodSpecificId(), FileSystemStorage.PRIVATEKEYS_DIR, FileSystemStorage.toPath(id)); } @@ -678,25 +685,25 @@ export class FileSystemStorage implements DIDStorage { return this.getDir(this.currentDataDir, FileSystemStorage.DID_DIR, did.getMethodSpecificId(), FileSystemStorage.PRIVATEKEYS_DIR); } - public containsPrivateKey(id: DIDURL): boolean { - let file = this.getPrivateKeyFile(id, false); - return file.exists(); + public async containsPrivateKey(id: DIDURL): Promise { + let file = await this.getPrivateKeyFile(id, false); + return await file.exists(); } - public storePrivateKey(id: DIDURL, privateKey: string) { + public async storePrivateKey(id: DIDURL, privateKey: string): Promise { try { - let file = this.getPrivateKeyFile(id, true); - file.writeText(privateKey); + let file = await this.getPrivateKeyFile(id, true); + await file.writeText(privateKey); } catch (e) { // IOException throw new DIDStorageException("Store private key error: " + id, e); } } - public loadPrivateKey(id: DIDURL): string { + public async loadPrivateKey(id: DIDURL): Promise { try { - let file = this.getPrivateKeyFile(id, false); - if (!file.exists()) + let file = await this.getPrivateKeyFile(id, false); + if (!(await file.exists())) return null; return file.readText(); @@ -705,27 +712,32 @@ export class FileSystemStorage implements DIDStorage { } } - public containsPrivateKeys(did: DID): boolean { + public async containsPrivateKeys(did: DID): Promise { let dir = this.getPrivateKeysDir(did); - if (!dir.exists()) + if (!(await dir.exists())) return false; - let keys = dir.listFiles().filter((file) => { - return file.isFile(); - }); + const files = await dir.listFiles(); + if (!files) + return false; - return keys == null ? false : keys.length > 0; + for (const file of files) { + if (await file.isFile()) { + return true; + } + } + return false; } - public deletePrivateKey(id: DIDURL): boolean { - let file = this.getPrivateKeyFile(id, false); - if (file.exists()) { - file.delete(); + public async deletePrivateKey(id: DIDURL): Promise { + let file = await this.getPrivateKeyFile(id, false); + if (await file.exists()) { + await file.delete(); // Remove the privatekeys directory is no privatekey exists. let dir = this.getPrivateKeysDir(id.getDid()); - if (dir.list().length == 0) - dir.delete(); + if ((await dir.list()).length == 0) + await dir.delete(); return true; } else { @@ -733,23 +745,21 @@ export class FileSystemStorage implements DIDStorage { } } - public listPrivateKeys(did: DID): DIDURL[] { + public async listPrivateKeys(did: DID): Promise { let dir = this.getPrivateKeysDir(did); - if (!dir.exists()) + if (!(await dir.exists())) return []; - let keys = dir.listFiles().filter((file) => { - return file.isFile(); - }); - - if (keys == null || keys.length == 0) - return []; - - let sks: DIDURL[] = []; - for (let key of keys) - sks.push(FileSystemStorage.toDIDURL(did, key.getName())); - - return sks; + let keys: DIDURL[] = []; + const files = await dir.listFiles(); + if (files) { + for (const file of files) { + if (await file.isFile()) { + keys.push(FileSystemStorage.toDIDURL(did, file.getName())); + } + } + } + return keys; } private needReencrypt(file: File): boolean { @@ -777,77 +787,75 @@ export class FileSystemStorage implements DIDStorage { return false; } - private copy(src: File, dest: File, reEncryptor: ReEncryptor) { - if (src.isDirectory()) { + private async copy(src: File, dest: File, reEncryptor: ReEncryptor): Promise { + if (await src.isDirectory()) { let dir = src; - if (!dest.exists()) { - dest.createDirectory(); + if (!(await dest.exists())) { + await dest.createDirectory(); } - let files = dir.list(); + let files = await dir.list(); for (let file of files) { let srcFile = new File(dir, file); let destFile = new File(dest, file); - this.copy(srcFile, destFile, reEncryptor); + await this.copy(srcFile, destFile, reEncryptor); } } else { if (this.needReencrypt(src)) { - let text = src.readText(); - dest.writeText(reEncryptor.reEncrypt(text)); + let text = await src.readText(); + await dest.writeText(reEncryptor.reEncrypt(text)); } else { - FileSystemStorage.copyFile(src, dest); + await FileSystemStorage.copyFile(src, dest); } } } - private postChangePassword() { + private async postChangePassword(): Promise { let dataDir = this.getDir(FileSystemStorage.DATA_DIR); let dataJournal = this.getDir(FileSystemStorage.DATA_DIR + FileSystemStorage.JOURNAL_SUFFIX); let timestamp = new Date().getTime() / 1000; let dataDeprecated = this.getDir(FileSystemStorage.DATA_DIR + "_" + timestamp); - let stageFile = this.getFile(false, "postChangePassword"); + let stageFile = await this.getFile(false, "postChangePassword"); - if (stageFile.exists()) { - if (dataJournal.exists()) { - if (dataDir.exists()) - dataDir.rename(dataDeprecated.getAbsolutePath()); + if (await stageFile.exists()) { + if (await dataJournal.exists()) { + if (await dataDir.exists()) + await dataDir.rename(dataDeprecated.getAbsolutePath()); - dataJournal.rename(dataDir.getAbsolutePath()); + await dataJournal.rename(dataDir.getAbsolutePath()); } - stageFile.delete(); + await stageFile.delete(); } else { - if (dataJournal.exists()) - dataJournal.delete(); + if (await dataJournal.exists()) + await dataJournal.delete(); } } - public changePassword(reEncryptor: ReEncryptor) { + public async changePassword(reEncryptor: ReEncryptor): Promise { try { let dataDir = this.getDir(FileSystemStorage.DATA_DIR); let dataJournal = this.getDir(FileSystemStorage.DATA_DIR + FileSystemStorage.JOURNAL_SUFFIX); - this.copy(dataDir, dataJournal, reEncryptor); + await this.copy(dataDir, dataJournal, reEncryptor); - let stageFile = this.getFile(true, "postChangePassword"); - stageFile.createFile(); + let stageFile = await this.getFile(true, "postChangePassword"); + await stageFile.createFile(); } catch (e) { if (e instanceof WrongPasswordException) throw e; // DIDStoreException | IOException throw new DIDStorageException("Change store password failed."); } finally { - this.postChangePassword(); + await this.postChangePassword(); } } - private postOperations() { - let stageFile = this.getFile(false, "postChangePassword"); - if (stageFile.exists()) { - this.postChangePassword(); - return; - } + private async postOperations(): Promise { + const stageFile = await this.getFile(false, "postChangePassword"); + if (await stageFile.exists()) + await this.postChangePassword(); } } diff --git a/src/fs.browser.ts b/src/fs.browser.ts index b462798d..ac35cccf 100644 --- a/src/fs.browser.ts +++ b/src/fs.browser.ts @@ -21,41 +21,95 @@ */ import BrowserFS, { BFSRequire } from "browserfs"; +import Stats from "browserfs/dist/node/core/node_fs_stats"; const fs = BFSRequire("fs"); -const { - existsSync, - mkdirSync, - readdirSync, - readFileSync, - renameSync, - rmdirSync, - statSync, - lstatSync, - writeFileSync, - unlinkSync -} = fs; + +export function existsSync(path: string): Promise { + return new Promise(resolve => fs.exists(path, exists => { + resolve(exists); + })); +} + +export function mkdirSync(path: string, mode?: number | string): Promise { + return new Promise((resolve, reject) => fs.mkdir(path, mode, e => { + e ? reject(e) : resolve(); + })); +} + +export function readdirSync(path: string): Promise { + return new Promise((resolve, reject) => fs.readdir(path, (e, rv) => { + e ? reject(e) : resolve(rv); + })); +} + +export function readFileSync(filename: string, options?: { encoding: string; flag?: string; }): Promise { + return new Promise((resolve, reject) => fs.readFile(filename, options, (e, rv: string) => { + e ? reject(e) : resolve(rv); + })); +} + +export function renameSync(oldPath: string, newPath: string): Promise { + return new Promise((resolve, reject) => fs.rename(oldPath, newPath, e => { + e ? reject(e) : resolve(); + })); +} + +export function rmdirSync(path: string): Promise { + return new Promise((resolve, reject) => fs.rmdir(path, e => { + e ? reject(e) : resolve(); + })); +} + +export function statSync(path: string): Promise { + return new Promise((resolve, reject) => fs.stat(path, (e, rv) => { + e ? reject(e) : resolve(rv); + })); +} + +export function lstatSync(path: string): Promise { + return new Promise((resolve, reject) => fs.lstat(path, (e, rv) => { + e ? reject(e) : resolve(rv); + })); +} + +export function writeFileSync(filename: string, data: any, options?): Promise { + return new Promise((resolve, reject) => fs.writeFile(filename, data, options, e => { + e ? reject(e) : resolve(); + })); +} + +export function unlinkSync(path: string): Promise { + return new Promise((resolve, reject) => fs.unlink(path, e => { + e ? reject(e) : resolve(); + })); +} + +// BrowserFS.configure({ +// fs: "LocalStorage", +// options: {} +// }, function(e) { +// if (e) { +// throw e; +// } +// else { +// //console.log("BrowserFS initialization complete"); +// } +// }); BrowserFS.configure({ - fs: "LocalStorage", - options: {} + fs: "MountableFileSystem", + options: { + "/": { + fs: "IndexedDB", + options: { + storeName: "DIDDatabase" + } + } + } }, function(e) { if (e) { + // An error occurred. throw e; } - else { - //console.log("BrowserFS initialization complete"); - } + // Otherwise, BrowserFS is ready to use! }); - -export { - existsSync, - mkdirSync, - readdirSync, - readFileSync, - renameSync, - rmdirSync, - statSync, - lstatSync, - writeFileSync, - unlinkSync -}; \ No newline at end of file diff --git a/src/fs.ts b/src/fs.ts index df803052..90d8c2de 100644 --- a/src/fs.ts +++ b/src/fs.ts @@ -20,19 +20,114 @@ * SOFTWARE. */ -// eslint-disable-next-line node/no-deprecated-api -export { - readdirSync, - readFileSync, - writeFileSync, - rmdirSync, - mkdirSync, - unlinkSync, - existsSync, - statSync, - accessSync, - renameSync, - lstatSync, +import * as fs from "fs"; + +export function existsSync(path: string): Promise { + return new Promise((resolve, reject) => { + try { + resolve(fs.existsSync(path)); + } catch (e) { + reject(e); + } + }); +} + +export function mkdirSync(path: string, mode?): Promise { + return new Promise((resolve, reject) => { + try { + fs.mkdirSync(path, mode); + resolve(); + } catch (e) { + reject(e); + } + }); +} + +export function readdirSync(path: string): Promise { + return new Promise((resolve, reject) => { + try { + resolve(fs.readdirSync(path)); + } catch (e) { + reject(e); + } + }); +} + +export function readFileSync(filename: string, options?: { encoding: BufferEncoding; flag?: string | undefined; } | BufferEncoding): Promise { + return new Promise((resolve, reject) => { + try { + const result: string = fs.readFileSync(filename, options); + resolve(result); + } catch (e) { + reject(e); + } + }); +} + +export function renameSync(oldPath: string, newPath: string): Promise { + return new Promise((resolve, reject) => { + try { + fs.renameSync(oldPath, newPath); + resolve(); + } catch (e) { + reject(e); + } + }); +} +export function rmdirSync(path: string): Promise { + return new Promise((resolve, reject) => { + try { + fs.rmdirSync(path); + resolve(); + } catch (e) { + reject(e); + } + }); +} + +export function statSync(path: string): Promise { + return new Promise((resolve, reject) => { + try { + resolve(fs.statSync(path)); + } catch (e) { + reject(e); + } + }); +} + +export function lstatSync(path: string): Promise { + return new Promise((resolve, reject) => { + try { + resolve(fs.lstatSync(path)); + } catch (e) { + reject(e); + } + }); +} + +export function writeFileSync(filename: string, data: any, options?): Promise { + return new Promise((resolve, reject) => { + try { + fs.writeFileSync(filename, data, options) + resolve(); + } catch (e) { + reject(e); + } + }); +} + +export function unlinkSync(path: string): Promise { + return new Promise((resolve, reject) => { + try { + fs.unlinkSync(path); + resolve(); + } catch (e) { + reject(e); + } + }); +} + +export { Stats -} from "fs"; \ No newline at end of file +} from "fs"; diff --git a/src/issuer.ts b/src/issuer.ts index 1c6d657e..9a6ac7ad 100644 --- a/src/issuer.ts +++ b/src/issuer.ts @@ -32,10 +32,10 @@ import { checkArgument, DID, DIDURL, VerifiableCredential } from "./internals"; * issuer's sign key. */ export class Issuer { - private self: DIDDocument; - private signKey: DIDURL; + private readonly self: DIDDocument; + private readonly signKey: DIDURL; - constructor(doc: DIDDocument, signKey?: DIDURL) { + private constructor(doc: DIDDocument, signKey?: DIDURL) { this.self = doc; if (signKey) { @@ -47,10 +47,16 @@ export class Issuer { throw new InvalidKeyException("Need explict sign key or effective controller"); } - if (!doc.hasPrivateKey(signKey)) + this.signKey = signKey; + } + + public static async create(doc: DIDDocument, signKey?: DIDURL): Promise { + const issuer = new Issuer(doc, signKey); + + if (!(await doc.hasPrivateKey(issuer.signKey))) throw new InvalidKeyException("No private key: " + signKey); - this.signKey = signKey; + return issuer; } /** @@ -61,17 +67,17 @@ export class Issuer { * @throws DIDStoreException there is no store to attatch * @throws InvalidKeyException the sign key is not an authenication key. */ - public static newWithDocument(doc: DIDDocument, signKey?: DIDURL | string): Issuer { + public static async newWithDocument(doc: DIDDocument, signKey?: DIDURL | string): Promise { checkArgument(doc != null, "Invalid document"); if (signKey) { if (signKey instanceof DIDURL) { - return new Issuer(doc, signKey); + return await Issuer.create(doc, signKey); } else { - return new Issuer(doc, DIDURL.from(signKey, doc.getSubject())); + return await Issuer.create(doc, DIDURL.from(signKey, doc.getSubject())); } } else { - return new Issuer(doc); + return await Issuer.create(doc); } } @@ -83,12 +89,12 @@ export class Issuer { if (signKey) { if (signKey instanceof DIDURL) { - return new Issuer(didDoc, signKey); + return await Issuer.create(didDoc, signKey); } else { - return new Issuer(didDoc, DIDURL.from(signKey, did)); + return await Issuer.create(didDoc, DIDURL.from(signKey, did)); } } else { - return new Issuer(didDoc); + return await Issuer.create(didDoc); } } diff --git a/src/rootidentity.ts b/src/rootidentity.ts index aac357b9..f28b7fb3 100644 --- a/src/rootidentity.ts +++ b/src/rootidentity.ts @@ -91,7 +91,7 @@ export class RootIdentity { * force = false, must not create new private identity if there is private identity. * @throws DIDStoreException there is private identity if user need unforce mode. */ - public static createFromMnemonic(mnemonic: string, passphrase: string, store: DIDStore, storepass: string, overwrite = false): RootIdentity { + public static async createFromMnemonic(mnemonic: string, passphrase: string, store: DIDStore, storepass: string, overwrite = false): Promise { checkArgument(mnemonic != null && mnemonic !== "", "Invalid mnemonic"); checkArgument(store != null, "Invalid DID store"); checkArgument(storepass != null && storepass !== "", "Invalid storepass"); @@ -107,11 +107,11 @@ export class RootIdentity { let identity = RootIdentity.newFromMnemonic(mnemonic, passphrase); - if (store.containsRootIdentity(identity.getId()) && !overwrite) + if (await store.containsRootIdentity(identity.getId()) && !overwrite) throw new RootIdentityAlreadyExistException(identity.getId() + " already exist"); identity.setMetadata(new RootIdentity.Metadata(identity.getId(), store)); - store.storeRootIdentity(identity, storepass); + await store.storeRootIdentity(identity, storepass); identity.wipe(); return identity; @@ -126,7 +126,7 @@ export class RootIdentity { * force = false, must not create new private identity if there is private identity. * @throws DIDStoreException there is private identity if user need unforce mode. */ - public static createFromPrivateKey(extentedPrivateKey: string, store: DIDStore, storepass: string, overwrite = false): RootIdentity { + public static async createFromPrivateKey(extentedPrivateKey: string, store: DIDStore, storepass: string, overwrite = false): Promise { checkArgument(extentedPrivateKey != null && extentedPrivateKey !== "", "Invalid extended private key"); checkArgument(store != null, "Invalid DID store"); @@ -135,11 +135,11 @@ export class RootIdentity { let rootPrivateKey = HDKey.deserializeBase58(extentedPrivateKey); let identity = RootIdentity.newFromPrivateKey(rootPrivateKey); - if (store.containsRootIdentity(identity.getId()) && !overwrite) + if (await store.containsRootIdentity(identity.getId()) && !overwrite) throw new RootIdentityAlreadyExistException(identity.getId() + " already exist"); identity.setMetadata(new RootIdentity.Metadata(identity.getId(), store)); - store.storeRootIdentity(identity, storepass); + await store.storeRootIdentity(identity, storepass); identity.wipe(); return identity; @@ -182,12 +182,12 @@ export class RootIdentity { return this.metadata.getAlias(); } - public setAlias(alias: string) { - this.metadata.setAlias(alias); + public setAlias(alias: string): Promise { + return this.metadata.setAlias(alias); } - public setAsDefault() { - this.getStore().setDefaultRootIdentity(this); + public setAsDefault(): Promise { + return this.getStore().setDefaultRootIdentity(this); } public getDefaultDid(): DID { @@ -198,17 +198,17 @@ export class RootIdentity { return did; } - public setDefaultDid(did: DID | string) { + public async setDefaultDid(did: DID | string): Promise { if (did instanceof DID) - this.metadata.setDefaultDid(did); + await this.metadata.setDefaultDid(did); else - this.metadata.setDefaultDid(DID.from(did as string)); + await this.metadata.setDefaultDid(DID.from(did as string)); } - public setDefaultDidByIndex(index: number) { + public setDefaultDidByIndex(index: number): Promise { checkArgument(index >= 0, "Invalid index"); - this.metadata.setDefaultDid(this.getDid(index)); + return this.metadata.setDefaultDid(this.getDid(index)); } public getMnemonic(): string { @@ -233,14 +233,14 @@ export class RootIdentity { return this.index; } - protected setIndex(idx: number) { + protected setIndex(idx: number): Promise { this.index = idx; - this.getStore().storeRootIdentity(this); + return this.getStore().storeRootIdentity(this); } - protected incrementIndex(): number { + protected async incrementIndex(): Promise { let idx = ++this.index; - this.getStore().storeRootIdentity(this); + await this.getStore().storeRootIdentity(this); return idx; } @@ -278,7 +278,7 @@ export class RootIdentity { if (identity == null) return null; - let key = store.derive(identity, HDKey.DERIVE_PATH_PREFIX + + let key = await store.derive(identity, HDKey.DERIVE_PATH_PREFIX + doc.getMetadata().getIndex(), storepass); let pk = doc.getPublicKey(id); @@ -293,7 +293,7 @@ export class RootIdentity { } let sk = key.serialize(); - store.storePrivateKey(id, sk, storepass); + await store.storePrivateKey(id, sk, storepass); // JAVA: store.storePrivateKey(id, key.serialize(), storepass); // JAVA: let sk = key.serialize(); return sk; @@ -364,23 +364,23 @@ export class RootIdentity { log.debug("Creating new DID {} at index {}...", did.toString(), index); - let key = this.getStore().derive(this.getId(), HDKey.DERIVE_PATH_PREFIX + index, storepass); + let key = await this.getStore().derive(this.getId(), HDKey.DERIVE_PATH_PREFIX + index, storepass); try { let id = DIDURL.from("#primary", did); - this.getStore().storePrivateKey(id, key.serialize(), storepass); + await this.getStore().storePrivateKey(id, key.serialize(), storepass); let db = DIDDocument.Builder.newFromDID(did, this.getStore()); db.addAuthenticationKey(id, key.getPublicKeyBase58()); doc = await db.seal(storepass); - doc.getMetadata().setRootIdentityId(this.getId()); - doc.getMetadata().setIndex(index); + await doc.getMetadata().setRootIdentityId(this.getId()); + await doc.getMetadata().setIndex(index); doc.getMetadata().attachStore(this.getStore()); await this.getStore().storeDid(doc); if (shouldIncrementIndexAfterCompletion) - this.incrementIndex(); + await this.incrementIndex(); return doc; } catch (e) { @@ -406,7 +406,7 @@ export class RootIdentity { checkArgument(identifier != null && identifier!== "", "Invalid identifier"); let path = HDKey.PRE_DERIVED_PUBLICKEY_PATH + "/" + this.mapToDerivePath(identifier, securityCode); - let key = this.getStore().derive(this.getId(), path, storepass); + let key = await this.getStore().derive(this.getId(), path, storepass); let did = new DID(DID.METHOD, key.getAddress()); let doc = await this.getStore().loadDid(did); @@ -436,15 +436,15 @@ export class RootIdentity { try { let id = DIDURL.from("#primary", did); - this.getStore().storePrivateKey(id, key.serialize(), storepass); + await this.getStore().storePrivateKey(id, key.serialize(), storepass); let db = DIDDocument.Builder.newFromDID(did, this.getStore()); db.addAuthenticationKey(id, key.getPublicKeyBase58()); doc = await db.seal(storepass); - doc.getMetadata().setRootIdentityId(this.getId()); - doc.getMetadata().setExtra("application", identifier); - doc.getMetadata().setExtra("securityCode", securityCode); + await doc.getMetadata().setRootIdentityId(this.getId()); + await doc.getMetadata().setExtra("application", identifier); + await doc.getMetadata().setExtra("securityCode", securityCode); doc.getMetadata().attachStore(this.getStore()); await this.getStore().storeDid(doc); @@ -457,7 +457,7 @@ export class RootIdentity { } } - public hasMnemonic(): boolean { + public hasMnemonic(): Promise { return this.getStore().containsRootIdentityMnemonic(this.getId()); } @@ -468,7 +468,7 @@ export class RootIdentity { * @return the mnemonic string * @throws DIDStoreException there is no mnemonic in DID Store. */ - public exportMnemonic(storepass: string): string { + public exportMnemonic(storepass: string): Promise { checkArgument(storepass != null && storepass !== "", "Invalid storepass"); return this.getStore().exportRootIdentityMnemonic(this.getId(), storepass); @@ -506,7 +506,7 @@ export class RootIdentity { log.debug("{} on-chain copy conflict with local copy.", did.toString()); // Local copy was modified - finalDoc = handle.merge(resolvedDoc, localDoc); + finalDoc = await handle.merge(resolvedDoc, localDoc); if (finalDoc == null || !finalDoc.getSubject().equals(did)) { log.error("Conflict handle merge the DIDDocument error."); throw new DIDStoreException("deal with local modification error."); @@ -517,17 +517,17 @@ export class RootIdentity { } let metadata = finalDoc.getMetadata(); - metadata.setPublished(resolvedDoc.getMetadata().getPublished()); - metadata.setSignature(resolvedDoc.getProof().getSignature()); + await metadata.setPublished(resolvedDoc.getMetadata().getPublished()); + await metadata.setSignature(resolvedDoc.getProof().getSignature()); if (resolvedDoc.getMetadata().isDeactivated()) - metadata.setDeactivated(true); + await metadata.setDeactivated(true); - metadata.setRootIdentityId(this.getId()); - metadata.setIndex(index); + await metadata.setRootIdentityId(this.getId()); + await metadata.setIndex(index); if (localDoc != null) localDoc.getMetadata().attachStore(this.getStore()) await this.getStore().storeDid(finalDoc); - this.getStore().storeLazyPrivateKey(finalDoc.getDefaultPublicKeyId()); + await this.getStore().storeLazyPrivateKey(finalDoc.getDefaultPublicKeyId()); return true; } @@ -562,7 +562,7 @@ export class RootIdentity { } if (lastIndex >= this.getIndex()) - this.setIndex(lastIndex + 1); + await this.setIndex(lastIndex + 1); } } @@ -587,8 +587,8 @@ export namespace RootIdentity { * * @param txid the transaction id string */ - public setDefaultDid(did: DID) { - this.put(Metadata.DEFAULT_DID, did.toString()); + public setDefaultDid(did: DID): Promise { + return this.put(Metadata.DEFAULT_DID, did.toString()); } /** @@ -600,10 +600,10 @@ export namespace RootIdentity { return DID.from(this.get(Metadata.DEFAULT_DID) as string); } - protected save() { + protected async save(): Promise { if (this.attachedStore()) { try { - this.getStore().storeRootIdentityMetadata(this.id, this); + await this.getStore().storeRootIdentityMetadata(this.id, this); } catch (e) { if (e instanceof DIDStoreException) log.error("INTERNAL - error store metadata for credential {}", this.id); diff --git a/src/transferticket.ts b/src/transferticket.ts index cd947b33..92f5cb77 100644 --- a/src/transferticket.ts +++ b/src/transferticket.ts @@ -77,7 +77,7 @@ export class TransferTicket extends DIDEntity { throw new NotCustomizedDIDException(target.getSubject().toString() + "isn't a customized did"); let doc = await target.getSubject().resolve(); - target.getMetadata().setTransactionId(doc.getMetadata().getTransactionId()); + await target.getMetadata().setTransactionId(doc.getMetadata().getTransactionId()); let newTicket = new TransferTicket(target.getSubject(), to, target.getMetadata().getTransactionId()); newTicket.doc = target; diff --git a/src/verifiablecredential.ts b/src/verifiablecredential.ts index 7ce28350..a71d8b3c 100644 --- a/src/verifiablecredential.ts +++ b/src/verifiablecredential.ts @@ -378,7 +378,7 @@ export class VerifiableCredential extends DIDEntity implem let revoked = bio.getStatus().equals(CredentialBiographyStatus.REVOKED); if (revoked) - this.getMetadata().setRevoked(revoked); + await this.getMetadata().setRevoked(revoked); return revoked; } diff --git a/src/verifiablepresentation.ts b/src/verifiablepresentation.ts index b72b0329..5ac2ada5 100644 --- a/src/verifiablepresentation.ts +++ b/src/verifiablepresentation.ts @@ -461,7 +461,7 @@ export class VerifiablePresentation extends DIDEntity { throw new InvalidKeyException(signKey.toString()+ " isn't the authencation key"); } - if (!holder.hasPrivateKey(signKey)) + if (!await holder.hasPrivateKey(signKey)) throw new InvalidKeyException("No private key: " + signKey); return new VerifiablePresentation.Builder(holder, signKey); diff --git a/tests/src-no-jest/index.ts b/tests/src-no-jest/index.ts index b218d677..8ca08cf9 100644 --- a/tests/src-no-jest/index.ts +++ b/tests/src-no-jest/index.ts @@ -2,6 +2,6 @@ import { DIDStore } from "../../typings"; import { TestConfig } from "../src/utils/testconfig"; import { TestData } from "../src/utils/testdata"; -let identity = new TestData().getRootIdentity(); -let doc = identity.newDid(TestConfig.storePass); +let identity = await (await TestData.create()).getRootIdentity(); +let doc = await identity.newDid(TestConfig.storePass); console.log("END"); \ No newline at end of file diff --git a/tests/src/diddocument.test.ts b/tests/src/diddocument.test.ts index aca21a93..4801f599 100644 --- a/tests/src/diddocument.test.ts +++ b/tests/src/diddocument.test.ts @@ -124,7 +124,7 @@ describe('DIDDocument Tests', () => { let testData: TestData; let store: DIDStore; beforeEach(async () => { - testData = new TestData(); + testData = await TestData.create(); await testData.cleanup(); store = await testData.getStore(); }); @@ -433,18 +433,18 @@ describe('DIDDocument Tests', () => { // recovery used by authorization, should failed. let id = DIDURL.from("#recovery", doc.getSubject()); - expect(() => { db.removePublicKey(id) }).toThrowError(); + await expect(async () => { await db.removePublicKey(id) }).rejects.toThrowError(); // force remove public key, should success - db.removePublicKey(id, true); - db.removePublicKey("#key2", true); + await db.removePublicKey(id, true); + await db.removePublicKey("#key2", true); // Key not exist, should fail. - expect(() => { db.removePublicKey("#notExistKey", true); }).toThrowError(); + await expect(async () => { await db.removePublicKey("#notExistKey", true); }).rejects.toThrowError(); // Can not remove default publickey, should fail. let d = doc; - expect(() => { db.removePublicKey(d.getDefaultPublicKeyId(), true); }).toThrowError(); + await expect(async () => { await db.removePublicKey(d.getDefaultPublicKeyId(), true); }).rejects.toThrowError(); doc = await db.seal(TestConfig.storePass); expect(doc).not.toBeNull(); @@ -485,18 +485,18 @@ describe('DIDDocument Tests', () => { // Can not remove the controller's key let key2 = DIDURL.from("#key2", user1.getSubject()); - expect(() => { db.removePublicKey(key2); }).toThrowError(); + await expect(async () => { await db.removePublicKey(key2); }).rejects.toThrowError(); // key2 used by authentication, should failed. let id = DIDURL.from("#key2", doc.getSubject()); - expect(() => { db.removePublicKey(id); }).toThrowError(); + await expect(async () => { await db.removePublicKey(id); }).rejects.toThrowError(); // force remove public key, should success - db.removePublicKey(id, true); - db.removePublicKey("#key3", true); + await db.removePublicKey(id, true); + await db.removePublicKey("#key3", true); // Key not exist, should fail. - expect(() => { db.removePublicKey("#notExistKey", true); }).toThrowError(); + await expect(async () => { await db.removePublicKey("#notExistKey", true); }).rejects.toThrowError(); doc = await db.seal(TestConfig.storePass); doc = await user1.signWithDocument(doc, TestConfig.storePass); @@ -1034,7 +1034,7 @@ describe('DIDDocument Tests', () => { db.removeAuthenticationKey(DIDURL.from("#key2", doc.getSubject())) .removeAuthenticationKey("#key3"); - db.removePublicKey("#key3"); + await db.removePublicKey("#key3"); // Key not exist, should fail. expect(() => { db.removeAuthenticationKey("#notExistKey"); }).toThrowError(); @@ -2238,13 +2238,13 @@ describe('DIDDocument Tests', () => { let cd = testData.getCompatibleData(source.version); await cd.loadAll(); - let compactJson = cd.getDocumentJson(source.did, "compact"); + let compactJson = await cd.getDocumentJson(source.did, "compact"); let compact = await DIDDocument.parseAsync(compactJson); expect(compact).not.toBeNull(); let valid = await compact.isValid(); expect(valid).toBeTruthy(); - let normalizedJson = cd.getDocumentJson(source.did, "normalized"); + let normalizedJson = await cd.getDocumentJson(source.did, "normalized"); let normalized = await DIDDocument.parseAsync(normalizedJson); expect(normalized).not.toBeNull(); valid = await normalized.isValid(); @@ -2300,7 +2300,7 @@ describe('DIDDocument Tests', () => { for(let source of csvSource){ let cd = testData.getCompatibleData(source.version); await cd.loadAll(); - let compactJson = cd.getDocumentJson(source.did, "compact"); + let compactJson = await cd.getDocumentJson(source.did, "compact"); let compact = await DIDDocument.parseAsync(compactJson); expect(compact).not.toBeNull(); let valid = await compact.isValid(); @@ -2315,7 +2315,7 @@ describe('DIDDocument Tests', () => { expect(listener.toString().startsWith(" - ")).toBeTruthy(); listener.reset(); - let normalizedJson = cd.getDocumentJson(source.did, "normalized"); + let normalizedJson = await cd.getDocumentJson(source.did, "normalized"); let normalized = await DIDDocument.parseAsync(normalizedJson); expect(normalized).not.toBeNull(); valid = await normalized.isValid(); @@ -3365,7 +3365,7 @@ describe('DIDDocument Tests', () => { expect(resolved).not.toBeNull(); expect(resolved.toString()).toEqual(doc.toString()) - doc.getMetadata().setPreviousSignature(null); + await doc.getMetadata().setPreviousSignature(null); // Update again db = DIDDocument.Builder.newFromDocument(doc).edit(); @@ -3414,7 +3414,7 @@ describe('DIDDocument Tests', () => { expect(resolved).not.toBeNull(); expect(resolved.toString()).toEqual(doc.toString()); - doc.getMetadata().setSignature(null); + await doc.getMetadata().setSignature(null); // Update again db = DIDDocument.Builder.newFromDocument(doc).edit(); @@ -3446,8 +3446,8 @@ describe('DIDDocument Tests', () => { expect(resolved).not.toBeNull() expect(resolved.toString()).toEqual(doc.toString()); - doc.getMetadata().setPreviousSignature(null); - doc.getMetadata().setSignature(null); + await doc.getMetadata().setPreviousSignature(null); + await doc.getMetadata().setSignature(null); // Update let db = DIDDocument.Builder.newFromDocument(doc).edit(); @@ -3479,8 +3479,8 @@ describe('DIDDocument Tests', () => { expect(resolved).not.toBeNull(); expect(resolved.toString()).toEqual(doc.toString()) - doc.getMetadata().setPreviousSignature(null); - doc.getMetadata().setSignature(null); + await doc.getMetadata().setPreviousSignature(null); + await doc.getMetadata().setSignature(null); // Update let db = DIDDocument.Builder.newFromDocument(doc).edit(); @@ -3529,7 +3529,7 @@ describe('DIDDocument Tests', () => { expect(resolved).not.toBeNull(); expect(resolved.toString()).toEqual(doc.toString()); - doc.getMetadata().setPreviousSignature("1234567890"); + await doc.getMetadata().setPreviousSignature("1234567890"); // Update db = DIDDocument.Builder.newFromDocument(doc).edit(); @@ -3578,7 +3578,7 @@ describe('DIDDocument Tests', () => { expect(resolved).not.toBeNull(); expect(resolved.toString()).toEqual(doc.toString()); - doc.getMetadata().setSignature("1234567890"); + await doc.getMetadata().setSignature("1234567890"); // Update db = DIDDocument.Builder.newFromDocument(doc).edit(); @@ -3610,7 +3610,7 @@ describe('DIDDocument Tests', () => { expect(resolved).not.toBeNull(); expect(resolved.toString()).toEqual(doc.toString()) - doc.getMetadata().setPreviousSignature("1234567890"); + await doc.getMetadata().setPreviousSignature("1234567890"); // Update let db = DIDDocument.Builder.newFromDocument(doc).edit(); let key = TestData.generateKeypair(); @@ -3642,7 +3642,7 @@ describe('DIDDocument Tests', () => { expect(resolved).not.toBeNull(); expect(resolved.toString()).toEqual(doc.toString()); - doc.getMetadata().setSignature("1234567890"); + await doc.getMetadata().setSignature("1234567890"); // Update let db = DIDDocument.Builder.newFromDocument(doc).edit(); @@ -4420,8 +4420,8 @@ describe('DIDDocument Tests', () => { let id = DIDURL.from("#key-2", doc.getSubject()); db.addAuthenticationKey(id, key.getPublicKeyBase58()); - store.storePrivateKey(id, key.serialize(), TestConfig.storePass); - expect(store.containsPrivateKey(id)).toBeTruthy(); + await store.storePrivateKey(id, key.serialize(), TestConfig.storePass); + expect(await store.containsPrivateKey(id)).toBeTruthy(); doc = await db.seal(TestConfig.storePass); let valid = await doc.isValid(); @@ -4469,7 +4469,7 @@ describe('DIDDocument Tests', () => { let key = TestData.generateKeypair(); let id = DIDURL.from("#key-2", doc.getSubject()); db.addAuthenticationKey(id, key.getPublicKeyBase58()); - store.storePrivateKey(id, key.serialize(), TestConfig.storePass); + await store.storePrivateKey(id, key.serialize(), TestConfig.storePass); doc = await db.seal(TestConfig.storePass); let valid = await doc.isValid(); expect(valid).toBeTruthy(); diff --git a/tests/src/didstore.test.ts b/tests/src/didstore.test.ts index 0a9ca98f..654e7452 100644 --- a/tests/src/didstore.test.ts +++ b/tests/src/didstore.test.ts @@ -34,13 +34,13 @@ let store: DIDStore; describe("DIDStore Tests", ()=>{ beforeEach(async () => { - testData = new TestData(); + testData = await TestData.create(); await testData.cleanup(); store = await testData.getStore(); }) afterEach(async () => { - testData.cleanup(); + await testData.cleanup(); }); // Java: @ExtendWith(DIDTestExtension.class) @@ -60,8 +60,8 @@ describe("DIDStore Tests", ()=>{ test("testLoadRootIdentityFromEmptyStore", async () => { let file = getFile(".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); let identity = await store.loadRootIdentity(); expect(identity).toBeNull(); @@ -69,40 +69,40 @@ describe("DIDStore Tests", ()=>{ test("testBulkCreate", async ()=>{ let file = getFile(".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); let identity = await testData.getRootIdentity(); file = getFile("roots", identity.getId(), "mnemonic"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("roots", identity.getId(), "private"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("roots", identity.getId(), "public"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("roots", identity.getId(), "index"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("roots", identity.getId(), ".metadata"); - expect(file.exists()).toBeFalsy(); + expect(await file.exists()).toBeFalsy(); - identity.setAlias("default"); + await identity.setAlias("default"); file = getFile("roots", identity.getId(), ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); let valid : boolean; for (let i = 0; i < TestConfig.DID_INDEX_LOOPS; i++) { let alias = "my did " + i; let doc = await identity.newDid(TestConfig.storePass); - doc.getMetadata().setAlias(alias); + await doc.getMetadata().setAlias(alias); valid = await doc.isValid(); expect(valid).toBeTruthy(); @@ -113,12 +113,12 @@ describe("DIDStore Tests", ()=>{ await DIDTestExtension.awaitStandardPublishingDelay(); file = getFile("ids", doc.getSubject().getMethodSpecificId(), "document"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", doc.getSubject().getMethodSpecificId(), ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); resolved = await doc.getSubject().resolve(); expect(resolved).not.toBeNull(); @@ -133,7 +133,7 @@ describe("DIDStore Tests", ()=>{ let dids = await store.listDids(); expect(dids.length).toBe(TestConfig.DID_INDEX_LOOPS); - expect(store.containsDids()).toBeTruthy(); + expect(await store.containsDids()).toBeTruthy(); }); test("testDeleteDID", async ()=>{ @@ -144,7 +144,7 @@ describe("DIDStore Tests", ()=>{ for (let i = 0; i < TestConfig.DID_INDEX_LOOPS; i++) { let alias = "my did " + i; let doc = await identity.newDid(TestConfig.storePass); - doc.getMetadata().setAlias(alias); + await doc.getMetadata().setAlias(alias); await doc.publish(TestConfig.storePass); await DIDTestExtension.awaitStandardPublishingDelay(); dids.push(doc.getSubject()); @@ -156,13 +156,13 @@ describe("DIDStore Tests", ()=>{ let did = dids[i]; - let deleted = store.deleteDid(did); + let deleted = await store.deleteDid(did); expect(deleted).toBeTruthy(); let file = getFile("ids", did.getMethodSpecificId()); - expect(file.exists()).toBeFalsy(); + expect(await file.exists()).toBeFalsy(); - deleted = store.deleteDid(did); + deleted = await store.deleteDid(did); expect(deleted).toBeFalsy(); } @@ -175,22 +175,22 @@ describe("DIDStore Tests", ()=>{ let issuer = await testData.getInstantData().getIssuerDocument(); let file = getFile("ids", issuer.getSubject().getMethodSpecificId(), "document"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", issuer.getSubject().getMethodSpecificId(), ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); let test = await testData.getInstantData().getUser1Document(); file = getFile("ids", test.getSubject().getMethodSpecificId(), "document"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", test.getSubject().getMethodSpecificId(), ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); let doc = await store.loadDid(issuer.getSubject()); expect(issuer.getSubject().equals(doc.getSubject())).toBeTruthy(); @@ -214,56 +214,56 @@ describe("DIDStore Tests", ()=>{ let user = await testData.getInstantData().getUser1Document(); let vc = user.getCredential("#profile"); - vc.getMetadata().setAlias("MyProfile"); + await vc.getMetadata().setAlias("MyProfile"); let file = getFile("ids", vc.getId().getDid().getMethodSpecificId(), "credentials", "#" + vc.getId().getFragment(), "credential"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", vc.getId().getDid().getMethodSpecificId(), "credentials", "#" + vc.getId().getFragment(), ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); vc = user.getCredential("#email"); - vc.getMetadata().setAlias("Email"); + await vc.getMetadata().setAlias("Email"); file = getFile("ids", vc.getId().getDid().getMethodSpecificId(), "credentials", "#" + vc.getId().getFragment(), "credential"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", vc.getId().getDid().getMethodSpecificId(), "credentials", "#" + vc.getId().getFragment(), ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); vc = await testData.getInstantData().getUser1TwitterCredential(); - vc.getMetadata().setAlias("Twitter"); + await vc.getMetadata().setAlias("Twitter"); file = getFile("ids", vc.getId().getDid().getMethodSpecificId(), "credentials", "#" + vc.getId().getFragment(), "credential"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", vc.getId().getDid().getMethodSpecificId(), "credentials", "#" + vc.getId().getFragment(), ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); vc = await testData.getInstantData().getUser1PassportCredential(); - vc.getMetadata().setAlias("Passport"); + await vc.getMetadata().setAlias("Passport"); file = getFile("ids", vc.getId().getDid().getMethodSpecificId(), "credentials", "#" + vc.getId().getFragment(), "credential"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", vc.getId().getDid().getMethodSpecificId(), "credentials", "#" + vc.getId().getFragment(), ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); let id = DIDURL.from("#profile", user.getSubject()); vc = await store.loadCredential(id); @@ -292,10 +292,10 @@ describe("DIDStore Tests", ()=>{ expect(vc).toBeNull(); id = DIDURL.from("#twitter", user.getSubject()); - expect(store.containsCredential(id)).toBeTruthy(); - expect(store.containsCredential(id.toString())).toBeTruthy(); - expect(store.containsCredentials(user.getSubject())).toBeTruthy(); - expect(store.containsCredential(DIDURL.from("#notExists", user.getSubject()))).toBeFalsy(); + expect(await store.containsCredential(id)).toBeTruthy(); + expect(await store.containsCredential(id.toString())).toBeTruthy(); + expect(await store.containsCredentials(user.getSubject())).toBeTruthy(); + expect(await store.containsCredential(DIDURL.from("#notExists", user.getSubject()))).toBeFalsy(); }); test("testListCredentials", async ()=>{ @@ -305,13 +305,13 @@ describe("DIDStore Tests", ()=>{ await testData.getInstantData().getIssuerDocument(); let user = await testData.getInstantData().getUser1Document(); let vc = user.getCredential("#profile"); - vc.getMetadata().setAlias("MyProfile"); + await vc.getMetadata().setAlias("MyProfile"); vc = user.getCredential("#email"); - vc.getMetadata().setAlias("Email"); + await vc.getMetadata().setAlias("Email"); vc = await testData.getInstantData().getUser1TwitterCredential(); - vc.getMetadata().setAlias("Twitter"); + await vc.getMetadata().setAlias("Twitter"); vc = await testData.getInstantData().getUser1PassportCredential(); - vc.getMetadata().setAlias("Passport"); + await vc.getMetadata().setAlias("Passport"); let vcs = await store.listCredentials(user.getSubject()); expect(vcs.length).toBe(4); @@ -334,56 +334,56 @@ describe("DIDStore Tests", ()=>{ await testData.getInstantData().getIssuerDocument(); let user = await testData.getInstantData().getUser1Document(); let vc = user.getCredential("#profile"); - vc.getMetadata().setAlias("MyProfile"); + await vc.getMetadata().setAlias("MyProfile"); vc = user.getCredential("#email"); - vc.getMetadata().setAlias("Email"); + await vc.getMetadata().setAlias("Email"); vc = await testData.getInstantData().getUser1TwitterCredential(); - vc.getMetadata().setAlias("Twitter"); + await vc.getMetadata().setAlias("Twitter"); vc = await testData.getInstantData().getUser1PassportCredential(); - vc.getMetadata().setAlias("Passport"); + await vc.getMetadata().setAlias("Passport"); let file = getFile("ids", user.getSubject().getMethodSpecificId(), "credentials", "#twitter", "credential"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", user.getSubject().getMethodSpecificId(), "credentials", "#twitter", ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", user.getSubject().getMethodSpecificId(), "credentials", "#passport", "credential"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", user.getSubject().getMethodSpecificId(), "credentials", "#passport", ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); - let deleted = store.deleteCredential(DIDURL.from("#twitter", user.getSubject())); + let deleted = await store.deleteCredential(DIDURL.from("#twitter", user.getSubject())); expect(deleted).toBeTruthy(); - deleted = store.deleteCredential(DIDURL.from("#passport", user.getSubject()).toString()); + deleted = await store.deleteCredential(DIDURL.from("#passport", user.getSubject()).toString()); expect(deleted).toBeTruthy(); - deleted = store.deleteCredential(user.getSubject().toString() + "#notExist"); + deleted = await store.deleteCredential(user.getSubject().toString() + "#notExist"); expect(deleted).toBeFalsy(); file = getFile("ids", user.getSubject().getMethodSpecificId(), "credentials", "#twitter"); - expect(file.exists()).toBeFalsy(); + expect(await file.exists()).toBeFalsy(); file = getFile("ids", user.getSubject().getMethodSpecificId(), "credentials", "#passport"); - expect(file.exists()).toBeFalsy(); + expect(await file.exists()).toBeFalsy(); - expect(store.containsCredential(DIDURL.from("#email", user.getSubject()))).toBeTruthy(); - expect(store.containsCredential(user.getSubject().toString() + "#profile")).toBeTruthy(); + expect(await store.containsCredential(DIDURL.from("#email", user.getSubject()))).toBeTruthy(); + expect(await store.containsCredential(user.getSubject().toString() + "#profile")).toBeTruthy(); - expect(store.containsCredential(DIDURL.from("#twitter", user.getSubject()))).toBeFalsy(); - expect(store.containsCredential(user.getSubject().toString() + "#passport")).toBeFalsy(); + expect(await store.containsCredential(DIDURL.from("#twitter", user.getSubject()))).toBeFalsy(); + expect(await store.containsCredential(user.getSubject().toString() + "#passport")).toBeFalsy(); }); test("testSynchronizeStore", async ()=> { @@ -392,7 +392,7 @@ describe("DIDStore Tests", ()=>{ for (let i = 0; i < 5; i++) { let alias = "my did " + i; let doc = await identity.newDid(TestConfig.storePass); - doc.getMetadata().setAlias(alias); + await doc.getMetadata().setAlias(alias); valid = await doc.isValid(); expect(valid).toBeTruthy(); @@ -409,7 +409,7 @@ describe("DIDStore Tests", ()=>{ let dids: DID[] = Array.from(await store.listDids()); dids.sort((a,b) => a.compareTo(b)); for (let did of dids) { - expect(store.deleteDid(did)).toBeTruthy(); + expect(await store.deleteDid(did)).toBeTruthy(); } let empty: DID[] = Array.from(await store.listDids()); @@ -431,7 +431,7 @@ describe("DIDStore Tests", ()=>{ for (let i = 0; i < LOOP_COUNT; i++) { let alias = "my did " + i; let doc = await identity.newDid(TestConfig.storePass); - doc.getMetadata().setAlias(alias); + await doc.getMetadata().setAlias(alias); valid = await doc.isValid(); expect(valid).toBeTruthy(); @@ -442,16 +442,16 @@ describe("DIDStore Tests", ()=>{ await DIDTestExtension.awaitStandardPublishingDelay(); let file = getFile("ids", doc.getSubject().getMethodSpecificId(), "document"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", doc.getSubject().getMethodSpecificId(), ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", doc.getSubject().getMethodSpecificId(), "privatekeys", "#primary"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); resolved = await doc.getSubject().resolve(); expect(resolved).not.toBeNull(); @@ -468,7 +468,7 @@ describe("DIDStore Tests", ()=>{ let dids: DID[] = Array.from(await store.listDids()); expect(dids.length).toBe(LOOP_COUNT); - store.changePassword(TestConfig.storePass, "newpasswd"); + await store.changePassword(TestConfig.storePass, "newpasswd"); dids = Array.from(await store.listDids()); expect(dids.length).toBe(LOOP_COUNT); @@ -482,16 +482,16 @@ describe("DIDStore Tests", ()=>{ expect(valid).toBeTruthy(); let file = getFile("ids", did.getMethodSpecificId(), "document"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", did.getMethodSpecificId(), ".metadata"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); file = getFile("ids", did.getMethodSpecificId(), "privatekeys", "#primary"); - expect(file.exists()).toBeTruthy(); - expect(file.isFile()).toBeTruthy(); + expect(await file.exists()).toBeTruthy(); + expect(await file.isFile()).toBeTruthy(); expect(alias).toEqual(doc.getMetadata().getAlias()); } @@ -507,7 +507,7 @@ describe("DIDStore Tests", ()=>{ for (let i = 0; i < 4; i++) { let alias = "my did " + i; let doc = await identity.newDid(TestConfig.storePass); - doc.getMetadata().setAlias(alias); + await doc.getMetadata().setAlias(alias); valid = await doc.isValid(); expect(valid).toBeTruthy(); } @@ -515,9 +515,9 @@ describe("DIDStore Tests", ()=>{ let dids = await store.listDids(); expect(dids.length).toBe(4); - expect(() => { - store.changePassword("wrongpasswd", "newpasswd"); - }).toThrowError(Exceptions.WrongPasswordException); + await expect(async () => { + await store.changePassword("wrongpasswd", "newpasswd"); + }).rejects.toThrowError(Exceptions.WrongPasswordException); }); //js can't need to check v1 @@ -541,19 +541,19 @@ describe("DIDStore Tests", ()=>{ expect(vcs.length).toBe(1); for (let id of vcs) - expect(store.loadCredential(id)).not.toBeNull(); + expect(await store.loadCredential(id)).not.toBeNull(); } else if (alias === "User1") { let vcs = await store.listCredentials(did); expect(vcs.length).toBe(parseFloat(version) >= 2.0 ? 5 : 4); for (let id of vcs) - expect(store.loadCredential(id)).not.toBeNull(); + expect(await store.loadCredential(id)).not.toBeNull(); } else if (alias === "User2") { let vcs = await store.listCredentials(did); expect(vcs.length).toBe(1); for (let id of vcs) - expect(store.loadCredential(id)).not.toBeNull(); + expect(await store.loadCredential(id)).not.toBeNull(); } else if (alias === "User3") { let vcs = await store.listCredentials(did); expect(vcs.length).toBe(0); @@ -589,7 +589,7 @@ describe("DIDStore Tests", ()=>{ let doc = await identity.newDid(TestConfig.storePass); expect(doc).not.toBeNull(); - store.deleteDid(doc.getSubject()); + await store.deleteDid(doc.getSubject()); let did = identity.getDid(1000); @@ -597,7 +597,7 @@ describe("DIDStore Tests", ()=>{ expect(doc).not.toBeNull(); expect(doc.getSubject().equals(did)).toBeTruthy(); - store.deleteDid(doc.getSubject()); + await store.deleteDid(doc.getSubject()); }); }); @@ -615,8 +615,8 @@ describe("DIDStore Tests", ()=>{ for (let i = 0; i < 10; i++) { let alias = "my did " + i; let doc = await identity.newDid(TestConfig.storePass); - doc.getMetadata().setAlias(alias); - let issuer = new Issuer(doc); + await doc.getMetadata().setAlias(alias); + let issuer = await Issuer.create(doc); let cb = issuer.issueFor(doc.getSubject()); let vc = await cb.id("#cred-1") .typeWithContext("SelfProclaimedCredential", "https://ns.elastos.org/credentials/v1") @@ -640,8 +640,8 @@ describe("DIDStore Tests", ()=>{ store = await DIDStore.open(TestConfig.storeRoot, 0, 0); let mnemonic = Mnemonic.getInstance().generate(); - RootIdentity.createFromMnemonic(mnemonic, TestConfig.passphrase, - store, TestConfig.storePass, true); + await RootIdentity.createFromMnemonic(mnemonic, TestConfig.passphrase, + store, TestConfig.storePass, true); await createDataForPerformanceTest(store); @@ -676,7 +676,7 @@ describe("DIDStore Tests", ()=>{ stores[i] = await DIDStore.open(TestConfig.storeRoot + i); expect(stores[i]).not.toBeNull(); let mnemonic = Mnemonic.getInstance().generate(); - RootIdentity.createFromMnemonic(mnemonic, "", stores[i], TestConfig.storePass); + await RootIdentity.createFromMnemonic(mnemonic, "", stores[i], TestConfig.storePass); } for (let i = 0; i < stores.length; i++) { @@ -693,10 +693,10 @@ describe("DIDStore Tests", ()=>{ test("testOpenStoreOnExistEmptyFolder", async ()=>{ let emptyFolder = new File(TestConfig.tempDir + File.SEPARATOR + "DIDTest-EmptyStore"); - if (emptyFolder.exists()) - emptyFolder.delete(); + if (await emptyFolder.exists()) + await emptyFolder.delete(); - emptyFolder.createDirectory(); + await emptyFolder.createDirectory(); let store = await DIDStore.open(emptyFolder.getAbsolutePath()); expect(store).not.toBeNull(); @@ -715,23 +715,23 @@ describe("DIDStore Tests", ()=>{ let did = (await store.listDids())[0]; let tempDir = new File(TestConfig.tempDir); - tempDir.createDirectory(true); + await tempDir.createDirectory(true); //let exportFile = new File(tempDir, "didexport.json"); let data = await store.exportDid(did, "password", TestConfig.storePass); - //exportFile.writeText(data); + //await exportFile.writeText(data); let restoreDir = new File(tempDir, "restore"); - Utils.deleteFile(restoreDir); + await Utils.deleteFile(restoreDir); let store2 = await DIDStore.open(restoreDir.getAbsolutePath()); await store2.importDid(data, "password", TestConfig.storePass); let path = "data" + File.SEPARATOR + "ids" + File.SEPARATOR + did.getMethodSpecificId(); let didDir = new File(storeDir, path); let reDidDir = new File(restoreDir, path); - expect(didDir.exists()).toBeTruthy(); - expect(reDidDir.exists()).toBeTruthy(); - expect(Utils.equals(reDidDir, didDir)).toBeTruthy(); + expect(await didDir.exists()).toBeTruthy(); + expect(await reDidDir.exists()).toBeTruthy(); + expect(await Utils.equals(reDidDir, didDir)).toBeTruthy(); }); test("testExportAndImportRootIdentity", async ()=>{ @@ -746,7 +746,7 @@ describe("DIDStore Tests", ()=>{ let id = rootidentity.getId(); let tempDir = new File(TestConfig.tempDir); - tempDir.createDirectory(); + await tempDir.createDirectory(); //let exportFile = new File(tempDir, "idexport.json"); let data = await store.exportRootIdentity(id, "password", TestConfig.storePass); @@ -759,9 +759,9 @@ describe("DIDStore Tests", ()=>{ let path = "data" + File.SEPARATOR + "roots" + File.SEPARATOR + id; let privateDir = new File(storeDir, path); let rePrivateDir = new File(restoreDir, path); - expect(privateDir.exists()).toBeTruthy(); - expect(rePrivateDir.exists()).toBeTruthy(); - expect(Utils.equals(rePrivateDir, privateDir)).toBeTruthy(); + expect(await privateDir.exists()).toBeTruthy(); + expect(await rePrivateDir.exists()).toBeTruthy(); + expect(await Utils.equals(rePrivateDir, privateDir)).toBeTruthy(); }); test("testExportAndImportStore", async ()=>{ @@ -772,16 +772,16 @@ describe("DIDStore Tests", ()=>{ await instance.getIssuerDocument(); let user = await instance.getUser1Document(); let vc = user.getCredential("#profile"); - vc.getMetadata().setAlias("MyProfile"); + await vc.getMetadata().setAlias("MyProfile"); vc = user.getCredential("#email"); - vc.getMetadata().setAlias("Email"); + await vc.getMetadata().setAlias("Email"); vc = await instance.getUser1TwitterCredential(); - vc.getMetadata().setAlias("Twitter"); + await vc.getMetadata().setAlias("Twitter"); vc = await instance.getUser1PassportCredential(); - vc.getMetadata().setAlias("Passport"); + await vc.getMetadata().setAlias("Passport"); let tempDir = new File(TestConfig.tempDir); - tempDir.createDirectory(); + await tempDir.createDirectory(); let exportFile = new File(tempDir, "storeexport.zip"); await store.exportStore(exportFile.getAbsolutePath(), "password", TestConfig.storePass); @@ -793,9 +793,9 @@ describe("DIDStore Tests", ()=>{ let storeDir = new File(TestConfig.storeRoot); - expect(storeDir.exists()).toBeTruthy(); - expect(restoreDir.exists()).toBeTruthy(); - expect(Utils.equals(restoreDir, storeDir)).toBeTruthy(); + expect(await storeDir.exists()).toBeTruthy(); + expect(await restoreDir.exists()).toBeTruthy(); + expect(await Utils.equals(restoreDir, storeDir)).toBeTruthy(); }); test("testImportCompatible", async ()=>{ @@ -806,7 +806,7 @@ describe("DIDStore Tests", ()=>{ let exportFile = new File(cb.getDataPath(), "store-export.zip"); let tempDir = new File(TestConfig.tempDir); - tempDir.createDirectory(); + await tempDir.createDirectory(); let restoreDir = new File(tempDir, "imported-store"); Utils.deleteFile(restoreDir); diff --git a/tests/src/idchainoperations.test.ts b/tests/src/idchainoperations.test.ts index 21e944e5..12cf85d3 100644 --- a/tests/src/idchainoperations.test.ts +++ b/tests/src/idchainoperations.test.ts @@ -75,7 +75,7 @@ function genRandomString(len): string { // tests depend on each other. describe('IDChainOperations Tests', () => { beforeAll(async ()=> { - testData = new TestData(true); + testData = await TestData.create(true); await testData.cleanup(); await testData.getRootIdentity(); dids = []; @@ -130,7 +130,7 @@ describe('IDChainOperations Tests', () => { let keyid = DIDURL.from("#key1", did); let key = TestData.generateKeypair(); db.addAuthenticationKey(keyid, key.getPublicKeyBase58()); - store.storePrivateKey(keyid, key.serialize(), TestConfig.storePass); + await store.storePrivateKey(keyid, key.serialize(), TestConfig.storePass); doc = await db.seal(TestConfig.storePass); expect(doc.getPublicKeyCount()).toEqual(2); @@ -216,7 +216,7 @@ describe('IDChainOperations Tests', () => { let keyid1 = DIDURL.from("#key1", doc.getSubject()); let key = TestData.generateKeypair(); db.addAuthenticationKey(keyid1, key.getPublicKeyBase58()); - store.storePrivateKey(keyid1, key.serialize(), TestConfig.storePass); + await store.storePrivateKey(keyid1, key.serialize(), TestConfig.storePass); let subject = { "passport": "S653258Z07" @@ -289,7 +289,7 @@ describe('IDChainOperations Tests', () => { let keyid2 = DIDURL.from("#key2", doc.getSubject()); let key = TestData.generateKeypair(); db.addAuthenticationKey(keyid2, key.getPublicKeyBase58()); - store.storePrivateKey(keyid2, key.serialize(), TestConfig.storePass); + await store.storePrivateKey(keyid2, key.serialize(), TestConfig.storePass); db.removeAuthenticationKey("#key1"); db.addService("#test-svc-1", @@ -368,7 +368,7 @@ describe('IDChainOperations Tests', () => { let keyid2 = DIDURL.from("#key2", doc.getSubject()); let key = TestData.generateKeypair(); db.addAuthenticationKey(keyid2, key.getPublicKeyBase58()); - store.storePrivateKey(keyid2, key.serialize(), TestConfig.storePass); + await store.storePrivateKey(keyid2, key.serialize(), TestConfig.storePass); db.addService("#test-svc-1", "Service.Testing", "https://www.elastos.org/testing1"); @@ -489,7 +489,7 @@ describe('IDChainOperations Tests', () => { let doc = await identity.newDid(TestConfig.storePass); let did = doc.getSubject(); - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); let cb = selfIssuer.issueFor(did); let props= { @@ -559,7 +559,7 @@ describe('IDChainOperations Tests', () => { log.debug("Last transaction id {}", lastTxid); //Update: add kyc credential and one authentication key - let issuer = new Issuer(issuerDoc); + let issuer = await Issuer.create(issuerDoc); let cb = issuer.issueFor(did); let props = { @@ -578,7 +578,7 @@ describe('IDChainOperations Tests', () => { let keyid1 = DIDURL.from("#key1", doc.getSubject()); let key = TestData.generateKeypair(); db.addAuthenticationKey(keyid1, key.getPublicKeyBase58()); - store.storePrivateKey(keyid1, key.serialize(), TestConfig.storePass); + await store.storePrivateKey(keyid1, key.serialize(), TestConfig.storePass); doc = await db.seal(TestConfig.storePass); expect(doc).not.toBeNull(); @@ -642,7 +642,7 @@ describe('IDChainOperations Tests', () => { log.debug("Last transaction id {}", lastTxid); // Update again: add self-claimed credential and remove passport credential - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); let cb = selfIssuer.issueFor(did); let props = { @@ -721,7 +721,7 @@ describe('IDChainOperations Tests', () => { let doc = await identity.newDid(TestConfig.storePass); let did = doc.getSubject(); - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); let cb = selfIssuer.issueFor(did); let props = { @@ -787,7 +787,7 @@ describe('IDChainOperations Tests', () => { log.debug("Last transaction id {}", lastTxid); // Update: add a self-claimed credential and an authorization key - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); let cb = selfIssuer.issueFor(did); let props = { @@ -936,12 +936,12 @@ describe('IDChainOperations Tests', () => { let keyid1 = DIDURL.from("#key1", customizeDid); let key = TestData.generateKeypair(); db.addAuthenticationKey(keyid1, key.getPublicKeyBase58()); - store.storePrivateKey(keyid1, key.serialize(), TestConfig.storePass); + await store.storePrivateKey(keyid1, key.serialize(), TestConfig.storePass); let keyid2 = DIDURL.from("#key2", customizeDid); key = TestData.generateKeypair(); db.addAuthenticationKey(keyid2, key.getPublicKeyBase58()); - store.storePrivateKey(keyid2, key.serialize(), TestConfig.storePass); + await store.storePrivateKey(keyid2, key.serialize(), TestConfig.storePass); doc = await db.seal(TestConfig.storePass); expect(doc.getPublicKeyCount()).toBe(4); @@ -966,7 +966,7 @@ describe('IDChainOperations Tests', () => { expect(issuerDoc).not.toBeNull(); let issuerId = issuerDoc.getSubject(); - let issuer = new Issuer(issuerDoc); + let issuer = await Issuer.create(issuerDoc); let cb = issuer.issueFor(customizeDid); let props = { @@ -1048,7 +1048,7 @@ describe('IDChainOperations Tests', () => { expect(valid).toBeFalsy(); const d = doc; - expect(async () => { await ctrl1.signWithDocument(d, TestConfig.storePass); }).rejects.toThrowError(); + await expect(async () => await ctrl1.signWithDocument(d, TestConfig.storePass)).rejects.toThrowError(); doc = await ctrl2.signWithDocument(doc, TestConfig.storePass); valid = await doc.isValid(); @@ -1094,7 +1094,7 @@ describe('IDChainOperations Tests', () => { let keyid1 = DIDURL.from("#key1", multiCustomizeDid); let key = TestData.generateKeypair(); db.addAuthenticationKey(keyid1, key.getPublicKeyBase58()); - store.storePrivateKey(keyid1, key.serialize(), TestConfig.storePass); + await store.storePrivateKey(keyid1, key.serialize(), TestConfig.storePass); let json = "{\"twitter\":\"@john\"}"; await db.createAndAddCredential(TestConfig.storePass, "#twitter", json); @@ -1119,12 +1119,12 @@ describe('IDChainOperations Tests', () => { let keyid2 = DIDURL.from("#key2", multiCustomizeDid); key = TestData.generateKeypair(); db.addAuthenticationKey(keyid2, key.getPublicKeyBase58()); - store.storePrivateKey(keyid2, key.serialize(), TestConfig.storePass); + await store.storePrivateKey(keyid2, key.serialize(), TestConfig.storePass); let issuerDoc = await store.loadDid(customizeDid); expect(issuerDoc).not.toBeNull(); - let issuer = new Issuer(issuerDoc, DIDURL.from("#key1", issuerDoc.getSubject())); + let issuer = await Issuer.create(issuerDoc, DIDURL.from("#key1", issuerDoc.getSubject())); expect(issuer).not.toBeNull(); let cb = issuer.issueFor(multiCustomizeDid); @@ -1468,10 +1468,10 @@ describe('IDChainOperations Tests', () => { let filePath = TestConfig.tempDir + "/cleanstore"; let path = new File(filePath); - Utils.deleteFile(path); + await Utils.deleteFile(path); let cleanStore = await DIDStore.open(filePath); - let rootIdentity = RootIdentity.createFromMnemonic(mnemonic, + let rootIdentity = await RootIdentity.createFromMnemonic(mnemonic, TestConfig.passphrase, cleanStore, TestConfig.storePass, true); log.debug("Synchronizing from IDChain..."); @@ -1515,10 +1515,10 @@ describe('IDChainOperations Tests', () => { let filePath = TestConfig.tempDir + "/cleanstore"; let path = new File(filePath); - Utils.deleteFile(path); + await Utils.deleteFile(path); let cleanStore = await DIDStore.open(filePath); - let rootIdentity = RootIdentity.createFromMnemonic(mnemonic, + let rootIdentity = await RootIdentity.createFromMnemonic(mnemonic, TestConfig.passphrase, cleanStore, TestConfig.storePass, true); log.debug("Synchronizing from IDChain..."); @@ -1546,12 +1546,12 @@ describe('IDChainOperations Tests', () => { log.debug("Synchronizing from IDChain..."); let start = Date.now(); await identity.synchronize({ - merge(c, l): DIDDocument { + async merge(c, l): Promise { expect(l.getProof().getSignature()).toEqual(c.getProof().getSignature()); expect(l.getLastModified().getTime()).toEqual(c.getLastModified().getTime()); - l.getMetadata().setPublished(c.getMetadata().getPublished()); - l.getMetadata().setSignature(c.getMetadata().getSignature()); + await l.getMetadata().setPublished(c.getMetadata().getPublished()); + await l.getMetadata().setSignature(c.getMetadata().getSignature()); return l; } }) @@ -1581,12 +1581,12 @@ describe('IDChainOperations Tests', () => { let start = Date.now(); let ch = { - merge(c: DIDDocument, l: DIDDocument) { + async merge(c: DIDDocument, l: DIDDocument) { expect(l.getProof().getSignature()).toEqual(c.getProof().getSignature()); expect(l.getLastModified().getTime()).toEqual(c.getLastModified().getTime()); - l.getMetadata().setPublished(c.getMetadata().getPublished()); - l.getMetadata().setSignature(c.getMetadata().getSignature()); + await l.getMetadata().setPublished(c.getMetadata().getPublished()); + await l.getMetadata().setSignature(c.getMetadata().getSignature()); return l; } } @@ -1616,10 +1616,10 @@ describe('IDChainOperations Tests', () => { // Sync to a clean store first let filePath = TestConfig.tempDir + "/cleanstore"; let path = new File(filePath); - Utils.deleteFile(path); + await Utils.deleteFile(path); let cleanStore = await DIDStore.open(filePath); - let rootIdentity = RootIdentity.createFromMnemonic(mnemonic, + let rootIdentity = await RootIdentity.createFromMnemonic(mnemonic, TestConfig.passphrase, cleanStore, TestConfig.storePass, true); log.debug("Synchronizing from IDChain..."); @@ -1676,10 +1676,10 @@ describe('IDChainOperations Tests', () => { // Sync to a clean store first let filePath = TestConfig.tempDir + "/cleanstore"; let path = new File(filePath); - Utils.deleteFile(path); + await Utils.deleteFile(path); let cleanStore = await DIDStore.open(filePath); - let rootIdentity = RootIdentity.createFromMnemonic(mnemonic, + let rootIdentity = await RootIdentity.createFromMnemonic(mnemonic, TestConfig.passphrase, cleanStore, TestConfig.storePass, true); log.debug("Synchronizing from IDChain..."); @@ -1711,7 +1711,7 @@ describe('IDChainOperations Tests', () => { log.debug("Synchronizing again from IDChain..."); start = Date.now(); await rootIdentity.synchronize({ - merge(c, l) { return c; } + merge(c, l) { return Promise.resolve(c); } }); duration = (Date.now() - start + 500) / 1000; log.debug("Synchronize again from IDChain...OK({}s)", duration); @@ -1739,10 +1739,10 @@ describe('IDChainOperations Tests', () => { // Sync to a clean store first let filePath = TestConfig.tempDir + "/cleanstore"; let path = new File(filePath); - Utils.deleteFile(path); + await Utils.deleteFile(path); let cleanStore = await DIDStore.open(filePath); - let rootIdentity = RootIdentity.createFromMnemonic(mnemonic, + let rootIdentity = await RootIdentity.createFromMnemonic(mnemonic, TestConfig.passphrase, cleanStore, TestConfig.storePass, true); log.debug("Synchronizing from IDChain..."); @@ -1774,7 +1774,7 @@ describe('IDChainOperations Tests', () => { log.debug("Synchronizing again from IDChain..."); let start2 = Date.now(); await rootIdentity.synchronize({ - merge(c, l) { return c; } + merge(c, l) { return Promise.resolve(c); } }); duration = (Date.now() - start2 + 500) / 1000; log.debug("Synchronize again from IDChain...OK({}s)", duration); @@ -1804,7 +1804,7 @@ describe('IDChainOperations Tests', () => { for (let did of listdids) { let doc = await store.loadDid(did); if (!doc.isCustomizedDid()) - expect(store.deleteDid(did)).toBeTruthy(); + expect(await store.deleteDid(did)).toBeTruthy(); } let empty: DID[] = Array.from(await store.listDids()); @@ -1828,16 +1828,16 @@ describe('IDChainOperations Tests', () => { let doc = await store.loadDid(multiCustomizeDid); expect(doc).not.toBeNull(); - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); let cb = selfIssuer.issueFor(doc.getSubject()); let props: JSONObject = {}; let dirPath = join(__dirname, "data/i18n"); let i18nDir = new File(dirPath); - let i18nRes = i18nDir.listFiles(); + let i18nRes = await i18nDir.listFiles(); for (let res of i18nRes) { - props[res.getName()] = res.readText(); + props[res.getName()] = await res.readText(); } let vc = await cb.id("#i18n") @@ -2050,7 +2050,7 @@ describe('IDChainOperations Tests', () => { let doc = await store.loadDid(dids[0]); let did = doc.getSubject(); - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); for (let i = 0; i < 36; i++) { log.trace("Creating test credential {}...", i); @@ -2340,17 +2340,17 @@ describe('IDChainOperations Tests', () => { let doc = await identity.newDid(TestConfig.storePass); let did = doc.getSubject(); - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); let cb = selfIssuer.issueFor(did); let props: JSONObject = {}; let dirPath = join(__dirname, "data/i18n"); let i18nDir = new File(dirPath); - let i18nRes = i18nDir.listFiles(); + let i18nRes = await i18nDir.listFiles(); for (let res of i18nRes) { - props[res.getName()] = res.readText(); + props[res.getName()] = await res.readText(); } let vc = await cb.id("#profile") diff --git a/tests/src/issuer.test.ts b/tests/src/issuer.test.ts index da31d3c0..6cb5acef 100644 --- a/tests/src/issuer.test.ts +++ b/tests/src/issuer.test.ts @@ -38,7 +38,7 @@ describe("Issuer Tests", ()=>{ let testDoc : DIDDocument; beforeEach(async ()=>{ - testData = new TestData(); + testData = await TestData.create(); await testData.cleanup(); store = await testData.getStore(); await testData.getRootIdentity(); @@ -65,17 +65,17 @@ describe("Issuer Tests", ()=>{ expect(issuer.getSignKey().equals(issuerDoc.getDefaultPublicKeyId())).toBeTruthy(); }) - test('New Issuer Test With Invalid Key', () => { + test('New Issuer Test With Invalid Key', async () => { let signKey = new DIDURL("#testKey", issuerDoc.getSubject()); let doc = issuerDoc; - expect(() =>{Issuer.newWithDocument(doc, signKey)}).toThrowError(); + await expect(async () => await Issuer.newWithDocument(doc, signKey)).rejects.toThrowError(); }) - test('New Issuer Test With Invalid Key 2', () => { + test('New Issuer Test With Invalid Key 2', async () => { let signKey = new DIDURL("#recovery", issuerDoc.getSubject()); let doc = issuerDoc; - expect(()=>{Issuer.newWithDocument(doc, signKey)}).toThrowError(); + await expect(async ()=>Issuer.newWithDocument(doc, signKey)).rejects.toThrowError(); }) test('Issue Kyc Credential Test', async () => { @@ -87,7 +87,7 @@ describe("Issuer Tests", ()=>{ twitter: "@john" }; - let issuer = new Issuer(issuerDoc); + let issuer = await Issuer.create(issuerDoc); let cb = issuer.issueFor(testDoc.getSubject()); let vc = await cb.id("#testCredential") @@ -101,10 +101,10 @@ describe("Issuer Tests", ()=>{ expect(vcId.equals(vc.getId())).toBeTruthy(); - expect(vc.getType().includes("ProfileCredential")).toBeTruthy();; - expect(vc.getType().includes("EmailCredential")).toBeTruthy();; - expect(vc.getType().includes("SocialCredential")).toBeTruthy();; - expect(vc.getType().includes("VerifiableCredential")).toBeTruthy();; + expect(vc.getType().includes("ProfileCredential")).toBeTruthy(); + expect(vc.getType().includes("EmailCredential")).toBeTruthy(); + expect(vc.getType().includes("SocialCredential")).toBeTruthy(); + expect(vc.getType().includes("VerifiableCredential")).toBeTruthy(); expect(vc.getType().includes("SelfProclaimedCredential")).toBeFalsy(); expect(issuerDoc.getSubject().equals(vc.getIssuer())).toBeTruthy(); @@ -128,7 +128,7 @@ describe("Issuer Tests", ()=>{ email: "issuer@example.com" }; - let issuer = new Issuer(issuerDoc); + let issuer = await Issuer.create(issuerDoc); let cb = issuer.issueFor(testDoc.getSubject()); let vc = await cb.id("#myCredential") @@ -169,7 +169,7 @@ describe("Issuer Tests", ()=>{ twitter: "@john" }; - let issuer = new Issuer(issuerDoc); + let issuer = await Issuer.create(issuerDoc); let cb = issuer.issueFor(testDoc.getSubject()); let vc = await cb.id("#testCredential") @@ -212,7 +212,7 @@ describe("Issuer Tests", ()=>{ twitter: "@john" }; - let issuer = new Issuer(issuerDoc); + let issuer = await Issuer.create(issuerDoc); let cb = issuer.issueFor(testDoc.getSubject()); let vc = await cb.id("#testCredential") @@ -253,7 +253,7 @@ describe("Issuer Tests", ()=>{ email: "issuer@example.com" }; - let issuer = new Issuer(issuerDoc); + let issuer = await Issuer.create(issuerDoc); let cb = issuer.issueFor(issuerDoc.getSubject()); let vc = await cb.id("#myCredential") @@ -286,7 +286,7 @@ describe("Issuer Tests", ()=>{ test('Issue Json Props Credential Test', async () => { let props = "{\"name\":\"Jay Holtslander\",\"alternateName\":\"Jason Holtslander\",\"booleanValue\":true,\"numberValue\":1234,\"doubleValue\":9.5,\"nationality\":\"Canadian\",\"birthPlace\":{\"type\":\"Place\",\"address\":{\"type\":\"PostalAddress\",\"addressLocality\":\"Vancouver\",\"addressRegion\":\"BC\",\"addressCountry\":\"Canada\"}},\"affiliation\":[{\"type\":\"Organization\",\"name\":\"Futurpreneur\",\"sameAs\":[\"https://twitter.com/futurpreneur\",\"https://www.facebook.com/futurpreneur/\",\"https://www.linkedin.com/company-beta/100369/\",\"https://www.youtube.com/user/CYBF\"]}],\"alumniOf\":[{\"type\":\"CollegeOrUniversity\",\"name\":\"Vancouver Film School\",\"sameAs\":\"https://en.wikipedia.org/wiki/Vancouver_Film_School\",\"year\":2000},{\"type\":\"CollegeOrUniversity\",\"name\":\"CodeCore Bootcamp\"}],\"gender\":\"Male\",\"Description\":\"Technologist\",\"disambiguatingDescription\":\"Co-founder of CodeCore Bootcamp\",\"jobTitle\":\"Technical Director\",\"worksFor\":[{\"type\":\"Organization\",\"name\":\"Skunkworks Creative Group Inc.\",\"sameAs\":[\"https://twitter.com/skunkworks_ca\",\"https://www.facebook.com/skunkworks.ca\",\"https://www.linkedin.com/company/skunkworks-creative-group-inc-\",\"https://plus.google.com/+SkunkworksCa\"]}],\"url\":\"https://jay.holtslander.ca\",\"image\":\"https://s.gravatar.com/avatar/961997eb7fd5c22b3e12fb3c8ca14e11?s=512&r=g\",\"address\":{\"type\":\"PostalAddress\",\"addressLocality\":\"Vancouver\",\"addressRegion\":\"BC\",\"addressCountry\":\"Canada\"},\"sameAs\":[\"https://twitter.com/j_holtslander\",\"https://pinterest.com/j_holtslander\",\"https://instagram.com/j_holtslander\",\"https://www.facebook.com/jay.holtslander\",\"https://ca.linkedin.com/in/holtslander/en\",\"https://plus.google.com/+JayHoltslander\",\"https://www.youtube.com/user/jasonh1234\",\"https://github.com/JayHoltslander\",\"https://profiles.wordpress.org/jasonh1234\",\"https://angel.co/j_holtslander\",\"https://www.foursquare.com/user/184843\",\"https://jholtslander.yelp.ca\",\"https://codepen.io/j_holtslander/\",\"https://stackoverflow.com/users/751570/jay\",\"https://dribbble.com/j_holtslander\",\"http://jasonh1234.deviantart.com/\",\"https://www.behance.net/j_holtslander\",\"https://www.flickr.com/people/jasonh1234/\",\"https://medium.com/@j_holtslander\"]}"; - let issuer = new Issuer(issuerDoc); + let issuer = await Issuer.create(issuerDoc); let cb = issuer.issueFor(issuerDoc.getSubject()); let vc = await cb.id("#myCredential") @@ -319,7 +319,7 @@ describe("Issuer Tests", ()=>{ }) test('Issue Credential Test', async () => { - let issuer = new Issuer(issuerDoc); + let issuer = await Issuer.create(issuerDoc); let cb = issuer.issueFor(issuerDoc.getSubject()); let vc = await cb.id("#myCredential") diff --git a/tests/src/jwt/jwt.test.ts b/tests/src/jwt/jwt.test.ts index 7fcd1d43..7b950340 100644 --- a/tests/src/jwt/jwt.test.ts +++ b/tests/src/jwt/jwt.test.ts @@ -60,7 +60,7 @@ let doc: DIDDocument; describe('JWT Tests', () => { beforeAll(async () => { - testData = new TestData(); + testData = await TestData.create(); await testData.cleanup(); let identity = await testData.getRootIdentity(); doc = await identity.newDid(TestConfig.storePass); @@ -70,7 +70,7 @@ describe('JWT Tests', () => { let id = new DIDURL("#key2", doc.getSubject()); db.addAuthenticationKey(id, key.getPublicKeyBase58()); let store = await testData.getStore(); - store.storePrivateKey(id, key.serialize(), TestConfig.storePass); + await store.storePrivateKey(id, key.serialize(), TestConfig.storePass); doc = await db.seal(TestConfig.storePass); await store.storeDid(doc); @@ -682,7 +682,7 @@ describe('JWT Tests', () => { test('jwsTestCompatible', async () => { let mnemonic = "have scorpion powder shoulder pretty sentence humble tenant frog march finger title"; - let identity = RootIdentity.createFromMnemonic(mnemonic, "secret", await testData.getStore(), TestConfig.storePass); + let identity = await RootIdentity.createFromMnemonic(mnemonic, "secret", await testData.getStore(), TestConfig.storePass); let issuerDoc = await identity.newDid(TestConfig.storePass, 0, true); await issuerDoc.publish(TestConfig.storePass); diff --git a/tests/src/mnemonic.test.ts b/tests/src/mnemonic.test.ts index 1d38cef5..770a646e 100644 --- a/tests/src/mnemonic.test.ts +++ b/tests/src/mnemonic.test.ts @@ -29,7 +29,7 @@ describe('Mnemonic Tests', () => { let store: DIDStore; beforeEach(async () => { - testData = new TestData(); + testData = await TestData.create(); await testData.cleanup(); store = await testData.getStore(); }) @@ -37,7 +37,7 @@ describe('Mnemonic Tests', () => { afterEach(async () => { }); - test('Test builtin wordlist', () => { + test('Test builtin wordlist', async () => { let languages = [ Mnemonic.DEFAULT, Mnemonic.CHINESE_SIMPLIFIED, @@ -45,18 +45,18 @@ describe('Mnemonic Tests', () => { Mnemonic.FRENCH, ]; - languages.forEach(lang => { + for (const lang of languages) { let mc = Mnemonic.getInstance(lang); let mnemonic = mc.generate(); expect(mc.isValid(mnemonic)).toBeTruthy(); expect(Mnemonic.checkIsValid(mnemonic)).toBeTruthy(); - RootIdentity.createFromMnemonic(mnemonic, TestConfig.passphrase, store, TestConfig.storePass, true); + await RootIdentity.createFromMnemonic(mnemonic, TestConfig.passphrase, store, TestConfig.storePass, true); expect(mc.isValid(mnemonic + "z")).toBeFalsy(); expect(Mnemonic.checkIsValid(mnemonic + "z")).toBeFalsy(); - }); + } }); test('Test french mnemonic', () => { diff --git a/tests/src/rootidentity.test.ts b/tests/src/rootidentity.test.ts index ac12c53b..43c187a9 100644 --- a/tests/src/rootidentity.test.ts +++ b/tests/src/rootidentity.test.ts @@ -36,7 +36,7 @@ let store: DIDStore; describe("RootIdentity Tests", ()=>{ beforeEach(async () => { - testData = new TestData(); + testData = await TestData.create(); await testData.cleanup(); store = await testData.getStore(); }); @@ -45,21 +45,21 @@ describe("RootIdentity Tests", ()=>{ }); test("testInitPrivateIdentity", async () => { - expect(store.containsRootIdentities()).toBeFalsy(); + expect(await store.containsRootIdentities()).toBeFalsy(); let identity = await testData.getRootIdentity(); - expect(store.containsRootIdentities()).toBeTruthy(); + expect(await store.containsRootIdentities()).toBeTruthy(); let store2 = await DIDStore.open(TestConfig.storeRoot); - expect(store2.containsRootIdentities()).toBeTruthy(); + expect(await store2.containsRootIdentities()).toBeTruthy(); let identity2 = await store2.loadRootIdentity(); expect(identity2).not.toBeNull(); - expect(store2.containsRootIdentity(identity2.getId())).toBeTruthy(); + expect(await store2.containsRootIdentity(identity2.getId())).toBeTruthy(); expect(identity.getPreDerivedPublicKey().serializePublicKeyBase58()).toEqual( identity2.getPreDerivedPublicKey().serializePublicKeyBase58()); - let exportedMnemonic = identity2.exportMnemonic(TestConfig.storePass); + let exportedMnemonic = await identity2.exportMnemonic(TestConfig.storePass); expect(testData.getMnemonic()).toEqual(exportedMnemonic); }); @@ -67,14 +67,14 @@ describe("RootIdentity Tests", ()=>{ let expectedIDString = "iY4Ghz9tCuWvB5rNwvn4ngWvthZMNzEA7U"; let mnemonic = "cloth always junk crash fun exist stumble shift over benefit fun toe"; - expect(store.containsRootIdentities()).toBeFalsy(); + expect(await store.containsRootIdentities()).toBeFalsy(); - let identity = RootIdentity.createFromMnemonic(mnemonic, "", store, TestConfig.storePass); - expect(store.containsRootIdentities()).toBeTruthy(); + let identity = await RootIdentity.createFromMnemonic(mnemonic, "", store, TestConfig.storePass); + expect(await store.containsRootIdentities()).toBeTruthy(); expect(identity.getId()).toEqual(RootIdentity.getIdFromMnemonic(mnemonic, "")); let store2 = await DIDStore.open(TestConfig.storeRoot); - expect(store2.containsRootIdentities()).toBeTruthy(); + expect(await store2.containsRootIdentities()).toBeTruthy(); let identity2 = await store2.loadRootIdentity(); @@ -87,13 +87,13 @@ describe("RootIdentity Tests", ()=>{ let expectedIDString = "iYbPqEA98rwvDyA5YT6a3mu8UZy87DLEMR"; let rootKey = "xprv9s21ZrQH143K4biiQbUq8369meTb1R8KnstYFAKtfwk3vF8uvFd1EC2s49bMQsbdbmdJxUWRkuC48CXPutFfynYFVGnoeq8LJZhfd9QjvUt"; - expect(store.containsRootIdentities()).toBeFalsy(); + expect(await store.containsRootIdentities()).toBeFalsy(); - RootIdentity.createFromPrivateKey(rootKey, store, TestConfig.storePass); - expect(store.containsRootIdentities()).toBeTruthy(); + await RootIdentity.createFromPrivateKey(rootKey, store, TestConfig.storePass); + expect(await store.containsRootIdentities()).toBeTruthy(); let store2 = await DIDStore.open(TestConfig.storeRoot); - expect(store2.containsRootIdentities()).toBeTruthy(); + expect(await store2.containsRootIdentities()).toBeTruthy(); let identity2 = await store2.loadRootIdentity(); @@ -108,7 +108,7 @@ describe("RootIdentity Tests", ()=>{ let alias = "my first did"; let doc = await identity.newDid(TestConfig.storePass); - doc.getMetadata().setAlias(alias); + await doc.getMetadata().setAlias(alias); let valid = await doc.isValid(); expect(valid).toBeTruthy(); @@ -163,9 +163,9 @@ describe("RootIdentity Tests", ()=>{ expect(did.equals(doc.getSubject())).toBeTruthy(); // eslint-disable-next-line @typescript-eslint/no-floating-promises - expect(() => identity.newDid(TestConfig.storePass)).rejects.toThrowError("DID already exists in the store."); + await expect(() => identity.newDid(TestConfig.storePass)).rejects.toThrowError("DID already exists in the store."); - let success = store.deleteDid(did); + let success = await store.deleteDid(did); expect(success).toBeTruthy(); doc = await identity.newDid(TestConfig.storePass); valid = await doc.isValid(); @@ -202,7 +202,7 @@ describe("RootIdentity Tests", ()=>{ await expect(async () => { await identity.newDidFromIdentifier(TestConfig.storePass, appId, appCode); }).rejects.toThrowError(); - let success = store.deleteDid(did); + let success = await store.deleteDid(did); expect(success).toBeTruthy(); doc = await identity.newDidFromIdentifier(TestConfig.storePass, appId, appCode); valid = await doc.isValid(); diff --git a/tests/src/transferticket.test.ts b/tests/src/transferticket.test.ts index f101bc84..76fb74af 100644 --- a/tests/src/transferticket.test.ts +++ b/tests/src/transferticket.test.ts @@ -34,7 +34,7 @@ describe('TransferTicket Tests', () => { let store: DIDStore; beforeEach(async () => { - testData = new TestData(); + testData = await TestData.create(); await testData.cleanup(); store = await testData.getStore(); }); diff --git a/tests/src/utils/browserdataimport.ts b/tests/src/utils/browserdataimport.ts index 358d15e3..ecfa4351 100644 --- a/tests/src/utils/browserdataimport.ts +++ b/tests/src/utils/browserdataimport.ts @@ -27,38 +27,39 @@ import { runningInBrowser } from "./utils"; /** * Converts a bundle entry into a real folder or file in browserfs file system. */ -function importBundledBrowserDataToFS(rootFolderPath, folder) { - Object.keys(folder).forEach((file: string)=>{ +async function importBundledBrowserDataToFS(rootFolderPath, folder): Promise { + const files = Object.keys(folder); + for (const file of files) { if ("_content" in folder[file]) { // File let fullPath = rootFolderPath+"/"+file; //console.log("Writing to file ", fullPath); - new File(fullPath).writeText(folder[file]["_content"]); + await new File(fullPath).writeText(folder[file]["_content"]); } else { // Folder let fullPath = rootFolderPath+"/"+file - new File(fullPath).createDirectory(); - importBundledBrowserDataToFS(rootFolderPath+"/"+file, folder[file]); + await new File(fullPath).createDirectory(); + await importBundledBrowserDataToFS(rootFolderPath+"/"+file, folder[file]); } - }); + } } var importBundledBrowserData; var dataWasImported = false; // Remember if we imported the data during this session or not, to avoid browser tests to do the same thing many times. if (runningInBrowser()) { - importBundledBrowserData = () => { + importBundledBrowserData = async () => { // We have to really append those files into browser's file system for methods such as DIDStore.open() // work from the SDK. So we recursively import all entries if (!dataWasImported) { console.log("Importing bundled browser data to FS"); - importBundledBrowserDataToFS("/testresources", browserBundledData); + await importBundledBrowserDataToFS("/testresources", browserBundledData); dataWasImported = true; } } } else { - importBundledBrowserData = () => {} + importBundledBrowserData = async () => Promise.resolve(); } export { diff --git a/tests/src/utils/testdata.ts b/tests/src/utils/testdata.ts index e8c3a952..7390f2fe 100644 --- a/tests/src/utils/testdata.ts +++ b/tests/src/utils/testdata.ts @@ -48,12 +48,15 @@ export class TestData { private v2_2: CompatibleData; private instantData: InstantData; - public constructor(dummy ?: boolean) { + private constructor(dummy ?: boolean) {} + + public static async create(dummy ?: boolean): Promise { + const testData = new TestData(dummy); try { TestConfig.initialize(); - if (File.exists(TestConfig.storeRoot)) - (new File(TestConfig.storeRoot)).delete(); - importBundledBrowserData(); + if (await File.exists(TestConfig.storeRoot)) + await new File(TestConfig.storeRoot).delete(); + await importBundledBrowserData(); DIDTestExtension.setup(dummy); } @@ -62,6 +65,7 @@ export class TestData { console.error("Catched exception in TestData constructor", e); throw e; } + return testData; } public async cleanup(): Promise { @@ -95,7 +99,7 @@ export class TestData { public async getRootIdentity(): Promise { if (this.identity == null) { this.mnemonic = Mnemonic.getInstance().generate(); - this.identity = RootIdentity.createFromMnemonic(this.mnemonic, TestConfig.passphrase, + this.identity = await RootIdentity.createFromMnemonic(this.mnemonic, TestConfig.passphrase, await this.getStore(), TestConfig.storePass, true); } @@ -200,19 +204,19 @@ export class CompatibleData { return parseFloat(this.version) >= 2.0; } - private fileContent(path: string): string { + private async fileContent(path: string): Promise { let file = new File(path); - if (!file.exists()) + if (!(await file.exists())) throw new Error("No file exists at "+path); - return file.readText(); + return await file.readText(); } - private dirContent(path: string): string[] { + private dirContent(path: string): Promise { return (new File(path)).list(); } - private getDidFile(name: string, type: string): string { + private getDidFile(name: string, type: string): Promise { let fileName = name + ".id"; if (type != null) fileName += "." + type; @@ -221,7 +225,7 @@ export class CompatibleData { return this.fileContent(this.dataPath + "/" + fileName); } - private getCredentialFile(did: string, vc: string, type: string): string { + private getCredentialFile(did: string, vc: string, type: string): Promise { let fileName = did + ".vc." + vc; if (type != null) fileName += "." + type; @@ -230,7 +234,7 @@ export class CompatibleData { return this.fileContent(this.dataPath + "/" + fileName); } - private getPresentationFile(did: string, vp: string, type: string): string { + private getPresentationFile(did: string, vp: string, type: string): Promise { let fileName = did + ".vp." + vp; if (type != null) fileName += "." + type; @@ -239,7 +243,7 @@ export class CompatibleData { return this.fileContent(this.dataPath + "/" + fileName); } - private getTransferTicketFile(name : string) : string { + private getTransferTicketFile(name : string) : Promise { if (parseFloat(this.version) < 2.0) return null; @@ -253,12 +257,12 @@ export class CompatibleData { return this.data[key]; // load the document - let doc = await DIDDocument.parseAsync(this.getDidFile(did, type)); + let doc = await DIDDocument.parseAsync(await this.getDidFile(did, type)); if (!(baseKey in this.data)) { // If not stored before, store it and load private keys await this.testData.store.storeDid(doc); - let kfs = this.dirContent(this.dataPath).filter((fileName: string, index: number, array: string []) => { + let kfs = (await this.dirContent(this.dataPath)).filter((fileName: string, index: number, array: string []) => { return fileName.startsWith(did + ".id.") && fileName.endsWith(".sk"); }); @@ -268,8 +272,8 @@ export class CompatibleData { let fragment = kf.substring(start, end); let id = new DIDURL("#" + fragment, doc.getSubject()); - let sk = HDKey.deserializeBase58(this.fileContent(this.dataPath + "/" + kf)).serialize(); - this.testData.store.storePrivateKey(id, sk, TestConfig.storePass); + let sk = HDKey.deserializeBase58(await this.fileContent(this.dataPath + "/" + kf)).serialize(); + await this.testData.store.storePrivateKey(id, sk, TestConfig.storePass); } switch (did) { @@ -291,8 +295,8 @@ export class CompatibleData { return doc; } - public getDocumentJson(did: string, type: string) : string { - let file = this.getDidFile(did, type) + public async getDocumentJson(did: string, type: string) : Promise { + let file = await this.getDidFile(did, type) let fileName = did + ".id"; if (type != null) fileName += "." + type; @@ -311,7 +315,7 @@ export class CompatibleData { if (this.data[key] !== null && this.data[key] !== undefined) return this.data[key]; - let credential = VerifiableCredential.parse(this.getCredentialFile(did, vc, type)); + let credential = VerifiableCredential.parse(await this.getCredentialFile(did, vc, type)); await this.testData.store.storeCredential(credential); @@ -319,8 +323,8 @@ export class CompatibleData { return credential } - public getCredentialJson(did: string, vc: string, type: string): string{ - let file = this.getCredentialFile(did, vc, type); + public async getCredentialJson(did: string, vc: string, type: string): Promise{ + let file = await this.getCredentialFile(did, vc, type); let fileName = did + ".vc." + vc; if (type != null) fileName += "." + type; @@ -346,13 +350,13 @@ export class CompatibleData { return this.data[key]; // load the presentation - let presentation = VerifiablePresentation.parse(this.getPresentationFile(did, vp, type)); + let presentation = VerifiablePresentation.parse(await this.getPresentationFile(did, vp, type)); this.data[key] = presentation; return presentation; } - public getPresentationJson(did: string, vp: string, type: string): string{ - let file = this.getPresentationFile(did, vp, type); + public async getPresentationJson(did: string, vp: string, type: string): Promise{ + let file = await this.getPresentationFile(did, vp, type); let fileName = did + ".vp." + vp; if (type != null) fileName += "." + type; @@ -379,7 +383,7 @@ export class CompatibleData { return this.data[key] as TransferTicket; // load the ticket - let tt = TransferTicket.parse(this.getTransferTicketFile(did)); + let tt = TransferTicket.parse(await this.getTransferTicketFile(did)); this.data[key] = tt; return tt; @@ -444,9 +448,9 @@ export class InstantData { await this.testData.getRootIdentity(); let doc = await (await this.testData.getRootIdentity()).newDid(TestConfig.storePass); - doc.getMetadata().setAlias("Issuer"); + await doc.getMetadata().setAlias("Issuer"); - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); let cb = selfIssuer.issueFor(doc.getSubject()); let props = { @@ -467,7 +471,7 @@ export class InstantData { let key = TestData.generateKeypair(); let id = DIDURL.from("#key2", doc.getSubject()); db.addAuthenticationKey(id, key.getPublicKeyBase58()); - this.testData.store.storePrivateKey(id, key.serialize(), TestConfig.storePass); + await this.testData.store.storePrivateKey(id, key.serialize(), TestConfig.storePass); // No private key for testKey key = TestData.generateKeypair(); @@ -496,19 +500,19 @@ export class InstantData { await this.getIssuerDocument(); let doc = await (await this.testData.getRootIdentity()).newDid(TestConfig.storePass); - doc.getMetadata().setAlias("User1"); + await doc.getMetadata().setAlias("User1"); // Test document with two embedded credentials let db = DIDDocument.Builder.newFromDocument(doc).edit(); - let temp = TestData.generateKeypair(); + let temp = await TestData.generateKeypair(); db.addAuthenticationKey("#key2", temp.getPublicKeyBase58()); - this.testData.store.storePrivateKey(DIDURL.from("#key2", doc.getSubject()), + await this.testData.store.storePrivateKey(DIDURL.from("#key2", doc.getSubject()), temp.serialize(), TestConfig.storePass); temp = TestData.generateKeypair(); db.addAuthenticationKey("#key3", temp.getPublicKeyBase58()); - this.testData.store.storePrivateKey(DIDURL.from("#key3", doc.getSubject()), + await this.testData.store.storePrivateKey(DIDURL.from("#key3", doc.getSubject()), temp.serialize(), TestConfig.storePass); temp = TestData.generateKeypair(); @@ -549,7 +553,7 @@ export class InstantData { db.addService("#carrier", "CarrierAddress", "carrier://X2tDd1ZTErwnHNot8pTdhp7C7Y9FxMPGD8ppiasUT4UsHH2BpF1d", map); - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); let cb = selfIssuer.issueFor(doc.getSubject()); props = { @@ -568,7 +572,7 @@ export class InstantData { .properties(props) .seal(TestConfig.storePass); - let kycIssuer = new Issuer(this.idIssuer); + let kycIssuer = await Issuer.create(this.idIssuer); cb = kycIssuer.issueFor(doc.getSubject()); props = { @@ -599,7 +603,7 @@ export class InstantData { let id = new DIDURL("#passport", doc.getSubject()); - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); let cb = selfIssuer.issueFor(doc.getSubject()); let props = { @@ -611,7 +615,7 @@ export class InstantData { .type("https://ns.elastos.org/credentials/v1#SelfProclaimedCredential") .properties(props) .seal(TestConfig.storePass); - vcPassport.getMetadata().setAlias("Passport"); + await vcPassport.getMetadata().setAlias("Passport"); await this.testData.store.storeCredential(vcPassport); this.vcUser1Passport = vcPassport; @@ -626,7 +630,7 @@ export class InstantData { let id = new DIDURL("#twitter", doc.getSubject()); - let kycIssuer = new Issuer(this.idIssuer); + let kycIssuer = await Issuer.create(this.idIssuer); let cb = kycIssuer.issueFor(doc.getSubject()); let props = { @@ -637,7 +641,7 @@ export class InstantData { .typeWithContext("SocialCredential", "https://ns.elastos.org/credentials/social/v1") .properties(props) .seal(TestConfig.storePass); - vcTwitter.getMetadata().setAlias("Twitter"); + await vcTwitter.getMetadata().setAlias("Twitter"); await this.testData.store.storeCredential(vcTwitter); this.vcUser1Twitter = vcTwitter; @@ -653,7 +657,7 @@ export class InstantData { let id = new DIDURL("#json", doc.getSubject()); - let kycIssuer = new Issuer(this.idIssuer); + let kycIssuer = await Issuer.create(this.idIssuer); let cb = kycIssuer.issueFor(doc.getSubject()); let jsonProps = "{\"name\":\"Jay Holtslander\",\"alternateName\":\"Jason Holtslander\",\"booleanValue\":true,\"numberValue\":1234,\"doubleValue\":9.5,\"nationality\":\"Canadian\",\"birthPlace\":{\"type\":\"Place\",\"address\":{\"type\":\"PostalAddress\",\"addressLocality\":\"Vancouver\",\"addressRegion\":\"BC\",\"addressCountry\":\"Canada\"}},\"affiliation\":[{\"type\":\"Organization\",\"name\":\"Futurpreneur\",\"sameAs\":[\"https://twitter.com/futurpreneur\",\"https://www.facebook.com/futurpreneur/\",\"https://www.linkedin.com/company-beta/100369/\",\"https://www.youtube.com/user/CYBF\"]}],\"alumniOf\":[{\"type\":\"CollegeOrUniversity\",\"name\":\"Vancouver Film School\",\"sameAs\":\"https://en.wikipedia.org/wiki/Vancouver_Film_School\",\"year\":2000},{\"type\":\"CollegeOrUniversity\",\"name\":\"CodeCore Bootcamp\"}],\"gender\":\"Male\",\"Description\":\"Technologist\",\"disambiguatingDescription\":\"Co-founder of CodeCore Bootcamp\",\"jobTitle\":\"Technical Director\",\"worksFor\":[{\"type\":\"Organization\",\"name\":\"Skunkworks Creative Group Inc.\",\"sameAs\":[\"https://twitter.com/skunkworks_ca\",\"https://www.facebook.com/skunkworks.ca\",\"https://www.linkedin.com/company/skunkworks-creative-group-inc-\",\"https://plus.google.com/+SkunkworksCa\"]}],\"url\":\"https://jay.holtslander.ca\",\"image\":\"https://s.gravatar.com/avatar/961997eb7fd5c22b3e12fb3c8ca14e11?s=512&r=g\",\"address\":{\"type\":\"PostalAddress\",\"addressLocality\":\"Vancouver\",\"addressRegion\":\"BC\",\"addressCountry\":\"Canada\"},\"sameAs\":[\"https://twitter.com/j_holtslander\",\"https://pinterest.com/j_holtslander\",\"https://instagram.com/j_holtslander\",\"https://www.facebook.com/jay.holtslander\",\"https://ca.linkedin.com/in/holtslander/en\",\"https://plus.google.com/+JayHoltslander\",\"https://www.youtube.com/user/jasonh1234\",\"https://github.com/JayHoltslander\",\"https://profiles.wordpress.org/jasonh1234\",\"https://angel.co/j_holtslander\",\"https://www.foursquare.com/user/184843\",\"https://jholtslander.yelp.ca\",\"https://codepen.io/j_holtslander/\",\"https://stackoverflow.com/users/751570/jay\",\"https://dribbble.com/j_holtslander\",\"http://jasonh1234.deviantart.com/\",\"https://www.behance.net/j_holtslander\",\"https://www.flickr.com/people/jasonh1234/\",\"https://medium.com/@j_holtslander\"]}"; @@ -661,7 +665,7 @@ export class InstantData { let vcJson = await cb.id(id) .properties(jsonProps) .seal(TestConfig.storePass); - vcJson.getMetadata().setAlias("json"); + await vcJson.getMetadata().setAlias("json"); await this.testData.store.storeCredential(vcJson); this.vcUser1Json = vcJson; } @@ -677,7 +681,7 @@ export class InstantData { let id = new DIDURL("#email", doc.getSubject()); - let kycIssuer = new Issuer(this.idExampleCorp); + let kycIssuer = await Issuer.create(this.idExampleCorp); let cb = kycIssuer.issueFor(doc.getSubject()); let props = { @@ -735,7 +739,7 @@ export class InstantData { public async getUser2Document() : Promise { if (this.idUser2 == null) { let doc = await (await this.testData.getRootIdentity()).newDid(TestConfig.storePass); - doc.getMetadata().setAlias("User2"); + await doc.getMetadata().setAlias("User2"); let db = DIDDocument.Builder.newFromDocument(doc).edit(); @@ -770,7 +774,7 @@ export class InstantData { public async getUser3Document() : Promise { if (this.idUser3 == null) { let doc = await (await this.testData.getRootIdentity()).newDid(TestConfig.storePass); - doc.getMetadata().setAlias("User3"); + await doc.getMetadata().setAlias("User3"); await doc.publish(TestConfig.storePass); await DIDTestExtension.awaitStandardPublishingDelay(); @@ -783,7 +787,7 @@ export class InstantData { public async getUser4Document() : Promise { if (this.idUser4 == null) { let doc = await (await this.testData.getRootIdentity()).newDid(TestConfig.storePass); - doc.getMetadata().setAlias("User4"); + await doc.getMetadata().setAlias("User4"); await doc.publish(TestConfig.storePass); await DIDTestExtension.awaitStandardPublishingDelay(); @@ -800,7 +804,7 @@ export class InstantData { let did = new DID("did:elastos:example"); let doc = await this.idIssuer.newCustomized(did, TestConfig.storePass); - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); let cb = selfIssuer.issueFor(doc.getSubject()); let props = { @@ -822,7 +826,7 @@ export class InstantData { let key = TestData.generateKeypair(); let id = new DIDURL("#key2", doc.getSubject()); db.addAuthenticationKey(id, key.getPublicKeyBase58()); - this.testData.store.storePrivateKey(id, key.serialize(), TestConfig.storePass); + await this.testData.store.storePrivateKey(id, key.serialize(), TestConfig.storePass); // No private key for testKey key = TestData.generateKeypair(); @@ -859,12 +863,12 @@ export class InstantData { let temp = TestData.generateKeypair(); db.addAuthenticationKey("#key2", temp.getPublicKeyBase58()); - this.testData.store.storePrivateKey(DIDURL.from("#key2", doc.getSubject()), + await this.testData.store.storePrivateKey(DIDURL.from("#key2", doc.getSubject()), temp.serialize(), TestConfig.storePass); temp = TestData.generateKeypair(); db.addAuthenticationKey("#key3", temp.getPublicKeyBase58()); - this.testData.store.storePrivateKey(DIDURL.from("#key3", doc.getSubject()), + await this.testData.store.storePrivateKey(DIDURL.from("#key3", doc.getSubject()), temp.serialize(), TestConfig.storePass); db.addService("#vault", "Hive.Vault.Service", @@ -901,7 +905,7 @@ export class InstantData { db.addService("#vcr", "CredentialRepositoryService", "https://foobar.com/credentials", props); - let selfIssuer = new Issuer(doc, signKey); + let selfIssuer = await Issuer.create(doc, signKey); let cb = selfIssuer.issueFor(doc.getSubject()); props = { @@ -917,7 +921,7 @@ export class InstantData { .properties(props) .seal(TestConfig.storePass); - let kycIssuer = new Issuer(this.idExampleCorp); + let kycIssuer = await Issuer.create(this.idExampleCorp); cb = kycIssuer.issueFor(doc.getSubject()); props = { @@ -949,7 +953,7 @@ export class InstantData { let id = new DIDURL("#services", doc.getSubject()); - let selfIssuer = new Issuer(doc, this.idUser1.getDefaultPublicKeyId()); + let selfIssuer = await Issuer.create(doc, this.idUser1.getDefaultPublicKeyId()); let cb = selfIssuer.issueFor(doc.getSubject()); let props = { @@ -980,7 +984,7 @@ export class InstantData { let id = new DIDURL("#license", doc.getSubject()); - let kycIssuer = new Issuer(this.idExampleCorp); + let kycIssuer = await Issuer.create(this.idExampleCorp); let cb = kycIssuer.issueFor(doc.getSubject()); let props = { @@ -1083,7 +1087,7 @@ export class InstantData { let id = new DIDURL("#email", doc.getSubject()); - let kycIssuer = new Issuer(this.idIssuer); + let kycIssuer = await Issuer.create(this.idIssuer); let cb = kycIssuer.issueFor(doc.getSubject()); let props = { diff --git a/tests/src/utils/utils.ts b/tests/src/utils/utils.ts index 1b5879b1..3c58efc8 100644 --- a/tests/src/utils/utils.ts +++ b/tests/src/utils/utils.ts @@ -73,7 +73,7 @@ export class Utils { return list; } - public static equals(file1: File, file2: File): boolean { + public static async equals(file1: File, file2: File): Promise { if (file1 == null && file2 == null) return true; @@ -83,19 +83,19 @@ export class Utils { /* if (file1.compareTo(file2) == 0) // TODO TS: IF THE FILES HAVE THE SAME NAME WE RETURN TRUE? return true; */ - if (file1.exists() !== file2.exists()) + if (await file1.exists() !== await file2.exists()) return false; - if (!file1.exists()) + if (!await file1.exists()) return true; - if (file1.isDirectory() !== file2.isDirectory()) + if (await file1.isDirectory() !== await file2.isDirectory()) return false; - if (file1.isDirectory()) { + if (await file1.isDirectory()) { - let files1 = this.removeIgnoredFiles(file1.list()); - let files2 = this.removeIgnoredFiles(file2.list()); + let files1 = this.removeIgnoredFiles(await file1.list()); + let files2 = this.removeIgnoredFiles(await file2.list()); if (files1.length != files2.length) return false; @@ -110,21 +110,21 @@ export class Utils { let f1 = new File(file1, files[i]); let f2 = new File(file2, files[i]); - if (!this.equals(f1, f2)) + if (!await this.equals(f1, f2)) return false; } return true; } else { - if (file1.length() != file2.length()) + if (await file1.length() != await file2.length()) return false; - return file1.readText() === file2.readText(); // BAD PERF + return await file1.readText() === await file2.readText(); // BAD PERF } } - public static deleteFile(file: File) { - file.delete(); + public static deleteFile(file: File): Promise { + return file.delete(); } /*public static void dumpHex(String prompt, byte[] bytes) { diff --git a/tests/src/verifiablecredential.test.ts b/tests/src/verifiablecredential.test.ts index f6549c55..288cf531 100644 --- a/tests/src/verifiablecredential.test.ts +++ b/tests/src/verifiablecredential.test.ts @@ -46,7 +46,7 @@ describe('let Tests', () => { let store: DIDStore; beforeEach(async () => { - testData = new TestData(); + testData = await TestData.create(); await testData.cleanup(); store = await testData.getStore(); }); @@ -293,10 +293,10 @@ describe('let Tests', () => { let cd = testData.getCompatibleData(csv.version); await cd.loadAll(); - let normalizedJson = cd.getCredentialJson(csv.did, csv.vc, "normalized"); + let normalizedJson = await cd.getCredentialJson(csv.did, csv.vc, "normalized"); let normalized = VerifiableCredential.parse(normalizedJson); - let compactJson = cd.getCredentialJson(csv.did, csv.vc, "compact"); + let compactJson = await cd.getCredentialJson(csv.did, csv.vc, "compact"); let compact = VerifiableCredential.parse(compactJson); let credential = await cd.getCredential(csv.did, csv.vc); @@ -976,7 +976,7 @@ describe('let Tests', () => { let doc = await sd.getUser1Document(); let did = doc.getSubject(); - let selfIssuer = new Issuer(doc); + let selfIssuer = await Issuer.create(doc); for (let i = 0; i < 36; i++) { console.log("Creating test credential {}...", i); diff --git a/tests/src/verifiablepresentation.test.ts b/tests/src/verifiablepresentation.test.ts index 50583b28..5dfa4883 100644 --- a/tests/src/verifiablepresentation.test.ts +++ b/tests/src/verifiablepresentation.test.ts @@ -36,7 +36,7 @@ let store: DIDStore; describe('VerifiablePresentation Tests', () => { beforeEach(async () => { - testData = new TestData(); + testData = await TestData.create(); await testData.cleanup(); store = await testData.getStore(); }); From bafdc151ae6e5bfcc3bbca2f483a65ebb4ee4d3b Mon Sep 17 00:00:00 2001 From: Fred Chen Date: Wed, 26 Oct 2022 17:09:24 +0800 Subject: [PATCH 2/2] CU-3q8w246 - Refine test cases for async file APIs and add switch to support IndexedDB. --- src/file.ts | 3 -- src/filesystemstorage.ts | 29 +++++------ src/fs.browser.ts | 61 ++++++++++++------------ src/issuer.ts | 2 + tests/src/didstore.test.ts | 10 ++-- tests/src/verifiablepresentation.test.ts | 2 +- 6 files changed, 51 insertions(+), 56 deletions(-) diff --git a/src/file.ts b/src/file.ts index 7bd17bf5..c43bb8a1 100644 --- a/src/file.ts +++ b/src/file.ts @@ -22,9 +22,6 @@ import path from "path"; import * as fs from "./fs"; -import {Logger} from "./logger"; - -const log = new Logger("File"); /** * Internal class mimicing Java File class in order to reduce the divergence with Java implementation diff --git a/src/filesystemstorage.ts b/src/filesystemstorage.ts index fc83c713..19c0f468 100644 --- a/src/filesystemstorage.ts +++ b/src/filesystemstorage.ts @@ -387,23 +387,18 @@ export class FileSystemStorage implements DIDStorage { if (!(await dir.exists())) return []; - let children = (await dir.listFiles()).filter(async (file) => { - if (!(await file.isDirectory())) - return false; - - let sk = new File(file, FileSystemStorage.ROOT_IDENTITY_PRIVATEKEY_FILE); - return await sk.exists() && await sk.isFile(); - }); - - if (children == null || children.length == 0) - return []; - let ids: RootIdentity[] = []; - for (let id of children) { - let identity = await this.loadRootIdentity(id.getName()); - ids.push(identity); - } + const files = await dir.listFiles(); + if (files) { + for (const file of files) { + if (!(await file.isDirectory())) + continue; + let sk = new File(file, FileSystemStorage.ROOT_IDENTITY_PRIVATEKEY_FILE); + if (await sk.exists() && await sk.isFile()) + ids.push(await this.loadRootIdentity(file.getName())); + } + } return ids; } @@ -521,7 +516,7 @@ export class FileSystemStorage implements DIDStorage { const didRoot = new File(file, FileSystemStorage.DOCUMENT_FILE); if (await didRoot.exists() && await didRoot.isFile()) - dids.push(new DID(DID.METHOD, didRoot.getName())); + dids.push(new DID(DID.METHOD, file.getName())); } } return dids; @@ -669,7 +664,7 @@ export class FileSystemStorage implements DIDStorage { let vc = new File(file, FileSystemStorage.CREDENTIAL_FILE); if (await vc.exists() && await vc.isFile()) { - credentials.push(FileSystemStorage.toDIDURL(did, vc.getName())); + credentials.push(FileSystemStorage.toDIDURL(did, file.getName())); } } } diff --git a/src/fs.browser.ts b/src/fs.browser.ts index ac35cccf..ceef9445 100644 --- a/src/fs.browser.ts +++ b/src/fs.browser.ts @@ -24,6 +24,37 @@ import BrowserFS, { BFSRequire } from "browserfs"; import Stats from "browserfs/dist/node/core/node_fs_stats"; const fs = BFSRequire("fs"); +if (typeof window != 'undefined' && 'didUseIndexedDb' in window) { //IndexedDB + BrowserFS.configure({ + fs: "MountableFileSystem", + options: { + "/": { + fs: "IndexedDB", + options: { + storeName: "DIDDatabase" + } + } + } + }, function (e) { + if (e) { + // An error occurred. + throw e; + } + // Otherwise, BrowserFS is ready to use! + }); +} else { //Local Storage + BrowserFS.configure({ + fs: "LocalStorage", + options: {} + }, function (e) { + if (e) { + throw e; + } else { + //console.log("BrowserFS initialization complete"); + } + }); +} + export function existsSync(path: string): Promise { return new Promise(resolve => fs.exists(path, exists => { resolve(exists); @@ -83,33 +114,3 @@ export function unlinkSync(path: string): Promise { e ? reject(e) : resolve(); })); } - -// BrowserFS.configure({ -// fs: "LocalStorage", -// options: {} -// }, function(e) { -// if (e) { -// throw e; -// } -// else { -// //console.log("BrowserFS initialization complete"); -// } -// }); - -BrowserFS.configure({ - fs: "MountableFileSystem", - options: { - "/": { - fs: "IndexedDB", - options: { - storeName: "DIDDatabase" - } - } - } -}, function(e) { - if (e) { - // An error occurred. - throw e; - } - // Otherwise, BrowserFS is ready to use! -}); diff --git a/src/issuer.ts b/src/issuer.ts index 9a6ac7ad..4d630b95 100644 --- a/src/issuer.ts +++ b/src/issuer.ts @@ -51,6 +51,8 @@ export class Issuer { } public static async create(doc: DIDDocument, signKey?: DIDURL): Promise { + checkArgument(doc != null, "Invalid document"); + const issuer = new Issuer(doc, signKey); if (!(await doc.hasPrivateKey(issuer.signKey))) diff --git a/tests/src/didstore.test.ts b/tests/src/didstore.test.ts index 654e7452..eee7d0c8 100644 --- a/tests/src/didstore.test.ts +++ b/tests/src/didstore.test.ts @@ -632,7 +632,7 @@ describe("DIDStore Tests", ()=>{ [false, true].forEach((cached)=>{ test("testStoreCachePerformance", async ()=>{ - Utils.deleteFile(new File(TestConfig.storeRoot)); + await Utils.deleteFile(new File(TestConfig.storeRoot)); let store: DIDStore = null; if (cached) store = await DIDStore.open(TestConfig.storeRoot); @@ -672,7 +672,7 @@ describe("DIDStore Tests", ()=>{ let docs: DIDDocument[] = []; for (let i = 0; i < stores.length; i++) { - Utils.deleteFile(new File(TestConfig.storeRoot + i)); + await Utils.deleteFile(new File(TestConfig.storeRoot + i)); stores[i] = await DIDStore.open(TestConfig.storeRoot + i); expect(stores[i]).not.toBeNull(); let mnemonic = Mnemonic.getInstance().generate(); @@ -752,7 +752,7 @@ describe("DIDStore Tests", ()=>{ let data = await store.exportRootIdentity(id, "password", TestConfig.storePass); let restoreDir = new File(tempDir, "restore"); - Utils.deleteFile(restoreDir); + await Utils.deleteFile(restoreDir); let store2 = await DIDStore.open(restoreDir.getAbsolutePath()); await store2.importRootIdentity(data, "password", TestConfig.storePass); @@ -787,7 +787,7 @@ describe("DIDStore Tests", ()=>{ await store.exportStore(exportFile.getAbsolutePath(), "password", TestConfig.storePass); let restoreDir = new File(tempDir, "restore"); - Utils.deleteFile(restoreDir); + await Utils.deleteFile(restoreDir); let store2 = await DIDStore.open(restoreDir.getAbsolutePath()); await store2.importStore(exportFile.getAbsolutePath(), "password", TestConfig.storePass); @@ -808,7 +808,7 @@ describe("DIDStore Tests", ()=>{ let tempDir = new File(TestConfig.tempDir); await tempDir.createDirectory(); let restoreDir = new File(tempDir, "imported-store"); - Utils.deleteFile(restoreDir); + await Utils.deleteFile(restoreDir); let store2 = await DIDStore.open(restoreDir.getAbsolutePath()); await store2.importStore(exportFile.getAbsolutePath(), "password", TestConfig.storePass); diff --git a/tests/src/verifiablepresentation.test.ts b/tests/src/verifiablepresentation.test.ts index 5dfa4883..2be6bb2c 100644 --- a/tests/src/verifiablepresentation.test.ts +++ b/tests/src/verifiablepresentation.test.ts @@ -176,7 +176,7 @@ describe('VerifiablePresentation Tests', () => { check = await vp.isValid(); expect(check).toBeTruthy(); - let normalizedJson = cd.getPresentationJson(did, presentation, "normalized"); + let normalizedJson = await cd.getPresentationJson(did, presentation, "normalized"); let normalized = VerifiablePresentation.parse(normalizedJson); expect(normalized).not.toBeNull();