1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/keeweb_ynh.git synced 2024-09-03 19:26:33 +02:00

Sources 1.1.4 and YNH 2.4

This commit is contained in:
scith 2016-06-10 11:32:05 +02:00
parent 661fea5001
commit 590df5db5b
8 changed files with 407 additions and 137 deletions

View file

@ -3,7 +3,7 @@
Web client for reading and editing Keepass files locally. It can also sync with Dropbox.
![screenshot](https://habrastorage.org/files/ec9/108/3de/ec91083de3e64574a504bc438d038dec.png)
**Current version: 1.0.4**
**Current version: 1.1.4**
## Usage for Dropbox sync ##
1. [create](https://www.dropbox.com/developers/apps/create) a Dropbox app

View file

@ -1,4 +1,5 @@
{
"package_format": 1,
"name": "Keeweb",
"id": "keeweb",
"description": {
@ -16,6 +17,9 @@
"nginx",
"php5-fpm"
],
"requirements": {
"yunohost": ">= 2.2"
},
"arguments": {
"install" : [
{
@ -52,7 +56,7 @@
"fr": "Est-ce une application publique ?"
},
"choices": ["Yes", "No"],
"default": "Yes"
"default": "No"
}
]
}

View file

@ -5,16 +5,21 @@
var app = require('app'),
path = require('path'),
fs = require('fs'),
BrowserWindow = require('browser-window'),
Menu = require('menu'),
Tray = require('tray');
Tray = require('tray'),
globalShortcut = require('electron').globalShortcut;
var mainWindow = null,
appIcon = null,
openFile = process.argv.filter(function(arg) { return /\.kdbx$/i.test(arg); })[0],
ready = false,
restartPending = false,
htmlPath = path.join(__dirname, 'index.html');
htmlPath = path.join(__dirname, 'index.html'),
mainWindowPosition = {},
updateMainWindowPositionTimeout = null,
windowPositionFileName = path.join(app.getPath('userData'), 'window-position.json');
process.argv.forEach(function(arg) {
if (arg.lastIndexOf('--htmlpath=', 0) === 0) {
@ -25,6 +30,7 @@ process.argv.forEach(function(arg) {
app.on('window-all-closed', function() {
if (restartPending) {
// unbind all handlers, load new app.js module and pass control to it
globalShortcut.unregisterAll();
app.removeAllListeners('window-all-closed');
app.removeAllListeners('ready');
app.removeAllListeners('open-file');
@ -40,7 +46,9 @@ app.on('window-all-closed', function() {
}
});
app.on('ready', function() {
setAppOptions();
createMainWindow();
setGlobalShortcuts();
});
app.on('open-file', function(e, path) {
e.preventDefault();
@ -54,6 +62,9 @@ app.on('activate', function() {
}
}
});
app.on('will-quit', function() {
globalShortcut.unregisterAll();
});
app.restartApp = function() {
restartPending = true;
mainWindow.close();
@ -63,7 +74,7 @@ app.openWindow = function(opts) {
return new BrowserWindow(opts);
};
app.minimizeApp = function() {
if (process.platform === 'win32') {
if (process.platform !== 'darwin') {
mainWindow.minimize();
mainWindow.setSkipTaskbar(true);
appIcon = new Tray(path.join(__dirname, 'icon.png'));
@ -80,10 +91,14 @@ app.getMainWindow = function() {
return mainWindow;
};
function setAppOptions() {
app.commandLine.appendSwitch('disable-background-timer-throttling');
}
function createMainWindow() {
mainWindow = new BrowserWindow({
show: false,
width: 1000, height: 700, 'min-width': 600, 'min-height': 300,
width: 1000, height: 700, 'min-width': 700, 'min-height': 400,
icon: path.join(__dirname, 'icon.png')
});
setMenu();
@ -95,12 +110,17 @@ function createMainWindow() {
notifyOpenFile();
}, 50);
});
mainWindow.on('resize', delaySaveMainWindowPosition);
mainWindow.on('move', delaySaveMainWindowPosition);
mainWindow.on('close', updateMainWindowPositionIfPending);
mainWindow.on('closed', function() {
mainWindow = null;
saveMainWindowPosition();
});
mainWindow.on('minimize', function() {
emitBackboneEvent('launcher-minimize');
});
restoreMainWindowPosition();
}
function restoreMainWindow() {
@ -116,6 +136,68 @@ function closeMainWindow() {
emitBackboneEvent('launcher-exit-request');
}
function delaySaveMainWindowPosition() {
if (updateMainWindowPositionTimeout) {
clearTimeout(updateMainWindowPositionTimeout);
}
updateMainWindowPositionTimeout = setTimeout(updateMainWindowPosition, 500);
}
function updateMainWindowPositionIfPending() {
if (updateMainWindowPositionTimeout) {
clearTimeout(updateMainWindowPositionTimeout);
updateMainWindowPosition();
}
}
function updateMainWindowPosition() {
if (!mainWindow) {
return;
}
updateMainWindowPositionTimeout = null;
var bounds = mainWindow.getBounds();
if (!mainWindow.isMaximized() && !mainWindow.isMinimized() && !mainWindow.isFullScreen()) {
mainWindowPosition.x = bounds.x;
mainWindowPosition.y = bounds.y;
mainWindowPosition.width = bounds.width;
mainWindowPosition.height = bounds.height;
}
mainWindowPosition.maximized = mainWindow.isMaximized();
mainWindowPosition.fullScreen = mainWindow.isFullScreen();
mainWindowPosition.displayBounds = require('screen').getDisplayMatching(bounds).bounds;
mainWindowPosition.changed = true;
}
function saveMainWindowPosition() {
if (!mainWindowPosition.changed) {
return;
}
delete mainWindowPosition.changed;
try {
fs.writeFileSync(windowPositionFileName, JSON.stringify(mainWindowPosition), 'utf8');
} catch (e) {}
}
function restoreMainWindowPosition() {
fs.readFile(windowPositionFileName, 'utf8', function(err, data) {
if (data) {
mainWindowPosition = JSON.parse(data);
if (mainWindow && mainWindowPosition) {
if (mainWindowPosition.width && mainWindowPosition.height) {
var displayBounds = require('screen').getDisplayMatching(mainWindowPosition).bounds;
var db = mainWindowPosition.displayBounds;
if (displayBounds.x === db.x && displayBounds.y === db.y &&
displayBounds.width === db.width && displayBounds.height === db.height) {
mainWindow.setBounds(mainWindowPosition);
}
}
if (mainWindowPosition.maximized) { mainWindow.maximize(); }
if (mainWindowPosition.fullScreen) { mainWindow.setFullScreen(true); }
}
}
});
}
function emitBackboneEvent(e) {
mainWindow.webContents.executeJavaScript('Backbone.trigger("' + e + '");');
}
@ -164,3 +246,21 @@ function notifyOpenFile() {
openFile = null;
}
}
function setGlobalShortcuts() {
var shortcutModifiers = process.platform === 'darwin' ? 'Ctrl+Alt+' : 'Shift+Alt+';
var shortcuts = {
C: 'copy-password',
B: 'copy-user',
U: 'copy-url'
};
Object.keys(shortcuts).forEach(function(key) {
var shortcut = shortcutModifiers + key;
var eventName = shortcuts[key];
try {
globalShortcut.register(shortcut, function () {
emitBackboneEvent(eventName);
});
} catch (e) {}
});
}

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
# node-stream-zip
# node-stream-zip [![Build status](https://travis-ci.org/antelle/node-stream-zip.svg?branch=master)](https://travis-ci.org/antelle/node-stream-zip)
node.js library for reading and extraction of ZIP archives.
Features:
@ -10,6 +10,7 @@ Features:
- no dependencies, no binary addons
- decompression with built-in zlib module
- deflate, deflate64, sfx, macosx/windows built-in archives
- ZIP64 support
# Installation
@ -55,6 +56,13 @@ zip.on('entry', function(entry) {
});
```
If you pass `storeEntries: true` to constructor, you will be able to access entries inside zip archive with:
- `zip.entries()` - get all entries description
- `zip.entry(name)` - get entry description by name
- `zip.stream(entry, function(err, stm) { })` - get entry data reader stream
- `zip.entryDataSync(entry)` - get entry data in sync way
# Building
The project doesn't require building. To run unit tests with [nodeunit](https://github.com/caolan/nodeunit):

View file

@ -60,6 +60,7 @@ var consts = {
/* The entries in the end of central directory */
ENDHDR : 22, // END header size
ENDSIG : 0x06054b50, // "PK\005\006"
ENDSIGFIRST : 0x50,
ENDSUB : 8, // number of entries on this disk
ENDTOT : 10, // total number of entries
ENDSIZ : 12, // central directory size in bytes
@ -67,6 +68,21 @@ var consts = {
ENDCOM : 20, // zip file comment length
MAXFILECOMMENT : 0xFFFF,
/* The entries in the end of ZIP64 central directory locator */
ENDL64HDR : 20, // ZIP64 end of central directory locator header size
ENDL64SIG : 0x07064b50, // ZIP64 end of central directory locator signature
ENDL64SIGFIRST : 0x50,
ENDL64OFS : 8, // ZIP64 end of central directory offset
/* The entries in the end of ZIP64 central directory */
END64HDR : 56, // ZIP64 end of central directory header size
END64SIG : 0x06064b50, // ZIP64 end of central directory signature
END64SIGFIRST : 0x50,
END64SUB : 24, // number of entries on this disk
END64TOT : 32, // total number of entries
END64SIZ : 40,
END64OFF : 48,
/* Compression methods */
STORED : 0, // no compression
SHRUNK : 1, // shrunk
@ -123,11 +139,7 @@ var consts = {
ID_POSZIP : 0x4690,
EF_ZIP64_OR_32 : 0xffffffff,
EF_ZIP64_OR_16 : 0xffff,
EF_ZIP64_SUNCOMP : 0,
EF_ZIP64_SCOMP : 8,
EF_ZIP64_RHO : 16,
EF_ZIP64_DSN : 24
EF_ZIP64_OR_16 : 0xffff
};
// endregion
@ -165,6 +177,36 @@ var StreamZip = function(config) {
});
}
function readUntilFoundCallback(err, bytesRead) {
if (err || !bytesRead)
return that.emit('error', err || 'Archive read error');
var
buffer = op.win.buffer,
pos = op.lastPos,
bufferPosition = pos - op.win.position,
minPos = op.minPos;
while (--pos >= minPos && --bufferPosition >= 0) {
if (buffer[bufferPosition] === op.firstByte) { // quick check first signature byte
if (buffer.readUInt32LE(bufferPosition) === op.sig) {
op.lastBufferPosition = bufferPosition;
op.lastBytesRead = bytesRead;
op.complete();
return;
}
}
}
if (pos === minPos) {
return that.emit('error', 'Bad archive');
}
op.lastPos = pos + 1;
op.chunkSize *= 2;
if (pos <= minPos)
return that.emit('error', 'Bad archive');
var expandLength = Math.min(op.chunkSize, pos - minPos);
op.win.expandLeft(expandLength, readUntilFoundCallback);
}
function readCentralDirectory() {
var totalReadLength = Math.min(consts.ENDHDR + consts.MAXFILECOMMENT, fileSize);
op = {
@ -172,51 +214,89 @@ var StreamZip = function(config) {
totalReadLength: totalReadLength,
minPos: fileSize - totalReadLength,
lastPos: fileSize,
chunkSize: 1024
chunkSize: Math.min(1024, chunkSize),
firstByte: consts.ENDSIGFIRST,
sig: consts.ENDSIG,
complete: readCentralDirectoryComplete
};
op.win.read(fileSize - op.chunkSize, op.chunkSize, readCentralDirectoryCallback);
op.win.read(fileSize - op.chunkSize, op.chunkSize, readUntilFoundCallback);
}
function readCentralDirectoryCallback(err, bytesRead) {
if (err || !bytesRead)
return that.emit('error', err || 'Archive read error');
var
buffer = op.win.buffer,
pos = op.lastPos,
bufferPosition = pos - op.win.position,
minPos = Math.max(op.minPos, bufferPosition);
while (--pos >= minPos && --bufferPosition >= 0) {
if (buffer[bufferPosition] === 0x50) { // quick check that the byte is 'P'
if (buffer.readUInt32LE(bufferPosition) === consts.ENDSIG) { // "PK\005\006"
op = {};
function readCentralDirectoryComplete() {
var buffer = op.win.buffer;
var pos = op.lastBufferPosition;
try {
centralDirectory = new CentralDirectoryHeader();
centralDirectory.read(buffer.slice(bufferPosition, bufferPosition + consts.ENDHDR));
centralDirectory.headerOffset = pos;
centralDirectory.read(buffer.slice(pos, pos + consts.ENDHDR));
centralDirectory.headerOffset = op.win.position + pos;
if (centralDirectory.commentLength)
that.comment = buffer.slice(bufferPosition + consts.ENDHDR,
bufferPosition + consts.ENDHDR + centralDirectory.commentLength).toString();
that.comment = buffer.slice(pos + consts.ENDHDR,
pos + consts.ENDHDR + centralDirectory.commentLength).toString();
else
that.comment = null;
that.entriesCount = centralDirectory.volumeEntries;
that.centralDirectory = centralDirectory;
if (centralDirectory.volumeEntries === consts.EF_ZIP64_OR_16 && centralDirectory.totalEntries === consts.EF_ZIP64_OR_16
|| centralDirectory.size === consts.EF_ZIP64_OR_32 || centralDirectory.offset === consts.EF_ZIP64_OR_32) {
readZip64CentralDirectoryLocator();
} else {
op = {};
readEntries();
}
} catch (err) {
that.emit('error', err);
}
return;
}
function readZip64CentralDirectoryLocator() {
var length = consts.ENDL64HDR;
if (op.lastBufferPosition > length) {
op.lastBufferPosition -= length;
readZip64CentralDirectoryLocatorComplete();
} else {
op = {
win: op.win,
totalReadLength: length,
minPos: op.win.position - length,
lastPos: op.win.position,
chunkSize: op.chunkSize,
firstByte: consts.ENDL64SIGFIRST,
sig: consts.ENDL64SIG,
complete: readZip64CentralDirectoryLocatorComplete
};
op.win.read(op.lastPos - op.chunkSize, op.chunkSize, readUntilFoundCallback);
}
}
function readZip64CentralDirectoryLocatorComplete() {
var buffer = op.win.buffer;
var locHeader = new CentralDirectoryLoc64Header();
locHeader.read(buffer.slice(op.lastBufferPosition, op.lastBufferPosition + consts.ENDL64HDR));
var readLength = fileSize - locHeader.headerOffset;
op = {
win: op.win,
totalReadLength: readLength,
minPos: locHeader.headerOffset,
lastPos: op.lastPos,
chunkSize: op.chunkSize,
firstByte: consts.END64SIGFIRST,
sig: consts.END64SIG,
complete: readZip64CentralDirectoryComplete
};
op.win.read(fileSize - op.chunkSize, op.chunkSize, readUntilFoundCallback);
}
if (pos === minPos) {
return that.emit('error', 'Bad archive format');
}
op.lastPos = pos + 1;
op.chunkSize *= 2;
if (pos <= minPos)
return that.emit('error', 'Bad archive');
var expandLength = Math.min(op.chunkSize, pos - minPos);
op.win.expandLeft(expandLength, readCentralDirectoryCallback);
function readZip64CentralDirectoryComplete() {
var buffer = op.win.buffer;
var zip64cd = new CentralDirectoryZip64Header();
zip64cd.read(buffer.slice(op.lastBufferPosition, op.lastBufferPosition + consts.END64HDR));
that.centralDirectory.volumeEntries = zip64cd.volumeEntries;
that.centralDirectory.totalEntries = zip64cd.totalEntries;
that.centralDirectory.size = zip64cd.size;
that.centralDirectory.offset = zip64cd.offset;
that.entriesCount = zip64cd.volumeEntries;
op = {};
readEntries();
}
function readEntries() {
@ -242,7 +322,7 @@ var StreamZip = function(config) {
if (!entry) {
entry = new ZipEntry();
entry.readHeader(buffer, bufferPos);
entry.headerOffset = op.pos;
entry.headerOffset = op.win.position + bufferPos;
op.entry = entry;
op.pos += consts.CENHDR;
bufferPos += consts.CENHDR;
@ -369,7 +449,7 @@ var StreamZip = function(config) {
function canVerifyCrc(entry) {
// if bit 3 (0x08) of the general-purpose flags field is set, then the CRC-32 and file sizes are not known when the header is written
return (entry.flags & 0x8) != 0x8
return (entry.flags & 0x8) != 0x8;
}
function extract(entry, outPath, callback) {
@ -502,7 +582,7 @@ var CentralDirectoryHeader = function() {
CentralDirectoryHeader.prototype.read = function(data) {
if (data.length != consts.ENDHDR || data.readUInt32LE(0) != consts.ENDSIG)
throw 'Invalid central directoty';
throw 'Invalid central directory';
// number of entries on this volume
this.volumeEntries = data.readUInt16LE(consts.ENDSUB);
// total number of entries
@ -517,6 +597,40 @@ CentralDirectoryHeader.prototype.read = function(data) {
// endregion
// region CentralDirectoryLoc64Header
var CentralDirectoryLoc64Header = function() {
};
CentralDirectoryLoc64Header.prototype.read = function(data) {
if (data.length != consts.ENDL64HDR || data.readUInt32LE(0) != consts.ENDL64SIG)
throw 'Invalid zip64 central directory locator';
// ZIP64 EOCD header offset
this.headerOffset = Util.readUInt64LE(data, consts.ENDSUB);
};
// endregion
// region CentralDirectoryZip64Header
var CentralDirectoryZip64Header = function() {
};
CentralDirectoryZip64Header.prototype.read = function(data) {
if (data.length != consts.END64HDR || data.readUInt32LE(0) != consts.END64SIG)
throw 'Invalid central directory';
// number of entries on this volume
this.volumeEntries = Util.readUInt64LE(data, consts.END64SUB);
// total number of entries
this.totalEntries = Util.readUInt64LE(data, consts.END64TOT);
// central directory size in bytes
this.size = Util.readUInt64LE(data, consts.END64SIZ);
// offset of first CEN header
this.offset = Util.readUInt64LE(data, consts.END64OFF);
};
// endregion
// region ZipEntry
var ZipEntry = function() {
@ -611,18 +725,22 @@ ZipEntry.prototype.readExtra = function(data, offset) {
};
ZipEntry.prototype.parseZip64Extra = function(data, offset, length) {
if (length >= consts.EF_ZIP64_SCOMP && this.size === consts.EF_ZIP64_OR_32)
this.size = this.readUInt64LE(data, offset + consts.EF_ZIP64_SUNCOMP);
if (length >= consts.EF_ZIP64_RHO && this.compressedSize === consts.EF_ZIP64_OR_32)
this.compressedSize = this.readUInt64LE(data, offset + consts.EF_ZIP64_SCOMP);
if (length >= consts.EF_ZIP64_DSN && this.offset === consts.EF_ZIP64_OR_32)
this.offset = this.readUInt64LE(data, offset + consts.EF_ZIP64_RHO);
if (length >= consts.EF_ZIP64_DSN + 4 && this.diskStart === consts.EF_ZIP64_OR_16)
this.diskStart = data.readUInt32LE(consts.EF_ZIP64_DSN);
};
ZipEntry.prototype.readUInt64LE = function(buffer, offset) {
return (buffer.readUInt32LE(offset + 4) << 4) + buffer.readUInt32LE(offset);
if (length >= 8 && this.size === consts.EF_ZIP64_OR_32) {
this.size = Util.readUInt64LE(data, offset);
offset += 8; length -= 8;
}
if (length >= 8 && this.compressedSize === consts.EF_ZIP64_OR_32) {
this.compressedSize = Util.readUInt64LE(data, offset);
offset += 8; length -= 8;
}
if (length >= 8 && this.offset === consts.EF_ZIP64_OR_32) {
this.offset = Util.readUInt64LE(data, offset);
offset += 8; length -= 8;
}
if (length >= 4 && this.diskStart === consts.EF_ZIP64_OR_16) {
this.diskStart = data.readUInt32LE(offset);
// offset += 4; length -= 4;
}
};
Object.defineProperty(ZipEntry.prototype, 'encrypted', {
@ -842,6 +960,16 @@ CrcVerify.getCrcTable = function() {
// endregion
// region Util
var Util = {
readUInt64LE: function(buffer, offset) {
return (buffer.readUInt32LE(offset + 4) * 0x0000000100000000) + buffer.readUInt32LE(offset);
}
};
// endregion
// region exports
module.exports = StreamZip;

View file

@ -1,65 +1,91 @@
{
"name": "node-stream-zip",
"version": "1.2.1",
"description": "node.js library for reading and extraction of ZIP archives",
"keywords": [
"zip",
"archive",
"unzip",
"stream"
"_args": [
[
"node-stream-zip@^1.3.3",
"/Users/Antelle/Documents/Proj/keeweb/electron"
]
],
"homepage": "https://github.com/antelle/node-stream-zip",
"author": {
"name": "Antelle",
"_from": "node-stream-zip@>=1.3.3 <2.0.0",
"_id": "node-stream-zip@1.3.3",
"_inCache": true,
"_installable": true,
"_location": "/node-stream-zip",
"_nodeVersion": "5.7.1",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/node-stream-zip-1.3.3.tgz_1459876107672_0.010327554773539305"
},
"_npmUser": {
"email": "antelle.net@gmail.com",
"name": "antelle"
},
"_npmVersion": "3.6.0",
"_phantomChildren": {},
"_requested": {
"name": "node-stream-zip",
"raw": "node-stream-zip@^1.3.3",
"rawSpec": "^1.3.3",
"scope": null,
"spec": ">=1.3.3 <2.0.0",
"type": "range"
},
"_requiredBy": [
"/"
],
"_shasum": "0094360b2074ae8926d43df0eef976d3897d7207",
"_shrinkwrap": null,
"_spec": "node-stream-zip@^1.3.3",
"_where": "/Users/Antelle/Documents/Proj/keeweb/electron",
"author": {
"email": "antelle.net@gmail.com",
"name": "Antelle",
"url": "https://github.com/antelle"
},
"bugs": {
"url": "https://github.com/antelle/node-stream-zip/issues",
"email": "antelle.net@gmail.com"
"email": "antelle.net@gmail.com",
"url": "https://github.com/antelle/node-stream-zip/issues"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/antelle/node-stream-zip/blob/master/MIT-LICENSE.txt"
}
],
"files": [
"node_stream_zip.js"
],
"scripts": {
"test": "nodeunit test/tests.js"
"dependencies": {},
"description": "node.js library for reading and extraction of ZIP archives",
"devDependencies": {
"nodeunit": "^0.9.1"
},
"main": "node_stream_zip.js",
"repository": {
"type": "git",
"url": "git+https://github.com/antelle/node-stream-zip.git"
"directories": {},
"dist": {
"shasum": "0094360b2074ae8926d43df0eef976d3897d7207",
"tarball": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.3.3.tgz"
},
"engines": {
"node": ">=0.10.0"
},
"devDependencies": {},
"gitHead": "527b59025358dd69ee8d71c4e34798deff3375d3",
"_id": "node-stream-zip@1.2.1",
"_shasum": "98882b14651694added2c5a567ec150d59a30985",
"_from": "node-stream-zip@>=1.2.1 <2.0.0",
"_npmVersion": "2.5.1",
"_nodeVersion": "0.12.0",
"_npmUser": {
"name": "antelle",
"email": "antelle.net@gmail.com"
},
"files": [
"node_stream_zip.js"
],
"gitHead": "269a5cb11f44823e858872b36d6f518406e8bcc2",
"homepage": "https://github.com/antelle/node-stream-zip",
"keywords": [
"archive",
"stream",
"unzip",
"zip"
],
"license": "MIT",
"main": "node_stream_zip.js",
"maintainers": [
{
"name": "antelle",
"email": "antelle.net@gmail.com"
}
],
"dist": {
"shasum": "98882b14651694added2c5a567ec150d59a30985",
"tarball": "http://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.2.1.tgz"
"name": "node-stream-zip",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/antelle/node-stream-zip.git"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.2.1.tgz",
"readme": "ERROR: No README data found!"
"scripts": {
"test": "nodeunit test/tests.js"
},
"version": "1.3.3"
}

View file

@ -1,6 +1,6 @@
{
"name": "KeeWeb",
"version": "1.0.4",
"version": "1.1.4",
"description": "KeePass web app",
"main": "main.js",
"repository": "https://github.com/antelle/keeweb",
@ -8,6 +8,6 @@
"license": "MIT",
"readme": "../README.md",
"dependencies": {
"node-stream-zip": "^1.2.1"
"node-stream-zip": "^1.3.3"
}
}