diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 496ee0f86bd..c02acbccbab 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -16,6 +16,7 @@ import { Observable, Subscription } from 'rxjs'; // Providers import { + AddressBookProvider, AnalyticsProvider, AppProvider, BitPayCardProvider, @@ -159,8 +160,9 @@ export class CopayApp { private themeProvider: ThemeProvider, private logsProvider: LogsProvider, private dynamicLinksProvider: DynamicLinksProvider, - private analyticsProvider: AnalyticsProvider, - private locationProvider: LocationProvider + private locationProvider: LocationProvider, + private addressBookProvider: AddressBookProvider, + private analyticsProvider: AnalyticsProvider ) { this.imageLoaderConfig.setFileNameCachedWithExtension(true); this.imageLoaderConfig.useImageTag(true); @@ -442,6 +444,8 @@ export class CopayApp { } }); } + + this.addressBookProvider.migrateOldContacts(); } private updateDesktopOnFocus() { diff --git a/src/providers/address-book/address-book.spec.ts b/src/providers/address-book/address-book.spec.ts index 557d8d47783..a829b336840 100644 --- a/src/providers/address-book/address-book.spec.ts +++ b/src/providers/address-book/address-book.spec.ts @@ -291,14 +291,14 @@ describe('AddressBookProvider', () => { }); it('If setAddressBook fails, remove function will reject', () => { const response = { - '1Q2aGBWZHNuZ7WjB9komwj9fF9GmnK5AzU (btc)': { + 'btc-1Q2aGBWZHNuZ7WjB9komwj9fF9GmnK5AzU': { address: '1Q2aGBWZHNuZ7WjB9komwj9fF9GmnK5AzU', email: 'test@test.com', name: 'test', coin: 'btc', network: 'livenet' }, - 'mnH3XUZ8CmH8CMruEfCDXGc83XLSn8szbm (btc)': { + 'btc-mnH3XUZ8CmH8CMruEfCDXGc83XLSn8szbm': { address: 'mnH3XUZ8CmH8CMruEfCDXGc83XLSn8szbm', email: 'asd@sad.com', name: 'jp', diff --git a/src/providers/address-book/address-book.ts b/src/providers/address-book/address-book.ts index 6a00217b005..509165b197a 100644 --- a/src/providers/address-book/address-book.ts +++ b/src/providers/address-book/address-book.ts @@ -28,9 +28,6 @@ export class AddressBookProvider { private currencyProvider: CurrencyProvider ) { this.logger.debug('AddressBookProvider initialized'); - this.migrateOldContacts().then(() => { - this.logger.debug('Old AddressBook processed'); - }); } public get(addr: string, network: string): Promise { @@ -83,8 +80,10 @@ export class AddressBookProvider { if (ab && _.isString(ab)) ab = JSON.parse(ab); ab = ab || {}; _.each(ab, contact => { - const ctc = this.getContact(contact); - if (ctc) contacts.push(ctc); + if (contact.address) { + const ctc = this.getContact(contact); + if (ctc) contacts.push(ctc); + } }); return resolve(contacts); } catch (err) { @@ -105,22 +104,24 @@ export class AddressBookProvider { coin: contactStr.coin, network: contactStr.network } - : { - ...this.addressProvider.getCoinAndNetwork( - contactStr.address, - contactStr.network - ) - }; + : this.addressProvider.getCoinAndNetwork( + contactStr.address, + contactStr.network + ) || undefined; - const contact: Contact = { - address: contactStr.address, - coin: coinInfo.coin, - network: coinInfo.network, - name: _.isObject(contactStr) ? contactStr.name : contactStr, - tag: _.isObject(contactStr) ? contactStr.tag : null, - email: _.isObject(contactStr) ? contactStr.email : null - }; - return contact; + if (!coinInfo) { + return undefined; + } else { + const contact: Contact = { + address: contactStr.address, + coin: coinInfo.coin, + network: coinInfo.network, + name: _.isObject(contactStr) ? contactStr.name : contactStr, + tag: _.isObject(contactStr) ? contactStr.tag : null, + email: _.isObject(contactStr) ? contactStr.email : null + }; + return contact; + } } public add(entry: Contact): Promise { @@ -164,7 +165,7 @@ export class AddressBookProvider { let msg = this.translate.instant('Entry already exist'); return reject(msg); } - ab[entry.address + ' (' + entry.coin.toLowerCase() + ')'] = addrData; + ab[entry.coin.toLowerCase() + '-' + entry.address] = addrData; this.persistenceProvider .setAddressBook(addrData.network, JSON.stringify(ab)) .then(() => { @@ -208,11 +209,11 @@ export class AddressBookProvider { let msg = this.translate.instant('Addressbook is empty'); return reject(msg); } - if (!ab[addr + ' (' + coin.toLowerCase() + ')']) { + if (!ab[coin.toLowerCase() + '-' + addr]) { let msg = this.translate.instant('Entry does not exist'); return reject(msg); } - delete ab[addr + ' (' + coin.toLowerCase() + ')']; + delete ab[coin.toLowerCase() + '-' + addr]; this.persistenceProvider .setAddressBook(network, JSON.stringify(ab)) .then(() => { @@ -236,7 +237,6 @@ export class AddressBookProvider { } public migrateOldContacts(): Promise { - this.logger.info('AddressBookProvider: migrating old contacts'); return Promise.all([ this.processNetworkContacts('livenet'), this.processNetworkContacts('testnet') @@ -247,6 +247,7 @@ export class AddressBookProvider { }) .catch(() => { this.migratingContactsSubject.next(false); + this.logger.debug('Failed to migrate old AddressBook'); return Promise.reject(false); }); } @@ -267,13 +268,18 @@ export class AddressBookProvider { } private processNetworkContacts(network: string): Promise { - return new Promise(async resolve => { + return new Promise(async (resolve, reject) => { try { const newABFile = await this.persistenceProvider.existsNewAddressBook( network ); - - if (!newABFile) { + const oldABFile = await this.persistenceProvider.existsOldAddressBook( + network + ); + if (oldABFile && !newABFile) { + this.logger.info( + `AddressBookProvider: migrating old ${network} contacts.` + ); this.migratingContactsSubject.next(true); const oldContacts = await this.list(network, false); if (oldContacts) { @@ -284,26 +290,26 @@ export class AddressBookProvider { ); let newContactJson = {}; _.each(oldContacts, old => { - newContactJson[ - old.address + ' (' + old.coin.toLowerCase() + ')' - ] = old; + newContactJson[old.coin.toLowerCase() + '-' + old.address] = old; }); this.persistenceProvider .setAddressBook(network, JSON.stringify(newContactJson), true) - .then(() => resolve(true)) + .then(() => { + this.logger.debug(`Old ${network} AddressBook processed.`); + return resolve(true); + }) .catch(err => { this.logger.error(err); - resolve(false); + return reject(err); }); } - } else { - this.logger.info('AddressBookProvider: Using new addressBook'); } return resolve(true); } catch { err => { + this.logger.error(`Failed to process old ${network} AddressBook.`); this.logger.error(err); - resolve(false); + return reject(err); }; } }); diff --git a/src/providers/persistence/persistence.ts b/src/providers/persistence/persistence.ts index a189c6325f2..6c62eb3afa8 100644 --- a/src/providers/persistence/persistence.ts +++ b/src/providers/persistence/persistence.ts @@ -26,7 +26,7 @@ export interface GiftCardMap { const Keys = { ADDRESS_BOOK: network => 'addressbook-' + network, - NEW_ADDRESS_BOOK: network => 'new-addressbook-' + network, + NEW_ADDRESS_BOOK: network => 'addressbook-v2-' + network, AGREE_DISCLAIMER: 'agreeDisclaimer', GIFT_CARD_USER_INFO: 'amazonUserInfo', // keeps legacy key for backwards compatibility APP_IDENTITY: network => 'appIdentity-' + network, @@ -428,6 +428,10 @@ export class PersistenceProvider { return this.storage.exists(Keys.NEW_ADDRESS_BOOK(network)); } + existsOldAddressBook(network: string) { + return this.storage.exists(Keys.ADDRESS_BOOK(network)); + } + setAddressBook(network: string, addressbook, newAddressBook: boolean = true) { return this.storage.set( newAddressBook