Error: spawn EACCES [ERROR] An error occurred while running cordova build ios (exit code 1) with jscrambler.js

I am running into some kind of problem when attempting to build my ionic v1 project with jscrambler.

I am using an Apple MAC with the following config

MYMAC:ECTGW_Ionic admin$ ionic info
[WARN] Error with ./www/lib/ionic/version.json file: FILE_NOT_FOUND, trying ./bower.json.
cli packages: (/usr/local/lib/node_modules)
@ionic/cli-utils : 1.15.2
ionic (Ionic CLI) : 3.15.2
global packages:
cordova (Cordova CLI) : 7.0.1
Gulp CLI : CLI version 3.9.1 Local version 3.9.1
local packages:
Cordova Platforms : ios 4.4.0
Ionic Framework : ionic1 1.3.4
System:
ios-sim : 5.0.13
Node : v6.11.5
npm : 3.10.10
OS : macOS Sierra
Xcode : Xcode 9.0.1 Build version 9A1004
Environment Variables:
ANDROID_HOME : not set
Misc:
backend : pro

Prior to adding jscrambler, my ionic project builds, runs, and deploys to iOS without any problem.

I don’t know if it is relevant to state this or if this is in some way related to the current problem which is described below, but the ONLY way I could get ionic to install on my Apple Mac was to use the following method. Prior to finding a knowledge article showing the below installation method I was encountering nonstop error after error and couldn’t get ionic installed.

1- Open a new command line window. Type in:
sudo npm install --global --unsafe-perm quickscrape
And hit enter.

Mac: You will need to type in your computer password on all commands beginning with ‘sudo’

2- Then type in:
sudo npm install -g cordova ionic --unsafe-perm quickscrape
And hit enter.

3- Finally type in:
sudo npm install -g ionic --unsafe-perm node-sass
And hit enter.

Ionic should be installed now.

I am following the procedure here Protecting Hybrid Mobile Apps with Ionic and JScrambler and have also engaged JScrambler Support but they told me its a permissions issue and have not provided any specific troubleshooting help yet other than to point me at a few knowledge articles and answer some questions.

What I really need is troubleshooting help. That’s what I need.

Anyway, once I run the command ionic prepare and create the hooks/after_prepare/ this is the point where I start running into issues.

There is a file in the hooks/after_prepare/ folder by default named 010_add_platform_class.js and that executes without incident.

This tells me the problem is not permissions related because if it was a permissions issue, the 010_add_platform_class.js would have problems executing.

Never the less, when I plop the jscrambler.js file in the hooks/after_prepare/ folder and run ionic cordova build ios I get the following problem.

MYMAC:ECTGW_Ionic admin$ ionic cordova build ios
[WARN] Not performing Ionic build for project type: ionic1.
> cordova build ios
cordova-custom-config: Skipping auto-restore of config file backup(s)
Running command: /Users/admin/Desktop/ECTGW_Ionic/hooks/after_prepare/010_add_platform_class.js /Users/admin/Desktop/ECTGW_Ionic
add to body class: platform-ios
Running command: /Users/admin/Desktop/ECTGW_Ionic/hooks/after_prepare/jscrambler.js /Users/admin/Desktop/ECTGW_Ionic
Error: spawn EACCES
[ERROR] An error occurred while running cordova build ios (exit code 1).

I already tried this:

MYMAC:ECTGW_Ionic admin$ chmod +x hooks/after_prepare/010_add_platform_class.js
MYMAC:ECTGW_Ionic admin$ chmod +x hooks/after_prepare/jscrambler.js

And that doesn’t fix my problem.

In fact ionic runs the following hook fine without incident.

hooks/after_prepare/010_add_platform_class.js

It just won’t run this hook

hooks/after_prepare/jscrambler.js

I also tried this:

MYMAC:ECTGW_Ionic admin$ ionic hooks add
[ERROR] Unable to find command: hooks add
MYMAC:ECTGW_Ionic admin$

MYMAC:ECTGW_Ionic admin$ ionic cordova hooks add
[ERROR] Unable to find command: cordova hooks add
MYMAC:ECTGW_Ionic admin$

Running it with sudo ends in the same result

MYMAC:ECTGW_Ionic admin$ sudo ionic hooks add
[ERROR] Unable to find command: hooks add
MYMAC:ECTGW_Ionic admin$

MYMAC:ECTGW_Ionic admin$ sudo ionic cordova hooks add
[ERROR] Unable to find command: cordova hooks add
MYMAC:ECTGW_Ionic admin$

