diff --git a/accounts/support-rest-api.js b/accounts/support-rest-api.js index 38e9df9..5bd293d 100644 --- a/accounts/support-rest-api.js +++ b/accounts/support-rest-api.js @@ -69,6 +69,14 @@ class SupportRestApi { HttpServer.sendAuthError ) + this.httpServer.app.get( + `/${keys.prefixes.support}/xpub/:xpub/delete`, + authMgr.checkHasAdminProfile.bind(authMgr), + this.validateArgsGetXpubDelete.bind(this), + this.getXpubDelete.bind(this), + HttpServer.sendAuthError + ) + this.httpServer.app.get( `/${keys.prefixes.support}/pairing/explorer`, authMgr.checkHasAdminProfile.bind(authMgr), @@ -120,32 +128,9 @@ class SupportRestApi { */ _formatAddressInfoResult(info) { const res = info.toPojoExtended() - /*res._endpoints = [] - - if (info.tracked) { - res._endpoints.push({ - task: 'Rescan this address from remote sources', - url: `/${keys.prefixes.support}/address/${info.address}/rescan` - }) - } - - if (info.xpub != null) { - res._endpoints.push({ - task: 'Get information about the HD account that owns this address', - url: `/${keys.prefixes.support}/xpub/${info.xpub}/info` - }) - - res._endpoints.push({ - task: 'Rescan the whole HD account that owns this address', - url: `/${keys.prefixes.support}/xpub/${info.xpub}/rescan` - }) - }*/ - return JSON.stringify(res, null, 2) } - - /** * Rescan the blockchain for a given address * @param {object} req - http request object @@ -162,10 +147,6 @@ class SupportRestApi { const ret = { status: 'Rescan complete', - /*_endpoints: [{ - task: 'Get updated information about this address', - url: `/${keys.prefixes.support}/address/${address}/info` - }]*/ } await addrService.rescan(address) @@ -224,12 +205,6 @@ class SupportRestApi { */ _formatXpubInfoResult(info) { const res = info.toPojoExtended() - - /*res._endpoints = [{ - task: 'Rescan the whole HD account from remote sources', - url: `/${keys.prefixes.support}/xpub/${info.xpub}/rescan` - }]*/ - return JSON.stringify(res, null, 2) } @@ -249,10 +224,6 @@ class SupportRestApi { const ret = { status: 'Rescan complete', - /*_endpoints: [{ - task: 'Get updated information about this HD account', - url: `/${keys.prefixes.support}/xpub/${xpub}/info` - }]*/ } const gapLimit = req.query.gap != null ? parseInt(req.query.gap) : 0 @@ -283,6 +254,36 @@ class SupportRestApi { } } + /** + * Delete all data related to a hd account + * @param {object} req - http request object + * @param {object} res - http response object + */ + async getXpubDelete(req, res) { + try { + // Parse the entities passed as url params + const entities = apiHelper.parseEntities(req.params.xpub).xpubs + if (entities.length == 0) + return HttpServer.sendError(res, errors.xpub.INVALID) + + const xpub = entities[0] + + try { + await hdaService.deleteHdAccount(xpub) + HttpServer.sendOk(res) + } catch(e) { + HttpServer.sendError(res, e) + } + + } catch(e) { + HttpServer.sendError(res, errors.generic.GEN) + + } finally { + debugApi && Logger.info(`API : Completed GET /support/xpub/${req.params.xpub}/delete`) + } + } + + /** * Get pairing info */ @@ -366,6 +367,23 @@ class SupportRestApi { } } + /** + * Validate arguments related to GET xpub delete requests + * @param {object} req - http request object + * @param {object} res - http response object + * @param {function} next - next express middleware + */ + validateArgsGetXpubDelete(req, res, next) { + const isValidXpub = validator.isAlphanumeric(req.params.xpub) + + if (!isValidXpub) { + HttpServer.sendError(res, errors.body.INVDATA) + Logger.error(null, `API : SupportRestApi.validateArgsGetXpubDelete() : Invalid xpub ${req.params.xpub}`) + } else { + next() + } + } + /** * Validate arguments related to addresses requests * @param {object} req - http request object diff --git a/static/admin/css/style.css b/static/admin/css/style.css index 7ffc507..a1da6e6 100644 --- a/static/admin/css/style.css +++ b/static/admin/css/style.css @@ -534,6 +534,17 @@ button { display: inline-block; } +#xpubs-deletion-actions span { + display: inline; +} + +#xpubs-deletion-actions input { + width: 50px; + margin-left: 5px; + margin-right: 5px; + display: inline-block; +} + #xpubs-tool-details #xpub-value { overflow: hidden; } diff --git a/static/admin/dmt/xpubs-tools/xpubs-tools.html b/static/admin/dmt/xpubs-tools/xpubs-tools.html index 2eeb6b9..fd7017e 100644 --- a/static/admin/dmt/xpubs-tools/xpubs-tools.html +++ b/static/admin/dmt/xpubs-tools/xpubs-tools.html @@ -61,6 +61,7 @@
+
@@ -77,6 +78,14 @@ +
+
+ Do you want to delete this xpub? + + +
+
+
diff --git a/static/admin/dmt/xpubs-tools/xpubs-tools.js b/static/admin/dmt/xpubs-tools/xpubs-tools.js index 930663e..2ada7e5 100644 --- a/static/admin/dmt/xpubs-tools/xpubs-tools.js +++ b/static/admin/dmt/xpubs-tools/xpubs-tools.js @@ -11,8 +11,11 @@ const screenXpubsToolsScript = { $('#btn-xpub-search-go').click(() => {this.searchXpub()}) $('#btn-xpub-details-reset').click(() => {this.showSearchForm()}) $('#btn-xpub-details-rescan').click(() => {this.showRescanForm()}) + $('#btn-xpub-details-delete').click(() => {this.showDeletionForm()}) $('#btn-xpub-rescan-go').click(() => {this.rescanXpub()}) $('#btn-xpub-rescan-cancel').click(() => {this.hideRescanForm()}) + $('#btn-xpub-delete-go').click(() => {this.deleteXpub()}) + $('#btn-xpub-delete-cancel').click(() => {this.hideDeletionForm()}) $('#btn-xpub-import-go').click(() => {this.importXpub()}) $('#btn-xpub-details-retype').click(() => {this.showImportForm(true)}) $('#btn-xpub-import-cancel').click(() => {this.hideImportForm(this.isReimport)}) @@ -25,6 +28,7 @@ const screenXpubsToolsScript = { preparePage: function() { this.hideRescanForm() + this.hideDeletionForm() this.showSearchForm() $("#xpub").focus() }, @@ -128,6 +132,18 @@ const screenXpubsToolsScript = { } }, + deleteXpub: function() { + lib_msg.displayMessage('Deleting a xpub. Please wait...') + return lib_api.getXpubDelete(this.currentXpub) + .then(result => { + this.currentXpub = null + this.preparePage() + lib_msg.displayInfo('Xpub successfully deleted') + }).catch(e => { + lib_errors.processError(e) + }) + }, + checkRescanStatus: function(callback) { this.rescanStatusTimerId = setTimeout(() => { lib_api.getXpubRescanStatus(this.currentXpub) @@ -281,6 +297,17 @@ const screenXpubsToolsScript = { $('#xpubs-tool-actions').show() }, + showDeletionForm: function() { + $('#xpubs-tool-actions').hide() + $('#xpubs-deletion-actions').show() + lib_msg.cleanMessagesUi() + }, + + hideDeletionForm: function() { + $('#xpubs-deletion-actions').hide() + $('#xpubs-tool-actions').show() + }, + } screenScripts.set('#screen-xpubs-tools', screenXpubsToolsScript) diff --git a/static/admin/lib/api-wrapper.js b/static/admin/lib/api-wrapper.js index 47f492d..2fdae1d 100644 --- a/static/admin/lib/api-wrapper.js +++ b/static/admin/lib/api-wrapper.js @@ -110,6 +110,15 @@ const lib_api = { ) }, + /** + * Deletes a xpub + */ + getXpubDelete: function(xpub) { + let prefix = conf['prefixes']['support'] + let uri = this.baseUri + '/' + prefix + '/xpub/' + xpub + '/delete' + return this.sendGetUriEncoded(uri, {}) + }, + /** * Gets the status of a xpub rescan */