@capgo/cli 2.0.1 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [2.1.1](https://github.com/Cap-go/capgo-cli/compare/v2.1.0...v2.1.1) (2022-11-30)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **deps:** update dependency fs-extra to v11 ([b011994](https://github.com/Cap-go/capgo-cli/commit/b011994bd49eb3b3bb09a6e72407d6e3b7313505))
11
+
12
+ ## [2.1.0](https://github.com/Cap-go/capgo-cli/compare/v2.0.1...v2.1.0) (2022-11-25)
13
+
14
+
15
+ ### Features
16
+
17
+ * add encrypt method ([349154e](https://github.com/Cap-go/capgo-cli/commit/349154efd05b76415f191cdeff5689e54b8f2ac3))
18
+
5
19
  ### [2.0.1](https://github.com/Cap-go/capgo-cli/compare/v2.0.0...v2.0.1) (2022-11-24)
6
20
 
7
21
 
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- (()=>{"use strict";var e={577:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkAppExistsAndHasPermission=void 0;const i=n(304);o.checkAppExistsAndHasPermission=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:r}=yield e.rpc("exist_app",{appid:o,apikey:n});t&&!r||i.program.error("No permission for this app")}))},978:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkVersionNotUsedInChannel=void 0;const i=n(304),r=n(880);o.checkVersionNotUsedInChannel=(e,o,n,a,s)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:p}=yield e.from("channels").select().eq("app_id",o).eq("created_by",n).eq("version",a.id);(t&&t.length||p)&&i.program.error(`Version ${o}@${s} is used in a channel, unlink it first ${(0,r.formatError)(p)}`)}))},386:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkVersionNotUsedInDeviceOverride=void 0;const i=n(304),r=n(880);o.checkVersionNotUsedInDeviceOverride=(e,o,n,a)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:s}=yield e.from("devices_override").select().eq("app_id",o).eq("version",n.id);(t&&t.length||s)&&i.program.error(`Version ${o} @${a} is used in a device override, unlink it first ${(0,r.formatError)(s)}`)}))},191:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteFromStorage=void 0;const i=n(304),r=n(880);o.deleteFromStorage=(e,o,n,a,s)=>t(void 0,void 0,void 0,(function*(){const{error:t}=yield e.storage.from("apps").remove([`${o}/${n}/versions/${a.bucket_id} `]);t&&i.program.error(`Something went wrong when trying to delete ${n} @${s} ${(0,r.formatError)(t)} `)}))},340:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.getVersionData=o.getActiveAppVersions=o.deleteSpecificVersion=o.deleteAppVersion=void 0;const i=n(304),r=n(880),a=n(978),s=n(386),p=n(191);o.deleteAppVersion=(e,o,n,a)=>t(void 0,void 0,void 0,(function*(){const{error:t}=yield e.from("app_versions").update({deleted:!0}).eq("app_id",o).eq("user_id",n).eq("name",a);t&&i.program.error(`App ${o}@${a} not found in database '${(0,r.formatError)(t)}'`)})),o.deleteSpecificVersion=(e,n,i,r)=>t(void 0,void 0,void 0,(function*(){const t=yield(0,o.getVersionData)(e,n,i,r);yield(0,a.checkVersionNotUsedInChannel)(e,n,i,t,r),yield(0,s.checkVersionNotUsedInDeviceOverride)(e,n,t,r),yield(0,p.deleteFromStorage)(e,i,n,t,r),yield(0,o.deleteAppVersion)(e,n,i,r)})),o.getActiveAppVersions=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:a}=yield e.from("app_versions").select().eq("app_id",o).eq("user_id",n).eq("deleted",!1).order("id");return a&&i.program.error(`App ${o} not found in database ${(0,r.formatError)(a)} `),t})),o.getVersionData=(e,o,n,a)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:s}=yield e.from("app_versions").select().eq("app_id",o).eq("user_id",n).eq("name",a).eq("deleted",!1).single();return t&&!s||i.program.error(`Version ${o}@${a} doesn't exist ${(0,r.formatError)(s)}`),t}))},870:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.addApp=void 0;const i=n(304),r=n(113),a=n(147),s=n(470),p=n(11),d=n(880),c="assets/icon.png";o.addApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t;let{name:l,icon:u}=o;const g=o.apikey||(0,d.findSavedKey)(),f=yield(0,d.getConfig)(),v=(0,d.useLogSnag)();e=e||(null===(n=null==f?void 0:f.app)||void 0===n?void 0:n.appId),l=l||(null===(t=null==f?void 0:f.app)||void 0===t?void 0:t.appName)||"Unknown",u=u||"resources/icon.png",g||i.program.error("Missing API key, you need to provide a API key to add your app"),e&&l||i.program.error("Missing argument, you need to provide a appid and a name, or be in a capacitor project"),console.log(`Add ${e} to Capgo`);const y=(0,d.createSupabaseClient)(g),m=yield(0,d.verifyUser)(y,g,["write","all"]);let h,b;yield(0,d.checkPlanValid)(y,m),console.log("Adding..."),u&&(0,s.existsSync)(u)?(h=(0,a.readFileSync)(u),b=(0,p.getType)(u)||"image/png",console.warn(`Found app icon ${u}`)):(0,s.existsSync)(c)?(h=(0,a.readFileSync)(c),b=(0,p.getType)(c)||"image/png",console.warn(`Found app icon ${c}`)):console.warn(`Cannot find app icon in any of the following locations: ${u}, ${c}`);const{data:_,error:k}=yield y.rpc("exist_app",{appid:e,apikey:g});(_||k)&&i.program.error(`App already exists ${(0,d.formatError)(k)}`);const w=`icon_${(0,r.randomUUID)()}`;let $="https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";if(h&&b){const{error:o}=yield y.storage.from(`images/${m}/${e}`).upload(w,h,{contentType:b});o&&i.program.error(`Could not add app ${(0,d.formatError)(o)}`);const{data:n}=yield y.storage.from(`images/${m}/${e}`).getPublicUrl(w);$=(null==n?void 0:n.publicURL)||$}const{error:x}=yield y.from("apps").insert({icon_url:$,user_id:m,name:l,app_id:e},{returning:"minimal"});x&&i.program.error(`Could not add app ${(0,d.formatError)(x)}`);const{error:C}=yield y.from("app_versions").insert([{user_id:m,deleted:!0,name:"unknown",app_id:e},{user_id:m,deleted:!0,name:"builtin",app_id:e}],{returning:"minimal"});C&&i.program.error(`Could not add app ${(0,d.formatError)(C)}`),v.publish({channel:"app",event:"App Added",icon:"🎉",tags:{"user-id":m,"app-id":e},notify:!1}).catch(),console.log("App added to server, you can upload a bundle now")}))},600:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.cleanupApp=void 0;const r=n(304),a=i(n(505)),s=i(n(616)),p=n(880),d=n(340),c=n(577),l=(0,s.default)();o.cleanupApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const t=o.apikey||(0,p.findSavedKey)(),{bundle:i,keep:s=4}=o,u=o.force||!1,g=yield(0,p.getConfig)();e=e||(null===(n=null==g?void 0:g.app)||void 0===n?void 0:n.appId),t||r.program.error("Missing API key, you need to provide an API key to delete your app"),e||r.program.error("Missing argument, you need to provide a appid, or be in a capacitor project");const f=`${a.default.inc(i,"major")}`;console.log(`Querying available versions in Capgo between ${i} and ${f}`);const v=(0,p.createSupabaseClient)(t),y=yield(0,p.verifyUser)(v,t);yield(0,c.checkAppExistsAndHasPermission)(v,e,t);const m=yield(0,d.getActiveAppVersions)(v,e,y);if(console.log(`Total active versions in Capgo: ${null==m?void 0:m.length}`),0===(null==m?void 0:m.length))return;const h=((e,o,n)=>{const t=[];return null==e||e.forEach((e=>{a.default.gte(e.name,o)&&a.default.lt(e.name,`${n}`)&&t.push(e)})),t})(m,i,f).reverse();console.log(`Active versions in Capgo between ${i} and ${f}: ${null==h?void 0:h.length}`);const b=h.slice(0,s),_=h.slice(s);if(b.forEach((e=>{console.log(`${e.name} created on ${(0,p.getHumanDate)(e)} will be kept`)})),b.length&&console.log("==================================================="),0!==_.length){if(_.forEach((e=>{console.log(`${e.name} created on ${(0,p.getHumanDate)(e)} will be removed`)})),!u&&"yes"!==l("Do you want to continue removing the versions specified? Type yes to confirm"))return void console.log("Not confirmed, aborting removal...");console.log("You have confirmed removal, removing versions now"),((e,o,n,t)=>{null==e||e.forEach((e=>{console.log(`Removing ${e.name} created on ${(0,p.getHumanDate)(e)}`),(0,d.deleteSpecificVersion)(o,n,t,e.name)}))})(_,v,e,y)}else console.log("Nothing to be removed, aborting removal...")}))},157:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.decodeZip=void 0;const r=n(304),a=n(147),s=i(n(339)),p=i(n(837)),d=n(880);o.decodeZip=(e,o,n)=>t(void 0,void 0,void 0,(function*(){(0,a.existsSync)(e)||r.program.error(`Zip not found at the path ${e}`);const t=yield(0,d.getConfig)(),{extConfig:i}=t.app;n.key||(0,a.existsSync)(d.baseKey)||i.plugins.CapacitorUpdater.privateKey||r.program.error(`Private Key not found at the path ${d.baseKey} or in ${t.app.extConfigFilePath}`);const c="string"==typeof n.key?n.key:d.baseKey;let l=i.plugins.CapacitorUpdater.privateKey;(0,a.existsSync)(c)||i.plugins.CapacitorUpdater.privateKey?(0,a.existsSync)(c)&&(l=(0,a.readFileSync)(c).toString()):r.program.error(`Cannot find public key ${c}`);const u=(0,a.readFileSync)(e),g=new s.default(l,"pkcs8-private-pem");g.isPublic()&&r.program.error("Cannot use public key to decode, please use private key");const f=g.decrypt(o,"base64");console.log("Session Key",f);const v=p.default.decrypt(u.toString(),f).toString();(0,a.writeFileSync)(`${e}decoded.zip`,v)}))},0:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteApp=void 0;const i=n(304),r=n(880),a=n(340);o.deleteApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const{bundle:t}=o,s=o.apikey||(0,r.findSavedKey)(),p=yield(0,r.getConfig)(),d=(0,r.useLogSnag)();e=e||(null===(n=null==p?void 0:p.app)||void 0===n?void 0:n.appId),s||i.program.error("Missing API key, you need to provide an API key to delete your app"),e||i.program.error("Missing argument, you need to provide a appid, or be in a capacitor project");const c=(0,r.createSupabaseClient)(s),l=yield(0,r.verifyUser)(c,s),{data:u,error:g}=yield c.rpc("exist_app",{appid:e,apikey:s});if(u&&!g||i.program.error("No permission to delete"),t)return console.log(`Delete ${e}@${t} from Capgo`),yield(0,a.deleteSpecificVersion)(c,e,l,t),void console.log(`${e}@${t} deleted from server`);console.log(`Delete ${e} from Capgo`);const{data:f,error:v}=yield c.from("app_versions").select().eq("app_id",e).eq("user_id",l);if(v&&i.program.error(`App ${e} not found in database ${(0,r.formatError)(v)} `),f&&f.length){const o=f.map((o=>`${l}/${e}/versions/${o.bucket_id} `)),{error:n}=yield c.storage.from("apps").remove(o);n&&i.program.error(`Cannot delete stored version for app ${e} from storage ${(0,r.formatError)(n)} `)}const{error:y}=yield c.from("app_versions").delete().eq("app_id",e).eq("user_id",l);y&&i.program.error(`Cannot delete version for app ${e} from database ${(0,r.formatError)(y)} `);const{error:m}=yield c.from("apps").delete().eq("app_id",e).eq("user_id",l);m&&i.program.error(`Cannot delete from database ${(0,r.formatError)(m)} `),d.publish({channel:"app",event:"App Deleted",icon:"😱",tags:{"user-id":l,"app-id":e},notify:!1}).catch(),console.log(`${e} deleted from server`)}))},731:function(e,o,n){var t=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0});const i=n(304),r=n(157),a=n(870),s=n(218),p=n(0),d=n(331),c=n(510),l=t(n(598)),u=n(621),g=n(272),f=n(600);i.program.description("Manage packages and bundle versions in capgo Cloud").version(l.default.version),i.program.command("add [appid]").alias("a").description("Add a new app to capgo Cloud").action(a.addApp).option("-n, --name <name>","app name").option("-i, --icon <icon>","app icon path").option("-a, --apikey <apikey>","apikey to link to your account"),i.program.command("login [apikey]").alias("l").description("Save apikey to your machine or folder").action(u.login).option("--local","Only save in local folder"),i.program.command("upload [appid]").alias("u").description("Upload a new bundle to capgo Cloud").action(c.uploadVersion).option("-a, --apikey <apikey>","apikey to link to your account").option("-p, --path <path>","path of the file to upload").option("-c, --channel <channel>","channel to link to").option("-e, --external <url>","link to external url intead of upload to capgo cloud").option("-f, --format <base64|hex|binary|utf8>","choose the upload format default base64").option("--key <key>","custom path for public signing key").option("--keyData <keyData>","base64 public signing key").option("--no-key","ignore signing key and send clear update").option("-b, --bundle <bundle>","bundle version number of the file to upload"),i.program.command("set [appid]").alias("s").description("Modify a channel configuration").action(d.setChannel).requiredOption("-c, --channel <channel>","channel to link to").option("-a, --apikey <apikey>","apikey to link to your account").option("-b, --bundle <bundle>","bundle version number of the file to set").option("-s, --state <state>","set the state of the channel, default or normal").option("--downgrade","Allow to downgrade to version under native one").option("--latest","get the latest version key in the package.json to set it to the channel").option("--no-downgrade","Disable downgrade to version under native one").option("--upgrade","Allow to upgrade to version above native one").option("--no-upgrade","Disable upgrade to version above native one").option("--ios","Allow sending update to ios devices").option("--no-ios","Disable sending update to ios devices").option("--android","Allow sending update to android devices").option("--no-android","Disable sending update to android devices").option("--self-assign","Allow to device to self assign to this channel").option("--no-self-assign","Disable devices to self assign to this channel"),i.program.command("delete [appid]").alias("d").description("Delete an app from capgo Cloud").action(p.deleteApp).option("-a, --apikey <apikey>","apikey to link to your account").option("-b, --bundle <bundle>","bundle version number of the app to delete"),i.program.command("list [appid]").alias("ls").description("List versions in capgo Cloud").action(g.listApp).option("-a, --apikey <apikey>","apikey to link to your account"),i.program.command("cleanup [appid]").alias("c").description("Cleanup versions in capgo Cloud").action(f.cleanupApp).requiredOption("-b, --bundle <bundle>","bundle version number of the app to delete").option("-a, --apikey <apikey>","apikey to link to your account").option("-k, --keep <keep>","number of version to keep").option("-f, --force","force removal"),i.program.command("key [option]").description("Save base64 signing key in capacitor config, usefull for CI").action(s.manageKey).option("-f, --force","force generate a new one"),i.program.command("decode [zipPath] [sessionKey]").alias("dec").description("Decode a signed zip update").action(r.decodeZip).option("--key <key>","custom path for private signing key").option("--keyData <keyData>","base64 private signing key"),i.program.parse(process.argv)},218:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.manageKey=void 0;const r=n(304),a=n(147),s=i(n(339)),p=n(778),d=n(880);o.manageKey=(e,o)=>t(void 0,void 0,void 0,(function*(){"create"===e?(e=>{t(void 0,void 0,void 0,(function*(){(0,a.existsSync)(".git")||r.program.error("To use local you should be in a git repository");const o=new s.default({b:512}).generateKeyPair(),n=o.exportKey("pkcs8-public-pem"),t=o.exportKey("pkcs8-private-pem").replace("-----BEGIN PRIVATE KEY-----","").replace("-----END PRIVATE KEY-----","").replace(/\s/g,"").replace(/\n/g,"");(0,a.existsSync)(d.baseKeyPub)&&!e.force&&r.program.error("Public Key already exists, use --force to overwrite"),(0,a.writeFileSync)(d.baseKeyPub,n);const i=yield(0,d.getConfig)(),{extConfig:c}=i.app;c&&(c.plugins||(c.plugins={}),c.plugins.CapacitorUpdater||(c.plugins.CapacitorUpdater={}),c.plugins.CapacitorUpdater.privateKey=t,(0,p.writeConfig)(c,i.app.extConfigFilePath)),console.log("Your RSA key has been generated using node-rsa with this settings:\n\n- encryptionScheme — 'pkcs1_oaep'.\n- signingScheme — 'pkcs8-sha256'.\n- bits — 2048.\n- exp — 65537.\n"),console.log(`public key saved into ${d.baseKeyPub} file in local directory\n`),console.log("This key will be use to encode your zipped bundle before sending it to Capgo,\nthan make them unreadable by Capgo and unmodifiable by anyone\n"),console.log(`Private key saved into ${i.app.extConfigFilePath} file in local directory`),console.log("Your app will decode with this key the zipped bundle\n")}))})(o):r.program.error("You should provide a valid option (create or save)")}))},272:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.listApp=void 0;const i=n(304),r=n(880),a=n(577),s=n(340);o.listApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const t=o.apikey||(0,r.findSavedKey)(),p=yield(0,r.getConfig)();e=e||(null===(n=null==p?void 0:p.app)||void 0===n?void 0:n.appId),t||i.program.error("Missing API key, you need to provide an API key to delete your app"),e||i.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),console.log("Querying available versions in Capgo");const d=(0,r.createSupabaseClient)(t),c=yield(0,r.verifyUser)(d,t);yield(0,a.checkAppExistsAndHasPermission)(d,e,t);const l=yield(0,s.getActiveAppVersions)(d,e,c);console.log(`Active versions in Capgo: ${null==l?void 0:l.length}`),null==l||l.forEach((e=>{console.log(`${e.name} created on ${(0,r.getHumanDate)(e)}`)}))}))},621:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.login=void 0;const i=n(304),r=n(147),a=n(37),s=n(880);o.login=(e,o)=>t(void 0,void 0,void 0,(function*(){const{local:n}=o,t=(0,s.useLogSnag)();if(n)(0,r.existsSync)(".git")||i.program.error("To use local you should be in a git repository"),(0,r.writeFileSync)(".capgo",`${e}\n`),(0,r.appendFileSync)(".gitignore",".capgo\n");else{const o=(0,a.homedir)();(0,r.writeFileSync)(`${o}/.capgo`,`${e}\n`)}const p=(0,s.createSupabaseClient)(e),d=yield(0,s.verifyUser)(p,e,["write","all","upload"]);t.publish({channel:"user-login",event:"User CLI login",icon:"✅",tags:{"user-id":d},notify:!1}).catch(),console.log(`login saved into .capgo file in ${n?"local":"home"} directory`)}))},331:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.setChannel=void 0;const i=n(304),r=n(880);o.setChannel=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t,a;const{bundle:s,latest:p,downgrade:d,upgrade:c,ios:l,android:u,selfAssign:g,channel:f,state:v}=o,y=o.apikey||(0,r.findSavedKey)(),m=yield(0,r.getConfig)(),h=(0,r.useLogSnag)();e=e||(null===(n=null==m?void 0:m.app)||void 0===n?void 0:n.appId),y||i.program.error("Missing API key, you need to provide a API key to add your app"),e||i.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),p&&s&&i.program.error("Cannot set latest and bundle at the same time"),void 0===s&&void 0===v&&void 0===p&&void 0===d&&void 0===c&&void 0===l&&void 0===u&&void 0===g&&i.program.error("Missing argument, you need to provide a option to set");try{const o=(0,r.createSupabaseClient)(y),n=yield(0,r.verifyUser)(o,y,["write","all"]);yield(0,r.checkPlanValid)(o,n);const b={created_by:n,app_id:e,name:f},_=p?null===(a=null===(t=null==m?void 0:m.app)||void 0===t?void 0:t.package)||void 0===a?void 0:a.version:s;if(_){const{data:t,error:r}=yield o.from("app_versions").select().eq("app_id",e).eq("name",_).eq("user_id",n).eq("deleted",!1);!r&&t&&t.length||i.program.error(`Cannot find version ${_}`),console.log(`Set ${e} channel: ${f} to @${s}`),b.version=t[0].id}void 0!==v&&("public"!==v&&"private"!==v||console.log(`Set ${e} channel: ${f} to public or private is deprecated, use default or normal instead`),console.log(`Set ${e} channel: ${f} to ${"public"===v||"default"===v?"default":"normal"}`),b.public="public"===v||"default"===v),void 0!==d&&(console.log(`Set ${e} channel: ${f} to ${d?"allow":"disallow"} downgrade`),b.disableAutoUpdateUnderNative=!d),void 0!==c&&(console.log(`Set ${e} channel: ${f} to ${c?"allow":"disallow"} upgrade`),b.disableAutoUpdateToMajor=!c),void 0!==l&&(console.log(`Set ${e} channel: ${f} to ${l?"allow":"disallow"} ios update`),b.ios=!!l),void 0!==u&&(console.log(`Set ${e} channel: ${f} to ${u?"allow":"disallow"} android update`),b.android=!!u),void 0!==g&&(console.log(`Set ${e} channel: ${f} to ${g?"allow":"disallow"} self assign to this channel`),b.allow_device_self_set=!!g);try{const{error:e}=yield(0,r.updateOrCreateChannel)(o,b,y);e&&i.program.error(`Cannot set channel ${(0,r.formatError)(e)}`)}catch(e){i.program.error(`Cannot set channel ${(0,r.formatError)(e)}`)}h.publish({channel:"app",event:"Set app",icon:"✅",tags:{"user-id":n,"app-id":e},notify:!1}).catch()}catch(e){i.program.error(`Unknow error ${(0,r.formatError)(e)}`)}console.log("Done ✅")}))},510:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.uploadVersion=void 0;const r=i(n(844)),a=n(304),s=n(113),p=i(n(837)),d=i(n(295)),c=n(147),l=i(n(339)),u=n(906),g=n(880);o.uploadVersion=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t,i,f;let{bundle:v,path:y,channel:m}=o;const{external:h,key:b=!1}=o,_=o.apikey||(0,g.findSavedKey)(),k=(0,g.useLogSnag)();m=m||"dev";const w=yield(0,g.getConfig)();e=e||(null===(n=null==w?void 0:w.app)||void 0===n?void 0:n.appId),v=v||(null===(i=null===(t=null==w?void 0:w.app)||void 0===t?void 0:t.package)||void 0===i?void 0:i.version),g.regexSemver.test(v)||a.program.error(`Your bundle name ${v}, is not valid it should follow semver convention : https://semver.org/`),y=y||(null===(f=null==w?void 0:w.app)||void 0===f?void 0:f.webDir),_||a.program.error("Missing API key, you need to provide a API key to add your app"),e&&v&&y||a.program.error("Missing argument, you need to provide a appid and a bundle and a path, or be in a capacitor project"),console.log(`Upload ${e}@${v} started from path "${y}" to Capgo cloud`);const $=(0,g.createSupabaseClient)(_),x=yield(0,g.verifyUser)($,_,["write","all","upload"]);yield(0,g.checkPlanValid)($,x,!1);const C=new d.default.MultiBar({clearOnComplete:!1,hideCursor:!0},d.default.Presets.shades_grey),S=C.create(7,0,{format:"Uploading: [{bar}] {percentage}% | ETA: {eta}s | {value}/{total} Part"},d.default.Presets.shades_grey);S.start(7,0,{speed:"N/A"});const{data:A,error:P}=yield $.rpc("exist_app_versions",{apikey:_,name_version:v,appid:e});(A||P)&&(C.stop(),a.program.error(`This app bundle already exist or was deleted, you cannot re-upload it ${(0,g.formatError)(P)}`)),S.increment();const{data:q,error:I}=yield $.rpc("is_trial",{userid:x}).single();(q&&q>0||I)&&C.log(`WARNING !!\nTrial expires in ${q} days, upgrade here: ${g.hostWeb}/dashboard/settings/plans\n`),S.increment();const{data:j,error:E}=yield $.rpc("exist_app",{appid:e,apikey:_});j&&!E||(C.stop(),a.program.error(`Cannot find app ${e} in your account \n${(0,g.formatError)(E)}`)),S.increment();const{data:D,error:M}=yield $.rpc("exist_app_versions",{appid:e,apikey:_,name_version:v});(D||M)&&a.program.error(`Version already exists ${(0,g.formatError)(M)}`),S.increment();const K=(0,s.randomUUID)();let U,V="";if(h)h&&!h.startsWith("https://")&&(C.stop(),a.program.error(`External link should should start with "https://" current is "${h}"`));else{const o=new r.default;o.addLocalFolder(y);let n=o.toBuffer();if(b||(0,c.existsSync)(g.baseKeyPub)){const e="string"==typeof b?b:g.baseKeyPub;(0,c.existsSync)(e)||a.program.error(`Cannot find public key ${e}`);const o=(0,c.readFileSync)(e),t=new l.default(o.toString());t.isPrivate()&&a.program.error("Cannot use private key to encode, please use public key");const i=p.default.encrypt(n.toString(),(0,s.randomUUID)());U=t.encrypt(i.key.toString(),"base64"),console.log("Session Key",i.key.toString()),n=Buffer.from(i.ciphertext.toString(),"base64")}V=yield(0,u.checksum)(n,"crc32");const t=Math.floor(n.byteLength/1024/1024),i=`apps/${x}/${e}/versions`;S.increment(),t>20&&(C.log(`WARNING !!\nThe app size is ${t} Mb, this may take a while to download for users\n`),k.publish({channel:"app-error",event:"App Too Large",icon:"🚛",tags:{"user-id":x,"app-id":e},notify:!1}).catch());const{error:d}=yield $.storage.from(i).upload(K,n,{contentType:"application/zip"});d&&(C.stop(),a.program.error(`Cannot upload ${(0,g.formatError)(d)}`))}S.increment();const{data:O,error:N}=yield(0,g.updateOrCreateVersion)($,{bucket_id:h?void 0:K,user_id:x,name:v,app_id:e,session_key:U,external_url:h,checksum:V},_);if(N&&(C.stop(),a.program.error(`Cannot add bundle ${(0,g.formatError)(N)}`)),S.increment(),O&&O.length){const{error:o}=yield(0,g.updateOrCreateChannel)($,{name:m,app_id:e,created_by:x,version:O[0].id},_);o&&C.log("Cannot set bundle with upload key, use key with more rights for that\n")}else C.log("Cannot set bundle with upload key, use key with more rights for that\n");C.stop();const z=e.replace(/\./g,"--");console.log("App uploaded to server"),console.log(`Try it in mobile app: ${g.host}/app_mobile`),console.log(`Or set the channel ${m} as public here: ${g.hostWeb}/app/package/${z}`),console.log("To use with live update in your own app"),console.log(`You can link specific device to this bundle to make user try it first, here: ${g.hostWeb}/app/p/${z}/devices`),k.publish({channel:"app",event:"App Uploaded",icon:"⏫",tags:{"user-id":x,"app-id":e},notify:!1}).catch()}))},880:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.getHumanDate=o.verifyUser=o.useLogSnag=o.updateOrCreateChannel=o.updateOrCreateVersion=o.getConfig=o.formatError=o.findSavedKey=o.checkPlanValid=o.isTrial=o.isPaying=o.isGoodPlan=o.checkKey=o.regexSemver=o.createSupabaseClient=o.supaAnon=o.hostSupa=o.hostWeb=o.host=o.baseKeyPub=o.baseKey=void 0;const r=n(778),a=n(304),s=n(885),p=i(n(867)),d=n(147),c=n(37),l=n(133);o.baseKey=".capgo_key",o.baseKeyPub=`${o.baseKey}.pub`,o.host="https://capgo.app",o.hostWeb="https://web.capgo.app",o.hostSupa="https://xvwzpoazmxkqosrdewyv.supabase.co",o.supaAnon="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYzNzgwNTAwOSwiZXhwIjoxOTUzMzgxMDA5fQ.8tgID1d4jodPwuo_fz4KHN4o1XKB9fnqyt0_GaJSj-w",o.createSupabaseClient=e=>(0,s.createClient)(o.hostSupa,o.supaAnon,{headers:{capgkey:e}}),o.regexSemver=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/,o.checkKey=(e,n,i)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:r}=yield e.rpc("is_allowed_capgkey",{apikey:n,keymode:i});t&&!r||a.program.error(`Invalid API key or insufficient permissions ${(0,o.formatError)(r)}`)})),o.isGoodPlan=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_good_plan_v2",{userid:o}).single();if(t)throw t;return n||!1})),o.isPaying=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_paying",{userid:o}).single();if(t)throw t;return n||!1})),o.isTrial=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_trial",{userid:o}).single();if(t)throw t;return n||0})),o.checkPlanValid=(e,n,i=!0)=>t(void 0,void 0,void 0,(function*(){const t=yield(0,o.isGoodPlan)(e,n),r=yield(0,o.isPaying)(e,n),s=yield(0,o.isTrial)(e,n);r&&t||!(s<0)||a.program.error(`You need to upgrade your plan to continue to use capgo.\n Upgrade here: ${o.hostWeb}/dashboard/settings/plans\n`),s>0&&i&&!r&&console.log(`WARNING !!\nTrial expires in ${s} days, upgrade here: ${o.hostWeb}/dashboard/settings/plans\n`)})),o.findSavedKey=()=>{let e=`${(0,c.homedir)()}/.capgo`;return(0,d.existsSync)(e)?(0,d.readFileSync)(e,"utf8").trim():(e=".capgo",(0,d.existsSync)(e)?(0,d.readFileSync)(e,"utf8").trim():null)},o.formatError=e=>e?`\n${p.default.render(e)}`:"",o.getConfig=()=>t(void 0,void 0,void 0,(function*(){let e;try{e=yield(0,r.loadConfig)()}catch(e){a.program.error("No capacitor config file found, run `cap init` first")}return e})),o.updateOrCreateVersion=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:i}=yield e.rpc("exist_app_versions",{appid:o.app_id,name_version:o.name,apikey:n});return t&&!i?(o.deleted=!1,e.from("app_versions").update(o).eq("app_id",o.app_id).eq("name",o.name)):e.from("app_versions").insert(o)})),o.updateOrCreateChannel=(e,o,n)=>t(void 0,void 0,void 0,(function*(){if(!o.app_id||!o.name||!o.created_by)return console.error("missing app_id, name, or created_by"),Promise.reject(new Error("missing app_id, name, or created_by"));const{data:t,error:i}=yield e.rpc("exist_channel",{appid:o.app_id,name_channel:o.name,apikey:n});return t&&!i?e.from("channels").update(o,{returning:"minimal"}).eq("app_id",o.app_id).eq("name",o.name).eq("created_by",o.created_by):e.from("channels").insert(o,{returning:"minimal"})})),o.useLogSnag=()=>new l.LogSnag({token:"c124f5e9d0ce5bdd14bbb48f815d5583",project:"capgo"}),o.verifyUser=(e,n,i=["all"])=>t(void 0,void 0,void 0,(function*(){yield(0,o.checkKey)(e,n,i);const{data:t,error:r}=yield e.rpc("get_user_id",{apikey:n}),s=t?t.toString():"";return s&&!r||a.program.error(`Cannot verify user ${(0,o.formatError)(r)}`),s})),o.getHumanDate=e=>new Date(e.created_at||"").toLocaleString()},778:e=>{e.exports=require("@capacitor/cli/dist/config")},885:e=>{e.exports=require("@supabase/supabase-js")},906:e=>{e.exports=require("@tomasklaen/checksum")},844:e=>{e.exports=require("adm-zip")},295:e=>{e.exports=require("cli-progress")},304:e=>{e.exports=require("commander")},837:e=>{e.exports=require("crypto-js/aes")},470:e=>{e.exports=require("fs-extra")},133:e=>{e.exports=require("logsnag")},11:e=>{e.exports=require("mime")},339:e=>{e.exports=require("node-rsa")},867:e=>{e.exports=require("prettyjson")},616:e=>{e.exports=require("prompt-sync")},505:e=>{e.exports=require("semver/preload")},113:e=>{e.exports=require("crypto")},147:e=>{e.exports=require("fs")},37:e=>{e.exports=require("os")},598:e=>{e.exports=JSON.parse('{"name":"@capgo/cli","version":"2.0.1","description":"A CLI to upload to capgo servers","main":"dist/index.js","bin":{"capgo":"dist/index.js"},"repository":{"type":"git","url":"git+https://github.com/Cap-go/capgo-cli.git"},"bugs":{"url":"https://github.com/Cap-go/capgo-cli/issues"},"keywords":["appflow alternative","ionic","capacitor","auto update","live update","capgo","cli","upload","capgo-cli"],"scripts":{"dev":"set NODE_ENV=development && npx webpack --config webpack.config.js","no-debug":"node dist/index.js","build":"npx webpack --config webpack.config.js","dev-build":"SUPA_DB=development npx webpack --config webpack.config.js","pack":"pkg","test_rls":"ts-node ./test/test_headers_rls.ts","lint":"eslint . --ext .ts --fix"},"author":"github.com/riderx","license":"Apache 2.0","dependencies":{"@capacitor/cli":"4.5.0","@supabase/supabase-js":"^1.35.7","@tomasklaen/checksum":"^1.1.0","adm-zip":"^0.5.9","cli-progress":"3.11.2","commander":"9.4.1","crypto-js":"^4.1.1","fs-extra":"10.1.0","logsnag":"^0.1.5","mime":"^3.0.0","node-rsa":"^1.1.1","prettyjson":"^1.2.5","prompt-sync":"^4.2.0","semver":"^7.3.8"},"devDependencies":{"@types/adm-zip":"0.5.0","@types/cli-progress":"^3.11.0","@types/crypto-js":"^4.1.1","@types/fs-extra":"^9.0.13","@types/mime":"^3.0.1","@types/node":"^18.11.9","@types/node-rsa":"^1.1.1","@types/prettyjson":"^0.0.30","@types/prompt-sync":"^4.2.0","@types/semver":"^7.3.13","@typescript-eslint/eslint-plugin":"5.44.0","@typescript-eslint/parser":"5.44.0","eslint":"8.28.0","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^8.5.0","eslint-import-resolver-typescript":"3.5.2","eslint-plugin-import":"2.26.0","eslint-plugin-prettier":"^4.2.1","git-format-staged":"3.0.0","husky":"^8.0.2","nodemon":"2.0.20","pkg":"5.8.0","prettier":"2.7.1","ts-loader":"^9.4.1","ts-node":"^10.9.1","tsconfig-paths":"4.1.0","typescript":"4.9.3","webpack":"5.75.0","webpack-cli":"^5.0.0","webpack-node-externals":"^3.0.0"}}')}},o={};!function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t].call(r.exports,r,r.exports,n),r.exports}(731)})();
2
+ (()=>{"use strict";var e={577:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkAppExistsAndHasPermission=void 0;const r=n(304);o.checkAppExistsAndHasPermission=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:i}=yield e.rpc("exist_app",{appid:o,apikey:n});t&&!i||r.program.error("No permission for this app")}))},978:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkVersionNotUsedInChannel=void 0;const r=n(304),i=n(880);o.checkVersionNotUsedInChannel=(e,o,n,a,s)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:p}=yield e.from("channels").select().eq("app_id",o).eq("created_by",n).eq("version",a.id);(t&&t.length||p)&&r.program.error(`Version ${o}@${s} is used in a channel, unlink it first ${(0,i.formatError)(p)}`)}))},113:function(e,o,n){var t=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.createRSA=o.encryptSource=o.decryptSource=void 0;const r=t(n(837)),i=t(n(339)),a=t(n(666)),s=n(304),p=n(663);o.decryptSource=(e,o,n)=>{const t=new i.default(n,"pkcs8-private-pem");t.isPrivate()||s.program.error("Cannot use public key to decode, please use private key"),console.log("\nivSessionKey",o);const[p,c]=o.split(":");console.log("\nsessionb64Encrypted",c),console.log("\nivB64",p);const d=t.decrypt(c,"base64");console.log("\nsessionDecrypted",d);const l=a.default.enc.Base64.parse(d);console.log("\nsessionb64",a.default.enc.Base64.stringify(l));const u=a.default.enc.Base64.parse(p);return r.default.decrypt(e,l,{iv:u}).toString()},o.encryptSource=(e,o)=>{const n=new i.default(o,"pkcs8-public-pem");n.isPrivate()&&s.program.error("Cannot use private key to encode, please use public key");const t=r.default.encrypt(a.default.enc.Base64.parse(e),(0,p.randomUUID)()),c=a.default.enc.Base64.stringify(t.key);console.log("\nsessionb64",c);const d=a.default.enc.Base64.stringify(t.iv);console.log("\nivB64",d);const l=n.encrypt(c,"base64");console.log("\nsessionb64Encrypted",l);const u=`${d}:${l}`;return console.log("\nivSessionKey",u),{encodedSource:a.default.enc.Base64.stringify(t.ciphertext),sessionKey:u}},o.createRSA=()=>{const e=new i.default({b:512}).generateKeyPair();return{publicKey:e.exportKey("pkcs8-public-pem"),privateKey:e.exportKey("pkcs8-private-pem")}}},386:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkVersionNotUsedInDeviceOverride=void 0;const r=n(304),i=n(880);o.checkVersionNotUsedInDeviceOverride=(e,o,n,a)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:s}=yield e.from("devices_override").select().eq("app_id",o).eq("version",n.id);(t&&t.length||s)&&r.program.error(`Version ${o} @${a} is used in a device override, unlink it first ${(0,i.formatError)(s)}`)}))},191:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteFromStorage=void 0;const r=n(304),i=n(880);o.deleteFromStorage=(e,o,n,a,s)=>t(void 0,void 0,void 0,(function*(){const{error:t}=yield e.storage.from("apps").remove([`${o}/${n}/versions/${a.bucket_id} `]);t&&r.program.error(`Something went wrong when trying to delete ${n} @${s} ${(0,i.formatError)(t)} `)}))},340:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.getVersionData=o.getActiveAppVersions=o.deleteSpecificVersion=o.deleteAppVersion=void 0;const r=n(304),i=n(880),a=n(978),s=n(386),p=n(191);o.deleteAppVersion=(e,o,n,a)=>t(void 0,void 0,void 0,(function*(){const{error:t}=yield e.from("app_versions").update({deleted:!0}).eq("app_id",o).eq("user_id",n).eq("name",a);t&&r.program.error(`App ${o}@${a} not found in database '${(0,i.formatError)(t)}'`)})),o.deleteSpecificVersion=(e,n,r,i)=>t(void 0,void 0,void 0,(function*(){const t=yield(0,o.getVersionData)(e,n,r,i);yield(0,a.checkVersionNotUsedInChannel)(e,n,r,t,i),yield(0,s.checkVersionNotUsedInDeviceOverride)(e,n,t,i),yield(0,p.deleteFromStorage)(e,r,n,t,i),yield(0,o.deleteAppVersion)(e,n,r,i)})),o.getActiveAppVersions=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:a}=yield e.from("app_versions").select().eq("app_id",o).eq("user_id",n).eq("deleted",!1).order("id");return a&&r.program.error(`App ${o} not found in database ${(0,i.formatError)(a)} `),t})),o.getVersionData=(e,o,n,a)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:s}=yield e.from("app_versions").select().eq("app_id",o).eq("user_id",n).eq("name",a).eq("deleted",!1).single();return t&&!s||r.program.error(`Version ${o}@${a} doesn't exist ${(0,i.formatError)(s)}`),t}))},870:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.addApp=void 0;const r=n(304),i=n(663),a=n(147),s=n(470),p=n(11),c=n(880),d="assets/icon.png";o.addApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t;let{name:l,icon:u}=o;const y=o.apikey||(0,c.findSavedKey)(),g=yield(0,c.getConfig)(),f=(0,c.useLogSnag)();e=e||(null===(n=null==g?void 0:g.app)||void 0===n?void 0:n.appId),l=l||(null===(t=null==g?void 0:g.app)||void 0===t?void 0:t.appName)||"Unknown",u=u||"resources/icon.png",y||r.program.error("Missing API key, you need to provide a API key to add your app"),e&&l||r.program.error("Missing argument, you need to provide a appid and a name, or be in a capacitor project"),console.log(`Add ${e} to Capgo`);const v=(0,c.createSupabaseClient)(y),m=yield(0,c.verifyUser)(v,y,["write","all"]);let h,b;yield(0,c.checkPlanValid)(v,m),console.log("Adding..."),u&&(0,s.existsSync)(u)?(h=(0,a.readFileSync)(u),b=(0,p.getType)(u)||"image/png",console.warn(`Found app icon ${u}`)):(0,s.existsSync)(d)?(h=(0,a.readFileSync)(d),b=(0,p.getType)(d)||"image/png",console.warn(`Found app icon ${d}`)):console.warn(`Cannot find app icon in any of the following locations: ${u}, ${d}`);const{data:_,error:k}=yield v.rpc("exist_app",{appid:e,apikey:y});(_||k)&&r.program.error(`App already exists ${(0,c.formatError)(k)}`);const w=`icon_${(0,i.randomUUID)()}`;let $="https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";if(h&&b){const{error:o}=yield v.storage.from(`images/${m}/${e}`).upload(w,h,{contentType:b});o&&r.program.error(`Could not add app ${(0,c.formatError)(o)}`);const{data:n}=yield v.storage.from(`images/${m}/${e}`).getPublicUrl(w);$=(null==n?void 0:n.publicURL)||$}const{error:x}=yield v.from("apps").insert({icon_url:$,user_id:m,name:l,app_id:e},{returning:"minimal"});x&&r.program.error(`Could not add app ${(0,c.formatError)(x)}`);const{error:S}=yield v.from("app_versions").insert([{user_id:m,deleted:!0,name:"unknown",app_id:e},{user_id:m,deleted:!0,name:"builtin",app_id:e}],{returning:"minimal"});S&&r.program.error(`Could not add app ${(0,c.formatError)(S)}`),f.publish({channel:"app",event:"App Added",icon:"🎉",tags:{"user-id":m,"app-id":e},notify:!1}).catch(),console.log("App added to server, you can upload a bundle now")}))},600:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.cleanupApp=void 0;const i=n(304),a=r(n(505)),s=r(n(616)),p=n(880),c=n(340),d=n(577),l=(0,s.default)();o.cleanupApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const t=o.apikey||(0,p.findSavedKey)(),{bundle:r,keep:s=4}=o,u=o.force||!1,y=yield(0,p.getConfig)();e=e||(null===(n=null==y?void 0:y.app)||void 0===n?void 0:n.appId),t||i.program.error("Missing API key, you need to provide an API key to delete your app"),e||i.program.error("Missing argument, you need to provide a appid, or be in a capacitor project");const g=`${a.default.inc(r,"major")}`;console.log(`Querying available versions in Capgo between ${r} and ${g}`);const f=(0,p.createSupabaseClient)(t),v=yield(0,p.verifyUser)(f,t);yield(0,d.checkAppExistsAndHasPermission)(f,e,t);const m=yield(0,c.getActiveAppVersions)(f,e,v);if(console.log(`Total active versions in Capgo: ${null==m?void 0:m.length}`),0===(null==m?void 0:m.length))return;const h=((e,o,n)=>{const t=[];return null==e||e.forEach((e=>{a.default.gte(e.name,o)&&a.default.lt(e.name,`${n}`)&&t.push(e)})),t})(m,r,g).reverse();console.log(`Active versions in Capgo between ${r} and ${g}: ${null==h?void 0:h.length}`);const b=h.slice(0,s),_=h.slice(s);if(b.forEach((e=>{console.log(`${e.name} created on ${(0,p.getHumanDate)(e)} will be kept`)})),b.length&&console.log("==================================================="),0!==_.length){if(_.forEach((e=>{console.log(`${e.name} created on ${(0,p.getHumanDate)(e)} will be removed`)})),!u&&"yes"!==l("Do you want to continue removing the versions specified? Type yes to confirm"))return void console.log("Not confirmed, aborting removal...");console.log("You have confirmed removal, removing versions now"),((e,o,n,t)=>{null==e||e.forEach((e=>{console.log(`Removing ${e.name} created on ${(0,p.getHumanDate)(e)}`),(0,c.deleteSpecificVersion)(o,n,t,e.name)}))})(_,f,e,v)}else console.log("Nothing to be removed, aborting removal...")}))},692:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.decryptZip=void 0;const r=n(304),i=n(147),a=n(113),s=n(880);o.decryptZip=(e,o,n)=>t(void 0,void 0,void 0,(function*(){(0,i.existsSync)(e)||r.program.error(`Zip not found at the path ${e}`);const t=yield(0,s.getConfig)(),{extConfig:p}=t.app;n.key||(0,i.existsSync)(s.baseKey)||p.plugins.CapacitorUpdater.privateKey||r.program.error(`Private Key not found at the path ${s.baseKey} or in ${t.app.extConfigFilePath}`);const c="string"==typeof n.key?n.key:s.baseKey;let{privateKey:d}=p.plugins.CapacitorUpdater;(0,i.existsSync)(c)||d?(0,i.existsSync)(c)&&(d=(0,i.readFileSync)(c).toString()):r.program.error(`Cannot find public key ${c}`);const l=(0,i.readFileSync)(e),u=(0,a.decryptSource)(l.toString("base64"),o,d);(0,i.writeFileSync)(`${e}_decrypted.zip`,u)}))},0:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteApp=void 0;const r=n(304),i=n(880),a=n(340);o.deleteApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const{bundle:t}=o,s=o.apikey||(0,i.findSavedKey)(),p=yield(0,i.getConfig)(),c=(0,i.useLogSnag)();e=e||(null===(n=null==p?void 0:p.app)||void 0===n?void 0:n.appId),s||r.program.error("Missing API key, you need to provide an API key to delete your app"),e||r.program.error("Missing argument, you need to provide a appid, or be in a capacitor project");const d=(0,i.createSupabaseClient)(s),l=yield(0,i.verifyUser)(d,s),{data:u,error:y}=yield d.rpc("exist_app",{appid:e,apikey:s});if(u&&!y||r.program.error("No permission to delete"),t)return console.log(`Delete ${e}@${t} from Capgo`),yield(0,a.deleteSpecificVersion)(d,e,l,t),void console.log(`${e}@${t} deleted from server`);console.log(`Delete ${e} from Capgo`);const{data:g,error:f}=yield d.from("app_versions").select().eq("app_id",e).eq("user_id",l);if(f&&r.program.error(`App ${e} not found in database ${(0,i.formatError)(f)} `),g&&g.length){const o=g.map((o=>`${l}/${e}/versions/${o.bucket_id} `)),{error:n}=yield d.storage.from("apps").remove(o);n&&r.program.error(`Cannot delete stored version for app ${e} from storage ${(0,i.formatError)(n)} `)}const{error:v}=yield d.from("app_versions").delete().eq("app_id",e).eq("user_id",l);v&&r.program.error(`Cannot delete version for app ${e} from database ${(0,i.formatError)(v)} `);const{error:m}=yield d.from("apps").delete().eq("app_id",e).eq("user_id",l);m&&r.program.error(`Cannot delete from database ${(0,i.formatError)(m)} `),c.publish({channel:"app",event:"App Deleted",icon:"😱",tags:{"user-id":l,"app-id":e},notify:!1}).catch(),console.log(`${e} deleted from server`)}))},128:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.encryptZip=void 0;const r=n(304),i=n(147),a=n(113),s=n(880);o.encryptZip=e=>t(void 0,void 0,void 0,(function*(){(0,i.existsSync)(e)||r.program.error(`Zip not found at the path ${e}`),(0,i.existsSync)(s.baseKeyPub)||r.program.error(`Public Key not found at the path ${s.baseKeyPub}`);const o=(0,i.readFileSync)(s.baseKeyPub).toString(),n=(0,i.readFileSync)(e),t=(0,a.encryptSource)(n.toString("base64"),o);(0,i.writeFileSync)(`${e}_encrypted.zip`,t.encodedSource)}))},731:function(e,o,n){var t=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0});const r=n(304),i=n(692),a=n(128),s=n(870),p=n(218),c=n(0),d=n(331),l=n(510),u=t(n(598)),y=n(621),g=n(272),f=n(600);r.program.description("Manage packages and bundle versions in capgo Cloud").version(u.default.version),r.program.command("add [appid]").alias("a").description("Add a new app to capgo Cloud").action(s.addApp).option("-n, --name <name>","app name").option("-i, --icon <icon>","app icon path").option("-a, --apikey <apikey>","apikey to link to your account"),r.program.command("login [apikey]").alias("l").description("Save apikey to your machine or folder").action(y.login).option("--local","Only save in local folder"),r.program.command("upload [appid]").alias("u").description("Upload a new bundle to capgo Cloud").action(l.uploadVersion).option("-a, --apikey <apikey>","apikey to link to your account").option("-p, --path <path>","path of the file to upload").option("-c, --channel <channel>","channel to link to").option("-e, --external <url>","link to external url intead of upload to capgo cloud").option("-f, --format <base64|hex|binary|utf8>","choose the upload format default base64").option("--key <key>","custom path for public signing key").option("--keyData <keyData>","base64 public signing key").option("--no-key","ignore signing key and send clear update").option("-b, --bundle <bundle>","bundle version number of the file to upload"),r.program.command("set [appid]").alias("s").description("Modify a channel configuration").action(d.setChannel).requiredOption("-c, --channel <channel>","channel to link to").option("-a, --apikey <apikey>","apikey to link to your account").option("-b, --bundle <bundle>","bundle version number of the file to set").option("-s, --state <state>","set the state of the channel, default or normal").option("--downgrade","Allow to downgrade to version under native one").option("--latest","get the latest version key in the package.json to set it to the channel").option("--no-downgrade","Disable downgrade to version under native one").option("--upgrade","Allow to upgrade to version above native one").option("--no-upgrade","Disable upgrade to version above native one").option("--ios","Allow sending update to ios devices").option("--no-ios","Disable sending update to ios devices").option("--android","Allow sending update to android devices").option("--no-android","Disable sending update to android devices").option("--self-assign","Allow to device to self assign to this channel").option("--no-self-assign","Disable devices to self assign to this channel"),r.program.command("delete [appid]").alias("d").description("Delete an app from capgo Cloud").action(c.deleteApp).option("-a, --apikey <apikey>","apikey to link to your account").option("-b, --bundle <bundle>","bundle version number of the app to delete"),r.program.command("list [appid]").alias("ls").description("List versions in capgo Cloud").action(g.listApp).option("-a, --apikey <apikey>","apikey to link to your account"),r.program.command("cleanup [appid]").alias("c").description("Cleanup versions in capgo Cloud").action(f.cleanupApp).requiredOption("-b, --bundle <bundle>","bundle version number of the app to delete").option("-a, --apikey <apikey>","apikey to link to your account").option("-k, --keep <keep>","number of version to keep").option("-f, --force","force removal"),r.program.command("key [option]").description("Save base64 signing key in capacitor config, usefull for CI").action(p.manageKey).option("-f, --force","force generate a new one"),r.program.command("decrypt [zipPath] [sessionKey]").description("Decrypt a signed zip update").action(i.decryptZip).option("--key <key>","custom path for private signing key").option("--keyData <keyData>","base64 private signing key"),r.program.command("encrypt [zipPath]").description("Encrypt a zip update").action(a.encryptZip).option("--key <key>","custom path for private signing key").option("--keyData <keyData>","base64 private signing key"),r.program.parse(process.argv)},218:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.manageKey=void 0;const r=n(304),i=n(147),a=n(778),s=n(113),p=n(880);o.manageKey=(e,o)=>t(void 0,void 0,void 0,(function*(){"create"===e?(e=>{t(void 0,void 0,void 0,(function*(){(0,i.existsSync)(".git")||r.program.error("To use local you should be in a git repository");const{publicKey:o,privateKey:n}=(0,s.createRSA)();(0,i.existsSync)(p.baseKeyPub)&&!e.force&&r.program.error("Public Key already exists, use --force to overwrite"),(0,i.writeFileSync)(p.baseKeyPub,o);const t=yield(0,p.getConfig)(),{extConfig:c}=t.app;c&&(c.plugins||(c.plugins={}),c.plugins.CapacitorUpdater||(c.plugins.CapacitorUpdater={}),c.plugins.CapacitorUpdater.privateKey=n,(0,a.writeConfig)(c,t.app.extConfigFilePath)),console.log("Your RSA key has been generated using node-rsa with this settings:\n\n- encryptionScheme — 'pkcs1_oaep'.\n- signingScheme — 'pkcs8-sha256'.\n- bits — 2048.\n- exp — 65537.\n"),console.log(`public key saved into ${p.baseKeyPub} file in local directory\n`),console.log("This key will be use to encode your zipped bundle before sending it to Capgo,\nthan make them unreadable by Capgo and unmodifiable by anyone\n"),console.log(`Private key saved into ${t.app.extConfigFilePath} file in local directory`),console.log("Your app will decode with this key the zipped bundle\n")}))})(o):r.program.error("You should provide a valid option (create or save)")}))},272:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.listApp=void 0;const r=n(304),i=n(880),a=n(577),s=n(340);o.listApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const t=o.apikey||(0,i.findSavedKey)(),p=yield(0,i.getConfig)();e=e||(null===(n=null==p?void 0:p.app)||void 0===n?void 0:n.appId),t||r.program.error("Missing API key, you need to provide an API key to delete your app"),e||r.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),console.log("Querying available versions in Capgo");const c=(0,i.createSupabaseClient)(t),d=yield(0,i.verifyUser)(c,t);yield(0,a.checkAppExistsAndHasPermission)(c,e,t);const l=yield(0,s.getActiveAppVersions)(c,e,d);console.log(`Active versions in Capgo: ${null==l?void 0:l.length}`),null==l||l.forEach((e=>{console.log(`${e.name} created on ${(0,i.getHumanDate)(e)}`)}))}))},621:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.login=void 0;const r=n(304),i=n(147),a=n(37),s=n(880);o.login=(e,o)=>t(void 0,void 0,void 0,(function*(){const{local:n}=o,t=(0,s.useLogSnag)();if(n)(0,i.existsSync)(".git")||r.program.error("To use local you should be in a git repository"),(0,i.writeFileSync)(".capgo",`${e}\n`),(0,i.appendFileSync)(".gitignore",".capgo\n");else{const o=(0,a.homedir)();(0,i.writeFileSync)(`${o}/.capgo`,`${e}\n`)}const p=(0,s.createSupabaseClient)(e),c=yield(0,s.verifyUser)(p,e,["write","all","upload"]);t.publish({channel:"user-login",event:"User CLI login",icon:"✅",tags:{"user-id":c},notify:!1}).catch(),console.log(`login saved into .capgo file in ${n?"local":"home"} directory`)}))},331:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.setChannel=void 0;const r=n(304),i=n(880);o.setChannel=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t,a;const{bundle:s,latest:p,downgrade:c,upgrade:d,ios:l,android:u,selfAssign:y,channel:g,state:f}=o,v=o.apikey||(0,i.findSavedKey)(),m=yield(0,i.getConfig)(),h=(0,i.useLogSnag)();e=e||(null===(n=null==m?void 0:m.app)||void 0===n?void 0:n.appId),v||r.program.error("Missing API key, you need to provide a API key to add your app"),e||r.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),p&&s&&r.program.error("Cannot set latest and bundle at the same time"),void 0===s&&void 0===f&&void 0===p&&void 0===c&&void 0===d&&void 0===l&&void 0===u&&void 0===y&&r.program.error("Missing argument, you need to provide a option to set");try{const o=(0,i.createSupabaseClient)(v),n=yield(0,i.verifyUser)(o,v,["write","all"]);yield(0,i.checkPlanValid)(o,n);const b={created_by:n,app_id:e,name:g},_=p?null===(a=null===(t=null==m?void 0:m.app)||void 0===t?void 0:t.package)||void 0===a?void 0:a.version:s;if(_){const{data:t,error:i}=yield o.from("app_versions").select().eq("app_id",e).eq("name",_).eq("user_id",n).eq("deleted",!1);!i&&t&&t.length||r.program.error(`Cannot find version ${_}`),console.log(`Set ${e} channel: ${g} to @${s}`),b.version=t[0].id}void 0!==f&&("public"!==f&&"private"!==f||console.log(`Set ${e} channel: ${g} to public or private is deprecated, use default or normal instead`),console.log(`Set ${e} channel: ${g} to ${"public"===f||"default"===f?"default":"normal"}`),b.public="public"===f||"default"===f),void 0!==c&&(console.log(`Set ${e} channel: ${g} to ${c?"allow":"disallow"} downgrade`),b.disableAutoUpdateUnderNative=!c),void 0!==d&&(console.log(`Set ${e} channel: ${g} to ${d?"allow":"disallow"} upgrade`),b.disableAutoUpdateToMajor=!d),void 0!==l&&(console.log(`Set ${e} channel: ${g} to ${l?"allow":"disallow"} ios update`),b.ios=!!l),void 0!==u&&(console.log(`Set ${e} channel: ${g} to ${u?"allow":"disallow"} android update`),b.android=!!u),void 0!==y&&(console.log(`Set ${e} channel: ${g} to ${y?"allow":"disallow"} self assign to this channel`),b.allow_device_self_set=!!y);try{const{error:e}=yield(0,i.updateOrCreateChannel)(o,b,v);e&&r.program.error(`Cannot set channel ${(0,i.formatError)(e)}`)}catch(e){r.program.error(`Cannot set channel ${(0,i.formatError)(e)}`)}h.publish({channel:"app",event:"Set app",icon:"✅",tags:{"user-id":n,"app-id":e},notify:!1}).catch()}catch(e){r.program.error(`Unknow error ${(0,i.formatError)(e)}`)}console.log("Done ✅")}))},510:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.uploadVersion=void 0;const i=r(n(844)),a=n(304),s=n(663),p=r(n(295)),c=n(147),d=n(906),l=n(113),u=n(880);o.uploadVersion=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t,r,y;let{bundle:g,path:f,channel:v}=o;const{external:m,key:h=!1}=o,b=o.apikey||(0,u.findSavedKey)(),_=(0,u.useLogSnag)();v=v||"dev";const k=yield(0,u.getConfig)();e=e||(null===(n=null==k?void 0:k.app)||void 0===n?void 0:n.appId),g=g||(null===(r=null===(t=null==k?void 0:k.app)||void 0===t?void 0:t.package)||void 0===r?void 0:r.version),u.regexSemver.test(g)||a.program.error(`Your bundle name ${g}, is not valid it should follow semver convention : https://semver.org/`),f=f||(null===(y=null==k?void 0:k.app)||void 0===y?void 0:y.webDir),b||a.program.error("Missing API key, you need to provide a API key to add your app"),e&&g&&f||a.program.error("Missing argument, you need to provide a appid and a bundle and a path, or be in a capacitor project"),console.log(`Upload ${e}@${g} started from path "${f}" to Capgo cloud`);const w=(0,u.createSupabaseClient)(b),$=yield(0,u.verifyUser)(w,b,["write","all","upload"]);yield(0,u.checkPlanValid)(w,$,!1);const x=new p.default.MultiBar({clearOnComplete:!1,hideCursor:!0},p.default.Presets.shades_grey),S=x.create(7,0,{format:"Uploading: [{bar}] {percentage}% | ETA: {eta}s | {value}/{total} Part"},p.default.Presets.shades_grey);S.start(7,0,{speed:"N/A"});const{data:C,error:A}=yield w.rpc("exist_app_versions",{apikey:b,name_version:g,appid:e});(C||A)&&(x.stop(),a.program.error(`This app bundle already exist or was deleted, you cannot re-upload it ${(0,u.formatError)(A)}`)),S.increment();const{data:P,error:q}=yield w.rpc("is_trial",{userid:$}).single();(P&&P>0||q)&&x.log(`WARNING !!\nTrial expires in ${P} days, upgrade here: ${u.hostWeb}/dashboard/settings/plans\n`),S.increment();const{data:K,error:j}=yield w.rpc("exist_app",{appid:e,apikey:b});K&&!j||(x.stop(),a.program.error(`Cannot find app ${e} in your account \n${(0,u.formatError)(j)}`)),S.increment();const{data:I,error:D}=yield w.rpc("exist_app_versions",{appid:e,apikey:b,name_version:g});(I||D)&&a.program.error(`Version already exists ${(0,u.formatError)(D)}`),S.increment();const M=(0,s.randomUUID)();let E,U="";if(m)m&&!m.startsWith("https://")&&(x.stop(),a.program.error(`External link should should start with "https://" current is "${m}"`));else{const o=new i.default;o.addLocalFolder(f);let n=o.toBuffer();if(U=yield(0,d.checksum)(n,"crc32"),h||(0,c.existsSync)(u.baseKeyPub)){const e="string"==typeof h?h:u.baseKeyPub;(0,c.existsSync)(e)||a.program.error(`Cannot find public key ${e}`);const o=(0,c.readFileSync)(e),t=(0,l.encryptSource)(n.toString(),o.toString());E=t.sessionKey,n=Buffer.from(t.encodedSource,"base64")}const t=Math.floor(n.byteLength/1024/1024),r=`apps/${$}/${e}/versions`;S.increment(),t>20&&(x.log(`WARNING !!\nThe app size is ${t} Mb, this may take a while to download for users\n`),_.publish({channel:"app-error",event:"App Too Large",icon:"🚛",tags:{"user-id":$,"app-id":e},notify:!1}).catch());const{error:s}=yield w.storage.from(r).upload(M,n,{contentType:"application/zip"});s&&(x.stop(),a.program.error(`Cannot upload ${(0,u.formatError)(s)}`))}S.increment();const{data:O,error:V}=yield(0,u.updateOrCreateVersion)(w,{bucket_id:m?void 0:M,user_id:$,name:g,app_id:e,session_key:E,external_url:m,checksum:U},b);if(V&&(x.stop(),a.program.error(`Cannot add bundle ${(0,u.formatError)(V)}`)),S.increment(),O&&O.length){const{error:o}=yield(0,u.updateOrCreateChannel)(w,{name:v,app_id:e,created_by:$,version:O[0].id},b);o&&x.log("Cannot set bundle with upload key, use key with more rights for that\n")}else x.log("Cannot set bundle with upload key, use key with more rights for that\n");x.stop();const z=e.replace(/\./g,"--");console.log("App uploaded to server"),console.log(`Try it in mobile app: ${u.host}/app_mobile`),console.log(`Or set the channel ${v} as public here: ${u.hostWeb}/app/package/${z}`),console.log("To use with live update in your own app"),console.log(`You can link specific device to this bundle to make user try it first, here: ${u.hostWeb}/app/p/${z}/devices`),_.publish({channel:"app",event:"App Uploaded",icon:"⏫",tags:{"user-id":$,"app-id":e},notify:!1}).catch()}))},880:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.getHumanDate=o.verifyUser=o.useLogSnag=o.updateOrCreateChannel=o.updateOrCreateVersion=o.getConfig=o.formatError=o.findSavedKey=o.checkPlanValid=o.isTrial=o.isPaying=o.isGoodPlan=o.checkKey=o.regexSemver=o.createSupabaseClient=o.supaAnon=o.hostSupa=o.hostWeb=o.host=o.baseKeyPub=o.baseKey=void 0;const i=n(778),a=n(304),s=n(885),p=r(n(867)),c=n(147),d=n(37),l=n(133);o.baseKey=".capgo_key",o.baseKeyPub=`${o.baseKey}.pub`,o.host="https://capgo.app",o.hostWeb="https://web.capgo.app",o.hostSupa="https://xvwzpoazmxkqosrdewyv.supabase.co",o.supaAnon="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYzNzgwNTAwOSwiZXhwIjoxOTUzMzgxMDA5fQ.8tgID1d4jodPwuo_fz4KHN4o1XKB9fnqyt0_GaJSj-w",o.createSupabaseClient=e=>(0,s.createClient)(o.hostSupa,o.supaAnon,{headers:{capgkey:e}}),o.regexSemver=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/,o.checkKey=(e,n,r)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:i}=yield e.rpc("is_allowed_capgkey",{apikey:n,keymode:r});t&&!i||a.program.error(`Invalid API key or insufficient permissions ${(0,o.formatError)(i)}`)})),o.isGoodPlan=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_good_plan_v2",{userid:o}).single();if(t)throw t;return n||!1})),o.isPaying=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_paying",{userid:o}).single();if(t)throw t;return n||!1})),o.isTrial=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_trial",{userid:o}).single();if(t)throw t;return n||0})),o.checkPlanValid=(e,n,r=!0)=>t(void 0,void 0,void 0,(function*(){const t=yield(0,o.isGoodPlan)(e,n),i=yield(0,o.isPaying)(e,n),s=yield(0,o.isTrial)(e,n);i&&t||!(s<0)||a.program.error(`You need to upgrade your plan to continue to use capgo.\n Upgrade here: ${o.hostWeb}/dashboard/settings/plans\n`),s>0&&r&&!i&&console.log(`WARNING !!\nTrial expires in ${s} days, upgrade here: ${o.hostWeb}/dashboard/settings/plans\n`)})),o.findSavedKey=()=>{let e=`${(0,d.homedir)()}/.capgo`;return(0,c.existsSync)(e)?(0,c.readFileSync)(e,"utf8").trim():(e=".capgo",(0,c.existsSync)(e)?(0,c.readFileSync)(e,"utf8").trim():null)},o.formatError=e=>e?`\n${p.default.render(e)}`:"",o.getConfig=()=>t(void 0,void 0,void 0,(function*(){let e;try{e=yield(0,i.loadConfig)()}catch(e){a.program.error("No capacitor config file found, run `cap init` first")}return e})),o.updateOrCreateVersion=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:r}=yield e.rpc("exist_app_versions",{appid:o.app_id,name_version:o.name,apikey:n});return t&&!r?(o.deleted=!1,e.from("app_versions").update(o).eq("app_id",o.app_id).eq("name",o.name)):e.from("app_versions").insert(o)})),o.updateOrCreateChannel=(e,o,n)=>t(void 0,void 0,void 0,(function*(){if(!o.app_id||!o.name||!o.created_by)return console.error("missing app_id, name, or created_by"),Promise.reject(new Error("missing app_id, name, or created_by"));const{data:t,error:r}=yield e.rpc("exist_channel",{appid:o.app_id,name_channel:o.name,apikey:n});return t&&!r?e.from("channels").update(o,{returning:"minimal"}).eq("app_id",o.app_id).eq("name",o.name).eq("created_by",o.created_by):e.from("channels").insert(o,{returning:"minimal"})})),o.useLogSnag=()=>new l.LogSnag({token:"c124f5e9d0ce5bdd14bbb48f815d5583",project:"capgo"}),o.verifyUser=(e,n,r=["all"])=>t(void 0,void 0,void 0,(function*(){yield(0,o.checkKey)(e,n,r);const{data:t,error:i}=yield e.rpc("get_user_id",{apikey:n}),s=t?t.toString():"";return s&&!i||a.program.error(`Cannot verify user ${(0,o.formatError)(i)}`),s})),o.getHumanDate=e=>new Date(e.created_at||"").toLocaleString()},778:e=>{e.exports=require("@capacitor/cli/dist/config")},885:e=>{e.exports=require("@supabase/supabase-js")},906:e=>{e.exports=require("@tomasklaen/checksum")},844:e=>{e.exports=require("adm-zip")},295:e=>{e.exports=require("cli-progress")},304:e=>{e.exports=require("commander")},666:e=>{e.exports=require("crypto-js")},837:e=>{e.exports=require("crypto-js/aes")},470:e=>{e.exports=require("fs-extra")},133:e=>{e.exports=require("logsnag")},11:e=>{e.exports=require("mime")},339:e=>{e.exports=require("node-rsa")},867:e=>{e.exports=require("prettyjson")},616:e=>{e.exports=require("prompt-sync")},505:e=>{e.exports=require("semver/preload")},663:e=>{e.exports=require("crypto")},147:e=>{e.exports=require("fs")},37:e=>{e.exports=require("os")},598:e=>{e.exports=JSON.parse('{"name":"@capgo/cli","version":"2.1.1","description":"A CLI to upload to capgo servers","main":"dist/index.js","bin":{"capgo":"dist/index.js"},"repository":{"type":"git","url":"git+https://github.com/Cap-go/capgo-cli.git"},"bugs":{"url":"https://github.com/Cap-go/capgo-cli/issues"},"keywords":["appflow alternative","ionic","capacitor","auto update","live update","capgo","cli","upload","capgo-cli"],"scripts":{"dev":"set NODE_ENV=development && npx webpack --config webpack.config.js","no-debug":"node dist/index.js","build":"npx webpack --config webpack.config.js","dev-build":"SUPA_DB=development npx webpack --config webpack.config.js","pack":"pkg","test_rls":"ts-node ./test/test_headers_rls.ts","lint":"eslint . --ext .ts --fix"},"author":"github.com/riderx","license":"Apache 2.0","dependencies":{"@capacitor/cli":"4.5.0","@supabase/supabase-js":"^1.35.7","@tomasklaen/checksum":"^1.1.0","adm-zip":"^0.5.9","cli-progress":"3.11.2","commander":"9.4.1","crypto-js":"^4.1.1","fs-extra":"11.1.0","logsnag":"^0.1.5","mime":"^3.0.0","node-rsa":"^1.1.1","prettyjson":"^1.2.5","prompt-sync":"^4.2.0","semver":"^7.3.8"},"devDependencies":{"@types/adm-zip":"0.5.0","@types/cli-progress":"^3.11.0","@types/crypto-js":"^4.1.1","@types/fs-extra":"^9.0.13","@types/mime":"^3.0.1","@types/node":"^18.11.9","@types/node-rsa":"^1.1.1","@types/prettyjson":"^0.0.30","@types/prompt-sync":"^4.2.0","@types/semver":"^7.3.13","@typescript-eslint/eslint-plugin":"5.45.0","@typescript-eslint/parser":"5.45.0","eslint":"8.28.0","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^8.5.0","eslint-import-resolver-typescript":"3.5.2","eslint-plugin-import":"2.26.0","eslint-plugin-prettier":"^4.2.1","git-format-staged":"3.0.0","husky":"^8.0.2","nodemon":"2.0.20","pkg":"5.8.0","prettier":"2.7.1","ts-loader":"^9.4.1","ts-node":"^10.9.1","tsconfig-paths":"4.1.0","typescript":"4.9.3","webpack":"5.75.0","webpack-cli":"^5.0.0","webpack-node-externals":"^3.0.0"}}')}},o={};!function n(t){var r=o[t];if(void 0!==r)return r.exports;var i=o[t]={exports:{}};return e[t].call(i.exports,i,i.exports,n),i.exports}(731)})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/cli",
3
- "version": "2.0.1",
3
+ "version": "2.1.1",
4
4
  "description": "A CLI to upload to capgo servers",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -43,7 +43,7 @@