I also tried this based on seeing some posts that claim removing platform iOS, then adding hooks, then re-installing platform iOS is the solution.

MYMAC:ECTGW_Ionic admin$ ionic cordova platform remove ios
MYMAC:ECTGW_Ionic admin$ ionic cordova hooks add 
[ERROR] Unable to find command: cordova hooks add
MYMAC:ECTGW_Ionic admin$

MYMAC:ECTGW_Ionic admin$ ionic cordova platform remove ios
MYMAC:ECTGW_Ionic admin$ ionic hooks add 
[ERROR] Unable to find command: hooks add
MYMAC:ECTGW_Ionic admin$

But I keep getting the message

[ERROR] Unable to find command: hooks add

Or

[ERROR] Unable to find command: cordova hooks add

I am at a complete loss as to why the build process ends in the following error

Error: spawn EACCES
[ERROR] An error occurred while running cordova build ios (exit code 1).

I am not a unix, linux, or mac expert. My background is in windows, so this mac development project with ionic is me taking a leap into the deep end of the ocean while trying to knit together a life vest so i don’t drown.

My gut is telling me that the contents of the jscrambler.js file itself is the root of the problem, but I don’t know enough about what it is supposed to contain to be able to troubleshoot it effectively.

I am hoping that someone here may have some experience with jscrambler and can provide some troubleshooting guidance so that I can determine what the actual problem is since jscrambler support is not yet helping me on that level.

I hope they will, but we didn’t get there yet and I don’t have time to waste.

Here is a copy of the jscrambler.js file with the critical key elements redacted for security.

#!/usr/local/bin/ node

var jscrambler = require('jscrambler').default;

jscrambler.protectAndDownload({
  keys: {
    accessKey: 'REDACTED FOR SECURITY',
    secretKey: 'REDACTED FOR SECURITY'
  },
  host: 'api4.jscrambler.com',
  port: 443,
  applicationId: 'REDACTED FOR SECURITY',
  filesSrc: [
    './www/*.{js,html}',
  ],
  filesDest: './',
  params: [  
    {
      'name': 'whitespaceRemoval'
    },
    {
      'name': 'duplicateLiteralsRemoval'
    }
  ]
})
.then(function () {
  console.log('All done!');
})
.catch(function (err) {
  console.error(err);
});

If anyone here can help me troubleshoot this, I would be greatly appreciative.

Thanks so much in advance.

I already tried what is shown in that link. You can see the specifics of what I already did in my description.

If there is something specific you are recommending I do, please list that exact specific action.

I already tried many things by reading random knowledge articles and nothing worked so pointing me to a random blog that seems to look like it might help is not useful at this point. There are hundreds of slightly different iterations of many things in that blog post and none of it is actual troubleshooting to determine the exact problem.

If you or someone can recommend a specific action, and can type that specific action in the response, I will try that.

I’ll also be happy to answer any questions about specifics to help a troubleshooter narrow down the exact problem to help me and others who may have this exact problem with the goal of providing a specific fix that will work.

I dont know much about jscrambler. I use cordova ugify which works. I faced the issue, where i went to the hooks folder, right click, get info, then added my Read & Write permissions then it worked.

I have read and write access on the /hooks folder

I also have read/write access on /hooks/after_prepare

I also have read/write access on hooks/after_prepare/010_add_platform_class.js

THE hooks/after_prepare/010_add_platform_class.js FILE RUNS FINE

I don’t believe the issue is a permissions issue. Any hooks file runs fine except jscrambler.js.

I am almost certain that the problem is specific to jscrambler.js

I also have read/write access on /hooks/after_prepare/jscrambler.js and that produces the following

Error: spawn EACCES
[ERROR] An error occurred while running cordova build ios (exit code 1).

Could this part of the jscrambler.js file be the cause of the problem?

 filesSrc: [
    './www/*.{js,html}',
  ],
  filesDest: './',

Is there a way to turn on some kind of verbose debugging in ionic so when i run ionic cordova build iOS I get more information than what is shown below?

YMAC:ECTGW_Ionic admin$ ionic cordova build ios
[WARN] Not performing Ionic build for project type: ionic1.
> cordova build ios
cordova-custom-config: Skipping auto-restore of config file backup(s)
Running command: /Users/admin/Desktop/ECTGW_Ionic/hooks/after_prepare/010_add_platform_class.js /Users/admin/Desktop/ECTGW_Ionic
add to body class: platform-ios
Running command: **/Users/admin/Desktop/ECTGW_Ionic/hooks/after_prepare/jscrambler.js /Users/admin/Desktop/ECTGW_Ionic**
**Error: spawn EACCES**
**[ERROR] An error occurred while running cordova build ios (exit code 1).**

