diff --git a/package-lock.json b/package-lock.json index 80c46ca..e976f93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -889,6 +889,11 @@ "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true }, + "adm-zip": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.13.tgz", + "integrity": "sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==" + }, "after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", @@ -1758,6 +1763,11 @@ } } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -3023,6 +3033,14 @@ } } }, + "easy-unzip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/easy-unzip/-/easy-unzip-1.1.0.tgz", + "integrity": "sha512-Nxsq0eh1Tn22UFPrqDM+VNdkAdZFoAjN8NTOOPzGXxqXoNxB5jCYu9/s3uOM6BFeshF/oTI/LYmOlLp0h5QKiA==", + "requires": { + "yauzl": "^2.10.0" + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -3575,6 +3593,14 @@ "bser": "^2.0.0" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", @@ -7641,6 +7667,11 @@ "sha.js": "^2.4.8" } }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -11463,6 +11494,15 @@ "decamelize": "^1.2.0" } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", diff --git a/package.json b/package.json index b97eb38..8cd5a53 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,8 @@ "build-backend": "tsc; webpack --display-error-details --config src/backend/webpack.prod.js --progress --colors; pwd; cp -r lib/PluginManager/* .", "build-frontend": "npm run build-dashboard; npm run build-widget", "build-dashboard": "cd src/frontend/dashboard; npm i; npm run build; cp -r dist/* ../../../static", - "build-widget": "rollup -c src/frontend/widget/rollup.config.js", - "clean": "rm -rf lib static dist widget .rpt2_cache *.js *.ts; rm -rf src/frontend/dashboard/dist", + "build-widget": "rollup -c src/frontend/widget/rollup.config.js; mkdir -p plugins/admin; cp FrontendPlugin.js plugins/admin", + "clean": "rm -rf lib static plugins kfs dist widget .rpt2_cache *.js *.ts; rm -rf src/frontend/dashboard/dist", "update-frontblock": "rm -rf node_modules/frontblock*; npm install" }, "repository": { @@ -23,11 +23,13 @@ "@angular/core": "^5.2.2", "@types/node": "^11.13.10", "@uirouter/angularjs": "^1.0.5", + "adm-zip": "^0.4.13", "angular": "^1.7.8", "bip39": "^3.0.2", "bitcoinjs-lib": "^5.0.4", "bsert": "0.0.10", "bsock": "^0.1.9", + "easy-unzip": "^1.1.0", "express": "^4.16.4", "frontblock-generic": "latest", "hdkey": "^1.1.1", diff --git a/src/backend/PluginManager/Plugin.ts b/src/backend/PluginManager/Plugin.ts index 88f7b22..20b5235 100644 --- a/src/backend/PluginManager/Plugin.ts +++ b/src/backend/PluginManager/Plugin.ts @@ -20,6 +20,8 @@ export default class PluginManagerPlugin extends PluginManager implements Plugin constructor(){ super() + + this.loadedPlugins[this.name] = {backend: this, frontend: this.loadFrontend(this.name)} } exportRPCs(): import("frontblock-generic/Plugin").socketioRPC[] { @@ -75,12 +77,22 @@ export default class PluginManagerPlugin extends PluginManager implements Plugin visibility: "private", rpc: async(conf) => { return this.updateConfig(conf) }, type: 'call' + },{ + name: "extractPlugin", + visibility: "private", + rpc: async(conf) => { return this.extractPlugin(conf) }, + type: 'call' + },{ + name: "downloadPlugin", + visibility: "private", + rpc: async(conf) => { return this.downloadPlugin(conf) }, + type: 'call' } ] } async start(): Promise { - await this.loadPlugin("admin") + } stop(): void { diff --git a/src/backend/PluginManager/PluginManager.ts b/src/backend/PluginManager/PluginManager.ts index b7d8108..7488931 100644 --- a/src/backend/PluginManager/PluginManager.ts +++ b/src/backend/PluginManager/PluginManager.ts @@ -5,8 +5,11 @@ import fetch = require('node-fetch'); import fs = require('fs'); import path = require('path') import unzip = require('unzip') +import easyunzip = require('easy-unzip') + import { Plugin, ConfigLoader } from 'frontblock-generic/Plugin'; import { SemVer, parse } from "semver"; +import { once } from 'events'; Logger.configure({ appenders: @@ -20,6 +23,7 @@ Logger.configure({ } }) const logger = Logger.getLogger("PluginManager") +const AdmZip = require('adm-zip'); type PluginVersion = { installed?: SemVer, @@ -55,16 +59,11 @@ export default class PluginManager extends ConfigLoader { - if (err && err.code === 'ENOENT') { - fs.mkdirSync(this.cacheDir, {recursive: true}) - logger.info('Manager installed to ' + this.conf.installDir) - } else { - logger.info('Manager already installed at ' + this.conf.installDir) - } - }) + fs.accessSync(this.cacheDir) + logger.info('Manager already installed at ' + this.conf.installDir) } catch (error) { - logger.error(error) + fs.mkdirSync(this.cacheDir, {recursive: true}) + logger.info('Manager installed to ' + this.cacheDir) } } @@ -79,12 +78,12 @@ export default class PluginManager extends ConfigLoader { + public getInstalledPlugins():string[] { try { - const installed = await fs.promises.readdir(this.conf.installDir) + const installed = fs.readdirSync(this.conf.installDir) return installed.filter( entry => entry[0] != '.') } catch (error) { - logger.error(error) + logger.error("getInstalledPlugins", error) throw error } } @@ -104,17 +103,18 @@ export default class PluginManager extends ConfigLoader {throw new Error(err)}) const response = await fetch(url) if (!response.ok) throw new Error(response.statusText) - await response.body.pipe(file) + response.body.pipe(file) + await once(file, 'finish'); + } catch (error) { - logger.error(error) + logger.error("downloadFile", error) await fs.promises.unlink(dest) } } private async getLatestRelease(pluginName:string):Promise{ - logger.info("Downloading Plugin", pluginName) + logger.info("Downloading Plugin", pluginName, "from", this.conf.resourceLocation + pluginName + '/releases') if(pluginName === this.name) pluginName = "admin" - logger.error(this.conf.resourceLocation + pluginName + '/releases') const response = await fetch(this.conf.resourceLocation + pluginName + '/releases') if (!response.ok) throw new Error(pluginName+": "+response.statusText) @@ -130,23 +130,20 @@ export default class PluginManager extends ConfigLoader asset.name === 'plugin.zip')[0].browser_download_url const checksumURL = latest.assets.filter(asset => asset.name === 'md5sum.txt')[0].browser_download_url if (!version || ! archiveURL || !checksumURL) throw new Error('Malformed response') - await fs.access(path.join(this.cacheDir, pluginName), err => { - if (err && err.code === 'ENOENT') { - fs.mkdirSync(path.join(this.cacheDir, pluginName), {recursive: true}) - } - }) + fs.mkdirSync(path.join(this.cacheDir, pluginName), {recursive: true}) await this.downloadFile(archiveURL, path.join(this.cacheDir, pluginName, 'plugin.zip')) await this.downloadFile(checksumURL, path.join(this.cacheDir, pluginName, 'md5sum.txt')) @@ -159,15 +156,18 @@ export default class PluginManager extends ConfigLoaderDashboard \ No newline at end of file diff --git a/src/frontend/static/inline.31e1fb380eb7cf3d75b1.bundle.js b/src/frontend/static/inline.31e1fb380eb7cf3d75b1.bundle.js deleted file mode 100644 index 6e4ec34..0000000 --- a/src/frontend/static/inline.31e1fb380eb7cf3d75b1.bundle.js +++ /dev/null @@ -1 +0,0 @@ -!function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];a\n
\n \n
\n\n
\n
\n \n
\n
\n\n'},Jnfr:function(e,t){function n(e){return Promise.resolve().then(function(){throw new Error("Cannot find module '"+e+"'.")})}n.keys=function(){return[]},n.resolve=n,e.exports=n,n.id="Jnfr"},Zhnu:function(e,t){e.exports=""},gs3p:function(e,t){e.exports='
\n
\n
\n'},okgc:function(e,t){e.exports=""},x35b:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n("WT6e"),r=n("4PVY"),i=n("OE0E"),c=n("ItHS"),a=this&&this.__decorate||function(e,t,n,o){var r,i=arguments.length,c=i<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,n):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,t,n,o);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(c=(i<3?r(c):i>3?r(t,n,c):r(t,n))||c);return i>3&&c&&Object.defineProperty(t,n,c),c},s=function(){function e(){}return e=a([Object(o.Component)({selector:"app-root",template:n("5xMp"),styles:[n("okgc")]})],e)}(),l=n("Xjw4"),u=n("7DMc"),f=n("WPXp"),p=this&&this.__decorate||function(e,t,n,o){var r,i=arguments.length,c=i<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,n):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,t,n,o);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(c=(i<3?r(c):i>3?r(t,n,c):r(t,n))||c);return i>3&&c&&Object.defineProperty(t,n,c),c},d=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},h=function(){function e(){}return e.prototype.getWidgetConfigs=function(){return fb.PluginManager.getLoadedPluginNames()},e=p([Object(o.Injectable)(),d("design:paramtypes",[])],e)}(),y=this&&this.__decorate||function(e,t,n,o){var r,i=arguments.length,c=i<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,n):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,t,n,o);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(c=(i<3?r(c):i>3?r(t,n,c):r(t,n))||c);return i>3&&c&&Object.defineProperty(t,n,c),c},m=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},g=this&&this.__awaiter||function(e,t,n,o){return new(n||(n=Promise))(function(r,i){function c(e){try{s(o.next(e))}catch(e){i(e)}}function a(e){try{s(o.throw(e))}catch(e){i(e)}}function s(e){e.done?r(e.value):new n(function(t){t(e.value)}).then(c,a)}s((o=o.apply(e,t||[])).next())})},b=this&&this.__generator||function(e,t){var n,o,r,i,c={label:0,sent:function(){if(1&r[0])throw r[1];return r[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;c;)try{if(n=1,o&&(r=o[2&i[0]?"return":i[0]?"throw":"next"])&&!(r=r.call(o,i[1])).done)return r;switch(o=0,r&&(i=[0,r.value]),i[0]){case 0:case 1:r=i;break;case 4:return c.label++,{value:i[1],done:!1};case 5:c.label++,o=i[1],i=[0];continue;case 7:i=c.ops.pop(),c.trys.pop();continue;default:if(!(r=(r=c.trys).length>0&&r[r.length-1])&&(6===i[0]||2===i[0])){c=0;continue}if(3===i[0]&&(!r||i[1]>r[0]&&i[1]=0;a--)(r=e[a])&&(c=(i<3?r(c):i>3?r(t,n,c):r(t,n))||c);return i>3&&c&&Object.defineProperty(t,n,c),c},w=function(){function e(){}return e=S([Object(o.NgModule)({imports:[l.CommonModule],declarations:[v],providers:[h],exports:[v]})],e)}(),j=this&&this.__decorate||function(e,t,n,o){var r,i=arguments.length,c=i<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,n):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,t,n,o);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(c=(i<3?r(c):i>3?r(t,n,c):r(t,n))||c);return i>3&&c&&Object.defineProperty(t,n,c),c};function O(e){return e.createCompiler()}var R=function(){function e(){}return e=j([Object(o.NgModule)({declarations:[s],imports:[i.BrowserModule,c.HttpClientModule,w],providers:[{provide:o.COMPILER_OPTIONS,useValue:{},multi:!0},{provide:o.CompilerFactory,useClass:r.JitCompilerFactory,deps:[o.COMPILER_OPTIONS]},{provide:o.Compiler,useFactory:O,deps:[o.CompilerFactory]}],bootstrap:[s]})],e)}();Object(o.enableProdMode)(),Object(r.platformBrowserDynamic)().bootstrapModule(R).catch(function(e){return console.log(e)})}},[0]); \ No newline at end of file diff --git a/src/frontend/static/polyfills.f153256f53043f1cd40e.bundle.js b/src/frontend/static/polyfills.f153256f53043f1cd40e.bundle.js deleted file mode 100644 index a225c65..0000000 --- a/src/frontend/static/polyfills.f153256f53043f1cd40e.bundle.js +++ /dev/null @@ -1 +0,0 @@ -webpackJsonp([0],{"/whu":function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},"0Rih":function(e,t,n){"use strict";var r=n("OzIq"),o=n("Ds5P"),i=n("R3AP"),a=n("A16L"),c=n("1aA0"),u=n("vmSO"),s=n("9GpA"),l=n("UKM+"),f=n("zgIt"),p=n("qkyc"),h=n("yYvK"),v=n("kic5");e.exports=function(e,t,n,d,y,g){var k=r[e],_=k,m=y?"set":"add",b=_&&_.prototype,w={},T=function(e){var t=b[e];i(b,e,"delete"==e?function(e){return!(g&&!l(e))&&t.call(this,0===e?0:e)}:"has"==e?function(e){return!(g&&!l(e))&&t.call(this,0===e?0:e)}:"get"==e?function(e){return g&&!l(e)?void 0:t.call(this,0===e?0:e)}:"add"==e?function(e){return t.call(this,0===e?0:e),this}:function(e,n){return t.call(this,0===e?0:e,n),this})};if("function"==typeof _&&(g||b.forEach&&!f(function(){(new _).entries().next()}))){var O=new _,E=O[m](g?{}:-0,1)!=O,S=f(function(){O.has(1)}),x=p(function(e){new _(e)}),D=!g&&f(function(){for(var e=new _,t=5;t--;)e[m](t,t);return!e.has(-0)});x||((_=t(function(t,n){s(t,_,e);var r=v(new k,t,_);return void 0!=n&&u(n,y,r[m],r),r})).prototype=b,b.constructor=_),(S||D)&&(T("delete"),T("has"),y&&T("get")),(D||E)&&T(m),g&&b.clear&&delete b.clear}else _=d.getConstructor(t,e,y,m),a(_.prototype,n),c.NEED=!0;return h(_,e),w[e]=_,o(o.G+o.W+o.F*(_!=k),w),g||d.setStrong(_,e,y),_}},1:function(e,t,n){e.exports=n("XS25")},"1aA0":function(e,t,n){var r=n("ulTY")("meta"),o=n("UKM+"),i=n("WBcL"),a=n("lDLk").f,c=0,u=Object.isExtensible||function(){return!0},s=!n("zgIt")(function(){return u(Object.preventExtensions({}))}),l=function(e){a(e,r,{value:{i:"O"+ ++c,w:{}}})},f=e.exports={KEY:r,NEED:!1,fastKey:function(e,t){if(!o(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!i(e,r)){if(!u(e))return"F";if(!t)return"E";l(e)}return e[r].i},getWeak:function(e,t){if(!i(e,r)){if(!u(e))return!0;if(!t)return!1;l(e)}return e[r].w},onFreeze:function(e){return s&&f.NEED&&u(e)&&!i(e,r)&&l(e),e}}},"2p1q":function(e,t,n){var r=n("lDLk"),o=n("fU25");e.exports=n("bUqO")?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},"3q4u":function(e,t,n){var r=n("wCso"),o=n("DIVP"),i=r.key,a=r.map,c=r.store;r.exp({deleteMetadata:function(e,t){var n=arguments.length<3?void 0:i(arguments[2]),r=a(o(t),n,!1);if(void 0===r||!r.delete(e))return!1;if(r.size)return!0;var u=c.get(t);return u.delete(n),!!u.size||c.delete(t)}})},"73qY":function(e,t,n){e.exports=n("VWgF")("native-function-to-string",Function.toString)},"7gX0":function(e,t){var n=e.exports={version:"2.6.9"};"number"==typeof __e&&(__e=n)},"7ylX":function(e,t,n){var r=n("DIVP"),o=n("twxM"),i=n("QKXm"),a=n("mZON")("IE_PROTO"),c=function(){},u=function(){var e,t=n("jhxf")("iframe"),r=i.length;for(t.style.display="none",n("d075").appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write("