43
43
  "cli-progress": "3.11.2",
44
44
  "commander": "9.4.1",
45
45
  "crypto-js": "^4.1.1",
46
- "fs-extra": "10.1.0",
46
+ "fs-extra": "11.1.0",
47
47
  "logsnag": "^0.1.5",
48
48
  "mime": "^3.0.0",
49
49
  "node-rsa": "^1.1.1",
@@ -62,8 +62,8 @@
62
62
  "@types/prettyjson": "^0.0.30",
63
63
  "@types/prompt-sync": "^4.2.0",
64
64
  "@types/semver": "^7.3.13",
65
- "@typescript-eslint/eslint-plugin": "5.44.0",
66
- "@typescript-eslint/parser": "5.44.0",
65
+ "@typescript-eslint/eslint-plugin": "5.45.0",
66
+ "@typescript-eslint/parser": "5.45.0",
67
67
  "eslint": "8.28.0",
68
68
  "eslint-config-airbnb-base": "^15.0.0",
69
69
  "eslint-config-prettier": "^8.5.0",
@@ -0,0 +1,68 @@
1
+ import aes from 'crypto-js/aes';
2
+ import NodeRSA from 'node-rsa'
3
+ import CryptoJS from 'crypto-js';
4
+ import { program } from 'commander';
5
+ import { randomUUID } from 'crypto';
6
+
7
+ export const decryptSource = (source: string, ivSessionKey: string, privateKey: string) => {
8
+ const nodeRsa = new NodeRSA(privateKey, 'pkcs8-private-pem');
9
+ if (!nodeRsa.isPrivate()) {
10
+ program.error(`Cannot use public key to decode, please use private key`)
11
+ }
12
+ console.log('\nivSessionKey', ivSessionKey)
13
+ const [ivB64, sessionb64Encrypted] = ivSessionKey.split(':');
14
+ console.log('\nsessionb64Encrypted', sessionb64Encrypted)
15
+ console.log('\nivB64', ivB64)
16
+ const sessionDecrypted = nodeRsa.decrypt(sessionb64Encrypted, 'base64')
17
+ console.log('\nsessionDecrypted', sessionDecrypted)
18
+ const sessionB64 = CryptoJS.enc.Base64.parse(sessionDecrypted);
19
+ console.log('\nsessionb64', CryptoJS.enc.Base64.stringify(sessionB64))
20
+ // iv to worldaaray
21
+ const iv = CryptoJS.enc.Base64.parse(ivB64);
22
+
23
+ const decodedSource = aes.decrypt(source, sessionB64, { iv }).toString()
24
+
25
+ return decodedSource
26
+ }
27
+ export interface Encoded {
28
+ sessionKey: string,
29
+ encodedSource: string
30
+ }
31
+ export const encryptSource = (source: string, publicKey: string): Encoded => {
32
+ const nodeRsa = new NodeRSA(publicKey, 'pkcs8-public-pem')
33
+ // check is key is private key
34
+ if (nodeRsa.isPrivate()) {
35
+ program.error(`Cannot use private key to encode, please use public key`)
36
+ }
37
+ // encrypt zip with key
38
+ const encrypted = aes.encrypt(CryptoJS.enc.Base64.parse(source), randomUUID())
39
+ // encrypt session key with public key
40
+ const sessionB64 = CryptoJS.enc.Base64.stringify(encrypted.key)
41
+ console.log('\nsessionb64', sessionB64)
42
+ const ivB64 = CryptoJS.enc.Base64.stringify(encrypted.iv)
43
+ console.log('\nivB64', ivB64)
44
+ const sessionb64Encrypted = nodeRsa.encrypt(sessionB64, 'base64')
45
+ console.log('\nsessionb64Encrypted', sessionb64Encrypted)
46
+ const sessionKey = `${ivB64}:${sessionb64Encrypted}`
47
+ console.log('\nivSessionKey', sessionKey)
48
+ // encrypted to buffer
49
+ const encodedSource = CryptoJS.enc.Base64.stringify(encrypted.ciphertext)
50
+ return {
51
+ encodedSource,
52
+ sessionKey
53
+ }
54
+ }
55
+ export interface RSAKeys {
56
+ publicKey: string,
57
+ privateKey: string
58
+ }
59
+ export const createRSA = (): RSAKeys => {
60
+ const key = new NodeRSA({ b: 512 });
61
+ const pair = key.generateKeyPair();
62
+ const publicKey = pair.exportKey('pkcs8-public-pem');
63
+ const privateKey = pair.exportKey('pkcs8-private-pem');
64
+ return {
65
+ publicKey,
66
+ privateKey,
67
+ }
68
+ }
@@ -0,0 +1,40 @@
1
+ import { program } from 'commander'
2
+ import { existsSync, readFileSync, writeFileSync } from 'fs'
3
+ import { decryptSource } from '../api/crypto';
4
+ import { baseKey, getConfig } from './utils';
5
+
6
+ interface Options {
7
+ key?: boolean | string
8
+ }
9
+
10
+ export const decryptZip = async (zipPath: string, ivsessionKey: string, options: Options) => {
11
+ // write in file .capgo the apikey in home directory
12
+
13
+ if (!existsSync(zipPath)) {
14
+ program.error(`Zip not found at the path ${zipPath}`);
15
+ }
16
+
17
+ const config = await getConfig();
18
+ const { extConfig } = config.app;
19
+
20
+ if (!options.key && !existsSync(baseKey) && !extConfig.plugins.CapacitorUpdater.privateKey) {
21
+ program.error(`Private Key not found at the path ${baseKey} or in ${config.app.extConfigFilePath}`);
22
+ }
23
+ const keyString = typeof options.key === 'string' ? options.key : baseKey
24
+ // check if publicKey exist
25
+
26
+ let { privateKey } = extConfig.plugins.CapacitorUpdater;
27
+
28
+ if (!existsSync(keyString) && !privateKey) {
29
+ program.error(`Cannot find public key ${keyString}`)
30
+ } else if (existsSync(keyString)) {
31
+ // open with fs publicKey path
32
+ const keyFile = readFileSync(keyString)
33
+ privateKey = keyFile.toString()
34
+ }
35
+
36
+ const zipFile = readFileSync(zipPath)
37
+ const decodedZip = decryptSource(zipFile.toString('base64'), ivsessionKey, privateKey)
38
+ // write decodedZip in a file
39
+ writeFileSync(`${zipPath}_decrypted.zip`, decodedZip)
40
+ }
@@ -0,0 +1,24 @@
1
+ import { program } from 'commander'
2
+ import { existsSync, readFileSync, writeFileSync } from 'fs'
3
+ import { encryptSource } from '../api/crypto';
4
+ import { baseKeyPub } from './utils';
5
+
6
+ export const encryptZip = async (zipPath: string) => {
7
+ // write in file .capgo the apikey in home directory
8
+
9
+ if (!existsSync(zipPath)) {
10
+ program.error(`Zip not found at the path ${zipPath}`);
11
+ }
12
+
13
+ if (!existsSync(baseKeyPub)) {
14
+ program.error(`Public Key not found at the path ${baseKeyPub}`);
15
+ }
16
+ // open with fs publicKey path
17
+ const keyFile = readFileSync(baseKeyPub)
18
+ const keyString = keyFile.toString()
19
+
20
+ const zipFile = readFileSync(zipPath)
21
+ const encodedZip = encryptSource(zipFile.toString('base64'), keyString)
22
+ // write decodedZip in a file
23
+ writeFileSync(`${zipPath}_encrypted.zip`, encodedZip.encodedSource)
24
+ }
package/src/bin/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { program } from 'commander';
2
- import { decodeZip } from './decode';
2
+ import { decryptZip } from './decrypt';
3
+ import { encryptZip } from './encrypt';
3
4
  import { addApp } from './add';