Where does ‘./’ write to? I am not a mac/unix/linux expert.

What directory is ‘./’ trying to write the scrambled files to?

What permissions are needed on ./www/*.{js,html} for jscrambler.js to read and process them?

Is ‘./www/*.{js,html}’ even pointing to the right place?

The www folder is in (using full path) MAC_HD/Users/admin/Desktop/ECTGW_Ionic/www

The platform ios www folder is in (using full path) MAC_HD/Users/admin/Desktop/ECTGW_ionic/platforms/ios/www

What directory does the hooks process actually run from?

Is that a proper way to understand what it is, a “hooks” process?

What is this at the top of the jscrambler.js file #!/usr/local/bin/ node

What does #!/usr/local/bin/ node mean and does it do anything?

If it does, could this be the problem?

If I try and go to/usr/local/bin I can get there but if I try and browse manually, I cannot.

My gut feeling is that the source of the problem has something to do with those things.

Still looking for help identifying the cause of the problem as well as a fix.

If this was something MS Windows related, like launching customprog.exe and passing it a path and files so it can “process” them, but something wasn’t working, I could assist the person and say

“If you are at a command prompt, and you the cursor has focus in C:\MyDir via the command prompt screen, that is your base of operations, or your root path per se. Everything will run from there, so when you launch the customprog.exe process that lives in C:\Program Files\Prog1\ from command prompt and are currently in the C:\MyDir directory, you need to execute the following ‘C:\Program Files\Prog1\customprog.exe’ and when it launches it will be running as if it is sitting in ‘C:\MyDir’ because that is where you are sitting. So you need to reference everything you feed to customprog.exe from the standpoint of C:\MyDir. If you are using relative paths, you must reference them from the standpoint of C:\MyDir as your root path. If you want to tell customprog.exe to read in data from the ‘C:\Windows\System32’ then you need to type that in and not use a virtual path or some other non-direct path for simplification purposes.”

I don’t know how to understand what is happening in mac/linux/unix when I type ionic cordova build iOS so I cannot easily determine the problem.

If I understand that as it relates to the hooks/after_prepare/jscrambler.js I would have already solved this problem and it would be a non-issue.

Any help zeroing in on this problem would be greatly appreciated.

All i know is there is no permissions problem with /hooks/after_prepare/ because other hooks files run fine inside of /hooks/after_prepare/ just not jscrambler.js

Hi,

This is the amazing issue. I tried to re-produce your issue and I fixed it successfully. You miss the configuration on the jscrambler file and the steps to make the build on the ionic. Let me give the solution to resolve it.

  1. Please remove your hooks folder first and add it again with command line : ionic hooks add

  2. About your jscrambler.js, please use comma for your variable like this.

var jscrambler = require('jscrambler').default;

jscrambler.protectAndDownload({
  'keys': {
    'accessKey': 'REDACTED FOR SECURITY',
    'secretKey': 'REDACTED FOR SECURITY'
  },
  'host': 'api4.jscrambler.com',
  'port': 443,
  'applicationId': 'REDACTED FOR SECURITY',
  'filesSrc': [
    './www/*.{js,html}',
  ],
  'filesDest': './',
  'params': [  
    {
      'name': 'whitespaceRemoval'
    },
    {
      'name': 'duplicateLiteralsRemoval'
    }
  ]
})
.then(function () {
  console.log('All done!');
})
.catch(function (err) {
  console.error(err);
});
  1. Your jscrambler.js miss a lot of the configuration. You can see my full configuration file for reference. Just replace the key and use it.
#!/usr/bin/env node

var jscrambler = require('jscrambler').default;

jscrambler.protectAndDownload({  
  'keys': {
    'accessKey': 'REDACTED FOR SECURITY',
    'secretKey': 'REDACTED FOR SECURITY'
  },
  'applicationId': 'REDACTED FOR SECURITY',
  'host': 'api4.jscrambler.com',
  'port': 443,
  'filesSrc': [
    './platforms/ios/www/*.{js,html}',
    './platforms/ios/www/js/*.js'
  ],
  'filesDest': './',
  'params': [
    {
      'name': 'whitespaceRemoval'
    },
    {
      'name': 'duplicateLiteralsRemoval'
    },
    {
      'name': 'functionReordering'
    },
    {
      'name': 'dotToBracketNotation'
    },
    {
      'name': 'functionOutlining'
    },
    {
      'name': 'booleanToAnything'
    },
    {
      'name': 'stringSplitting',
      'options': {
        'chunk': 0.25
      }
    },
    {
      'name': 'identifiersRenaming',
    },
    {
      'name': 'propertyKeysReordering'
    },
    {
      'name': 'propertyKeysObfuscation'
    }
  ],
  'areSubscribersOrdered': false,
  'applicationTypes': {
    'webBrowserApp': false,
    'desktopApp': false,
    'serverApp': false,
    'hybridMobileApp': false,
    'javascriptNativeApp': false,
    'html5GameApp': false
  },
  'languageSpecifications': {
    'es5': true,
    'es6': false,
    'es7': false
  }
})
.then(function() {
  console.log('Jscrambler done!');
})
.catch(function (err) {
  console.error(err);
});
  1. About the hook file, if we have two files, named 010_hook_1.js and 020_hook_2.js, hook_1 will always be performed before hook_2. So, PLEASE rename the jscrambler.js to 030_jscrambler.js. It will be executed after all.

  2. Make sure the jscrambler plugin is installed already and provide the execute permission
    npm install jscrambler --save-dev
    chmod +x hooks/after_prepare/jscrambler.js

  3. Remove the platforms folder first and add it again with command line :
    cordova platform add ios

  4. Run ionic prepare. It will add the jscrambler to your platform

  5. Run cordova build ios

The issue is gone. Let me know if you face the other issue.

Thanks,

1 Like

Thanks so much! I finally got it! Solution item numbers 2, 3, 4, 6, 7, and 8 were relevant to my situation.

Here is what I did.

  1. Step 1 wasn’t applicable. The command ionic hooks add presents the following error:

[ERROR] Unable to find command: hooks add

Since the hooks folder gets created when I create the ionic project via the command ionic start MyApp blank --type=ionic1 and other hooks run run, I am thinking there is absolutely nothing wrong with the hooks folder.

So I ended up skipping # 1.

  1. Yes, you seem to be right on there.

  2. Yes, I just took the jscrambler.js file you provided and swapped my information into it**

  3. This was the KEY. The file name needed to be 020_jscrambler.js

  4. I executed npm install jscrambler --save-dev and I did not have to do anything wit the permissions because there is no problem with the permissions on the hooks folder since other hooks files run.

I tried skipping ahead and ran ionic prepare followed by ionic cordova build ios but got some errors.

Therefore I did the ionic cordova platform remove ios followed by ionic cordova platform add ios

ThenI tried ionic cordova prepare followed by ionic cordova build ios and IT WORKED!

Hi there,

Just want to ask what you think of jscrambler. Is it worth it?
I’m in the process of hardening my app and finding some of the solutions a bit confusing.
At the moment, I just minify the code but dont think this is enough, keys are still in there and html files and visible. Can you keep the API keys in the client if you use this solution do you know?

Thanks,
Noel

The API keys are stored in the 020_jscrambler.js file which is in the Xcode project but is not compiled or stored in the app itself so it’s impossible for anyone to pull the keys from your app and then turn Aron d and use them to break into the app because the keys aren’t in it.

The cost of jscrambler is quite expensive so if cost is a concern you will want to encrypt only those files that absolutely need it.

The ~$450/year plan allows for 1 app and 25 protected files. If I remember correctly, it is the same plan you get during the 15 day free trial.

The next plan up is upwards of $100 per month and pricing goes up from there. I had to consolidate my code to be able to squeeze it into the $450/year plan.

As for how it works, it works great! It projects the app and makes it virtually impossible to steal the source code.

The more expensive plans even have self defending technology options you can use as part of the protection.

Jscrambler is pretty much the only player on earth so it will be nice if some competitors start popping up to keep everyone on their toes.

I wouldn’t expect anything from their support team though. They didn’t help me at all with any of my issues even though I am a paying customer and I emailed them all the details to make it easy for them to troubleshoot.

So if you don’t know exactly what to do, you may want to line up an outside expert you can call for help so you can actually get help because you won’t get help from jscrambler support unless something has radically changed since this past November when this blog post was written.

Thanks for the response. I’m glad I went with jscrambler, was relatively easy to setup and the code really looks unusable so very happy with level of protection. I actually got good support from them on two issues I had so they must of improved things. It’s a bit pricey but the first plan works fine for me and I’d prefer pay and have peace of mind and the support of commercial product.