Unzipping a password protected file in Node.js

I tried the spawn approach (the spawnSync actually worked better).

const result = spawnSync('unzip', ['-P', 'password', '-d', './files', './files/file.zip'], { encoding: 'utf-8' })

Nonetheless, this approach did not fully work as it introduced a new error:

Archive:  test.zip
   skipping: file.png                need PK compat. v5.1 (can do v4.6)

Eventually, I ended up going with 7zip approach:

import sevenBin from '7zip-bin'
import seven from 'node-7z'

const zipPath = './files/file.zip'
const downloadDirectory = './files'

const zipStream = seven.extractFull(zipPath, downloadDirectory, {
  password: 'password',
  $bin: sevenBin.path7za
})

zipStream.on('end', () => {
  // Do stuff with unzipped content
})

I was able to get this working, not the best way probably but it works at least using this line:

var newFile = spawn('unzip', [ '-P','ThisIsATestPassword', '-d','./lib/tmp/foo','./lib/mocks/tmp/this.zip' ])

This will just unzip all the files into the directory and then I was able to read them from there. My mistake was that the second parameter has to be an array.


I found the solution using unzipper.

Pasting the code from this blog

const unzipper = require('unzipper');

(async () => {
  try {
    const directory = await unzipper.Open.file('path/to/your.zip');
    const extracted = await directory.files[0].buffer('PASSWORD');
    console.log(extracted.toString()); // This will print the file content
  } catch(e) {
    console.log(e);
  }
})();

As @codyschaaf mentioned in his answer, we can use spawn or some other child_process but they're not always OS agnostic. So if I'm using this in production, I'll always go for an OS-agnostic solution if it exists.

Hope this helps someone.