4
5
  import { manageKey } from './key';
5
6
  import { deleteApp } from './delete';
@@ -99,10 +100,16 @@ program
99
100
 
100
101
 
101
102
  program
102
- .command('decode [zipPath] [sessionKey]')
103
- .alias('dec')
104
- .description('Decode a signed zip update')
105
- .action(decodeZip)
103
+ .command('decrypt [zipPath] [sessionKey]')
104
+ .description('Decrypt a signed zip update')
105
+ .action(decryptZip)
106
+ .option('--key <key>', 'custom path for private signing key')
107
+ .option('--keyData <keyData>', 'base64 private signing key');
108
+
109
+ program
110
+ .command('encrypt [zipPath]')
111
+ .description('Encrypt a zip update')
112
+ .action(encryptZip)
106
113
  .option('--key <key>', 'custom path for private signing key')
107
114
  .option('--keyData <keyData>', 'base64 private signing key');
108
115
 
package/src/bin/key.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { program } from 'commander'
2
2
  import { existsSync, writeFileSync } from 'fs'
3
- import NodeRSA from 'node-rsa'
4
3
  import { writeConfig } from '@capacitor/cli/dist/config';
4
+ import { createRSA } from '../api/crypto';
5
5
  import { baseKeyPub, getConfig } from './utils';
6
6
 
7
7
  interface Options {
@@ -40,17 +40,7 @@ const createKey = async (options: Options) => {
40
40
  if (!existsSync('.git')) {
41
41
  program.error('To use local you should be in a git repository');
42
42
  }
43
- const key = new NodeRSA({ b: 512 });
44
- const pair = key.generateKeyPair();
45
- const publicKey = pair.exportKey('pkcs8-public-pem');
46
- const privateKey = pair.exportKey('pkcs8-private-pem');
47
-
48
- // remove header and footer of privateKey
49
- const privateKeyClean = privateKey
50
- .replace('-----BEGIN PRIVATE KEY-----', '')
51
- .replace('-----END PRIVATE KEY-----', '')
52
- .replace(/\s/g, '')
53
- .replace(/\n/g, '');
43
+ const { publicKey, privateKey } = createRSA()
54
44
 
55
45
  // check if baseName already exist
56
46
  if (existsSync(baseKeyPub) && !options.force) {
@@ -67,7 +57,7 @@ const createKey = async (options: Options) => {
67
57
  if (!extConfig.plugins.CapacitorUpdater) {
68
58
  extConfig.plugins.CapacitorUpdater = {};
69
59
  }
70
- extConfig.plugins.CapacitorUpdater.privateKey = privateKeyClean;
60
+ extConfig.plugins.CapacitorUpdater.privateKey = privateKey;
71
61
  // console.log('extConfig', extConfig)
72
62
  writeConfig(extConfig, config.app.extConfigFilePath)
73
63
  }
package/src/bin/upload.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  import AdmZip from 'adm-zip';
2
2
  import { program } from 'commander';
3
3
  import { randomUUID } from 'crypto';
4
- import aes from 'crypto-js/aes';
5
4
  import cliProgress from 'cli-progress';
6
5
  import { existsSync, readFileSync } from 'fs';
7
- import NodeRSA from 'node-rsa'
8
6
  import { checksum as getChecksum } from '@tomasklaen/checksum';
7
+ import { encryptSource } from '../api/crypto';
9
8
  import {
10
9
  host, hostWeb, getConfig, createSupabaseClient,
11
10
  updateOrCreateChannel, updateOrCreateVersion, formatError, findSavedKey, checkPlanValid, useLogSnag, verifyUser, regexSemver, baseKeyPub
@@ -99,6 +98,7 @@ export const uploadVersion = async (appid: string, options: Options) => {
99
98
  const zip = new AdmZip();
100
99
  zip.addLocalFolder(path);
101
100
  let zipped = zip.toBuffer();
101
+ checksum = await getChecksum(zipped, 'crc32');
102
102
  if (key || existsSync(baseKeyPub)) {
103
103
  const publicKey = typeof key === 'string' ? key : baseKeyPub
104
104
  // check if publicKey exist
@@ -107,21 +107,11 @@ export const uploadVersion = async (appid: string, options: Options) => {
107
107
  }
108
108
  // open with fs publicKey path
109
109
  const keyFile = readFileSync(publicKey)
110
- const nodeRsa = new NodeRSA(keyFile.toString())
111
- // check is key is private key
112
- if (nodeRsa.isPrivate()) {
113
- program.error(`Cannot use private key to encode, please use public key`)
114
- }
115
- // encrypt zip with key
116
- const encrypted = aes.encrypt(zipped.toString(), randomUUID())
117
- // encrypt session key with public key
118
- sessionKey = nodeRsa.encrypt(encrypted.key.toString(), 'base64')
119
- console.log('Session Key', encrypted.key.toString())
120
-
121
- // encrypted to buffer
122
- zipped = Buffer.from(encrypted.ciphertext.toString(), 'base64')
110
+ // encrypt
111
+ const res = encryptSource(zipped.toString(), keyFile.toString())
112
+ sessionKey = res.sessionKey
113
+ zipped = Buffer.from(res.encodedSource, 'base64')
123
114
  }
124
- checksum = await getChecksum(zipped, 'crc32');
125
115
  const mbSize = Math.floor(zipped.byteLength / 1024 / 1024);
126
116
  const filePath = `apps/${userId}/${appid}/versions`
127
117
  b1.increment();
package/src/bin/decode.ts DELETED
@@ -1,48 +0,0 @@
1
- import { program } from 'commander'
2
- import { existsSync, readFileSync, writeFileSync } from 'fs'
3
- import NodeRSA from 'node-rsa'
4
- import aes from 'crypto-js/aes';
5
- import { baseKey, getConfig } from './utils';
6
-
7
- interface Options {
8
- key?: boolean | string
9
- }
10
-
11
- export const decodeZip = async (zipPath: string, sessionKey: string, options: Options) => {
12
- // write in file .capgo the apikey in home directory
13
-
14
- if (!existsSync(zipPath)) {
15
- program.error(`Zip not found at the path ${zipPath}`);
16
- }
17
-
18
- const config = await getConfig();
19
- const { extConfig } = config.app;
20
-
21
- if (!options.key && !existsSync(baseKey) && !extConfig.plugins.CapacitorUpdater.privateKey) {
22
- program.error(`Private Key not found at the path ${baseKey} or in ${config.app.extConfigFilePath}`);
23
- }
24
- const privateKey = typeof options.key === 'string' ? options.key : baseKey
25
- // check if publicKey exist
26
-
27
- let keyString = extConfig.plugins.CapacitorUpdater.privateKey;
28
-
29
- if (!existsSync(privateKey) && !extConfig.plugins.CapacitorUpdater.privateKey) {
30
- program.error(`Cannot find public key ${privateKey}`)
31
- } else if (existsSync(privateKey)) {
32
- // open with fs publicKey path
33
- const keyFile = readFileSync(privateKey)
34
- keyString = keyFile.toString()
35
- }
36
-
37
- const zipFile = readFileSync(zipPath)
38
- const nodeRsa = new NodeRSA(keyString, 'pkcs8-private-pem');
39
- if (nodeRsa.isPublic()) {
40
- program.error(`Cannot use public key to decode, please use private key`)
41
- }
42
- const decodedSessionKey = nodeRsa.decrypt(sessionKey, 'base64')
43
- console.log('Session Key', decodedSessionKey)
44
- const decodedZip = aes.decrypt(zipFile.toString(), decodedSessionKey).toString()
45
-
46
- // write decodedZip in a file
47
- writeFileSync(`${zipPath}decoded.zip`, decodedZip)
48
- }